package cli import ( "context" "os" "git.eeqj.de/sneak/vaultik/internal/log" "git.eeqj.de/sneak/vaultik/internal/vaultik" "github.com/spf13/cobra" "go.uber.org/fx" ) // NewRemoteCommand creates the remote command and subcommands func NewRemoteCommand() *cobra.Command { cmd := &cobra.Command{ Use: "remote", Short: "Remote storage management commands", Long: "Commands for inspecting and managing remote storage", } // Add subcommands cmd.AddCommand(newRemoteInfoCommand()) return cmd } // newRemoteInfoCommand creates the 'remote info' subcommand func newRemoteInfoCommand() *cobra.Command { var jsonOutput bool cmd := &cobra.Command{ Use: "info", Short: "Display remote storage information", Long: `Shows detailed information about remote storage, including: - Size of all snapshot metadata (per snapshot and total) - Count and total size of all blobs - Count and size of referenced blobs (from all manifests) - Count and size of orphaned blobs (not referenced by any manifest)`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { // Use unified config resolution configPath, err := ResolveConfigPath() if err != nil { return err } rootFlags := GetRootFlags() return RunWithApp(cmd.Context(), AppOptions{ ConfigPath: configPath, LogOptions: log.LogOptions{ Verbose: rootFlags.Verbose, Debug: rootFlags.Debug, Quiet: rootFlags.Quiet || jsonOutput, }, 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 { go func() { if err := v.RemoteInfo(jsonOutput); err != nil { if err != context.Canceled { if !jsonOutput { log.Error("Failed to get remote info", "error", err) } os.Exit(1) } } if err := v.Shutdowner.Shutdown(); err != nil { log.Error("Failed to shutdown", "error", err) } }() return nil }, OnStop: func(ctx context.Context) error { v.Cancel() return nil }, }) }), }, }) }, } cmd.Flags().BoolVar(&jsonOutput, "json", false, "Output in JSON format") return cmd }