package cli import ( "context" "fmt" "os" "git.eeqj.de/sneak/vaultik/internal/log" "git.eeqj.de/sneak/vaultik/internal/vaultik" "github.com/spf13/cobra" "go.uber.org/fx" ) // PurgeOptions contains options for the purge command type PurgeOptions struct { KeepLatest bool OlderThan string Force bool } // NewPurgeCommand creates the purge command func NewPurgeCommand() *cobra.Command { opts := &PurgeOptions{} cmd := &cobra.Command{ Use: "purge", Short: "Purge old snapshots", Long: `Removes snapshots based on age or count criteria. This command allows you to: - Keep only the latest snapshot (--keep-latest) - Remove snapshots older than a specific duration (--older-than) Config is located at /etc/vaultik/config.yml by default, but can be overridden by specifying a path using --config or by setting VAULTIK_CONFIG to a path.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { // Validate flags if !opts.KeepLatest && opts.OlderThan == "" { return fmt.Errorf("must specify either --keep-latest or --older-than") } if opts.KeepLatest && opts.OlderThan != "" { return fmt.Errorf("cannot specify both --keep-latest and --older-than") } // Use unified config resolution configPath, err := ResolveConfigPath() if err != nil { return err } // Use the app framework like other commands rootFlags := GetRootFlags() return RunWithApp(cmd.Context(), AppOptions{ ConfigPath: configPath, LogOptions: log.LogOptions{ Verbose: rootFlags.Verbose, Debug: rootFlags.Debug, }, Modules: []fx.Option{}, Invokes: []fx.Option{ fx.Invoke(func(v *vaultik.Vaultik, lc fx.Lifecycle) { lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { // Start the purge operation in a goroutine go func() { // Run the purge operation if err := v.PurgeSnapshots(opts.KeepLatest, opts.OlderThan, opts.Force); err != nil { if err != context.Canceled { log.Error("Purge operation failed", "error", err) os.Exit(1) } } // Shutdown the app when purge completes if err := v.Shutdowner.Shutdown(); err != nil { log.Error("Failed to shutdown", "error", err) } }() return nil }, OnStop: func(ctx context.Context) error { log.Debug("Stopping purge operation") v.Cancel() return nil }, }) }), }, }) }, } cmd.Flags().BoolVar(&opts.KeepLatest, "keep-latest", false, "Keep only the latest snapshot") cmd.Flags().StringVar(&opts.OlderThan, "older-than", "", "Remove snapshots older than duration (e.g. 30d, 6m, 1y)") cmd.Flags().BoolVar(&opts.Force, "force", false, "Skip confirmation prompts") return cmd }