diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index 99d49f9e0..70c0d2fb9 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -74,10 +74,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newBackupCommand()) -} - // BackupOptions bundles all options for the backup command. type BackupOptions struct { filter.ExcludePatternOptions diff --git a/cmd/restic/cmd_cache.go b/cmd/restic/cmd_cache.go index f9c6c3063..284c94cad 100644 --- a/cmd/restic/cmd_cache.go +++ b/cmd/restic/cmd_cache.go @@ -42,10 +42,6 @@ Exit status is 1 if there was any error. return cmd } -func init() { - cmdRoot.AddCommand(newCacheCommand()) -} - // CacheOptions bundles all options for the snapshots command. type CacheOptions struct { Cleanup bool diff --git a/cmd/restic/cmd_cat.go b/cmd/restic/cmd_cat.go index 6d7e68ac9..983e309dd 100644 --- a/cmd/restic/cmd_cat.go +++ b/cmd/restic/cmd_cat.go @@ -40,10 +40,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newCatCommand()) -} - func validateCatArgs(args []string) error { if len(args) < 1 { return errors.Fatal("type not specified") diff --git a/cmd/restic/cmd_check.go b/cmd/restic/cmd_check.go index 37d39ee68..f87303933 100644 --- a/cmd/restic/cmd_check.go +++ b/cmd/restic/cmd_check.go @@ -67,10 +67,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newCheckCommand()) -} - // CheckOptions bundles all options for the 'check' command. type CheckOptions struct { ReadData bool diff --git a/cmd/restic/cmd_copy.go b/cmd/restic/cmd_copy.go index 8ca78a341..cdf688dfa 100644 --- a/cmd/restic/cmd_copy.go +++ b/cmd/restic/cmd_copy.go @@ -54,10 +54,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newCopyCommand()) -} - // CopyOptions bundles all options for the copy command. type CopyOptions struct { secondaryRepoOptions diff --git a/cmd/restic/cmd_debug.go b/cmd/restic/cmd_debug.go index 9e7f1d38e..7e356b6c5 100644 --- a/cmd/restic/cmd_debug.go +++ b/cmd/restic/cmd_debug.go @@ -29,6 +29,12 @@ import ( "github.com/restic/restic/internal/restic" ) +func registerDebugCommand(cmd *cobra.Command) { + cmd.AddCommand( + newDebugCommand(), + ) +} + func newDebugCommand() *cobra.Command { cmd := &cobra.Command{ Use: "debug", @@ -41,10 +47,6 @@ func newDebugCommand() *cobra.Command { return cmd } -func init() { - cmdRoot.AddCommand(newDebugCommand()) -} - func newDebugDumpCommand() *cobra.Command { cmd := &cobra.Command{ Use: "dump [indexes|snapshots|all|packs]", diff --git a/cmd/restic/cmd_debug_disabled.go b/cmd/restic/cmd_debug_disabled.go new file mode 100644 index 000000000..34d06a467 --- /dev/null +++ b/cmd/restic/cmd_debug_disabled.go @@ -0,0 +1,9 @@ +//go:build !debug + +package main + +import "github.com/spf13/cobra" + +func registerDebugCommand(_ *cobra.Command) { + // No commands to register in non-debug mode +} diff --git a/cmd/restic/cmd_diff.go b/cmd/restic/cmd_diff.go index d8711e90f..35fe97fbb 100644 --- a/cmd/restic/cmd_diff.go +++ b/cmd/restic/cmd_diff.go @@ -60,10 +60,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newDiffCommand()) -} - // DiffOptions collects all options for the diff command. type DiffOptions struct { ShowMetadata bool diff --git a/cmd/restic/cmd_dump.go b/cmd/restic/cmd_dump.go index 9e78dfe82..978b64616 100644 --- a/cmd/restic/cmd_dump.go +++ b/cmd/restic/cmd_dump.go @@ -54,10 +54,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newDumpCommand()) -} - // DumpOptions collects all options for the dump command. type DumpOptions struct { restic.SnapshotFilter diff --git a/cmd/restic/cmd_features.go b/cmd/restic/cmd_features.go index edb84d3f9..7770e6a9f 100644 --- a/cmd/restic/cmd_features.go +++ b/cmd/restic/cmd_features.go @@ -57,7 +57,3 @@ Exit status is 1 if there was any error. return cmd } - -func init() { - cmdRoot.AddCommand(newFeaturesCommand()) -} diff --git a/cmd/restic/cmd_find.go b/cmd/restic/cmd_find.go index 580ef1c7a..d2fa3619a 100644 --- a/cmd/restic/cmd_find.go +++ b/cmd/restic/cmd_find.go @@ -56,10 +56,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newFindCommand()) -} - // FindOptions bundles all options for the find command. type FindOptions struct { Oldest string diff --git a/cmd/restic/cmd_forget.go b/cmd/restic/cmd_forget.go index 04bf92e47..2bfacc4de 100644 --- a/cmd/restic/cmd_forget.go +++ b/cmd/restic/cmd_forget.go @@ -59,10 +59,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newForgetCommand()) -} - type ForgetPolicyCount int var ErrNegativePolicyCount = errors.New("negative values not allowed, use 'unlimited' instead") diff --git a/cmd/restic/cmd_generate.go b/cmd/restic/cmd_generate.go index fb2d89270..5ced5fe01 100644 --- a/cmd/restic/cmd_generate.go +++ b/cmd/restic/cmd_generate.go @@ -36,10 +36,6 @@ Exit status is 1 if there was any error. return cmd } -func init() { - cmdRoot.AddCommand(newGenerateCommand()) -} - type generateOptions struct { ManDir string BashCompletionFile string @@ -56,7 +52,7 @@ func (opts *generateOptions) AddFlags(f *pflag.FlagSet) { f.StringVar(&opts.PowerShellCompletionFile, "powershell-completion", "", "write powershell completion `file` (`-` for stdout)") } -func writeManpages(dir string) error { +func writeManpages(root *cobra.Command, dir string) error { // use a fixed date for the man pages so that generating them is deterministic date, err := time.Parse("Jan 2006", "Jan 2017") if err != nil { @@ -71,7 +67,7 @@ func writeManpages(dir string) error { } Verbosef("writing man pages to directory %v\n", dir) - return doc.GenManTree(cmdRoot, header, dir) + return doc.GenManTree(root, header, dir) } func writeCompletion(filename string, shell string, generate func(w io.Writer) error) (err error) { @@ -119,8 +115,10 @@ func runGenerate(opts generateOptions, args []string) error { return errors.Fatal("the generate command expects no arguments, only options - please see `restic help generate` for usage and flags") } + cmdRoot := newRootCommand() + if opts.ManDir != "" { - err := writeManpages(opts.ManDir) + err := writeManpages(cmdRoot, opts.ManDir) if err != nil { return err } diff --git a/cmd/restic/cmd_init.go b/cmd/restic/cmd_init.go index 0e1da7a78..db2e97c93 100644 --- a/cmd/restic/cmd_init.go +++ b/cmd/restic/cmd_init.go @@ -40,10 +40,6 @@ Exit status is 1 if there was any error. return cmd } -func init() { - cmdRoot.AddCommand(newInitCommand()) -} - // InitOptions bundles all options for the init command. type InitOptions struct { secondaryRepoOptions diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index a94caa0d8..29d38bdce 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -4,17 +4,23 @@ import ( "github.com/spf13/cobra" ) -var cmdKey = &cobra.Command{ - Use: "key", - Short: "Manage keys (passwords)", - Long: ` +func newKeyCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "key", + Short: "Manage keys (passwords)", + Long: ` The "key" command allows you to set multiple access keys or passwords per repository. `, - DisableAutoGenTag: true, - GroupID: cmdGroupDefault, -} + DisableAutoGenTag: true, + GroupID: cmdGroupDefault, + } -func init() { - cmdRoot.AddCommand(cmdKey) + cmd.AddCommand( + newKeyAddCommand(), + newKeyListCommand(), + newKeyPasswdCommand(), + newKeyRemoveCommand(), + ) + return cmd } diff --git a/cmd/restic/cmd_key_add.go b/cmd/restic/cmd_key_add.go index 1bcf50d79..a7670a842 100644 --- a/cmd/restic/cmd_key_add.go +++ b/cmd/restic/cmd_key_add.go @@ -52,10 +52,6 @@ func (opts *KeyAddOptions) Add(flags *pflag.FlagSet) { flags.StringVarP(&opts.Hostname, "host", "", "", "the hostname for new key") } -func init() { - cmdKey.AddCommand(newKeyAddCommand()) -} - func runKeyAdd(ctx context.Context, gopts GlobalOptions, opts KeyAddOptions, args []string) error { if len(args) > 0 { return fmt.Errorf("the key add command expects no arguments, only options - please see `restic help key add` for usage and flags") diff --git a/cmd/restic/cmd_key_list.go b/cmd/restic/cmd_key_list.go index c97955aee..6a0509f0f 100644 --- a/cmd/restic/cmd_key_list.go +++ b/cmd/restic/cmd_key_list.go @@ -38,10 +38,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdKey.AddCommand(newKeyListCommand()) -} - func runKeyList(ctx context.Context, gopts GlobalOptions, args []string) error { if len(args) > 0 { return fmt.Errorf("the key list command expects no arguments, only options - please see `restic help key list` for usage and flags") diff --git a/cmd/restic/cmd_key_passwd.go b/cmd/restic/cmd_key_passwd.go index 71f71955e..378325216 100644 --- a/cmd/restic/cmd_key_passwd.go +++ b/cmd/restic/cmd_key_passwd.go @@ -39,10 +39,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdKey.AddCommand(newKeyPasswdCommand()) -} - type KeyPasswdOptions struct { KeyAddOptions } diff --git a/cmd/restic/cmd_key_remove.go b/cmd/restic/cmd_key_remove.go index e3849eb3d..f6713e4c2 100644 --- a/cmd/restic/cmd_key_remove.go +++ b/cmd/restic/cmd_key_remove.go @@ -35,10 +35,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdKey.AddCommand(newKeyRemoveCommand()) -} - func runKeyRemove(ctx context.Context, gopts GlobalOptions, args []string) error { if len(args) != 1 { return fmt.Errorf("key remove expects one argument as the key id") diff --git a/cmd/restic/cmd_list.go b/cmd/restic/cmd_list.go index db33506ff..cf0cec414 100644 --- a/cmd/restic/cmd_list.go +++ b/cmd/restic/cmd_list.go @@ -41,10 +41,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newListCommand()) -} - func runList(ctx context.Context, gopts GlobalOptions, args []string) error { if len(args) != 1 { return errors.Fatal("type not specified") diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index b9f625efd..7a24d4c9b 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -66,10 +66,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newLsCommand()) -} - // LsOptions collects all options for the ls command. type LsOptions struct { ListLong bool diff --git a/cmd/restic/cmd_migrate.go b/cmd/restic/cmd_migrate.go index 9f07705ce..d4e7d0ac1 100644 --- a/cmd/restic/cmd_migrate.go +++ b/cmd/restic/cmd_migrate.go @@ -45,10 +45,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newMigrateCommand()) -} - // MigrateOptions bundles all options for the 'check' command. type MigrateOptions struct { Force bool diff --git a/cmd/restic/cmd_mount.go b/cmd/restic/cmd_mount.go index 1c48c97cd..15760c6b7 100644 --- a/cmd/restic/cmd_mount.go +++ b/cmd/restic/cmd_mount.go @@ -22,6 +22,10 @@ import ( "github.com/anacrolix/fuse/fs" ) +func registerMountCommand(cmdRoot *cobra.Command) { + cmdRoot.AddCommand(newMountCommand()) +} + func newMountCommand() *cobra.Command { var opts MountOptions @@ -84,10 +88,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newMountCommand()) -} - // MountOptions collects all options for the mount command. type MountOptions struct { OwnerRoot bool diff --git a/cmd/restic/cmd_mount_disabled.go b/cmd/restic/cmd_mount_disabled.go new file mode 100644 index 000000000..8b83905e7 --- /dev/null +++ b/cmd/restic/cmd_mount_disabled.go @@ -0,0 +1,10 @@ +//go:build !darwin && !freebsd && !linux +// +build !darwin,!freebsd,!linux + +package main + +import "github.com/spf13/cobra" + +func registerMountCommand(_ *cobra.Command) { + // Mount command not supported on these platforms +} diff --git a/cmd/restic/cmd_options.go b/cmd/restic/cmd_options.go index f99ba9c04..34cf8656e 100644 --- a/cmd/restic/cmd_options.go +++ b/cmd/restic/cmd_options.go @@ -38,7 +38,3 @@ Exit status is 1 if there was any error. } return cmd } - -func init() { - cmdRoot.AddCommand(newOptionsCommand()) -} diff --git a/cmd/restic/cmd_prune.go b/cmd/restic/cmd_prune.go index 5184b8a75..a613f2255 100644 --- a/cmd/restic/cmd_prune.go +++ b/cmd/restic/cmd_prune.go @@ -51,10 +51,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newPruneCommand()) -} - // PruneOptions collects all options for the cleanup command. type PruneOptions struct { DryRun bool diff --git a/cmd/restic/cmd_recover.go b/cmd/restic/cmd_recover.go index 050fbd056..10284c111 100644 --- a/cmd/restic/cmd_recover.go +++ b/cmd/restic/cmd_recover.go @@ -38,10 +38,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newRecoverCommand()) -} - func runRecover(ctx context.Context, gopts GlobalOptions) error { hostname, err := os.Hostname() if err != nil { diff --git a/cmd/restic/cmd_repair.go b/cmd/restic/cmd_repair.go index 6a1a1f9dc..bb1c98d27 100644 --- a/cmd/restic/cmd_repair.go +++ b/cmd/restic/cmd_repair.go @@ -4,13 +4,18 @@ import ( "github.com/spf13/cobra" ) -var cmdRepair = &cobra.Command{ - Use: "repair", - Short: "Repair the repository", - GroupID: cmdGroupDefault, - DisableAutoGenTag: true, -} +func newRepairCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "repair", + Short: "Repair the repository", + GroupID: cmdGroupDefault, + DisableAutoGenTag: true, + } -func init() { - cmdRoot.AddCommand(cmdRepair) + cmd.AddCommand( + newRepairIndexCommand(), + newRepairPacksCommand(), + newRepairSnapshotsCommand(), + ) + return cmd } diff --git a/cmd/restic/cmd_repair_index.go b/cmd/restic/cmd_repair_index.go index 441232bcb..079b322a9 100644 --- a/cmd/restic/cmd_repair_index.go +++ b/cmd/restic/cmd_repair_index.go @@ -40,10 +40,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRepair.AddCommand(newRepairIndexCommand()) -} - // RepairIndexOptions collects all options for the repair index command. type RepairIndexOptions struct { ReadAllPacks bool @@ -76,11 +72,6 @@ func newRebuildIndexCommand() *cobra.Command { return cmd } -func init() { - // add alias for old name - cmdRoot.AddCommand(newRebuildIndexCommand()) -} - func runRebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOptions, term *termstatus.Terminal) error { ctx, repo, unlock, err := openWithExclusiveLock(ctx, gopts, false) if err != nil { diff --git a/cmd/restic/cmd_repair_packs.go b/cmd/restic/cmd_repair_packs.go index 4b787a2f9..aaaa2f08f 100644 --- a/cmd/restic/cmd_repair_packs.go +++ b/cmd/restic/cmd_repair_packs.go @@ -40,10 +40,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRepair.AddCommand(newRepairPacksCommand()) -} - func runRepairPacks(ctx context.Context, gopts GlobalOptions, term *termstatus.Terminal, args []string) error { ids := restic.NewIDSet() for _, arg := range args { diff --git a/cmd/restic/cmd_repair_snapshots.go b/cmd/restic/cmd_repair_snapshots.go index fb294b02f..ecca7900e 100644 --- a/cmd/restic/cmd_repair_snapshots.go +++ b/cmd/restic/cmd_repair_snapshots.go @@ -57,10 +57,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRepair.AddCommand(newRepairSnapshotsCommand()) -} - // RepairOptions collects all options for the repair command. type RepairOptions struct { DryRun bool diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index 0452322bb..a29b8a19e 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -56,10 +56,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newRestoreCommand()) -} - // RestoreOptions collects all options for the restore command. type RestoreOptions struct { filter.ExcludePatternOptions diff --git a/cmd/restic/cmd_rewrite.go b/cmd/restic/cmd_rewrite.go index 7e295f3df..4e5b39932 100644 --- a/cmd/restic/cmd_rewrite.go +++ b/cmd/restic/cmd_rewrite.go @@ -66,10 +66,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newRewriteCommand()) -} - type snapshotMetadata struct { Hostname string Time *time.Time diff --git a/cmd/restic/cmd_self_update.go b/cmd/restic/cmd_self_update.go index b3a5dbdc7..2247274ac 100644 --- a/cmd/restic/cmd_self_update.go +++ b/cmd/restic/cmd_self_update.go @@ -13,6 +13,12 @@ import ( "github.com/spf13/pflag" ) +func registerSelfUpdateCommand(cmd *cobra.Command) { + cmd.AddCommand( + newSelfUpdateCommand(), + ) +} + func newSelfUpdateCommand() *cobra.Command { var opts SelfUpdateOptions @@ -44,10 +50,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newSelfUpdateCommand()) -} - // SelfUpdateOptions collects all options for the update-restic command. type SelfUpdateOptions struct { Output string diff --git a/cmd/restic/cmd_self_update_disabled.go b/cmd/restic/cmd_self_update_disabled.go new file mode 100644 index 000000000..ce9af10d2 --- /dev/null +++ b/cmd/restic/cmd_self_update_disabled.go @@ -0,0 +1,9 @@ +//go:build !selfupdate + +package main + +import "github.com/spf13/cobra" + +func registerSelfUpdateCommand(_ *cobra.Command) { + // No commands to register in non-selfupdate mode +} diff --git a/cmd/restic/cmd_snapshots.go b/cmd/restic/cmd_snapshots.go index dae5cafe8..65e5753c3 100644 --- a/cmd/restic/cmd_snapshots.go +++ b/cmd/restic/cmd_snapshots.go @@ -44,10 +44,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newSnapshotsCommand()) -} - // SnapshotOptions bundles all options for the snapshots command. type SnapshotOptions struct { restic.SnapshotFilter diff --git a/cmd/restic/cmd_stats.go b/cmd/restic/cmd_stats.go index a906a9be0..1e7df11cb 100644 --- a/cmd/restic/cmd_stats.go +++ b/cmd/restic/cmd_stats.go @@ -73,10 +73,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newStatsCommand()) -} - // StatsOptions collects all options for the stats command. type StatsOptions struct { // the mode of counting to perform (see consts for available modes) diff --git a/cmd/restic/cmd_tag.go b/cmd/restic/cmd_tag.go index f99e1ee9b..39e9a16b5 100644 --- a/cmd/restic/cmd_tag.go +++ b/cmd/restic/cmd_tag.go @@ -50,10 +50,6 @@ Exit status is 12 if the password is incorrect. return cmd } -func init() { - cmdRoot.AddCommand(newTagCommand()) -} - // TagOptions bundles all options for the 'tag' command. type TagOptions struct { restic.SnapshotFilter diff --git a/cmd/restic/cmd_unlock.go b/cmd/restic/cmd_unlock.go index fc5755cb7..5932ffcaa 100644 --- a/cmd/restic/cmd_unlock.go +++ b/cmd/restic/cmd_unlock.go @@ -33,10 +33,6 @@ Exit status is 1 if there was any error. return cmd } -func init() { - cmdRoot.AddCommand(newUnlockCommand()) -} - // UnlockOptions collects all options for the unlock command. type UnlockOptions struct { RemoveAll bool diff --git a/cmd/restic/cmd_version.go b/cmd/restic/cmd_version.go index 57fce5628..533098b9b 100644 --- a/cmd/restic/cmd_version.go +++ b/cmd/restic/cmd_version.go @@ -55,7 +55,3 @@ Exit status is 1 if there was any error. } return cmd } - -func init() { - cmdRoot.AddCommand(newVersionCommand()) -} diff --git a/cmd/restic/flags_test.go b/cmd/restic/flags_test.go index 1ae20119c..b1001b7c5 100644 --- a/cmd/restic/flags_test.go +++ b/cmd/restic/flags_test.go @@ -8,7 +8,7 @@ import ( // TestFlags checks for double defined flags, the commands will panic on // ParseFlags() when a shorthand flag is defined twice. func TestFlags(t *testing.T) { - for _, cmd := range cmdRoot.Commands() { + for _, cmd := range newRootCommand().Commands() { t.Run(cmd.Name(), func(t *testing.T) { cmd.Flags().SetOutput(io.Discard) err := cmd.ParseFlags([]string{"--help"}) diff --git a/cmd/restic/global_release.go b/cmd/restic/global_release.go index 63ad6e17d..2c4f28b13 100644 --- a/cmd/restic/global_release.go +++ b/cmd/restic/global_release.go @@ -5,6 +5,6 @@ package main import "github.com/spf13/cobra" -func registerProfiling(cmd *cobra.Command) { +func registerProfiling(_ *cobra.Command) { // No profiling in release mode } diff --git a/cmd/restic/main.go b/cmd/restic/main.go index 49499a151..72a726b0e 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -29,60 +29,60 @@ func init() { var ErrOK = errors.New("ok") -// cmdRoot is the base command when no other command has been specified. -var cmdRoot = &cobra.Command{ - Use: "restic", - Short: "Backup and restore files", - Long: ` +var cmdGroupDefault = "default" +var cmdGroupAdvanced = "advanced" + +func newRootCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "restic", + Short: "Backup and restore files", + Long: ` restic is a backup program which allows saving multiple revisions of files and directories in an encrypted repository stored on different backends. The full documentation can be found at https://restic.readthedocs.io/ . `, - SilenceErrors: true, - SilenceUsage: true, - DisableAutoGenTag: true, + SilenceErrors: true, + SilenceUsage: true, + DisableAutoGenTag: true, - PersistentPreRunE: func(c *cobra.Command, _ []string) error { - // set verbosity, default is one - globalOptions.verbosity = 1 - if globalOptions.Quiet && globalOptions.Verbose > 0 { - return errors.Fatal("--quiet and --verbose cannot be specified at the same time") - } + PersistentPreRunE: func(c *cobra.Command, _ []string) error { + // set verbosity, default is one + globalOptions.verbosity = 1 + if globalOptions.Quiet && globalOptions.Verbose > 0 { + return errors.Fatal("--quiet and --verbose cannot be specified at the same time") + } - switch { - case globalOptions.Verbose >= 2: - globalOptions.verbosity = 3 - case globalOptions.Verbose > 0: - globalOptions.verbosity = 2 - case globalOptions.Quiet: - globalOptions.verbosity = 0 - } + switch { + case globalOptions.Verbose >= 2: + globalOptions.verbosity = 3 + case globalOptions.Verbose > 0: + globalOptions.verbosity = 2 + case globalOptions.Quiet: + globalOptions.verbosity = 0 + } + + // parse extended options + opts, err := options.Parse(globalOptions.Options) + if err != nil { + return err + } + globalOptions.extended = opts + if !needsPassword(c.Name()) { + return nil + } + pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD") + if err != nil { + fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err) + Exit(1) + } + globalOptions.password = pwd - // parse extended options - opts, err := options.Parse(globalOptions.Options) - if err != nil { - return err - } - globalOptions.extended = opts - if !needsPassword(c.Name()) { return nil - } - pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD") - if err != nil { - fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err) - Exit(1) - } - globalOptions.password = pwd - return nil - }, -} + }, + } -var cmdGroupDefault = "default" -var cmdGroupAdvanced = "advanced" - -func init() { - cmdRoot.AddGroup( + cmd.AddGroup( &cobra.Group{ ID: cmdGroupDefault, Title: "Available Commands:", @@ -93,12 +93,48 @@ func init() { }, ) - globalOptions.AddFlags(cmdRoot.PersistentFlags()) + globalOptions.AddFlags(cmd.PersistentFlags()) // Use our "generate" command instead of the cobra provided "completion" command - cmdRoot.CompletionOptions.DisableDefaultCmd = true + cmd.CompletionOptions.DisableDefaultCmd = true - registerProfiling(cmdRoot) + cmd.AddCommand( + newBackupCommand(), + newCacheCommand(), + newCatCommand(), + newCheckCommand(), + newCopyCommand(), + newDiffCommand(), + newDumpCommand(), + newFeaturesCommand(), + newFindCommand(), + newForgetCommand(), + newGenerateCommand(), + newInitCommand(), + newKeyCommand(), + newListCommand(), + newLsCommand(), + newMigrateCommand(), + newOptionsCommand(), + newPruneCommand(), + newRebuildIndexCommand(), + newRecoverCommand(), + newRepairCommand(), + newRestoreCommand(), + newRewriteCommand(), + newSnapshotsCommand(), + newStatsCommand(), + newTagCommand(), + newUnlockCommand(), + newVersionCommand(), + ) + + registerDebugCommand(cmd) + registerMountCommand(cmd) + registerSelfUpdateCommand(cmd) + registerProfiling(cmd) + + return cmd } // Distinguish commands that need the password from those that work without, @@ -165,7 +201,7 @@ func main() { version, runtime.Version(), runtime.GOOS, runtime.GOARCH) ctx := createGlobalContext() - err = cmdRoot.ExecuteContext(ctx) + err = newRootCommand().ExecuteContext(ctx) if err == nil { err = ctx.Err()