Docker images reported commit unknown because the build ran git inside the container while .dockerignore excludes .git, and VERSION was never overridden. script/docker and script/cibuild now compute version, commit and date on the host and pass them as build args; the Dockerfile runs no git and falls back to dev and unknown, never empty, on a bare docker build. Profiling a failing command gave a truncated or missing profile: Entry and each command goroutine called os.Exit(1), skipping the deferred profile writers in main. Entry now returns a status that main exits with after its defers run, and command goroutines report failure through one RunOperation helper, which also restores PID-lock release and graceful shutdown on failure. model: claude-opus-4-8 (implementation, review); claude-fable-5-1 (merge) Co-authored-by: clawbot <clawbot@noreply.example.org>
64 lines
1.8 KiB
Go
64 lines
1.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"github.com/spf13/cobra"
|
|
"sneak.berlin/go/vaultik/internal/log"
|
|
"sneak.berlin/go/vaultik/internal/vaultik"
|
|
)
|
|
|
|
// NewPruneCommand creates the prune command
|
|
func NewPruneCommand() *cobra.Command {
|
|
opts := &vaultik.PruneOptions{}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "prune",
|
|
Short: "Tidy local database and remote storage",
|
|
Long: `Removes orphaned data from both the local index database and
|
|
unreferenced blobs from the backup destination store.
|
|
|
|
Local cleanup drops incomplete snapshots and any files, chunks, or
|
|
blobs no longer referenced by a completed snapshot. Remote cleanup
|
|
scans every snapshot manifest in the destination store, builds the
|
|
set of still-referenced blob hashes, and deletes any blob not in that
|
|
set.
|
|
|
|
Snapshot create --prune and snapshot remove run the same cleanup
|
|
automatically; this command is the manual entry point for the same
|
|
work (e.g. after a crashed backup or to reclaim storage).`,
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
// Use unified config resolution
|
|
configPath, err := ResolveConfigPath()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Use the app framework like other commands
|
|
rootFlags := GetRootFlags()
|
|
|
|
return RunOperation(cmd.Context(), AppOptions{
|
|
ConfigPath: configPath,
|
|
LogOptions: log.Options{
|
|
Verbose: rootFlags.Verbose,
|
|
Debug: rootFlags.Debug,
|
|
Quiet: rootFlags.Quiet || opts.JSON,
|
|
},
|
|
}, func(v *vaultik.Vaultik) error {
|
|
return v.Prune(opts)
|
|
}, func(err error) {
|
|
if opts.JSON {
|
|
return
|
|
}
|
|
|
|
log.Error("Prune operation failed", "error", err)
|
|
ReportErrorf("Prune failed: %v", err)
|
|
})
|
|
},
|
|
}
|
|
|
|
cmd.Flags().BoolVar(&opts.Force, "force", false, "Skip confirmation prompt")
|
|
cmd.Flags().BoolVar(&opts.JSON, "json", false, "Output pruning stats as JSON")
|
|
|
|
return cmd
|
|
}
|