// Package cmd assembles the anchorage Cobra command tree. // // Each sub-command lives in its own file (serve.go, version.go, ...). The // root command is intentionally minimal: it sets up the tree and delegates // all wiring to the composition root in internal/app/anchorage, which is // created lazily by the sub-commands that need it. package cmd import ( "github.com/spf13/cobra" ) // globalFlags carries flags that every subcommand inherits via // PersistentFlags. Exposed as a struct so sub-commands can read them without // re-parsing the command line. type globalFlags struct { configPath string // Admin-only flags, populated by newAdminCmd's PersistentFlags. adminURL string adminToken string } // newRootCmd builds the top-level `anchorage` command. // // A factory is used (rather than a package-global var) so tests can construct // a fresh command tree with isolated flags. func newRootCmd() *cobra.Command { flags := &globalFlags{} root := &cobra.Command{ Use: "anchorage", Short: "anchorage — highly-available IPFS Pinning Service", Long: "anchorage runs the IPFS Pinning Service API, cluster coordination, and WebSocket event fan-out for a paired Kubo daemon.", SilenceUsage: true, SilenceErrors: true, } root.PersistentFlags().StringVarP(&flags.configPath, "config", "c", "", "path to anchorage config file (default: ./configs/anchorage.yaml, $HOME/.anchorage, /etc/anchorage)") root.AddCommand(newVersionCmd()) root.AddCommand(newServeCmd(flags)) root.AddCommand(newMigrateCmd(flags)) root.AddCommand(newAdminCmd(flags)) return root } // Execute runs the anchorage command tree against os.Args. // // It is intentionally the only exported symbol in this package so main.go // stays a thin wrapper. func Execute() error { return newRootCmd().Execute() }