package main import ( "fmt" "log/slog" "os" "github.com/spf13/cobra" "atcr.io/pkg/hold" ) var configFile string var rootCmd = &cobra.Command{ Use: "atcr-hold", Short: "ATCR Hold Service - BYOS blob storage", } var serveCmd = &cobra.Command{ Use: "serve", Short: "Start the hold service", Long: `Start the ATCR hold service with embedded PDS and S3 blob storage. Configuration is loaded in layers: defaults -> YAML file -> environment variables. Use --config to specify a YAML configuration file. Environment variables always override file values.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { cfg, err := hold.LoadConfig(configFile) if err != nil { return fmt.Errorf("failed to load config: %w", err) } server, err := hold.NewHoldServer(cfg) if err != nil { return fmt.Errorf("failed to initialize hold server: %w", err) } return server.Serve() }, } var configCmd = &cobra.Command{ Use: "config", Short: "Configuration management commands", } var configInitCmd = &cobra.Command{ Use: "init [path]", Short: "Generate an example configuration file", Long: `Generate an example YAML configuration file with all available options. If path is provided, writes to that file. Otherwise writes to stdout.`, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { yamlBytes, err := hold.ExampleYAML() if err != nil { return fmt.Errorf("failed to generate example config: %w", err) } if len(args) == 1 { if err := os.WriteFile(args[0], yamlBytes, 0644); err != nil { return fmt.Errorf("failed to write config file: %w", err) } fmt.Fprintf(os.Stderr, "Wrote example config to %s\n", args[0]) return nil } fmt.Print(string(yamlBytes)) return nil }, } func init() { serveCmd.Flags().StringVarP(&configFile, "config", "c", "", "path to YAML configuration file") configCmd.AddCommand(configInitCmd) rootCmd.AddCommand(serveCmd) rootCmd.AddCommand(configCmd) } func main() { if err := rootCmd.Execute(); err != nil { slog.Error("Command failed", "error", err) os.Exit(1) } }