4bfc246be4
REQ-041: ORCA_HOME is now the single namespace root for all components
(db, certs, init, daemon). store.Open("") and init command both
route through certpaths.Dir()/DBPath() instead of hardcoding ~/.orca.
Backward compatible: empty ORCA_HOME -> ~/.orca.
REQ-042: --system persistent flag on rootCmd sets ORCA_HOME=/root/.orca
via PersistentPreRunE. Errors on conflict with pre-set ORCA_HOME.
Tests: 7 new tests in namespace_test.go (default, ORCA_HOME override,
--system sets root, conflict detection, init --json, flag registered).
Full suite passes (no regressions).
Docs: docs/namespace.md covers default, ORCA_HOME, --system, ORCA_DB,
resolution order, and path layout tables.
---ci---
project: orca
phase: 1
milestone: v0.5
status: verify
---/ci---
71 lines
1.7 KiB
Go
71 lines
1.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
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)
|
|
}
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var (
|
|
jsonOutput bool
|
|
systemNamespace bool
|
|
)
|
|
|
|
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)")
|
|
}
|
|
|
|
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)
|
|
}
|