Skip to content

Commit

Permalink
Merge pull request #4647 from MichaelEischer/reduce-globals
Browse files Browse the repository at this point in the history
Remove all usages of the global command-specific options
  • Loading branch information
MichaelEischer committed Jan 23, 2024
2 parents 1419baf + 66103ae commit 5b36c4e
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 79 deletions.
2 changes: 1 addition & 1 deletion cmd/restic/cmd_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, ter
wg.Go(func() error { return sc.Scan(cancelCtx, targets) })
}

arch := archiver.New(repo, targetFS, archiver.Options{ReadConcurrency: backupOptions.ReadConcurrency})
arch := archiver.New(repo, targetFS, archiver.Options{ReadConcurrency: opts.ReadConcurrency})
arch.SelectByName = selectByNameFilter
arch.Select = selectFilter
arch.WithAtime = opts.WithAtime
Expand Down
46 changes: 25 additions & 21 deletions cmd/restic/cmd_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,23 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
},
}

var tryRepair bool
var repairByte bool
var extractPack bool
var reuploadBlobs bool
type DebugExamineOptions struct {
TryRepair bool
RepairByte bool
ExtractPack bool
ReuploadBlobs bool
}

var debugExamineOpts DebugExamineOptions

func init() {
cmdRoot.AddCommand(cmdDebug)
cmdDebug.AddCommand(cmdDebugDump)
cmdDebug.AddCommand(cmdDebugExamine)
cmdDebugExamine.Flags().BoolVar(&extractPack, "extract-pack", false, "write blobs to the current directory")
cmdDebugExamine.Flags().BoolVar(&reuploadBlobs, "reupload-blobs", false, "reupload blobs to the repository")
cmdDebugExamine.Flags().BoolVar(&tryRepair, "try-repair", false, "try to repair broken blobs with single bit flips")
cmdDebugExamine.Flags().BoolVar(&repairByte, "repair-byte", false, "try to repair broken blobs by trying bytes")
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")
}

func prettyPrintJSON(wr io.Writer, item interface{}) error {
Expand Down Expand Up @@ -196,7 +200,7 @@ var cmdDebugExamine = &cobra.Command{
Short: "Examine a pack file",
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runDebugExamine(cmd.Context(), globalOptions, args)
return runDebugExamine(cmd.Context(), globalOptions, debugExamineOpts, args)
},
}

Expand Down Expand Up @@ -315,7 +319,7 @@ func decryptUnsigned(ctx context.Context, k *crypto.Key, buf []byte) []byte {
return out
}

func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, list []restic.Blob) error {
func loadBlobs(ctx context.Context, opts DebugExamineOptions, repo restic.Repository, packID restic.ID, list []restic.Blob) error {
dec, err := zstd.NewReader(nil)
if err != nil {
panic(err)
Expand All @@ -328,7 +332,7 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li

wg, ctx := errgroup.WithContext(ctx)

if reuploadBlobs {
if opts.ReuploadBlobs {
repo.StartPackUploader(ctx, wg)
}

Expand Down Expand Up @@ -356,8 +360,8 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
filePrefix := ""
if err != nil {
Warnf("error decrypting blob: %v\n", err)
if tryRepair || repairByte {
plaintext = tryRepairWithBitflip(ctx, key, buf, repairByte)
if opts.TryRepair || opts.RepairByte {
plaintext = tryRepairWithBitflip(ctx, key, buf, opts.RepairByte)
}
if plaintext != nil {
outputPrefix = "repaired "
Expand Down Expand Up @@ -391,13 +395,13 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
Printf(" successfully %vdecrypted blob (length %v), hash is %v, ID matches\n", outputPrefix, len(plaintext), id)
prefix = "correct-"
}
if extractPack {
if opts.ExtractPack {
err = storePlainBlob(id, filePrefix+prefix, plaintext)
if err != nil {
return err
}
}
if reuploadBlobs {
if opts.ReuploadBlobs {
_, _, _, err := repo.SaveBlob(ctx, blob.Type, plaintext, id, true)
if err != nil {
return err
Expand All @@ -406,7 +410,7 @@ func loadBlobs(ctx context.Context, repo restic.Repository, packID restic.ID, li
}
}

if reuploadBlobs {
if opts.ReuploadBlobs {
return repo.Flush(ctx)
}
return nil
Expand Down Expand Up @@ -437,7 +441,7 @@ func storePlainBlob(id restic.ID, prefix string, plain []byte) error {
return nil
}

func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) error {
func runDebugExamine(ctx context.Context, gopts GlobalOptions, opts DebugExamineOptions, args []string) error {
repo, err := OpenRepository(ctx, gopts)
if err != nil {
return err
Expand Down Expand Up @@ -476,7 +480,7 @@ func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) er
}

for _, id := range ids {
err := examinePack(ctx, repo, id)
err := examinePack(ctx, opts, repo, id)
if err != nil {
Warnf("error: %v\n", err)
}
Expand All @@ -487,7 +491,7 @@ func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) er
return nil
}

func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) error {
func examinePack(ctx context.Context, opts DebugExamineOptions, repo restic.Repository, id restic.ID) error {
Printf("examine %v\n", id)

h := backend.Handle{
Expand Down Expand Up @@ -524,7 +528,7 @@ func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) erro

checkPackSize(blobs, fi.Size)

err = loadBlobs(ctx, repo, id, blobs)
err = loadBlobs(ctx, opts, repo, id, blobs)
if err != nil {
Warnf("error: %v\n", err)
} else {
Expand All @@ -542,7 +546,7 @@ func examinePack(ctx context.Context, repo restic.Repository, id restic.ID) erro
checkPackSize(blobs, fi.Size)

if !blobsLoaded {
return loadBlobs(ctx, repo, id, blobs)
return loadBlobs(ctx, opts, repo, id, blobs)
}
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/restic/cmd_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []

c := &Comparer{
repo: repo,
opts: diffOptions,
opts: opts,
printChange: func(change *Change) {
Printf("%-5s%v\n", change.Modifier, change.Path)
},
Expand Down
7 changes: 4 additions & 3 deletions cmd/restic/cmd_forget.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runForget(cmd.Context(), forgetOptions, globalOptions, args)
return runForget(cmd.Context(), forgetOptions, forgetPruneOptions, globalOptions, args)
},
}

Expand Down Expand Up @@ -98,6 +98,7 @@ type ForgetOptions struct {
}

var forgetOptions ForgetOptions
var forgetPruneOptions PruneOptions

func init() {
cmdRoot.AddCommand(cmdForget)
Expand Down Expand Up @@ -132,7 +133,7 @@ func init() {
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")

f.SortFlags = false
addPruneOptions(cmdForget)
addPruneOptions(cmdForget, &forgetPruneOptions)
}

func verifyForgetOptions(opts *ForgetOptions) error {
Expand All @@ -151,7 +152,7 @@ func verifyForgetOptions(opts *ForgetOptions) error {
return nil
}

func runForget(ctx context.Context, opts ForgetOptions, gopts GlobalOptions, args []string) error {
func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOptions, gopts GlobalOptions, args []string) error {
err := verifyForgetOptions(&opts)
if err != nil {
return err
Expand Down
5 changes: 4 additions & 1 deletion cmd/restic/cmd_forget_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ import (

func testRunForget(t testing.TB, gopts GlobalOptions, args ...string) {
opts := ForgetOptions{}
rtest.OK(t, runForget(context.TODO(), opts, gopts, args))
pruneOpts := PruneOptions{
MaxUnused: "5%",
}
rtest.OK(t, runForget(context.TODO(), opts, pruneOpts, gopts, args))
}
28 changes: 15 additions & 13 deletions cmd/restic/cmd_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ EXIT STATUS
Exit status is 0 if the command was successful, and non-zero if there was any error.
`,
DisableAutoGenTag: true,
RunE: runGenerate,
RunE: func(cmd *cobra.Command, args []string) error {
return runGenerate(genOpts, args)
},
}

type generateOptions struct {
Expand Down Expand Up @@ -90,48 +92,48 @@ func writePowerShellCompletion(file string) error {
return cmdRoot.GenPowerShellCompletionFile(file)
}

func runGenerate(_ *cobra.Command, args []string) error {
func runGenerate(opts generateOptions, args []string) error {
if len(args) > 0 {
return errors.Fatal("the generate command expects no arguments, only options - please see `restic help generate` for usage and flags")
}

if genOpts.ManDir != "" {
err := writeManpages(genOpts.ManDir)
if opts.ManDir != "" {
err := writeManpages(opts.ManDir)
if err != nil {
return err
}
}

if genOpts.BashCompletionFile != "" {
err := writeBashCompletion(genOpts.BashCompletionFile)
if opts.BashCompletionFile != "" {
err := writeBashCompletion(opts.BashCompletionFile)
if err != nil {
return err
}
}

if genOpts.FishCompletionFile != "" {
err := writeFishCompletion(genOpts.FishCompletionFile)
if opts.FishCompletionFile != "" {
err := writeFishCompletion(opts.FishCompletionFile)
if err != nil {
return err
}
}

if genOpts.ZSHCompletionFile != "" {
err := writeZSHCompletion(genOpts.ZSHCompletionFile)
if opts.ZSHCompletionFile != "" {
err := writeZSHCompletion(opts.ZSHCompletionFile)
if err != nil {
return err
}
}

if genOpts.PowerShellCompletionFile != "" {
err := writePowerShellCompletion(genOpts.PowerShellCompletionFile)
if opts.PowerShellCompletionFile != "" {
err := writePowerShellCompletion(opts.PowerShellCompletionFile)
if err != nil {
return err
}
}

var empty generateOptions
if genOpts == empty {
if opts == empty {
return errors.Fatal("nothing to do, please specify at least one output file/dir")
}

Expand Down
38 changes: 20 additions & 18 deletions cmd/restic/cmd_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,25 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runKey(cmd.Context(), globalOptions, args)
return runKey(cmd.Context(), globalOptions, keyOpts, args)
},
}

var (
newPasswordFile string
keyUsername string
keyHostname string
)
type KeyOptions struct {
NewPasswordFile string
Username string
Hostname string
}

var keyOpts KeyOptions

func init() {
cmdRoot.AddCommand(cmdKey)

flags := cmdKey.Flags()
flags.StringVarP(&newPasswordFile, "new-password-file", "", "", "`file` from which to read the new password")
flags.StringVarP(&keyUsername, "user", "", "", "the username for new keys")
flags.StringVarP(&keyHostname, "host", "", "", "the hostname for new keys")
flags.StringVarP(&keyOpts.NewPasswordFile, "new-password-file", "", "", "`file` from which to read the new password")
flags.StringVarP(&keyOpts.Username, "user", "", "", "the username for new keys")
flags.StringVarP(&keyOpts.Hostname, "host", "", "", "the hostname for new keys")
}

func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions) error {
Expand Down Expand Up @@ -105,7 +107,7 @@ func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions
// testKeyNewPassword is used to set a new password during integration testing.
var testKeyNewPassword string

func getNewPassword(gopts GlobalOptions) (string, error) {
func getNewPassword(gopts GlobalOptions, newPasswordFile string) (string, error) {
if testKeyNewPassword != "" {
return testKeyNewPassword, nil
}
Expand All @@ -124,13 +126,13 @@ func getNewPassword(gopts GlobalOptions) (string, error) {
"enter password again: ")
}

func addKey(ctx context.Context, repo *repository.Repository, gopts GlobalOptions) error {
pw, err := getNewPassword(gopts)
func addKey(ctx context.Context, repo *repository.Repository, gopts GlobalOptions, opts KeyOptions) error {
pw, err := getNewPassword(gopts, opts.NewPasswordFile)
if err != nil {
return err
}

id, err := repository.AddKey(ctx, repo, pw, keyUsername, keyHostname, repo.Key())
id, err := repository.AddKey(ctx, repo, pw, opts.Username, opts.Hostname, repo.Key())
if err != nil {
return errors.Fatalf("creating new key failed: %v\n", err)
}
Expand Down Expand Up @@ -160,8 +162,8 @@ func deleteKey(ctx context.Context, repo *repository.Repository, id restic.ID) e
return nil
}

func changePassword(ctx context.Context, repo *repository.Repository, gopts GlobalOptions) error {
pw, err := getNewPassword(gopts)
func changePassword(ctx context.Context, repo *repository.Repository, gopts GlobalOptions, newPasswordFile string) error {
pw, err := getNewPassword(gopts, newPasswordFile)
if err != nil {
return err
}
Expand Down Expand Up @@ -201,7 +203,7 @@ func switchToNewKeyAndRemoveIfBroken(ctx context.Context, repo *repository.Repos
return nil
}

func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
func runKey(ctx context.Context, gopts GlobalOptions, opts KeyOptions, args []string) error {
if len(args) < 1 || (args[0] == "remove" && len(args) != 2) || (args[0] != "remove" && len(args) != 1) {
return errors.Fatal("wrong number of arguments")
}
Expand Down Expand Up @@ -230,7 +232,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return err
}

return addKey(ctx, repo, gopts)
return addKey(ctx, repo, gopts, opts)
case "remove":
lock, ctx, err := lockRepoExclusive(ctx, repo, gopts.RetryLock, gopts.JSON)
defer unlockRepo(lock)
Expand All @@ -251,7 +253,7 @@ func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
return err
}

return changePassword(ctx, repo, gopts)
return changePassword(ctx, repo, gopts, opts.NewPasswordFile)
}

return nil
Expand Down

0 comments on commit 5b36c4e

Please sign in to comment.