move cli flags into AddFlags on option structs

This commit is contained in:
Michael Eischer 2025-02-06 21:52:02 +01:00
parent da47967316
commit dc9b6378f3
24 changed files with 307 additions and 231 deletions

View File

@ -15,6 +15,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"github.com/restic/restic/internal/archiver"
@ -97,6 +98,55 @@ type BackupOptions struct {
SkipIfUnchanged bool
}
func (opts *BackupOptions) AddFlags(f *pflag.FlagSet) {
f.StringVar(&opts.Parent, "parent", "", "use this parent `snapshot` (default: latest snapshot in the group determined by --group-by and not newer than the timestamp determined by --time)")
opts.GroupBy = restic.SnapshotGroupByOptions{Host: true, Path: true}
f.VarP(&opts.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma (disable grouping with '')")
f.BoolVarP(&opts.Force, "force", "f", false, `force re-reading the source files/directories (overrides the "parent" flag)`)
opts.ExcludePatternOptions.Add(f)
f.BoolVarP(&opts.ExcludeOtherFS, "one-file-system", "x", false, "exclude other file systems, don't cross filesystem boundaries and subvolumes")
f.StringArrayVar(&opts.ExcludeIfPresent, "exclude-if-present", nil, "takes `filename[:header]`, exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)")
f.BoolVar(&opts.ExcludeCaches, "exclude-caches", false, `excludes cache directories that are marked with a CACHEDIR.TAG file. See https://bford.info/cachedir/ for the Cache Directory Tagging Standard`)
f.StringVar(&opts.ExcludeLargerThan, "exclude-larger-than", "", "max `size` of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)")
f.BoolVar(&opts.Stdin, "stdin", false, "read backup from stdin")
f.StringVar(&opts.StdinFilename, "stdin-filename", "stdin", "`filename` to use when reading from stdin")
f.BoolVar(&opts.StdinCommand, "stdin-from-command", false, "interpret arguments as command to execute and store its stdout")
f.Var(&opts.Tags, "tag", "add `tags` for the new snapshot in the format `tag[,tag,...]` (can be specified multiple times)")
f.UintVar(&opts.ReadConcurrency, "read-concurrency", 0, "read `n` files concurrently (default: $RESTIC_READ_CONCURRENCY or 2)")
f.StringVarP(&opts.Host, "host", "H", "", "set the `hostname` for the snapshot manually (default: $RESTIC_HOST). To prevent an expensive rescan use the \"parent\" flag")
f.StringVar(&opts.Host, "hostname", "", "set the `hostname` for the snapshot manually")
err := f.MarkDeprecated("hostname", "use --host")
if err != nil {
// MarkDeprecated only returns an error when the flag could not be found
panic(err)
}
f.StringArrayVar(&opts.FilesFrom, "files-from", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringArrayVar(&opts.FilesFromVerbatim, "files-from-verbatim", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringArrayVar(&opts.FilesFromRaw, "files-from-raw", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringVar(&opts.TimeStamp, "time", "", "`time` of the backup (ex. '2012-11-01 22:08:41') (default: now)")
f.BoolVar(&opts.WithAtime, "with-atime", false, "store the atime for all files and directories")
f.BoolVar(&opts.IgnoreInode, "ignore-inode", false, "ignore inode number and ctime changes when checking for modified files")
f.BoolVar(&opts.IgnoreCtime, "ignore-ctime", false, "ignore ctime changes when checking for modified files")
f.BoolVarP(&opts.DryRun, "dry-run", "n", false, "do not upload or write any data, just show what would be done")
f.BoolVar(&opts.NoScan, "no-scan", false, "do not run scanner to estimate size of backup")
if runtime.GOOS == "windows" {
f.BoolVar(&opts.UseFsSnapshot, "use-fs-snapshot", false, "use filesystem snapshot where possible (currently only Windows VSS)")
f.BoolVar(&opts.ExcludeCloudFiles, "exclude-cloud-files", false, "excludes online-only cloud files (such as OneDrive Files On-Demand)")
}
f.BoolVar(&opts.SkipIfUnchanged, "skip-if-unchanged", false, "skip snapshot creation if identical to parent snapshot")
// parse read concurrency from env, on error the default value will be used
readConcurrency, _ := strconv.ParseUint(os.Getenv("RESTIC_READ_CONCURRENCY"), 10, 32)
opts.ReadConcurrency = uint(readConcurrency)
// parse host from env, if not exists or empty the default value will be used
if host := os.Getenv("RESTIC_HOST"); host != "" {
opts.Host = host
}
}
var backupOptions BackupOptions
var backupFSTestHook func(fs fs.FS) fs.FS
@ -105,54 +155,7 @@ var ErrInvalidSourceData = errors.New("at least one source file could not be rea
func init() {
cmdRoot.AddCommand(cmdBackup)
f := cmdBackup.Flags()
f.StringVar(&backupOptions.Parent, "parent", "", "use this parent `snapshot` (default: latest snapshot in the group determined by --group-by and not newer than the timestamp determined by --time)")
backupOptions.GroupBy = restic.SnapshotGroupByOptions{Host: true, Path: true}
f.VarP(&backupOptions.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma (disable grouping with '')")
f.BoolVarP(&backupOptions.Force, "force", "f", false, `force re-reading the source files/directories (overrides the "parent" flag)`)
backupOptions.ExcludePatternOptions.Add(f)
f.BoolVarP(&backupOptions.ExcludeOtherFS, "one-file-system", "x", false, "exclude other file systems, don't cross filesystem boundaries and subvolumes")
f.StringArrayVar(&backupOptions.ExcludeIfPresent, "exclude-if-present", nil, "takes `filename[:header]`, exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)")
f.BoolVar(&backupOptions.ExcludeCaches, "exclude-caches", false, `excludes cache directories that are marked with a CACHEDIR.TAG file. See https://bford.info/cachedir/ for the Cache Directory Tagging Standard`)
f.StringVar(&backupOptions.ExcludeLargerThan, "exclude-larger-than", "", "max `size` of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)")
f.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin")
f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "`filename` to use when reading from stdin")
f.BoolVar(&backupOptions.StdinCommand, "stdin-from-command", false, "interpret arguments as command to execute and store its stdout")
f.Var(&backupOptions.Tags, "tag", "add `tags` for the new snapshot in the format `tag[,tag,...]` (can be specified multiple times)")
f.UintVar(&backupOptions.ReadConcurrency, "read-concurrency", 0, "read `n` files concurrently (default: $RESTIC_READ_CONCURRENCY or 2)")
f.StringVarP(&backupOptions.Host, "host", "H", "", "set the `hostname` for the snapshot manually (default: $RESTIC_HOST). To prevent an expensive rescan use the \"parent\" flag")
f.StringVar(&backupOptions.Host, "hostname", "", "set the `hostname` for the snapshot manually")
err := f.MarkDeprecated("hostname", "use --host")
if err != nil {
// MarkDeprecated only returns an error when the flag could not be found
panic(err)
}
f.StringArrayVar(&backupOptions.FilesFrom, "files-from", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringArrayVar(&backupOptions.FilesFromVerbatim, "files-from-verbatim", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringArrayVar(&backupOptions.FilesFromRaw, "files-from-raw", nil, "read the files to backup from `file` (can be combined with file args; can be specified multiple times)")
f.StringVar(&backupOptions.TimeStamp, "time", "", "`time` of the backup (ex. '2012-11-01 22:08:41') (default: now)")
f.BoolVar(&backupOptions.WithAtime, "with-atime", false, "store the atime for all files and directories")
f.BoolVar(&backupOptions.IgnoreInode, "ignore-inode", false, "ignore inode number and ctime changes when checking for modified files")
f.BoolVar(&backupOptions.IgnoreCtime, "ignore-ctime", false, "ignore ctime changes when checking for modified files")
f.BoolVarP(&backupOptions.DryRun, "dry-run", "n", false, "do not upload or write any data, just show what would be done")
f.BoolVar(&backupOptions.NoScan, "no-scan", false, "do not run scanner to estimate size of backup")
if runtime.GOOS == "windows" {
f.BoolVar(&backupOptions.UseFsSnapshot, "use-fs-snapshot", false, "use filesystem snapshot where possible (currently only Windows VSS)")
f.BoolVar(&backupOptions.ExcludeCloudFiles, "exclude-cloud-files", false, "excludes online-only cloud files (such as OneDrive Files On-Demand)")
}
f.BoolVar(&backupOptions.SkipIfUnchanged, "skip-if-unchanged", false, "skip snapshot creation if identical to parent snapshot")
// parse read concurrency from env, on error the default value will be used
readConcurrency, _ := strconv.ParseUint(os.Getenv("RESTIC_READ_CONCURRENCY"), 10, 32)
backupOptions.ReadConcurrency = uint(readConcurrency)
// parse host from env, if not exists or empty the default value will be used
if host := os.Getenv("RESTIC_HOST"); host != "" {
backupOptions.Host = host
}
backupOptions.AddFlags(cmdBackup.Flags())
}
// filterExisting returns a slice of all existing items, or an error if no

View File

@ -13,6 +13,7 @@ import (
"github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/table"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdCache = &cobra.Command{
@ -41,15 +42,17 @@ type CacheOptions struct {
NoSize bool
}
func (opts *CacheOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.Cleanup, "cleanup", false, "remove old cache directories")
f.UintVar(&opts.MaxAge, "max-age", 30, "max age in `days` for cache directories to be considered old")
f.BoolVar(&opts.NoSize, "no-size", false, "do not output the size of the cache directories")
}
var cacheOptions CacheOptions
func init() {
cmdRoot.AddCommand(cmdCache)
f := cmdCache.Flags()
f.BoolVar(&cacheOptions.Cleanup, "cleanup", false, "remove old cache directories")
f.UintVar(&cacheOptions.MaxAge, "max-age", 30, "max age in `days` for cache directories to be considered old")
f.BoolVar(&cacheOptions.NoSize, "no-size", false, "do not output the size of the cache directories")
cacheOptions.AddFlags(cmdCache.Flags())
}
func runCache(opts CacheOptions, gopts GlobalOptions, args []string) error {

View File

@ -11,6 +11,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/restic/restic/internal/backend/cache"
"github.com/restic/restic/internal/checker"
@ -68,14 +69,9 @@ type CheckOptions struct {
WithCache bool
}
var checkOptions CheckOptions
func init() {
cmdRoot.AddCommand(cmdCheck)
f := cmdCheck.Flags()
f.BoolVar(&checkOptions.ReadData, "read-data", false, "read all data blobs")
f.StringVar(&checkOptions.ReadDataSubset, "read-data-subset", "", "read a `subset` of data packs, specified as 'n/t' for specific part, or either 'x%' or 'x.y%' or a size in bytes with suffixes k/K, m/M, g/G, t/T for a random subset")
func (opts *CheckOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.ReadData, "read-data", false, "read all data blobs")
f.StringVar(&opts.ReadDataSubset, "read-data-subset", "", "read a `subset` of data packs, specified as 'n/t' for specific part, or either 'x%' or 'x.y%' or a size in bytes with suffixes k/K, m/M, g/G, t/T for a random subset")
var ignored bool
f.BoolVar(&ignored, "check-unused", false, "find unused blobs")
err := f.MarkDeprecated("check-unused", "`--check-unused` is deprecated and will be ignored")
@ -83,7 +79,14 @@ func init() {
// MarkDeprecated only returns an error when the flag is not found
panic(err)
}
f.BoolVar(&checkOptions.WithCache, "with-cache", false, "use existing cache, only read uncached data from repository")
f.BoolVar(&opts.WithCache, "with-cache", false, "use existing cache, only read uncached data from repository")
}
var checkOptions CheckOptions
func init() {
cmdRoot.AddCommand(cmdCheck)
checkOptions.AddFlags(cmdCheck.Flags())
}
func checkFlags(opts CheckOptions) error {

View File

@ -11,6 +11,7 @@ import (
"golang.org/x/sync/errgroup"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdCopy = &cobra.Command{
@ -53,14 +54,16 @@ type CopyOptions struct {
restic.SnapshotFilter
}
func (opts *CopyOptions) AddFlags(f *pflag.FlagSet) {
initSecondaryRepoOptions(f, &opts.secondaryRepoOptions, "destination", "to copy snapshots from")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
}
var copyOptions CopyOptions
func init() {
cmdRoot.AddCommand(cmdCopy)
f := cmdCopy.Flags()
initSecondaryRepoOptions(f, &copyOptions.secondaryRepoOptions, "destination", "to copy snapshots from")
initMultiSnapshotFilter(f, &copyOptions.SnapshotFilter, true)
copyOptions.AddFlags(cmdCopy.Flags())
}
func runCopy(ctx context.Context, opts CopyOptions, gopts GlobalOptions, args []string) error {

View File

@ -18,6 +18,7 @@ import (
"github.com/klauspost/compress/zstd"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"github.com/restic/restic/internal/crypto"
@ -64,16 +65,20 @@ type DebugExamineOptions struct {
ReuploadBlobs bool
}
func (opts *DebugExamineOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.ExtractPack, "extract-pack", false, "write blobs to the current directory")
f.BoolVar(&opts.ReuploadBlobs, "reupload-blobs", false, "reupload blobs to the repository")
f.BoolVar(&opts.TryRepair, "try-repair", false, "try to repair broken blobs with single bit flips")
f.BoolVar(&opts.RepairByte, "repair-byte", false, "try to repair broken blobs by trying bytes")
}
var debugExamineOpts DebugExamineOptions
func init() {
cmdRoot.AddCommand(cmdDebug)
cmdDebug.AddCommand(cmdDebugDump)
cmdDebug.AddCommand(cmdDebugExamine)
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.ExtractPack, "extract-pack", false, "write blobs to the current directory")
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.ReuploadBlobs, "reupload-blobs", false, "reupload blobs to the repository")
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.TryRepair, "try-repair", false, "try to repair broken blobs with single bit flips")
cmdDebugExamine.Flags().BoolVar(&debugExamineOpts.RepairByte, "repair-byte", false, "try to repair broken blobs by trying bytes")
debugExamineOpts.AddFlags(cmdDebugExamine.Flags())
}
func prettyPrintJSON(wr io.Writer, item interface{}) error {

View File

@ -12,6 +12,7 @@ import (
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdDiff = &cobra.Command{
@ -57,13 +58,15 @@ type DiffOptions struct {
ShowMetadata bool
}
func (opts *DiffOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.ShowMetadata, "metadata", false, "print changes in metadata")
}
var diffOptions DiffOptions
func init() {
cmdRoot.AddCommand(cmdDiff)
f := cmdDiff.Flags()
f.BoolVar(&diffOptions.ShowMetadata, "metadata", false, "print changes in metadata")
diffOptions.AddFlags(cmdDiff.Flags())
}
func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.LoaderUnpacked, desc string) (*restic.Snapshot, string, error) {

View File

@ -13,6 +13,7 @@ import (
"github.com/restic/restic/internal/restic"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdDump = &cobra.Command{
@ -54,15 +55,17 @@ type DumpOptions struct {
Target string
}
func (opts *DumpOptions) AddFlags(f *pflag.FlagSet) {
initSingleSnapshotFilter(f, &opts.SnapshotFilter)
f.StringVarP(&opts.Archive, "archive", "a", "tar", "set archive `format` as \"tar\" or \"zip\"")
f.StringVarP(&opts.Target, "target", "t", "", "write the output to target `path`")
}
var dumpOptions DumpOptions
func init() {
cmdRoot.AddCommand(cmdDump)
flags := cmdDump.Flags()
initSingleSnapshotFilter(flags, &dumpOptions.SnapshotFilter)
flags.StringVarP(&dumpOptions.Archive, "archive", "a", "tar", "set archive `format` as \"tar\" or \"zip\"")
flags.StringVarP(&dumpOptions.Target, "target", "t", "", "write the output to target `path`")
dumpOptions.AddFlags(cmdDump.Flags())
}
func splitPath(p string) []string {

View File

@ -8,6 +8,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
@ -62,25 +63,27 @@ type FindOptions struct {
restic.SnapshotFilter
}
func (opts *FindOptions) AddFlags(f *pflag.FlagSet) {
f.StringVarP(&opts.Oldest, "oldest", "O", "", "oldest modification date/time")
f.StringVarP(&opts.Newest, "newest", "N", "", "newest modification date/time")
f.StringArrayVarP(&opts.Snapshots, "snapshot", "s", nil, "snapshot `id` to search in (can be given multiple times)")
f.BoolVar(&opts.BlobID, "blob", false, "pattern is a blob-ID")
f.BoolVar(&opts.TreeID, "tree", false, "pattern is a tree-ID")
f.BoolVar(&opts.PackID, "pack", false, "pattern is a pack-ID")
f.BoolVar(&opts.ShowPackID, "show-pack-id", false, "display the pack-ID the blobs belong to (with --blob or --tree)")
f.BoolVarP(&opts.CaseInsensitive, "ignore-case", "i", false, "ignore case for pattern")
f.BoolVarP(&opts.Reverse, "reverse", "R", false, "reverse sort order oldest to newest")
f.BoolVarP(&opts.ListLong, "long", "l", false, "use a long listing format showing size and mode")
f.BoolVar(&opts.HumanReadable, "human-readable", false, "print sizes in human readable format")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
}
var findOptions FindOptions
func init() {
cmdRoot.AddCommand(cmdFind)
f := cmdFind.Flags()
f.StringVarP(&findOptions.Oldest, "oldest", "O", "", "oldest modification date/time")
f.StringVarP(&findOptions.Newest, "newest", "N", "", "newest modification date/time")
f.StringArrayVarP(&findOptions.Snapshots, "snapshot", "s", nil, "snapshot `id` to search in (can be given multiple times)")
f.BoolVar(&findOptions.BlobID, "blob", false, "pattern is a blob-ID")
f.BoolVar(&findOptions.TreeID, "tree", false, "pattern is a tree-ID")
f.BoolVar(&findOptions.PackID, "pack", false, "pattern is a pack-ID")
f.BoolVar(&findOptions.ShowPackID, "show-pack-id", false, "display the pack-ID the blobs belong to (with --blob or --tree)")
f.BoolVarP(&findOptions.CaseInsensitive, "ignore-case", "i", false, "ignore case for pattern")
f.BoolVarP(&findOptions.Reverse, "reverse", "R", false, "reverse sort order oldest to newest")
f.BoolVarP(&findOptions.ListLong, "long", "l", false, "use a long listing format showing size and mode")
f.BoolVar(&findOptions.HumanReadable, "human-readable", false, "print sizes in human readable format")
initMultiSnapshotFilter(f, &findOptions.SnapshotFilter, true)
findOptions.AddFlags(cmdFind.Flags())
}
type findPattern struct {

View File

@ -11,6 +11,7 @@ import (
"github.com/restic/restic/internal/restic"
"github.com/restic/restic/internal/ui/termstatus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdForget = &cobra.Command{
@ -111,44 +112,46 @@ type ForgetOptions struct {
Prune bool
}
var forgetOptions ForgetOptions
var forgetPruneOptions PruneOptions
func (opts *ForgetOptions) AddFlags(f *pflag.FlagSet) {
f.VarP(&opts.Last, "keep-last", "l", "keep the last `n` snapshots (use 'unlimited' to keep all snapshots)")
f.VarP(&opts.Hourly, "keep-hourly", "H", "keep the last `n` hourly snapshots (use 'unlimited' to keep all hourly snapshots)")
f.VarP(&opts.Daily, "keep-daily", "d", "keep the last `n` daily snapshots (use 'unlimited' to keep all daily snapshots)")
f.VarP(&opts.Weekly, "keep-weekly", "w", "keep the last `n` weekly snapshots (use 'unlimited' to keep all weekly snapshots)")
f.VarP(&opts.Monthly, "keep-monthly", "m", "keep the last `n` monthly snapshots (use 'unlimited' to keep all monthly snapshots)")
f.VarP(&opts.Yearly, "keep-yearly", "y", "keep the last `n` yearly snapshots (use 'unlimited' to keep all yearly snapshots)")
f.VarP(&opts.Within, "keep-within", "", "keep snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&opts.WithinHourly, "keep-within-hourly", "", "keep hourly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&opts.WithinDaily, "keep-within-daily", "", "keep daily snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&opts.WithinWeekly, "keep-within-weekly", "", "keep weekly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&opts.WithinMonthly, "keep-within-monthly", "", "keep monthly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&opts.WithinYearly, "keep-within-yearly", "", "keep yearly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.Var(&opts.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
f.BoolVar(&opts.UnsafeAllowRemoveAll, "unsafe-allow-remove-all", false, "allow deleting all snapshots of a snapshot group")
func init() {
cmdRoot.AddCommand(cmdForget)
f := cmdForget.Flags()
f.VarP(&forgetOptions.Last, "keep-last", "l", "keep the last `n` snapshots (use 'unlimited' to keep all snapshots)")
f.VarP(&forgetOptions.Hourly, "keep-hourly", "H", "keep the last `n` hourly snapshots (use 'unlimited' to keep all hourly snapshots)")
f.VarP(&forgetOptions.Daily, "keep-daily", "d", "keep the last `n` daily snapshots (use 'unlimited' to keep all daily snapshots)")
f.VarP(&forgetOptions.Weekly, "keep-weekly", "w", "keep the last `n` weekly snapshots (use 'unlimited' to keep all weekly snapshots)")
f.VarP(&forgetOptions.Monthly, "keep-monthly", "m", "keep the last `n` monthly snapshots (use 'unlimited' to keep all monthly snapshots)")
f.VarP(&forgetOptions.Yearly, "keep-yearly", "y", "keep the last `n` yearly snapshots (use 'unlimited' to keep all yearly snapshots)")
f.VarP(&forgetOptions.Within, "keep-within", "", "keep snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&forgetOptions.WithinHourly, "keep-within-hourly", "", "keep hourly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&forgetOptions.WithinDaily, "keep-within-daily", "", "keep daily snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&forgetOptions.WithinWeekly, "keep-within-weekly", "", "keep weekly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&forgetOptions.WithinMonthly, "keep-within-monthly", "", "keep monthly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.VarP(&forgetOptions.WithinYearly, "keep-within-yearly", "", "keep yearly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
f.Var(&forgetOptions.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
f.BoolVar(&forgetOptions.UnsafeAllowRemoveAll, "unsafe-allow-remove-all", false, "allow deleting all snapshots of a snapshot group")
initMultiSnapshotFilter(f, &forgetOptions.SnapshotFilter, false)
f.StringArrayVar(&forgetOptions.Hosts, "hostname", nil, "only consider snapshots with the given `hostname` (can be specified multiple times)")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, false)
f.StringArrayVar(&opts.Hosts, "hostname", nil, "only consider snapshots with the given `hostname` (can be specified multiple times)")
err := f.MarkDeprecated("hostname", "use --host")
if err != nil {
// MarkDeprecated only returns an error when the flag is not found
panic(err)
}
f.BoolVarP(&forgetOptions.Compact, "compact", "c", false, "use compact output format")
forgetOptions.GroupBy = restic.SnapshotGroupByOptions{Host: true, Path: true}
f.VarP(&forgetOptions.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma (disable grouping with '')")
f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
f.BoolVarP(&opts.Compact, "compact", "c", false, "use compact output format")
opts.GroupBy = restic.SnapshotGroupByOptions{Host: true, Path: true}
f.VarP(&opts.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma (disable grouping with '')")
f.BoolVarP(&opts.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
f.BoolVar(&opts.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
f.SortFlags = false
addPruneOptions(cmdForget, &forgetPruneOptions)
}
var forgetOptions ForgetOptions
var forgetPruneOptions PruneOptions
func init() {
cmdRoot.AddCommand(cmdForget)
forgetOptions.AddFlags(cmdForget.Flags())
forgetPruneOptions.AddLimitedFlags(cmdForget.Flags())
}
func verifyForgetOptions(opts *ForgetOptions) error {

View File

@ -8,6 +8,7 @@ import (
"github.com/restic/restic/internal/errors"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
"github.com/spf13/pflag"
)
var cmdGenerate = &cobra.Command{
@ -37,16 +38,19 @@ type generateOptions struct {
PowerShellCompletionFile string
}
func (opts *generateOptions) AddFlags(f *pflag.FlagSet) {
f.StringVar(&opts.ManDir, "man", "", "write man pages to `directory`")
f.StringVar(&opts.BashCompletionFile, "bash-completion", "", "write bash completion `file` (`-` for stdout)")
f.StringVar(&opts.FishCompletionFile, "fish-completion", "", "write fish completion `file` (`-` for stdout)")
f.StringVar(&opts.ZSHCompletionFile, "zsh-completion", "", "write zsh completion `file` (`-` for stdout)")
f.StringVar(&opts.PowerShellCompletionFile, "powershell-completion", "", "write powershell completion `file` (`-` for stdout)")
}
var genOpts generateOptions
func init() {
cmdRoot.AddCommand(cmdGenerate)
fs := cmdGenerate.Flags()
fs.StringVar(&genOpts.ManDir, "man", "", "write man pages to `directory`")
fs.StringVar(&genOpts.BashCompletionFile, "bash-completion", "", "write bash completion `file` (`-` for stdout)")
fs.StringVar(&genOpts.FishCompletionFile, "fish-completion", "", "write fish completion `file` (`-` for stdout)")
fs.StringVar(&genOpts.ZSHCompletionFile, "zsh-completion", "", "write zsh completion `file` (`-` for stdout)")
fs.StringVar(&genOpts.PowerShellCompletionFile, "powershell-completion", "", "write powershell completion `file` (`-` for stdout)")
genOpts.AddFlags(cmdGenerate.Flags())
}
func writeManpages(dir string) error {

View File

@ -12,6 +12,7 @@ import (
"github.com/restic/restic/internal/restic"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdInit = &cobra.Command{
@ -40,15 +41,17 @@ type InitOptions struct {
RepositoryVersion string
}
func (opts *InitOptions) AddFlags(f *pflag.FlagSet) {
initSecondaryRepoOptions(f, &opts.secondaryRepoOptions, "secondary", "to copy chunker parameters from")
f.BoolVar(&opts.CopyChunkerParameters, "copy-chunker-params", false, "copy chunker parameters from the secondary repository (useful with the copy command)")
f.StringVar(&opts.RepositoryVersion, "repository-version", "stable", "repository format version to use, allowed values are a format version, 'latest' and 'stable'")
}
var initOptions InitOptions
func init() {
cmdRoot.AddCommand(cmdInit)
f := cmdInit.Flags()
initSecondaryRepoOptions(f, &initOptions.secondaryRepoOptions, "secondary", "to copy chunker parameters from")
f.BoolVar(&initOptions.CopyChunkerParameters, "copy-chunker-params", false, "copy chunker parameters from the secondary repository (useful with the copy command)")
f.StringVar(&initOptions.RepositoryVersion, "repository-version", "stable", "repository format version to use, allowed values are a format version, 'latest' and 'stable'")
initOptions.AddFlags(cmdInit.Flags())
}
func runInit(ctx context.Context, opts InitOptions, gopts GlobalOptions, args []string) error {

View File

@ -13,6 +13,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/fs"
@ -70,19 +71,21 @@ type LsOptions struct {
Reverse bool
}
func (opts *LsOptions) AddFlags(f *pflag.FlagSet) {
initSingleSnapshotFilter(f, &opts.SnapshotFilter)
f.BoolVarP(&opts.ListLong, "long", "l", false, "use a long listing format showing size and mode")
f.BoolVar(&opts.Recursive, "recursive", false, "include files in subfolders of the listed directories")
f.BoolVar(&opts.HumanReadable, "human-readable", false, "print sizes in human readable format")
f.BoolVar(&opts.Ncdu, "ncdu", false, "output NCDU export format (pipe into 'ncdu -f -')")
f.VarP(&opts.Sort, "sort", "s", "sort output by (name|size|time=mtime|atime|ctime|extension)")
f.BoolVar(&opts.Reverse, "reverse", false, "reverse sorted output")
}
var lsOptions LsOptions
func init() {
cmdRoot.AddCommand(cmdLs)
flags := cmdLs.Flags()
initSingleSnapshotFilter(flags, &lsOptions.SnapshotFilter)
flags.BoolVarP(&lsOptions.ListLong, "long", "l", false, "use a long listing format showing size and mode")
flags.BoolVar(&lsOptions.Recursive, "recursive", false, "include files in subfolders of the listed directories")
flags.BoolVar(&lsOptions.HumanReadable, "human-readable", false, "print sizes in human readable format")
flags.BoolVar(&lsOptions.Ncdu, "ncdu", false, "output NCDU export format (pipe into 'ncdu -f -')")
flags.VarP(&lsOptions.Sort, "sort", "s", "sort output by (name|size|time=mtime|atime|ctime|extension)")
flags.BoolVar(&lsOptions.Reverse, "reverse", false, "reverse sorted output")
lsOptions.AddFlags(cmdLs.Flags())
}
type lsPrinter interface {

View File

@ -9,6 +9,7 @@ import (
"github.com/restic/restic/internal/ui/termstatus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdMigrate = &cobra.Command{
@ -42,12 +43,15 @@ type MigrateOptions struct {
Force bool
}
func (opts *MigrateOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVarP(&opts.Force, "force", "f", false, `apply a migration a second time`)
}
var migrateOptions MigrateOptions
func init() {
cmdRoot.AddCommand(cmdMigrate)
f := cmdMigrate.Flags()
f.BoolVarP(&migrateOptions.Force, "force", "f", false, `apply a migration a second time`)
migrateOptions.AddFlags(cmdMigrate.Flags())
}
func checkMigrations(ctx context.Context, repo restic.Repository, printer progress.Printer) error {

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
@ -86,22 +87,24 @@ type MountOptions struct {
PathTemplates []string
}
func (opts *MountOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.OwnerRoot, "owner-root", false, "use 'root' as the owner of files and dirs")
f.BoolVar(&opts.AllowOther, "allow-other", false, "allow other users to access the data in the mounted directory")
f.BoolVar(&opts.NoDefaultPermissions, "no-default-permissions", false, "for 'allow-other', ignore Unix permissions and allow users to read all snapshot files")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
f.StringArrayVar(&opts.PathTemplates, "path-template", nil, "set `template` for path names (can be specified multiple times)")
f.StringVar(&opts.TimeTemplate, "snapshot-template", time.RFC3339, "set `template` to use for snapshot dirs")
f.StringVar(&opts.TimeTemplate, "time-template", time.RFC3339, "set `template` to use for times")
_ = f.MarkDeprecated("snapshot-template", "use --time-template")
}
var mountOptions MountOptions
func init() {
cmdRoot.AddCommand(cmdMount)
mountFlags := cmdMount.Flags()
mountFlags.BoolVar(&mountOptions.OwnerRoot, "owner-root", false, "use 'root' as the owner of files and dirs")
mountFlags.BoolVar(&mountOptions.AllowOther, "allow-other", false, "allow other users to access the data in the mounted directory")
mountFlags.BoolVar(&mountOptions.NoDefaultPermissions, "no-default-permissions", false, "for 'allow-other', ignore Unix permissions and allow users to read all snapshot files")
initMultiSnapshotFilter(mountFlags, &mountOptions.SnapshotFilter, true)
mountFlags.StringArrayVar(&mountOptions.PathTemplates, "path-template", nil, "set `template` for path names (can be specified multiple times)")
mountFlags.StringVar(&mountOptions.TimeTemplate, "snapshot-template", time.RFC3339, "set `template` to use for snapshot dirs")
mountFlags.StringVar(&mountOptions.TimeTemplate, "time-template", time.RFC3339, "set `template` to use for times")
_ = mountFlags.MarkDeprecated("snapshot-template", "use --time-template")
mountOptions.AddFlags(cmdMount.Flags())
}
func runMount(ctx context.Context, opts MountOptions, gopts GlobalOptions, args []string) error {

View File

@ -16,6 +16,7 @@ import (
"github.com/restic/restic/internal/ui/termstatus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdPrune = &cobra.Command{
@ -61,23 +62,25 @@ type PruneOptions struct {
RepackUncompressed bool
}
func (opts *PruneOptions) AddFlags(f *pflag.FlagSet) {
opts.AddLimitedFlags(f)
f.BoolVarP(&opts.DryRun, "dry-run", "n", false, "do not modify the repository, just print what would be done")
f.StringVarP(&opts.UnsafeNoSpaceRecovery, "unsafe-recover-no-free-space", "", "", "UNSAFE, READ THE DOCUMENTATION BEFORE USING! Try to recover a repository stuck with no free space. Do not use without trying out 'prune --max-repack-size 0' first.")
}
func (opts *PruneOptions) AddLimitedFlags(f *pflag.FlagSet) {
f.StringVar(&opts.MaxUnused, "max-unused", "5%", "tolerate given `limit` of unused data (absolute value in bytes with suffixes k/K, m/M, g/G, t/T, a value in % or the word 'unlimited')")
f.StringVar(&opts.MaxRepackSize, "max-repack-size", "", "stop after repacking this much data in total (allowed suffixes for `size`: k/K, m/M, g/G, t/T)")
f.BoolVar(&opts.RepackCacheableOnly, "repack-cacheable-only", false, "only repack packs which are cacheable")
f.BoolVar(&opts.RepackSmall, "repack-small", false, "repack pack files below 80% of target pack size")
f.BoolVar(&opts.RepackUncompressed, "repack-uncompressed", false, "repack all uncompressed data")
}
var pruneOptions PruneOptions
func init() {
cmdRoot.AddCommand(cmdPrune)
f := cmdPrune.Flags()
f.BoolVarP(&pruneOptions.DryRun, "dry-run", "n", false, "do not modify the repository, just print what would be done")
f.StringVarP(&pruneOptions.UnsafeNoSpaceRecovery, "unsafe-recover-no-free-space", "", "", "UNSAFE, READ THE DOCUMENTATION BEFORE USING! Try to recover a repository stuck with no free space. Do not use without trying out 'prune --max-repack-size 0' first.")
addPruneOptions(cmdPrune, &pruneOptions)
}
func addPruneOptions(c *cobra.Command, pruneOptions *PruneOptions) {
f := c.Flags()
f.StringVar(&pruneOptions.MaxUnused, "max-unused", "5%", "tolerate given `limit` of unused data (absolute value in bytes with suffixes k/K, m/M, g/G, t/T, a value in % or the word 'unlimited')")
f.StringVar(&pruneOptions.MaxRepackSize, "max-repack-size", "", "stop after repacking this much data in total (allowed suffixes for `size`: k/K, m/M, g/G, t/T)")
f.BoolVar(&pruneOptions.RepackCacheableOnly, "repack-cacheable-only", false, "only repack packs which are cacheable")
f.BoolVar(&pruneOptions.RepackSmall, "repack-small", false, "repack pack files below 80% of target pack size")
f.BoolVar(&pruneOptions.RepackUncompressed, "repack-uncompressed", false, "repack all uncompressed data")
pruneOptions.AddFlags(cmdPrune.Flags())
}
func verifyPruneOptions(opts *PruneOptions) error {

View File

@ -47,16 +47,18 @@ type RepairIndexOptions struct {
ReadAllPacks bool
}
func (opts *RepairIndexOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.ReadAllPacks, "read-all-packs", false, "read all pack files to generate new index from scratch")
}
var repairIndexOptions RepairIndexOptions
func init() {
cmdRepair.AddCommand(cmdRepairIndex)
repairIndexOptions.AddFlags(cmdRepairIndex.Flags())
// add alias for old name
cmdRoot.AddCommand(cmdRebuildIndex)
for _, f := range []*pflag.FlagSet{cmdRepairIndex.Flags(), cmdRebuildIndex.Flags()} {
f.BoolVar(&repairIndexOptions.ReadAllPacks, "read-all-packs", false, "read all pack files to generate new index from scratch")
}
repairIndexOptions.AddFlags(cmdRebuildIndex.Flags())
}
func runRebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOptions, term *termstatus.Terminal) error {

View File

@ -8,6 +8,7 @@ import (
"github.com/restic/restic/internal/walker"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdRepairSnapshots = &cobra.Command{
@ -57,16 +58,18 @@ type RepairOptions struct {
restic.SnapshotFilter
}
func (opts *RepairOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVarP(&opts.DryRun, "dry-run", "n", false, "do not do anything, just print what would be done")
f.BoolVarP(&opts.Forget, "forget", "", false, "remove original snapshots after creating new ones")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
}
var repairSnapshotOptions RepairOptions
func init() {
cmdRepair.AddCommand(cmdRepairSnapshots)
flags := cmdRepairSnapshots.Flags()
flags.BoolVarP(&repairSnapshotOptions.DryRun, "dry-run", "n", false, "do not do anything, just print what would be done")
flags.BoolVarP(&repairSnapshotOptions.Forget, "forget", "", false, "remove original snapshots after creating new ones")
initMultiSnapshotFilter(flags, &repairSnapshotOptions.SnapshotFilter, true)
repairSnapshotOptions.AddFlags(cmdRepairSnapshots.Flags())
}
func runRepairSnapshots(ctx context.Context, gopts GlobalOptions, opts RepairOptions, args []string) error {

View File

@ -15,6 +15,7 @@ import (
"github.com/restic/restic/internal/ui/termstatus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdRestore = &cobra.Command{
@ -63,26 +64,28 @@ type RestoreOptions struct {
IncludeXattrPattern []string
}
func (opts *RestoreOptions) AddFlags(f *pflag.FlagSet) {
f.StringVarP(&opts.Target, "target", "t", "", "directory to extract data to")
opts.ExcludePatternOptions.Add(f)
opts.IncludePatternOptions.Add(f)
f.StringArrayVar(&opts.ExcludeXattrPattern, "exclude-xattr", nil, "exclude xattr by `pattern` (can be specified multiple times)")
f.StringArrayVar(&opts.IncludeXattrPattern, "include-xattr", nil, "include xattr by `pattern` (can be specified multiple times)")
initSingleSnapshotFilter(f, &opts.SnapshotFilter)
f.BoolVar(&opts.DryRun, "dry-run", false, "do not write any data, just show what would be done")
f.BoolVar(&opts.Sparse, "sparse", false, "restore files as sparse")
f.BoolVar(&opts.Verify, "verify", false, "verify restored files content")
f.Var(&opts.Overwrite, "overwrite", "overwrite behavior, one of (always|if-changed|if-newer|never) (default: always)")
f.BoolVar(&opts.Delete, "delete", false, "delete files from target directory if they do not exist in snapshot. Use '--dry-run -vv' to check what would be deleted")
}
var restoreOptions RestoreOptions
func init() {
cmdRoot.AddCommand(cmdRestore)
flags := cmdRestore.Flags()
flags.StringVarP(&restoreOptions.Target, "target", "t", "", "directory to extract data to")
restoreOptions.ExcludePatternOptions.Add(flags)
restoreOptions.IncludePatternOptions.Add(flags)
flags.StringArrayVar(&restoreOptions.ExcludeXattrPattern, "exclude-xattr", nil, "exclude xattr by `pattern` (can be specified multiple times)")
flags.StringArrayVar(&restoreOptions.IncludeXattrPattern, "include-xattr", nil, "include xattr by `pattern` (can be specified multiple times)")
initSingleSnapshotFilter(flags, &restoreOptions.SnapshotFilter)
flags.BoolVar(&restoreOptions.DryRun, "dry-run", false, "do not write any data, just show what would be done")
flags.BoolVar(&restoreOptions.Sparse, "sparse", false, "restore files as sparse")
flags.BoolVar(&restoreOptions.Verify, "verify", false, "verify restored files content")
flags.Var(&restoreOptions.Overwrite, "overwrite", "overwrite behavior, one of (always|if-changed|if-newer|never) (default: always)")
flags.BoolVar(&restoreOptions.Delete, "delete", false, "delete files from target directory if they do not exist in snapshot. Use '--dry-run -vv' to check what would be deleted")
restoreOptions.AddFlags(cmdRestore.Flags())
}
func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/sync/errgroup"
"github.com/restic/restic/internal/debug"
@ -99,20 +100,22 @@ type RewriteOptions struct {
filter.ExcludePatternOptions
}
func (opts *RewriteOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVarP(&opts.Forget, "forget", "", false, "remove original snapshots after creating new ones")
f.BoolVarP(&opts.DryRun, "dry-run", "n", false, "do not do anything, just print what would be done")
f.StringVar(&opts.Metadata.Hostname, "new-host", "", "replace hostname")
f.StringVar(&opts.Metadata.Time, "new-time", "", "replace time of the backup")
f.BoolVarP(&opts.SnapshotSummary, "snapshot-summary", "s", false, "create snapshot summary record if it does not exist")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
opts.ExcludePatternOptions.Add(f)
}
var rewriteOptions RewriteOptions
func init() {
cmdRoot.AddCommand(cmdRewrite)
f := cmdRewrite.Flags()
f.BoolVarP(&rewriteOptions.Forget, "forget", "", false, "remove original snapshots after creating new ones")
f.BoolVarP(&rewriteOptions.DryRun, "dry-run", "n", false, "do not do anything, just print what would be done")
f.StringVar(&rewriteOptions.Metadata.Hostname, "new-host", "", "replace hostname")
f.StringVar(&rewriteOptions.Metadata.Time, "new-time", "", "replace time of the backup")
f.BoolVarP(&rewriteOptions.SnapshotSummary, "snapshot-summary", "s", false, "create snapshot summary record if it does not exist")
initMultiSnapshotFilter(f, &rewriteOptions.SnapshotFilter, true)
rewriteOptions.ExcludePatternOptions.Add(f)
rewriteOptions.AddFlags(cmdRewrite.Flags())
}
// rewriteFilterFunc returns the filtered tree ID or an error. If a snapshot summary is returned, the snapshot will

View File

@ -10,6 +10,7 @@ import (
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/selfupdate"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdSelfUpdate = &cobra.Command{
@ -41,13 +42,15 @@ type SelfUpdateOptions struct {
Output string
}
func (opts *SelfUpdateOptions) AddFlags(f *pflag.FlagSet) {
f.StringVar(&opts.Output, "output", "", "Save the downloaded file as `filename` (default: running binary itself)")
}
var selfUpdateOptions SelfUpdateOptions
func init() {
cmdRoot.AddCommand(cmdSelfUpdate)
flags := cmdSelfUpdate.Flags()
flags.StringVar(&selfUpdateOptions.Output, "output", "", "Save the downloaded file as `filename` (default: running binary itself)")
selfUpdateOptions.AddFlags(cmdSelfUpdate.Flags())
}
func runSelfUpdate(ctx context.Context, opts SelfUpdateOptions, gopts GlobalOptions, args []string) error {

View File

@ -12,6 +12,7 @@ import (
"github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/table"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdSnapshots = &cobra.Command{
@ -45,22 +46,24 @@ type SnapshotOptions struct {
GroupBy restic.SnapshotGroupByOptions
}
var snapshotOptions SnapshotOptions
func init() {
cmdRoot.AddCommand(cmdSnapshots)
f := cmdSnapshots.Flags()
initMultiSnapshotFilter(f, &snapshotOptions.SnapshotFilter, true)
f.BoolVarP(&snapshotOptions.Compact, "compact", "c", false, "use compact output format")
f.BoolVar(&snapshotOptions.Last, "last", false, "only show the last snapshot for each host and path")
func (opts *SnapshotOptions) AddFlags(f *pflag.FlagSet) {
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
f.BoolVarP(&opts.Compact, "compact", "c", false, "use compact output format")
f.BoolVar(&opts.Last, "last", false, "only show the last snapshot for each host and path")
err := f.MarkDeprecated("last", "use --latest 1")
if err != nil {
// MarkDeprecated only returns an error when the flag is not found
panic(err)
}
f.IntVar(&snapshotOptions.Latest, "latest", 0, "only show the last `n` snapshots for each host and path")
f.VarP(&snapshotOptions.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma")
f.IntVar(&opts.Latest, "latest", 0, "only show the last `n` snapshots for each host and path")
f.VarP(&opts.GroupBy, "group-by", "g", "`group` snapshots by host, paths and/or tags, separated by comma")
}
var snapshotOptions SnapshotOptions
func init() {
cmdRoot.AddCommand(cmdSnapshots)
snapshotOptions.AddFlags(cmdSnapshots.Flags())
}
func runSnapshots(ctx context.Context, opts SnapshotOptions, gopts GlobalOptions, args []string) error {

View File

@ -18,6 +18,7 @@ import (
"github.com/restic/restic/internal/walker"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var cmdStats = &cobra.Command{
@ -70,6 +71,11 @@ type StatsOptions struct {
restic.SnapshotFilter
}
func (opts *StatsOptions) AddFlags(f *pflag.FlagSet) {
f.StringVar(&opts.countMode, "mode", countModeRestoreSize, "counting mode: restore-size (default), files-by-contents, blobs-per-file or raw-data")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
}
var statsOptions StatsOptions
func must(err error) {
@ -80,13 +86,10 @@ func must(err error) {
func init() {
cmdRoot.AddCommand(cmdStats)
f := cmdStats.Flags()
f.StringVar(&statsOptions.countMode, "mode", countModeRestoreSize, "counting mode: restore-size (default), files-by-contents, blobs-per-file or raw-data")
statsOptions.AddFlags(cmdStats.Flags())
must(cmdStats.RegisterFlagCompletionFunc("mode", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return []string{countModeRestoreSize, countModeUniqueFilesByContents, countModeBlobsPerFile, countModeRawData}, cobra.ShellCompDirectiveDefault
}))
initMultiSnapshotFilter(f, &statsOptions.SnapshotFilter, true)
}
func runStats(ctx context.Context, opts StatsOptions, gopts GlobalOptions, args []string) error {

View File

@ -4,6 +4,7 @@ import (
"context"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
@ -50,16 +51,18 @@ type TagOptions struct {
RemoveTags restic.TagLists
}
func (opts *TagOptions) AddFlags(f *pflag.FlagSet) {
f.Var(&opts.SetTags, "set", "`tags` which will replace the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
f.Var(&opts.AddTags, "add", "`tags` which will be added to the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
f.Var(&opts.RemoveTags, "remove", "`tags` which will be removed from the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
initMultiSnapshotFilter(f, &opts.SnapshotFilter, true)
}
var tagOptions TagOptions
func init() {
cmdRoot.AddCommand(cmdTag)
tagFlags := cmdTag.Flags()
tagFlags.Var(&tagOptions.SetTags, "set", "`tags` which will replace the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
tagFlags.Var(&tagOptions.AddTags, "add", "`tags` which will be added to the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
tagFlags.Var(&tagOptions.RemoveTags, "remove", "`tags` which will be removed from the existing tags in the format `tag[,tag,...]` (can be given multiple times)")
initMultiSnapshotFilter(tagFlags, &tagOptions.SnapshotFilter, true)
tagOptions.AddFlags(cmdTag.Flags())
}
type changedSnapshot struct {

View File

@ -5,6 +5,7 @@ import (
"github.com/restic/restic/internal/repository"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var unlockCmd = &cobra.Command{
@ -31,12 +32,15 @@ type UnlockOptions struct {
RemoveAll bool
}
func (opts *UnlockOptions) AddFlags(f *pflag.FlagSet) {
f.BoolVar(&opts.RemoveAll, "remove-all", false, "remove all locks, even non-stale ones")
}
var unlockOptions UnlockOptions
func init() {
cmdRoot.AddCommand(unlockCmd)
unlockCmd.Flags().BoolVar(&unlockOptions.RemoveAll, "remove-all", false, "remove all locks, even non-stale ones")
unlockOptions.AddFlags(unlockCmd.Flags())
}
func runUnlock(ctx context.Context, opts UnlockOptions, gopts GlobalOptions) error {