From 7e2fbbea4ff70c7852830bf81bc39cb0d122fa12 Mon Sep 17 00:00:00 2001 From: Keepers Date: Tue, 6 Dec 2022 10:00:37 -0700 Subject: [PATCH] adds sharepoint restore cli commands (#1637) ## Description Adds restore commands to the cli for sharepoint. The restore process is only partially functional at this time. Library files that pass auth are able to be restored as expected. However, auth issues (not directly related to these changes) prevent restoration of all library items at this time. ## Type of change - [x] :sunflower: Feature ## Issue(s) * #1615 ## Test Plan - [x] :muscle: Manual - [x] :green_heart: E2E --- src/cli/backup/backup.go | 6 +- src/cli/backup/exchange.go | 14 +-- src/cli/backup/onedrive.go | 14 +-- src/cli/backup/sharepoint.go | 14 +-- src/cli/help/env.go | 4 +- src/cli/options/options.go | 8 +- src/cli/print/print.go | 4 +- src/cli/repo/repo.go | 6 +- src/cli/repo/s3.go | 12 +-- src/cli/restore/exchange.go | 8 +- src/cli/restore/onedrive.go | 8 +- src/cli/restore/restore.go | 7 +- src/cli/restore/sharepoint.go | 161 +++++++++++++++++++++++++++++ src/cli/restore/sharepoint_test.go | 50 +++++++++ src/cmd/factory/exchange.go | 8 +- src/cmd/factory/onedrive.go | 4 +- src/internal/observe/observe.go | 4 +- src/pkg/logger/logger.go | 4 +- 18 files changed, 274 insertions(+), 62 deletions(-) create mode 100644 src/cli/restore/sharepoint.go create mode 100644 src/cli/restore/sharepoint_test.go diff --git a/src/cli/backup/backup.go b/src/cli/backup/backup.go index 425b176e5..ed7c3a441 100644 --- a/src/cli/backup/backup.go +++ b/src/cli/backup/backup.go @@ -11,16 +11,16 @@ var subCommandFuncs = []func() *cobra.Command{ deleteCmd, } -var serviceCommands = []func(parent *cobra.Command) *cobra.Command{ +var serviceCommands = []func(cmd *cobra.Command) *cobra.Command{ addExchangeCommands, addOneDriveCommands, addSharePointCommands, } // AddCommands attaches all `corso backup * *` commands to the parent. -func AddCommands(parent *cobra.Command) { +func AddCommands(cmd *cobra.Command) { backupC := backupCmd() - parent.AddCommand(backupC) + cmd.AddCommand(backupC) for _, sc := range subCommandFuncs { subCommand := sc() diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 1271a55ce..beeecca86 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -96,16 +96,16 @@ corso backup details exchange --backup 1234abcd-12ab-cd34-56de-1234abcd \ --user alice@example.com --contact-name Andy` ) -// called by backup.go to map parent subcommands to provider-specific handling. -func addExchangeCommands(parent *cobra.Command) *cobra.Command { +// called by backup.go to map subcommands to provider-specific handling. +func addExchangeCommands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case createCommand: - c, fs = utils.AddCommand(parent, exchangeCreateCmd()) + c, fs = utils.AddCommand(cmd, exchangeCreateCmd()) c.Use = c.Use + " " + exchangeServiceCommandCreateUseSuffix c.Example = exchangeServiceCommandCreateExamples @@ -123,14 +123,14 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { options.AddOperationFlags(c) case listCommand: - c, fs = utils.AddCommand(parent, exchangeListCmd()) + c, fs = utils.AddCommand(cmd, exchangeListCmd()) fs.StringVar(&backupID, "backup", "", "ID of the backup to retrieve.") case detailsCommand: - c, fs = utils.AddCommand(parent, exchangeDetailsCmd()) + c, fs = utils.AddCommand(cmd, exchangeDetailsCmd()) c.Use = c.Use + " " + exchangeServiceCommandDetailsUseSuffix c.Example = exchangeServiceCommandDetailsExamples @@ -218,7 +218,7 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { "Select backup details for contacts whose contact name contains this value.") case deleteCommand: - c, fs = utils.AddCommand(parent, exchangeDeleteCmd()) + c, fs = utils.AddCommand(cmd, exchangeDeleteCmd()) c.Use = c.Use + " " + exchangeServiceCommandDeleteUseSuffix c.Example = exchangeServiceCommandDeleteExamples diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index 7ad598c58..4ee03a159 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -69,16 +69,16 @@ var ( fileModifiedBefore string ) -// called by backup.go to map parent subcommands to provider-specific handling. -func addOneDriveCommands(parent *cobra.Command) *cobra.Command { +// called by backup.go to map subcommands to provider-specific handling. +func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case createCommand: - c, fs = utils.AddCommand(parent, oneDriveCreateCmd()) + c, fs = utils.AddCommand(cmd, oneDriveCreateCmd()) c.Use = c.Use + " " + oneDriveServiceCommandCreateUseSuffix c.Example = oneDriveServiceCommandCreateExamples @@ -89,14 +89,14 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { options.AddOperationFlags(c) case listCommand: - c, fs = utils.AddCommand(parent, oneDriveListCmd()) + c, fs = utils.AddCommand(cmd, oneDriveListCmd()) fs.StringVar(&backupID, utils.BackupFN, "", "ID of the backup to retrieve.") case detailsCommand: - c, fs = utils.AddCommand(parent, oneDriveDetailsCmd()) + c, fs = utils.AddCommand(cmd, oneDriveDetailsCmd()) c.Use = c.Use + " " + oneDriveServiceCommandDetailsUseSuffix c.Example = oneDriveServiceCommandDetailsExamples @@ -139,7 +139,7 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { "Select backup details for files modified before this datetime.") case deleteCommand: - c, fs = utils.AddCommand(parent, oneDriveDeleteCmd()) + c, fs = utils.AddCommand(cmd, oneDriveDeleteCmd()) c.Use = c.Use + " " + oneDriveServiceCommandDeleteUseSuffix c.Example = oneDriveServiceCommandDeleteExamples diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index d6ce2b292..f20f0bcab 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -66,16 +66,16 @@ corso backup delete sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd` corso backup details sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --site ` ) -// called by backup.go to map parent subcommands to provider-specific handling. -func addSharePointCommands(parent *cobra.Command) *cobra.Command { +// called by backup.go to map subcommands to provider-specific handling. +func addSharePointCommands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case createCommand: - c, fs = utils.AddCommand(parent, sharePointCreateCmd(), utils.HideCommand()) + c, fs = utils.AddCommand(cmd, sharePointCreateCmd(), utils.HideCommand()) c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix c.Example = sharePointServiceCommandCreateExamples @@ -91,14 +91,14 @@ func addSharePointCommands(parent *cobra.Command) *cobra.Command { options.AddOperationFlags(c) case listCommand: - c, fs = utils.AddCommand(parent, sharePointListCmd(), utils.HideCommand()) + c, fs = utils.AddCommand(cmd, sharePointListCmd(), utils.HideCommand()) fs.StringVar(&backupID, utils.BackupFN, "", "ID of the backup to retrieve.") case detailsCommand: - c, fs = utils.AddCommand(parent, sharePointDetailsCmd()) + c, fs = utils.AddCommand(cmd, sharePointDetailsCmd()) c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix c.Example = sharePointServiceCommandDetailsExamples @@ -128,7 +128,7 @@ func addSharePointCommands(parent *cobra.Command) *cobra.Command { // "Select backup details for items created after this datetime.") case deleteCommand: - c, fs = utils.AddCommand(parent, sharePointDeleteCmd(), utils.HideCommand()) + c, fs = utils.AddCommand(cmd, sharePointDeleteCmd(), utils.HideCommand()) c.Use = c.Use + " " + sharePointServiceCommandDeleteUseSuffix c.Example = sharePointServiceCommandDeleteExamples diff --git a/src/cli/help/env.go b/src/cli/help/env.go index 40e92ba0a..24e1b7a08 100644 --- a/src/cli/help/env.go +++ b/src/cli/help/env.go @@ -7,8 +7,8 @@ import ( ) // AddCommands attaches all `corso env * *` commands to the parent. -func AddCommands(parent *cobra.Command) { - parent.AddCommand(envCmd()) +func AddCommands(cmd *cobra.Command) { + cmd.AddCommand(envCmd()) } // The env command: purely a help display. diff --git a/src/cli/options/options.go b/src/cli/options/options.go index be67faf45..66b061267 100644 --- a/src/cli/options/options.go +++ b/src/cli/options/options.go @@ -12,16 +12,16 @@ var ( ) // AddOperationFlags adds command-local operation flags -func AddOperationFlags(parent *cobra.Command) { - fs := parent.Flags() +func AddOperationFlags(cmd *cobra.Command) { + fs := cmd.Flags() fs.BoolVar(&fastFail, "fast-fail", false, "stop processing immediately if any error occurs") // TODO: reveal this flag when fail-fast support is implemented cobra.CheckErr(fs.MarkHidden("fast-fail")) } // AddGlobalOperationFlags adds the global operations flag set. -func AddGlobalOperationFlags(parent *cobra.Command) { - fs := parent.PersistentFlags() +func AddGlobalOperationFlags(cmd *cobra.Command) { + fs := cmd.PersistentFlags() fs.BoolVar(&noStats, "no-stats", false, "disable anonymous usage statistics gathering") } diff --git a/src/cli/print/print.go b/src/cli/print/print.go index f417c8def..f8d95c570 100644 --- a/src/cli/print/print.go +++ b/src/cli/print/print.go @@ -43,8 +43,8 @@ func getRootCmd(ctx context.Context) *cobra.Command { } // adds the persistent flag --output to the provided command. -func AddOutputFlag(parent *cobra.Command) { - fs := parent.PersistentFlags() +func AddOutputFlag(cmd *cobra.Command) { + fs := cmd.PersistentFlags() fs.BoolVar(&outputAsJSON, "json", false, "output data in JSON format") fs.BoolVar(&outputAsJSONDebug, "json-debug", false, "output all internal and debugging data in JSON format") cobra.CheckErr(fs.MarkHidden("json-debug")) diff --git a/src/cli/repo/repo.go b/src/cli/repo/repo.go index 4a5695c7b..d60f9265a 100644 --- a/src/cli/repo/repo.go +++ b/src/cli/repo/repo.go @@ -9,12 +9,12 @@ const ( connectCommand = "connect" ) -var repoCommands = []func(parent *cobra.Command) *cobra.Command{ +var repoCommands = []func(cmd *cobra.Command) *cobra.Command{ addS3Commands, } // AddCommands attaches all `corso repo * *` commands to the parent. -func AddCommands(parent *cobra.Command) { +func AddCommands(cmd *cobra.Command) { var ( // Get new instances so that setting the context during tests works // properly. @@ -23,7 +23,7 @@ func AddCommands(parent *cobra.Command) { connectCmd = connectCmd() ) - parent.AddCommand(repoCmd) + cmd.AddCommand(repoCmd) repoCmd.AddCommand(initCmd) repoCmd.AddCommand(connectCmd) diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index 01b12bf53..2dbf4cb9f 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -26,22 +26,22 @@ var ( succeedIfExists bool ) -// called by repo.go to map parent subcommands to provider-specific handling. -func addS3Commands(parent *cobra.Command) *cobra.Command { +// called by repo.go to map subcommands to provider-specific handling. +func addS3Commands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case initCommand: - c, fs = utils.AddCommand(parent, s3InitCmd()) + c, fs = utils.AddCommand(cmd, s3InitCmd()) case connectCommand: - c, fs = utils.AddCommand(parent, s3ConnectCmd()) + c, fs = utils.AddCommand(cmd, s3ConnectCmd()) } c.Use = c.Use + " " + s3ProviderCommandUseSuffix - c.SetUsageTemplate(parent.UsageTemplate()) + c.SetUsageTemplate(cmd.UsageTemplate()) // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic and more frequently used flags take precedence. diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 715234871..84d24945e 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -40,16 +40,16 @@ var ( eventSubject string ) -// called by restore.go to map parent subcommands to provider-specific handling. -func addExchangeCommands(parent *cobra.Command) *cobra.Command { +// called by restore.go to map subcommands to provider-specific handling. +func addExchangeCommands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case restoreCommand: - c, fs = utils.AddCommand(parent, exchangeRestoreCmd()) + c, fs = utils.AddCommand(cmd, exchangeRestoreCmd()) c.Use = c.Use + " " + exchangeServiceCommandUseSuffix diff --git a/src/cli/restore/onedrive.go b/src/cli/restore/onedrive.go index e4621d965..a31bffccf 100644 --- a/src/cli/restore/onedrive.go +++ b/src/cli/restore/onedrive.go @@ -25,16 +25,16 @@ var ( fileModifiedBefore string ) -// called by restore.go to map parent subcommands to provider-specific handling. -func addOneDriveCommands(parent *cobra.Command) *cobra.Command { +// called by restore.go to map subcommands to provider-specific handling. +func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { var ( c *cobra.Command fs *pflag.FlagSet ) - switch parent.Use { + switch cmd.Use { case restoreCommand: - c, fs = utils.AddCommand(parent, oneDriveRestoreCmd()) + c, fs = utils.AddCommand(cmd, oneDriveRestoreCmd()) c.Use = c.Use + " " + oneDriveServiceCommandUseSuffix diff --git a/src/cli/restore/restore.go b/src/cli/restore/restore.go index 541c9d37a..e6873f860 100644 --- a/src/cli/restore/restore.go +++ b/src/cli/restore/restore.go @@ -4,15 +4,16 @@ import ( "github.com/spf13/cobra" ) -var restoreCommands = []func(parent *cobra.Command) *cobra.Command{ +var restoreCommands = []func(cmd *cobra.Command) *cobra.Command{ addExchangeCommands, addOneDriveCommands, + addSharePointCommands, } // AddCommands attaches all `corso restore * *` commands to the parent. -func AddCommands(parent *cobra.Command) { +func AddCommands(cmd *cobra.Command) { restoreC := restoreCmd() - parent.AddCommand(restoreC) + cmd.AddCommand(restoreC) for _, addRestoreTo := range restoreCommands { addRestoreTo(restoreC) diff --git a/src/cli/restore/sharepoint.go b/src/cli/restore/sharepoint.go new file mode 100644 index 000000000..8cad8e272 --- /dev/null +++ b/src/cli/restore/sharepoint.go @@ -0,0 +1,161 @@ +package restore + +import ( + "github.com/pkg/errors" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "github.com/alcionai/corso/src/cli/config" + "github.com/alcionai/corso/src/cli/options" + . "github.com/alcionai/corso/src/cli/print" + "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/internal/common" + "github.com/alcionai/corso/src/pkg/control" + "github.com/alcionai/corso/src/pkg/repository" + "github.com/alcionai/corso/src/pkg/selectors" +) + +var ( + site []string + libraryPaths []string + libraryItems []string +) + +// called by restore.go to map subcommands to provider-specific handling. +func addSharePointCommands(cmd *cobra.Command) *cobra.Command { + var ( + c *cobra.Command + fs *pflag.FlagSet + ) + + switch cmd.Use { + case restoreCommand: + c, fs = utils.AddCommand(cmd, sharePointRestoreCmd(), utils.HideCommand()) + + c.Use = c.Use + " " + sharePointServiceCommandUseSuffix + + // Flags addition ordering should follow the order we want them to appear in help and docs: + // More generic (ex: --site) and more frequently used flags take precedence. + fs.SortFlags = false + + fs.StringVar(&backupID, + utils.BackupFN, "", + "ID of the backup to restore. (required)") + cobra.CheckErr(c.MarkFlagRequired(utils.BackupFN)) + + fs.StringSliceVar(&site, + utils.SiteFN, nil, + "Restore data by site ID; accepts '"+utils.Wildcard+"' to select all sites.") + + // sharepoint hierarchy (path/name) flags + + fs.StringSliceVar( + &folderPaths, + utils.LibraryFN, nil, + "Restore library items by SharePoint library") + + fs.StringSliceVar( + &libraryItems, + utils.LibraryItemFN, nil, + "Restore library items by file name or ID") + + // sharepoint info flags + + // fs.StringVar( + // &fileCreatedAfter, + // utils.FileCreatedAfterFN, "", + // "Restore files created after this datetime") + + // others + options.AddOperationFlags(c) + } + + return c +} + +const ( + sharePointServiceCommand = "sharepoint" + sharePointServiceCommandUseSuffix = "--backup " + + //nolint:lll + sharePointServiceCommandRestoreExamples = `# Restore file with ID 98765abcdef +corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd --file 98765abcdef + +# Restore 's file named "ServerRenderTemplate.xsl in "Display Templates/Style Sheets" from a specific backup +corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd \ + --site --file "ServerRenderTemplate.xsl" --folder "Display Templates/Style Sheets" + +# Restore all files from that were created before 2020 when captured in a specific backup +corso restore sharepoint --backup 1234abcd-12ab-cd34-56de-1234abcd + --site --folder "Display Templates/Style Sheets" --file-created-before 2020-01-01T00:00:00` +) + +// `corso restore sharepoint [...]` +func sharePointRestoreCmd() *cobra.Command { + return &cobra.Command{ + Use: sharePointServiceCommand, + Short: "Restore M365 SharePoint service data", + RunE: restoreSharePointCmd, + Args: cobra.NoArgs, + Example: sharePointServiceCommandRestoreExamples, + } +} + +// processes an sharepoint service restore. +func restoreSharePointCmd(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + if utils.HasNoFlagsAndShownHelp(cmd) { + return nil + } + + opts := utils.SharePointOpts{ + Sites: site, + LibraryPaths: libraryPaths, + LibraryItems: libraryItems, + // FileCreatedAfter: fileCreatedAfter, + + Populated: utils.GetPopulatedFlags(cmd), + } + + if err := utils.ValidateSharePointRestoreFlags(backupID, opts); err != nil { + return err + } + + s, a, err := config.GetStorageAndAccount(ctx, true, nil) + if err != nil { + return Only(ctx, err) + } + + r, err := repository.Connect(ctx, a, s, options.Control()) + if err != nil { + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + } + + defer utils.CloseRepo(ctx, r) + + sel := selectors.NewSharePointRestore() + utils.IncludeSharePointRestoreDataSelectors(sel, opts) + utils.FilterSharePointRestoreInfoSelectors(sel, opts) + + // if no selector flags were specified, get all data in the service. + if len(sel.Scopes()) == 0 { + sel.Include(sel.Sites(selectors.Any())) + } + + restoreDest := control.DefaultRestoreDestination(common.SimpleDateTimeOneDrive) + + ro, err := r.NewRestore(ctx, backupID, sel.Selector, restoreDest) + if err != nil { + return Only(ctx, errors.Wrap(err, "Failed to initialize SharePoint restore")) + } + + ds, err := ro.Run(ctx) + if err != nil { + return Only(ctx, errors.Wrap(err, "Failed to run SharePoint restore")) + } + + ds.PrintEntries(ctx) + + return nil +} diff --git a/src/cli/restore/sharepoint_test.go b/src/cli/restore/sharepoint_test.go new file mode 100644 index 000000000..a0e298a83 --- /dev/null +++ b/src/cli/restore/sharepoint_test.go @@ -0,0 +1,50 @@ +package restore + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/alcionai/corso/src/internal/tester" +) + +type SharePointSuite struct { + suite.Suite +} + +func TestSharePointSuite(t *testing.T) { + suite.Run(t, new(SharePointSuite)) +} + +func (suite *SharePointSuite) TestAddSharePointCommands() { + expectUse := sharePointServiceCommand + " " + sharePointServiceCommandUseSuffix + + table := []struct { + name string + use string + expectUse string + expectShort string + expectRunE func(*cobra.Command, []string) error + }{ + {"restore onedrive", restoreCommand, expectUse, sharePointRestoreCmd().Short, restoreSharePointCmd}, + } + for _, test := range table { + suite.T().Run(test.name, func(t *testing.T) { + cmd := &cobra.Command{Use: test.use} + + c := addSharePointCommands(cmd) + require.NotNil(t, c) + + cmds := cmd.Commands() + require.Len(t, cmds, 1) + + child := cmds[0] + assert.Equal(t, test.expectUse, child.Use) + assert.Equal(t, test.expectShort, child.Short) + tester.AreSameFunc(t, test.expectRunE, child.RunE) + }) + } +} diff --git a/src/cmd/factory/exchange.go b/src/cmd/factory/exchange.go index 04691221d..bf175a622 100644 --- a/src/cmd/factory/exchange.go +++ b/src/cmd/factory/exchange.go @@ -30,10 +30,10 @@ var ( } ) -func addExchangeCommands(parent *cobra.Command) { - parent.AddCommand(emailsCmd) - parent.AddCommand(eventsCmd) - parent.AddCommand(contactsCmd) +func addExchangeCommands(cmd *cobra.Command) { + cmd.AddCommand(emailsCmd) + cmd.AddCommand(eventsCmd) + cmd.AddCommand(contactsCmd) } func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error { diff --git a/src/cmd/factory/onedrive.go b/src/cmd/factory/onedrive.go index c4bc5e01f..a76d222b9 100644 --- a/src/cmd/factory/onedrive.go +++ b/src/cmd/factory/onedrive.go @@ -13,8 +13,8 @@ var filesCmd = &cobra.Command{ RunE: handleOneDriveFileFactory, } -func addOneDriveCommands(parent *cobra.Command) { - parent.AddCommand(filesCmd) +func addOneDriveCommands(cmd *cobra.Command) { + cmd.AddCommand(filesCmd) } func handleOneDriveFileFactory(cmd *cobra.Command, args []string) error { diff --git a/src/internal/observe/observe.go b/src/internal/observe/observe.go index 0d66f1825..1e27794d2 100644 --- a/src/internal/observe/observe.go +++ b/src/internal/observe/observe.go @@ -38,8 +38,8 @@ func init() { // adds the persistent boolean flag --hide-progress to the provided command. // This is a hack for help displays. Due to seeding the context, we also // need to parse the configuration before we execute the command. -func AddProgressBarFlags(parent *cobra.Command) { - fs := parent.PersistentFlags() +func AddProgressBarFlags(cmd *cobra.Command) { + fs := cmd.PersistentFlags() fs.Bool(hideProgressBarsFN, false, "turn off the progress bar displays") fs.Bool(retainProgressBarsFN, false, "retain the progress bar displays after completion") } diff --git a/src/pkg/logger/logger.go b/src/pkg/logger/logger.go index 9f73175ff..13982463a 100644 --- a/src/pkg/logger/logger.go +++ b/src/pkg/logger/logger.go @@ -39,8 +39,8 @@ const ( // defaults to "info". // This is a hack for help displays. Due to seeding the context, we also // need to parse the log level before we execute the command. -func AddLogLevelFlag(parent *cobra.Command) { - fs := parent.PersistentFlags() +func AddLogLevelFlag(cmd *cobra.Command) { + fs := cmd.PersistentFlags() fs.StringVar(&llFlag, logLevelFN, "info", "set the log level to debug|info|warn|error") fs.Bool(