package cli import ( "context" "encoding/json" "fmt" "os" "github.com/spf13/cobra" "git.cloudinit.dev/coreci/orca/internal/config" ) type configCtxKey struct{} var ( version = "0.1.0-dev" gitCommit = "unknown" buildTime = "unknown" ) const systemNamespaceRoot = "/root/.orca" var rootCmd = &cobra.Command{ Use: "orca", Short: "Orca — offline/CLI-first orchestration engine", Long: `Orca is a minimalist, offline-first, CLI-first orchestration engine inspired by HashiCorp Nomad, prioritizing stability, security, and simplicity over feature richness.`, SilenceUsage: true, SilenceErrors: true, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if systemNamespace { if existing := os.Getenv("ORCA_HOME"); existing != "" && existing != systemNamespaceRoot { return fmt.Errorf("--system conflicts with ORCA_HOME=%q (already set); unset ORCA_HOME or drop --system", existing) } if err := os.Setenv("ORCA_HOME", systemNamespaceRoot); err != nil { return fmt.Errorf("set ORCA_HOME for --system: %w", err) } } if configPath != "" { cfg, err := config.Load(configPath) if err != nil { return fmt.Errorf("load config %s: %w", configPath, err) } cmd.SetContext(context.WithValue(cmd.Context(), configCtxKey{}, cfg)) } return nil }, } var ( jsonOutput bool systemNamespace bool configPath string ) func init() { rootCmd.PersistentFlags().BoolVar(&jsonOutput, "json", false, "output in JSON format") rootCmd.PersistentFlags().BoolVar(&systemNamespace, "system", false, "use system-level namespace root (/root/.orca) instead of user-level (~/.orca)") rootCmd.PersistentFlags().StringVar(&configPath, "config", "", "path to config.hcl (overrides ~/.orca/config.hcl)") } func configFromCtx(ctx context.Context) *config.Config { if v, ok := ctx.Value(configCtxKey{}).(*config.Config); ok { return v } return nil } func Execute() error { return rootCmd.Execute() } func printJSON(v any) error { enc := json.NewEncoder(rootCmd.OutOrStdout()) enc.SetIndent("", " ") return enc.Encode(v) } func printText(format string, args ...any) { fmt.Fprintf(rootCmd.OutOrStdout(), format, args...) } func printResult(text string, jsonObj any) { if jsonOutput { _ = printJSON(jsonObj) return } printText("%s\n", text) }