Files
orca/internal/cli/root.go
T
Jon Chery fc94326b0e feat(P00): deprecation sweep + bash tooling gate + render contract + doc banners (v0.9 P00)
P00 — Re-architecture Foundation (deprecation/migration/test-infra/persona/docs).

Deprecation sweep (REQ-068, REQ-072, REQ-089):
- Add // Deprecated: doc comments to internal/daemon (R-001), internal/transport
  (REQ-073), internal/security/ca.go+csr.go (D-101/REQ-076), internal/engine/
  dispatcher.go+peer.go (CLI-side scheduler), internal/cli/daemon.go.
- orca daemon emits slog.Warn deprecation banner on every run (ungated); fires
  R-001 + v0.10-P05 drain-and-stop + v0.10-P14 deletion.
- orca cert and orca node join (mTLS path) emit deprecation warnings; proxmox
  SSH path (the v0.9 replacement) does not warn.
- Add --no-deprecation-warnings global flag on root command (PersistentPreRunE)
  for orca upgrade migrations.
- 12 new daemon/cert/node deprecation tests in internal/cli/daemon_test.go
  (cli coverage 81.9%, warnDeprecated 100%).
- Add DEPRECATED banners to v0.8 sections of ARCHITECTURE.md (verified the
  v0.9 supersession section + Supersession Table from prior turn are present).

Bash tooling gate (grill C-06, C-15, C-16, C-17, C-18):
- scripts/tests/test_helper.bash + example_test.bash — bats framework + helpers.
- scripts/lib/orca-log.sh — slog-compatible JSON logging to syslog (C-17).
- scripts/orca-verify-render.sh — render-contract validator skeleton (C-16).
- scripts/tests/orca-log_test.bash + orca-verify-render_test.bash — 20 bats
  tests total (happy + failure paths per C-15).
- .shellcheckrc — project shellcheck config.
- Makefile: test-bash + lint-bash targets (graceful skip if tools missing);
  wired into test + lint targets.
- internal/emit/contract.go + contract_test.go — versioned JSON render
  contract (orca.emit/v1) between Go emitters and bash appliers (C-16).
- .ciagent/BASH_CAPABILITY_MAP_v0.9.md — maps shipped internal/transport
  capabilities to bash-side equivalents or accepted drops (C-18).
- D-186 recorded in PROJECT.md: bash exempt from Go coverage gate; compensating
  control is bats + shellcheck + shfmt (C-06).

verify-reqs: 90 requirements consistent. Build/test/lint/fmt all green.
20 bats tests pass. Go tests pass. No v0.8 code deleted — only marked deprecated
(deletion deferred to v0.10-P14 per REQ-090 dual-write window).

---ci---
project: orca
phase: P00
milestone: v0.9
status: execute
---/ci---
2026-08-05 16:26:26 +00:00

105 lines
2.8 KiB
Go

package cli
import (
"context"
"encoding/json"
"fmt"
"log/slog"
"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
noDeprecationWarnings 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)")
rootCmd.PersistentFlags().StringVar(&configPath, "config", "", "path to config.hcl (overrides ~/.orca/config.hcl)")
rootCmd.PersistentFlags().BoolVar(&noDeprecationWarnings, "no-deprecation-warnings", false, "suppress v0.9 deprecation warnings (use during `orca upgrade` migrations)")
}
// warnDeprecated emits a v0.9 deprecation warning via slog.Warn unless
// the --no-deprecation-warnings global flag is set. Callers pass a
// human-readable message describing what changed. REQ-068.
func warnDeprecated(msg string) {
if noDeprecationWarnings {
return
}
slog.Warn(msg)
}
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)
}