diff --git a/src/cli/backup/backup.go b/src/cli/backup/backup.go index c721e4c3f..f43cd6474 100644 --- a/src/cli/backup/backup.go +++ b/src/cli/backup/backup.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/idname" @@ -58,31 +59,21 @@ func AddCommands(cmd *cobra.Command) { // common flags and flag attachers for commands // --------------------------------------------------------------------------- -// list output filter flags -var ( - failedItemsFN = "failed-items" - listFailedItems string - skippedItemsFN = "skipped-items" - listSkippedItems string - recoveredErrorsFN = "recovered-errors" - listRecoveredErrors string -) - func addFailedItemsFN(cmd *cobra.Command) { cmd.Flags().StringVar( - &listFailedItems, failedItemsFN, "show", + &flags.ListFailedItemsFV, flags.FailedItemsFN, "show", "Toggles showing or hiding the list of items that failed.") } func addSkippedItemsFN(cmd *cobra.Command) { cmd.Flags().StringVar( - &listSkippedItems, skippedItemsFN, "show", + &flags.ListSkippedItemsFV, flags.SkippedItemsFN, "show", "Toggles showing or hiding the list of items that were skipped.") } func addRecoveredErrorsFN(cmd *cobra.Command) { cmd.Flags().StringVar( - &listRecoveredErrors, recoveredErrorsFN, "show", + &flags.ListRecoveredErrorsFV, flags.RecoveredErrorsFN, "show", "Toggles showing or hiding the list of errors which corso recovered from.") } @@ -318,7 +309,11 @@ func genericListCommand(cmd *cobra.Command, bID string, service path.ServiceType } b.Print(ctx) - fe.PrintItems(ctx, !ifShow(listFailedItems), !ifShow(listSkippedItems), !ifShow(listRecoveredErrors)) + fe.PrintItems( + ctx, + !ifShow(flags.ListFailedItemsFV), + !ifShow(flags.ListSkippedItemsFV), + !ifShow(flags.ListRecoveredErrorsFV)) return nil } diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index af71c6a30..06a231a3d 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/data" @@ -31,7 +31,7 @@ const ( const ( exchangeServiceCommand = "exchange" - exchangeServiceCommandCreateUseSuffix = "--mailbox | '" + utils.Wildcard + "'" + exchangeServiceCommandCreateUseSuffix = "--mailbox | '" + flags.Wildcard + "'" exchangeServiceCommandDeleteUseSuffix = "--backup " exchangeServiceCommandDetailsUseSuffix = "--backup " ) @@ -82,20 +82,20 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --user) and more frequently used flags take precedence. - utils.AddMailBoxFlag(c) - utils.AddDataFlag(c, []string{dataEmail, dataContacts, dataEvents}, false) - options.AddFetchParallelismFlag(c) - options.AddFailFastFlag(c) - options.AddDisableIncrementalsFlag(c) - options.AddDisableDeltaFlag(c) - options.AddEnableImmutableIDFlag(c) - options.AddDisableConcurrencyLimiterFlag(c) + flags.AddMailBoxFlag(c) + flags.AddDataFlag(c, []string{dataEmail, dataContacts, dataEvents}, false) + flags.AddFetchParallelismFlag(c) + flags.AddFailFastFlag(c) + flags.AddDisableIncrementalsFlag(c) + flags.AddDisableDeltaFlag(c) + flags.AddEnableImmutableIDFlag(c) + flags.AddDisableConcurrencyLimiterFlag(c) case listCommand: c, fs = utils.AddCommand(cmd, exchangeListCmd()) fs.SortFlags = false - utils.AddBackupIDFlag(c, false) + flags.AddBackupIDFlag(c, false) addFailedItemsFN(c) addSkippedItemsFN(c) addRecoveredErrorsFN(c) @@ -107,12 +107,12 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + exchangeServiceCommandDetailsUseSuffix c.Example = exchangeServiceCommandDetailsExamples - options.AddSkipReduceFlag(c) + flags.AddSkipReduceFlag(c) // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --user) and more frequently used flags take precedence. - utils.AddBackupIDFlag(c, true) - utils.AddExchangeDetailsAndRestoreFlags(c) + flags.AddBackupIDFlag(c, true) + flags.AddExchangeDetailsAndRestoreFlags(c) case deleteCommand: c, fs = utils.AddCommand(cmd, exchangeDeleteCmd()) @@ -121,7 +121,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + exchangeServiceCommandDeleteUseSuffix c.Example = exchangeServiceCommandDeleteExamples - utils.AddBackupIDFlag(c, true) + flags.AddBackupIDFlag(c, true) } return c @@ -149,7 +149,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { return nil } - if err := validateExchangeBackupCreateFlags(utils.UserFV, utils.CategoryDataFV); err != nil { + if err := validateExchangeBackupCreateFlags(flags.UserFV, flags.CategoryDataFV); err != nil { return err } @@ -160,7 +160,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - sel := exchangeBackupCreateSelectors(utils.UserFV, utils.CategoryDataFV) + sel := exchangeBackupCreateSelectors(flags.UserFV, flags.CategoryDataFV) ins, err := utils.UsersMap(ctx, *acct, fault.New(true)) if err != nil { @@ -235,7 +235,7 @@ func exchangeListCmd() *cobra.Command { // lists the history of backup operations func listExchangeCmd(cmd *cobra.Command, args []string) error { - return genericListCommand(cmd, utils.BackupIDFV, path.ExchangeService, args) + return genericListCommand(cmd, flags.BackupIDFV, path.ExchangeService, args) } // ------------------------------------------------------------------------------------------------ @@ -269,9 +269,9 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - ctrlOpts := options.Control() + ctrlOpts := utils.Control() - ds, err := runDetailsExchangeCmd(ctx, r, utils.BackupIDFV, opts, ctrlOpts.SkipReduce) + ds, err := runDetailsExchangeCmd(ctx, r, flags.BackupIDFV, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } @@ -340,5 +340,5 @@ func exchangeDeleteCmd() *cobra.Command { // deletes an exchange service backup. func deleteExchangeCmd(cmd *cobra.Command, args []string) error { - return genericDeleteCommand(cmd, utils.BackupIDFV, "Exchange", args) + return genericDeleteCommand(cmd, flags.BackupIDFV, "Exchange", args) } diff --git a/src/cli/backup/exchange_e2e_test.go b/src/cli/backup/exchange_e2e_test.go index 9400f0d90..517f42e88 100644 --- a/src/cli/backup/exchange_e2e_test.go +++ b/src/cli/backup/exchange_e2e_test.go @@ -16,8 +16,8 @@ import ( "github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli/config" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/print" - "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/m365/exchange" "github.com/alcionai/corso/src/internal/operations" @@ -469,7 +469,7 @@ func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category p cmd := tester.StubRootCmd( "backup", "details", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(bID)) + "--"+flags.BackupFN, string(bID)) cli.BuildCommandTree(cmd) cmd.SetOut(&suite.recorder) @@ -568,7 +568,7 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd() { cmd := tester.StubRootCmd( "backup", "delete", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) + "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) cli.BuildCommandTree(cmd) // run the command @@ -597,7 +597,7 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd_UnknownID cmd := tester.StubRootCmd( "backup", "delete", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, uuid.NewString()) + "--"+flags.BackupFN, uuid.NewString()) cli.BuildCommandTree(cmd) // unknown backupIDs should error since the modelStore can't find the backup @@ -617,8 +617,8 @@ func buildExchangeBackupCmd( cmd := tester.StubRootCmd( "backup", "create", "exchange", "--config-file", configFile, - "--"+utils.UserFN, user, - "--"+utils.CategoryDataFN, category) + "--"+flags.UserFN, user, + "--"+flags.CategoryDataFN, category) cli.BuildCommandTree(cmd) cmd.SetOut(recorder) diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index ec78978a2..6bd078797 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -10,8 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/alcionai/corso/src/cli/options" - "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/version" @@ -43,14 +42,14 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { expectUse + " " + exchangeServiceCommandCreateUseSuffix, exchangeCreateCmd().Short, []string{ - utils.UserFN, - utils.CategoryDataFN, - options.DisableIncrementalsFN, - options.DisableDeltaFN, - options.FailFastFN, - options.FetchParallelismFN, - options.SkipReduceFN, - options.NoStatsFN, + flags.UserFN, + flags.CategoryDataFN, + flags.DisableIncrementalsFN, + flags.DisableDeltaFN, + flags.FailFastFN, + flags.FetchParallelismFN, + flags.SkipReduceFN, + flags.NoStatsFN, }, createExchangeCmd, }, @@ -60,10 +59,10 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { expectUse, exchangeListCmd().Short, []string{ - utils.BackupFN, - failedItemsFN, - skippedItemsFN, - recoveredErrorsFN, + flags.BackupFN, + flags.FailedItemsFN, + flags.SkippedItemsFN, + flags.RecoveredErrorsFN, }, listExchangeCmd, }, @@ -73,23 +72,23 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { expectUse + " " + exchangeServiceCommandDetailsUseSuffix, exchangeDetailsCmd().Short, []string{ - utils.BackupFN, - utils.ContactFN, - utils.ContactFolderFN, - utils.ContactNameFN, - utils.EmailFN, - utils.EmailFolderFN, - utils.EmailReceivedAfterFN, - utils.EmailReceivedBeforeFN, - utils.EmailSenderFN, - utils.EmailSubjectFN, - utils.EventFN, - utils.EventCalendarFN, - utils.EventOrganizerFN, - utils.EventRecursFN, - utils.EventStartsAfterFN, - utils.EventStartsBeforeFN, - utils.EventSubjectFN, + flags.BackupFN, + flags.ContactFN, + flags.ContactFolderFN, + flags.ContactNameFN, + flags.EmailFN, + flags.EmailFolderFN, + flags.EmailReceivedAfterFN, + flags.EmailReceivedBeforeFN, + flags.EmailSenderFN, + flags.EmailSubjectFN, + flags.EventFN, + flags.EventCalendarFN, + flags.EventOrganizerFN, + flags.EventRecursFN, + flags.EventStartsAfterFN, + flags.EventStartsBeforeFN, + flags.EventSubjectFN, }, detailsExchangeCmd, }, @@ -98,7 +97,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { deleteCommand, expectUse + " " + exchangeServiceCommandDeleteUseSuffix, exchangeDeleteCmd().Short, - []string{utils.BackupFN}, + []string{flags.BackupFN}, deleteExchangeCmd, }, } @@ -171,7 +170,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, no data", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, expectIncludeLen: 3, }, { @@ -181,7 +180,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, contacts", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataContacts}, expectIncludeLen: 1, }, @@ -193,7 +192,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, email", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataEmail}, expectIncludeLen: 1, }, @@ -205,7 +204,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, events", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataEvents}, expectIncludeLen: 1, }, @@ -217,7 +216,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, contacts + email", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataContacts, dataEmail}, expectIncludeLen: 2, }, @@ -229,7 +228,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, email + events", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataEmail, dataEvents}, expectIncludeLen: 2, }, @@ -241,7 +240,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() { }, { name: "any users, events + contacts", - user: []string{utils.Wildcard}, + user: []string{flags.Wildcard}, data: []string{dataEvents, dataContacts}, expectIncludeLen: 2, }, diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index b47acd496..11efd93fe 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/data" @@ -25,7 +25,7 @@ import ( const ( oneDriveServiceCommand = "onedrive" - oneDriveServiceCommandCreateUseSuffix = "--user | '" + utils.Wildcard + "'" + oneDriveServiceCommandCreateUseSuffix = "--user | '" + flags.Wildcard + "'" oneDriveServiceCommandDeleteUseSuffix = "--backup " oneDriveServiceCommandDetailsUseSuffix = "--backup " ) @@ -70,15 +70,15 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + oneDriveServiceCommandCreateUseSuffix c.Example = oneDriveServiceCommandCreateExamples - utils.AddUserFlag(c) - options.AddFailFastFlag(c) - options.AddDisableIncrementalsFlag(c) + flags.AddUserFlag(c) + flags.AddFailFastFlag(c) + flags.AddDisableIncrementalsFlag(c) case listCommand: c, fs = utils.AddCommand(cmd, oneDriveListCmd()) fs.SortFlags = false - utils.AddBackupIDFlag(c, false) + flags.AddBackupIDFlag(c, false) addFailedItemsFN(c) addSkippedItemsFN(c) addRecoveredErrorsFN(c) @@ -90,9 +90,9 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + oneDriveServiceCommandDetailsUseSuffix c.Example = oneDriveServiceCommandDetailsExamples - options.AddSkipReduceFlag(c) - utils.AddBackupIDFlag(c, true) - utils.AddOneDriveDetailsAndRestoreFlags(c) + flags.AddSkipReduceFlag(c) + flags.AddBackupIDFlag(c, true) + flags.AddOneDriveDetailsAndRestoreFlags(c) case deleteCommand: c, fs = utils.AddCommand(cmd, oneDriveDeleteCmd()) @@ -101,7 +101,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + oneDriveServiceCommandDeleteUseSuffix c.Example = oneDriveServiceCommandDeleteExamples - utils.AddBackupIDFlag(c, true) + flags.AddBackupIDFlag(c, true) } return c @@ -130,7 +130,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error { return nil } - if err := validateOneDriveBackupCreateFlags(utils.UserFV); err != nil { + if err := validateOneDriveBackupCreateFlags(flags.UserFV); err != nil { return err } @@ -141,7 +141,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - sel := oneDriveBackupCreateSelectors(utils.UserFV) + sel := oneDriveBackupCreateSelectors(flags.UserFV) ins, err := utils.UsersMap(ctx, *acct, fault.New(true)) if err != nil { @@ -193,7 +193,7 @@ func oneDriveListCmd() *cobra.Command { // lists the history of backup operations func listOneDriveCmd(cmd *cobra.Command, args []string) error { - return genericListCommand(cmd, utils.BackupIDFV, path.OneDriveService, args) + return genericListCommand(cmd, flags.BackupIDFV, path.OneDriveService, args) } // ------------------------------------------------------------------------------------------------ @@ -227,9 +227,9 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - ctrlOpts := options.Control() + ctrlOpts := utils.Control() - ds, err := runDetailsOneDriveCmd(ctx, r, utils.BackupIDFV, opts, ctrlOpts.SkipReduce) + ds, err := runDetailsOneDriveCmd(ctx, r, flags.BackupIDFV, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } @@ -295,5 +295,5 @@ func oneDriveDeleteCmd() *cobra.Command { // deletes a oneDrive service backup. func deleteOneDriveCmd(cmd *cobra.Command, args []string) error { - return genericDeleteCommand(cmd, utils.BackupIDFV, "OneDrive", args) + return genericDeleteCommand(cmd, flags.BackupIDFV, "OneDrive", args) } diff --git a/src/cli/backup/onedrive_e2e_test.go b/src/cli/backup/onedrive_e2e_test.go index 6ae96f368..07024f612 100644 --- a/src/cli/backup/onedrive_e2e_test.go +++ b/src/cli/backup/onedrive_e2e_test.go @@ -14,8 +14,8 @@ import ( "github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli/config" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/print" - "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/tester" @@ -108,7 +108,7 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() { cmd := tester.StubRootCmd( "backup", "create", "onedrive", "--config-file", suite.cfgFP, - "--"+utils.UserFN, "foo@nothere.com") + "--"+flags.UserFN, "foo@nothere.com") cli.BuildCommandTree(cmd) cmd.SetOut(&recorder) @@ -200,7 +200,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() { cmd := tester.StubRootCmd( "backup", "delete", "onedrive", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) + "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) cli.BuildCommandTree(cmd) cmd.SetErr(&suite.recorder) @@ -240,7 +240,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd_unknownID cmd := tester.StubRootCmd( "backup", "delete", "onedrive", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, uuid.NewString()) + "--"+flags.BackupFN, uuid.NewString()) cli.BuildCommandTree(cmd) // unknown backupIDs should error since the modelStore can't find the backup diff --git a/src/cli/backup/onedrive_test.go b/src/cli/backup/onedrive_test.go index caa52561b..3ac476aa7 100644 --- a/src/cli/backup/onedrive_test.go +++ b/src/cli/backup/onedrive_test.go @@ -10,8 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/alcionai/corso/src/cli/options" - "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/version" @@ -43,9 +42,9 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { expectUse + " " + oneDriveServiceCommandCreateUseSuffix, oneDriveCreateCmd().Short, []string{ - utils.UserFN, - options.DisableIncrementalsFN, - options.FailFastFN, + flags.UserFN, + flags.DisableIncrementalsFN, + flags.FailFastFN, }, createOneDriveCmd, }, @@ -55,10 +54,10 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { expectUse, oneDriveListCmd().Short, []string{ - utils.BackupFN, - failedItemsFN, - skippedItemsFN, - recoveredErrorsFN, + flags.BackupFN, + flags.FailedItemsFN, + flags.SkippedItemsFN, + flags.RecoveredErrorsFN, }, listOneDriveCmd, }, @@ -68,13 +67,13 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { expectUse + " " + oneDriveServiceCommandDetailsUseSuffix, oneDriveDetailsCmd().Short, []string{ - utils.BackupFN, - utils.FolderFN, - utils.FileFN, - utils.FileCreatedAfterFN, - utils.FileCreatedBeforeFN, - utils.FileModifiedAfterFN, - utils.FileModifiedBeforeFN, + flags.BackupFN, + flags.FolderFN, + flags.FileFN, + flags.FileCreatedAfterFN, + flags.FileCreatedBeforeFN, + flags.FileModifiedAfterFN, + flags.FileModifiedBeforeFN, }, detailsOneDriveCmd, }, @@ -83,7 +82,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { deleteCommand, expectUse + " " + oneDriveServiceCommandDeleteUseSuffix, oneDriveDeleteCmd().Short, - []string{utils.BackupFN}, + []string{flags.BackupFN}, deleteOneDriveCmd, }, } diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index 2197252ea..2d730e51c 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -9,7 +9,7 @@ import ( "github.com/spf13/pflag" "golang.org/x/exp/slices" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/idname" @@ -34,7 +34,7 @@ const ( const ( sharePointServiceCommand = "sharepoint" - sharePointServiceCommandCreateUseSuffix = "--site | '" + utils.Wildcard + "'" + sharePointServiceCommandCreateUseSuffix = "--site | '" + flags.Wildcard + "'" sharePointServiceCommandDeleteUseSuffix = "--backup " sharePointServiceCommandDetailsUseSuffix = "--backup " ) @@ -84,17 +84,17 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix c.Example = sharePointServiceCommandCreateExamples - utils.AddSiteFlag(c) - utils.AddSiteIDFlag(c) - utils.AddDataFlag(c, []string{dataLibraries}, true) - options.AddFailFastFlag(c) - options.AddDisableIncrementalsFlag(c) + flags.AddSiteFlag(c) + flags.AddSiteIDFlag(c) + flags.AddDataFlag(c, []string{dataLibraries}, true) + flags.AddFailFastFlag(c) + flags.AddDisableIncrementalsFlag(c) case listCommand: c, fs = utils.AddCommand(cmd, sharePointListCmd()) fs.SortFlags = false - utils.AddBackupIDFlag(c, false) + flags.AddBackupIDFlag(c, false) addFailedItemsFN(c) addSkippedItemsFN(c) addRecoveredErrorsFN(c) @@ -106,9 +106,9 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix c.Example = sharePointServiceCommandDetailsExamples - options.AddSkipReduceFlag(c) - utils.AddBackupIDFlag(c, true) - utils.AddSharePointDetailsAndRestoreFlags(c) + flags.AddSkipReduceFlag(c) + flags.AddBackupIDFlag(c, true) + flags.AddSharePointDetailsAndRestoreFlags(c) case deleteCommand: c, fs = utils.AddCommand(cmd, sharePointDeleteCmd()) @@ -117,7 +117,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { c.Use = c.Use + " " + sharePointServiceCommandDeleteUseSuffix c.Example = sharePointServiceCommandDeleteExamples - utils.AddBackupIDFlag(c, true) + flags.AddBackupIDFlag(c, true) } return c @@ -146,7 +146,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return nil } - if err := validateSharePointBackupCreateFlags(utils.SiteIDFV, utils.WebURLFV, utils.CategoryDataFV); err != nil { + if err := validateSharePointBackupCreateFlags(flags.SiteIDFV, flags.WebURLFV, flags.CategoryDataFV); err != nil { return err } @@ -165,7 +165,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return Only(ctx, clues.Wrap(err, "Failed to retrieve M365 sites")) } - sel, err := sharePointBackupCreateSelectors(ctx, ins, utils.SiteIDFV, utils.WebURLFV, utils.CategoryDataFV) + sel, err := sharePointBackupCreateSelectors(ctx, ins, flags.SiteIDFV, flags.WebURLFV, flags.CategoryDataFV) if err != nil { return Only(ctx, clues.Wrap(err, "Retrieving up sharepoint sites by ID and URL")) } @@ -188,8 +188,8 @@ func validateSharePointBackupCreateFlags(sites, weburls, cats []string) error { if len(sites) == 0 && len(weburls) == 0 { return clues.New( "requires one or more --" + - utils.SiteFN + " urls, or the wildcard --" + - utils.SiteFN + " *", + flags.SiteFN + " urls, or the wildcard --" + + flags.SiteFN + " *", ) } @@ -214,11 +214,11 @@ func sharePointBackupCreateSelectors( return selectors.NewSharePointBackup(selectors.None()), nil } - if filters.PathContains(sites).Compare(utils.Wildcard) { + if filters.PathContains(sites).Compare(flags.Wildcard) { return includeAllSitesWithCategories(ins, cats), nil } - if filters.PathContains(weburls).Compare(utils.Wildcard) { + if filters.PathContains(weburls).Compare(flags.Wildcard) { return includeAllSitesWithCategories(ins, cats), nil } @@ -265,7 +265,7 @@ func sharePointListCmd() *cobra.Command { // lists the history of backup operations func listSharePointCmd(cmd *cobra.Command, args []string) error { - return genericListCommand(cmd, utils.BackupIDFV, path.SharePointService, args) + return genericListCommand(cmd, flags.BackupIDFV, path.SharePointService, args) } // ------------------------------------------------------------------------------------------------ @@ -285,7 +285,7 @@ func sharePointDeleteCmd() *cobra.Command { // deletes a sharePoint service backup. func deleteSharePointCmd(cmd *cobra.Command, args []string) error { - return genericDeleteCommand(cmd, utils.BackupIDFV, "SharePoint", args) + return genericDeleteCommand(cmd, flags.BackupIDFV, "SharePoint", args) } // ------------------------------------------------------------------------------------------------ @@ -319,9 +319,9 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - ctrlOpts := options.Control() + ctrlOpts := utils.Control() - ds, err := runDetailsSharePointCmd(ctx, r, utils.BackupIDFV, opts, ctrlOpts.SkipReduce) + ds, err := runDetailsSharePointCmd(ctx, r, flags.BackupIDFV, opts, ctrlOpts.SkipReduce) if err != nil { return Only(ctx, err) } diff --git a/src/cli/backup/sharepoint_e2e_test.go b/src/cli/backup/sharepoint_e2e_test.go index e3c3c5570..25afc1f8e 100644 --- a/src/cli/backup/sharepoint_e2e_test.go +++ b/src/cli/backup/sharepoint_e2e_test.go @@ -14,8 +14,8 @@ import ( "github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli/config" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/print" - "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/tester" @@ -164,7 +164,7 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd() { cmd := tester.StubRootCmd( "backup", "delete", "sharepoint", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) + "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) cli.BuildCommandTree(cmd) cmd.SetErr(&suite.recorder) @@ -205,7 +205,7 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd_unkno cmd := tester.StubRootCmd( "backup", "delete", "sharepoint", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, uuid.NewString()) + "--"+flags.BackupFN, uuid.NewString()) cli.BuildCommandTree(cmd) // unknown backupIDs should error since the modelStore can't find the backup diff --git a/src/cli/backup/sharepoint_test.go b/src/cli/backup/sharepoint_test.go index 0469a40ef..648d3e8c4 100644 --- a/src/cli/backup/sharepoint_test.go +++ b/src/cli/backup/sharepoint_test.go @@ -10,8 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" - "github.com/alcionai/corso/src/cli/options" - "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/tester" @@ -45,9 +44,9 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { expectUse + " " + sharePointServiceCommandCreateUseSuffix, sharePointCreateCmd().Short, []string{ - utils.SiteFN, - options.DisableIncrementalsFN, - options.FailFastFN, + flags.SiteFN, + flags.DisableIncrementalsFN, + flags.FailFastFN, }, createSharePointCmd, }, @@ -57,10 +56,10 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { expectUse, sharePointListCmd().Short, []string{ - utils.BackupFN, - failedItemsFN, - skippedItemsFN, - recoveredErrorsFN, + flags.BackupFN, + flags.FailedItemsFN, + flags.SkippedItemsFN, + flags.RecoveredErrorsFN, }, listSharePointCmd, }, @@ -70,14 +69,14 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { expectUse + " " + sharePointServiceCommandDetailsUseSuffix, sharePointDetailsCmd().Short, []string{ - utils.BackupFN, - utils.LibraryFN, - utils.FolderFN, - utils.FileFN, - utils.FileCreatedAfterFN, - utils.FileCreatedBeforeFN, - utils.FileModifiedAfterFN, - utils.FileModifiedBeforeFN, + flags.BackupFN, + flags.LibraryFN, + flags.FolderFN, + flags.FileFN, + flags.FileCreatedAfterFN, + flags.FileCreatedBeforeFN, + flags.FileModifiedAfterFN, + flags.FileModifiedBeforeFN, }, detailsSharePointCmd, }, @@ -86,7 +85,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { deleteCommand, expectUse + " " + sharePointServiceCommandDeleteUseSuffix, sharePointDeleteCmd().Short, - []string{utils.BackupFN}, + []string{flags.BackupFN}, deleteSharePointCmd, }, } @@ -183,13 +182,13 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() { }, { name: "site wildcard", - site: []string{utils.Wildcard}, + site: []string{flags.Wildcard}, expect: bothIDs, expectScopesLen: 2, }, { name: "url wildcard", - weburl: []string{utils.Wildcard}, + weburl: []string{flags.Wildcard}, expect: bothIDs, expectScopesLen: 2, }, @@ -221,7 +220,7 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() { }, { name: "unnecessary site wildcard", - site: []string{id1, utils.Wildcard}, + site: []string{id1, flags.Wildcard}, weburl: []string{url1, url2}, expect: bothIDs, expectScopesLen: 2, @@ -229,7 +228,7 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() { { name: "unnecessary url wildcard", site: []string{id1}, - weburl: []string{url1, utils.Wildcard}, + weburl: []string{url1, flags.Wildcard}, expect: bothIDs, expectScopesLen: 2, }, diff --git a/src/cli/cli.go b/src/cli/cli.go index eb1276cb5..e69d89eb5 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -11,8 +11,8 @@ import ( "github.com/alcionai/corso/src/cli/backup" "github.com/alcionai/corso/src/cli/config" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/help" - "github.com/alcionai/corso/src/cli/options" "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/repo" "github.com/alcionai/corso/src/cli/restore" @@ -44,11 +44,11 @@ func preRun(cc *cobra.Command, args []string) error { ctx := cc.Context() log := logger.Ctx(ctx) - flags := utils.GetPopulatedFlags(cc) - flagSl := make([]string, 0, len(flags)) + fs := flags.GetPopulatedFlags(cc) + flagSl := make([]string, 0, len(fs)) // currently only tracking flag names to avoid pii leakage. - for f := range flags { + for f := range fs { flagSl = append(flagSl, f) } @@ -87,7 +87,7 @@ func preRun(cc *cobra.Command, args []string) error { cfg.Account.ID(), map[string]any{"command": cc.CommandPath()}, cfg.RepoID, - options.Control()) + utils.Control()) } // handle deprecated user flag in Backup exchange command @@ -138,7 +138,7 @@ func CorsoCommand() *cobra.Command { func BuildCommandTree(cmd *cobra.Command) { // want to order flags explicitly cmd.PersistentFlags().SortFlags = false - utils.AddRunModeFlag(cmd, true) + flags.AddRunModeFlag(cmd, true) cmd.Flags().BoolP("version", "v", false, "current version info") cmd.PersistentPreRunE = preRun @@ -146,7 +146,7 @@ func BuildCommandTree(cmd *cobra.Command) { logger.AddLoggingFlags(cmd) observe.AddProgressBarFlags(cmd) print.AddOutputFlag(cmd) - options.AddGlobalOperationFlags(cmd) + flags.AddGlobalOperationFlags(cmd) cmd.SetUsageTemplate(indentExamplesTemplate(corsoCmd.UsageTemplate())) cmd.CompletionOptions.DisableDefaultCmd = true diff --git a/src/cli/flags/exchange.go b/src/cli/flags/exchange.go new file mode 100644 index 000000000..c859e84a1 --- /dev/null +++ b/src/cli/flags/exchange.go @@ -0,0 +1,124 @@ +package flags + +import ( + "github.com/spf13/cobra" +) + +const ( + ContactFN = "contact" + ContactFolderFN = "contact-folder" + ContactNameFN = "contact-name" + + EmailFN = "email" + EmailFolderFN = "email-folder" + EmailReceivedAfterFN = "email-received-after" + EmailReceivedBeforeFN = "email-received-before" + EmailSenderFN = "email-sender" + EmailSubjectFN = "email-subject" + + EventFN = "event" + EventCalendarFN = "event-calendar" + EventOrganizerFN = "event-organizer" + EventRecursFN = "event-recurs" + EventStartsAfterFN = "event-starts-after" + EventStartsBeforeFN = "event-starts-before" + EventSubjectFN = "event-subject" +) + +// flag values (ie: FV) +var ( + ContactFV []string + ContactFolderFV []string + ContactNameFV string + + EmailFV []string + EmailFolderFV []string + EmailReceivedAfterFV string + EmailReceivedBeforeFV string + EmailSenderFV string + EmailSubjectFV string + + EventFV []string + EventCalendarFV []string + EventOrganizerFV string + EventRecursFV string + EventStartsAfterFV string + EventStartsBeforeFV string + EventSubjectFV string +) + +// AddExchangeDetailsAndRestoreFlags adds flags that are common to both the +// details and restore commands. +func AddExchangeDetailsAndRestoreFlags(cmd *cobra.Command) { + fs := cmd.Flags() + + // email flags + fs.StringSliceVar( + &EmailFV, + EmailFN, nil, + "Select email messages by ID; accepts '"+Wildcard+"' to select all emails.") + fs.StringSliceVar( + &EmailFolderFV, + EmailFolderFN, nil, + "Select emails within a folder; accepts '"+Wildcard+"' to select all email folders.") + fs.StringVar( + &EmailSubjectFV, + EmailSubjectFN, "", + "Select emails with a subject containing this value.") + fs.StringVar( + &EmailSenderFV, + EmailSenderFN, "", + "Select emails from a specific sender.") + fs.StringVar( + &EmailReceivedAfterFV, + EmailReceivedAfterFN, "", + "Select emails received after this datetime.") + fs.StringVar( + &EmailReceivedBeforeFV, + EmailReceivedBeforeFN, "", + "Select emails received before this datetime.") + + // event flags + fs.StringSliceVar( + &EventFV, + EventFN, nil, + "Select events by event ID; accepts '"+Wildcard+"' to select all events.") + fs.StringSliceVar( + &EventCalendarFV, + EventCalendarFN, nil, + "Select events under a calendar; accepts '"+Wildcard+"' to select all events.") + fs.StringVar( + &EventSubjectFV, + EventSubjectFN, "", + "Select events with a subject containing this value.") + fs.StringVar( + &EventOrganizerFV, + EventOrganizerFN, "", + "Select events from a specific organizer.") + fs.StringVar( + &EventRecursFV, + EventRecursFN, "", + "Select recurring events. Use `--event-recurs false` to select non-recurring events.") + fs.StringVar( + &EventStartsAfterFV, + EventStartsAfterFN, "", + "Select events starting after this datetime.") + fs.StringVar( + &EventStartsBeforeFV, + EventStartsBeforeFN, "", + "Select events starting before this datetime.") + + // contact flags + fs.StringSliceVar( + &ContactFV, + ContactFN, nil, + "Select contacts by contact ID; accepts '"+Wildcard+"' to select all contacts.") + fs.StringSliceVar( + &ContactFolderFV, + ContactFolderFN, nil, + "Select contacts within a folder; accepts '"+Wildcard+"' to select all contact folders.") + fs.StringVar( + &ContactNameFV, + ContactNameFN, "", + "Select contacts whose contact name contains this value.") +} diff --git a/src/cli/flags/flags.go b/src/cli/flags/flags.go new file mode 100644 index 000000000..dd9ac1ddc --- /dev/null +++ b/src/cli/flags/flags.go @@ -0,0 +1,36 @@ +package flags + +import ( + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +const Wildcard = "*" + +type PopulatedFlags map[string]struct{} + +func (fs PopulatedFlags) populate(pf *pflag.Flag) { + if pf == nil { + return + } + + if pf.Changed { + fs[pf.Name] = struct{}{} + } +} + +// GetPopulatedFlags returns a map of flags that have been +// populated by the user. Entry keys match the flag's long +// name. Values are empty. +func GetPopulatedFlags(cmd *cobra.Command) PopulatedFlags { + pop := PopulatedFlags{} + + fs := cmd.Flags() + if fs == nil { + return pop + } + + fs.VisitAll(pop.populate) + + return pop +} diff --git a/src/cli/flags/m365_common.go b/src/cli/flags/m365_common.go new file mode 100644 index 000000000..d4a0c0231 --- /dev/null +++ b/src/cli/flags/m365_common.go @@ -0,0 +1,42 @@ +package flags + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" +) + +var CategoryDataFV []string + +const CategoryDataFN = "data" + +func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) { + var ( + allowedMsg string + fs = cmd.Flags() + ) + + switch len(allowed) { + case 0: + return + case 1: + allowedMsg = allowed[0] + case 2: + allowedMsg = fmt.Sprintf("%s or %s", allowed[0], allowed[1]) + default: + allowedMsg = fmt.Sprintf( + "%s or %s", + strings.Join(allowed[:len(allowed)-1], ", "), + allowed[len(allowed)-1]) + } + + fs.StringSliceVar( + &CategoryDataFV, + CategoryDataFN, nil, + "Select one or more types of data to backup: "+allowedMsg+".") + + if hide { + cobra.CheckErr(fs.MarkHidden(CategoryDataFN)) + } +} diff --git a/src/cli/flags/m365_resource.go b/src/cli/flags/m365_resource.go new file mode 100644 index 000000000..d00897cf2 --- /dev/null +++ b/src/cli/flags/m365_resource.go @@ -0,0 +1,40 @@ +package flags + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +const ( + UserFN = "user" + MailBoxFN = "mailbox" +) + +var UserFV []string + +// AddUserFlag adds the --user flag. +func AddUserFlag(cmd *cobra.Command) { + cmd.Flags().StringSliceVar( + &UserFV, + UserFN, nil, + "Backup a specific user's data; accepts '"+Wildcard+"' to select all users.") + cobra.CheckErr(cmd.MarkFlagRequired(UserFN)) +} + +// AddMailBoxFlag adds the --user and --mailbox flag. +func AddMailBoxFlag(cmd *cobra.Command) { + flags := cmd.Flags() + + flags.StringSliceVar( + &UserFV, + UserFN, nil, + "Backup a specific user's data; accepts '"+Wildcard+"' to select all users.") + + cobra.CheckErr(flags.MarkDeprecated(UserFN, fmt.Sprintf("use --%s instead", MailBoxFN))) + + flags.StringSliceVar( + &UserFV, + MailBoxFN, nil, + "Backup a specific mailbox's data; accepts '"+Wildcard+"' to select all mailbox.") +} diff --git a/src/cli/flags/maintenance.go b/src/cli/flags/maintenance.go new file mode 100644 index 000000000..2c512603a --- /dev/null +++ b/src/cli/flags/maintenance.go @@ -0,0 +1,41 @@ +package flags + +import ( + "github.com/spf13/cobra" + + "github.com/alcionai/corso/src/pkg/control/repository" +) + +const ( + MaintenanceModeFN = "mode" + ForceMaintenanceFN = "force" +) + +var ( + MaintenanceModeFV string + ForceMaintenanceFV bool +) + +func AddMaintenanceModeFlag(cmd *cobra.Command) { + fs := cmd.Flags() + fs.StringVar( + &MaintenanceModeFV, + MaintenanceModeFN, + repository.CompleteMaintenance.String(), + "Type of maintenance operation to run. Pass '"+ + repository.MetadataMaintenance.String()+"' to run a faster maintenance "+ + "that does minimal clean-up and optimization. Pass '"+ + repository.CompleteMaintenance.String()+"' to fully compact existing "+ + "data and delete unused data.") + cobra.CheckErr(fs.MarkHidden(MaintenanceModeFN)) +} + +func AddForceMaintenanceFlag(cmd *cobra.Command) { + fs := cmd.Flags() + fs.BoolVar( + &ForceMaintenanceFV, + ForceMaintenanceFN, + false, + "Force maintenance. Caution: user must ensure this is not run concurrently on a single repo") + cobra.CheckErr(fs.MarkHidden(ForceMaintenanceFN)) +} diff --git a/src/cli/flags/onedrive.go b/src/cli/flags/onedrive.go new file mode 100644 index 000000000..62f69f0b7 --- /dev/null +++ b/src/cli/flags/onedrive.go @@ -0,0 +1,60 @@ +package flags + +import ( + "github.com/spf13/cobra" +) + +const ( + FileFN = "file" + FolderFN = "folder" + + FileCreatedAfterFN = "file-created-after" + FileCreatedBeforeFN = "file-created-before" + FileModifiedAfterFN = "file-modified-after" + FileModifiedBeforeFN = "file-modified-before" +) + +var ( + FolderPathFV []string + FileNameFV []string + + FileCreatedAfterFV string + FileCreatedBeforeFV string + FileModifiedAfterFV string + FileModifiedBeforeFV string +) + +// AddOneDriveDetailsAndRestoreFlags adds flags that are common to both the +// details and restore commands. +func AddOneDriveDetailsAndRestoreFlags(cmd *cobra.Command) { + fs := cmd.Flags() + + fs.StringSliceVar( + &FolderPathFV, + FolderFN, nil, + "Select files by OneDrive folder; defaults to root.") + + fs.StringSliceVar( + &FileNameFV, + FileFN, nil, + "Select files by name.") + + fs.StringVar( + &FileCreatedAfterFV, + FileCreatedAfterFN, "", + "Select files created after this datetime.") + fs.StringVar( + &FileCreatedBeforeFV, + FileCreatedBeforeFN, "", + "Select files created before this datetime.") + + fs.StringVar( + &FileModifiedAfterFV, + FileModifiedAfterFN, "", + "Select files modified after this datetime.") + + fs.StringVar( + &FileModifiedBeforeFV, + FileModifiedBeforeFN, "", + "Select files modified before this datetime.") +} diff --git a/src/cli/options/options.go b/src/cli/flags/options.go similarity index 66% rename from src/cli/options/options.go rename to src/cli/flags/options.go index ac76b41b8..046d3c8d7 100644 --- a/src/cli/options/options.go +++ b/src/cli/flags/options.go @@ -1,65 +1,59 @@ -package options +package flags import ( "github.com/spf13/cobra" - - "github.com/alcionai/corso/src/pkg/control" ) -// Control produces the control options based on the user's flags. -func Control() control.Options { - opt := control.Defaults() - - if failFastFV { - opt.FailureHandling = control.FailFast - } - - opt.DisableMetrics = noStatsFV - opt.RestorePermissions = restorePermissionsFV - opt.SkipReduce = skipReduceFV - opt.ToggleFeatures.DisableIncrementals = disableIncrementalsFV - opt.ToggleFeatures.DisableDelta = disableDeltaFV - opt.ToggleFeatures.ExchangeImmutableIDs = enableImmutableID - opt.ToggleFeatures.DisableConcurrencyLimiter = disableConcurrencyLimiterFV - opt.Parallelism.ItemFetch = fetchParallelismFV - - return opt -} - -// --------------------------------------------------------------------------- -// Operations Flags -// --------------------------------------------------------------------------- - const ( - FailFastFN = "fail-fast" - FetchParallelismFN = "fetch-parallelism" - NoStatsFN = "no-stats" - RestorePermissionsFN = "restore-permissions" - SkipReduceFN = "skip-reduce" + DisableConcurrencyLimiterFN = "disable-concurrency-limiter" DisableDeltaFN = "disable-delta" DisableIncrementalsFN = "disable-incrementals" EnableImmutableIDFN = "enable-immutable-id" - DisableConcurrencyLimiterFN = "disable-concurrency-limiter" + FailFastFN = "fail-fast" + FailedItemsFN = "failed-items" + FetchParallelismFN = "fetch-parallelism" + NoStatsFN = "no-stats" + RecoveredErrorsFN = "recovered-errors" + RestorePermissionsFN = "restore-permissions" + RunModeFN = "run-mode" + SkippedItemsFN = "skipped-items" + SkipReduceFN = "skip-reduce" ) var ( - failFastFV bool - fetchParallelismFV int - noStatsFV bool - restorePermissionsFV bool - skipReduceFV bool + DisableConcurrencyLimiterFV bool + DisableDeltaFV bool + DisableIncrementalsFV bool + EnableImmutableIDFV bool + FailFastFV bool + FetchParallelismFV int + ListFailedItemsFV string + ListSkippedItemsFV string + ListRecoveredErrorsFV string + NoStatsFV bool + // RunMode describes the type of run, such as: + // flagtest, dry, run. Should default to 'run'. + RunModeFV string + RestorePermissionsFV bool + SkipReduceFV bool +) + +// well-known flag values +const ( + RunModeFlagTest = "flag-test" + RunModeRun = "run" ) // AddGlobalOperationFlags adds the global operations flag set. func AddGlobalOperationFlags(cmd *cobra.Command) { fs := cmd.PersistentFlags() - fs.BoolVar(&noStatsFV, NoStatsFN, false, "disable anonymous usage statistics gathering") + fs.BoolVar(&NoStatsFV, NoStatsFN, false, "disable anonymous usage statistics gathering") } // AddFailFastFlag adds a flag to toggle fail-fast error handling behavior. func AddFailFastFlag(cmd *cobra.Command) { fs := cmd.Flags() - fs.BoolVar(&failFastFV, FailFastFN, false, "stop processing immediately if any error occurs") + fs.BoolVar(&FailFastFV, FailFastFN, false, "stop processing immediately if any error occurs") // TODO: reveal this flag when fail-fast support is implemented cobra.CheckErr(fs.MarkHidden(FailFastFN)) } @@ -67,14 +61,14 @@ func AddFailFastFlag(cmd *cobra.Command) { // AddRestorePermissionsFlag adds OneDrive flag for restoring permissions func AddRestorePermissionsFlag(cmd *cobra.Command) { fs := cmd.Flags() - fs.BoolVar(&restorePermissionsFV, RestorePermissionsFN, false, "Restore permissions for files and folders") + fs.BoolVar(&RestorePermissionsFV, RestorePermissionsFN, false, "Restore permissions for files and folders") } // AddSkipReduceFlag adds a hidden flag that allows callers to skip the selector // reduction step. Currently only intended for details commands, not restore. func AddSkipReduceFlag(cmd *cobra.Command) { fs := cmd.Flags() - fs.BoolVar(&skipReduceFV, SkipReduceFN, false, "Skip the selector reduce filtering") + fs.BoolVar(&SkipReduceFV, SkipReduceFN, false, "Skip the selector reduce filtering") cobra.CheckErr(fs.MarkHidden(SkipReduceFN)) } @@ -83,28 +77,19 @@ func AddSkipReduceFlag(cmd *cobra.Command) { func AddFetchParallelismFlag(cmd *cobra.Command) { fs := cmd.Flags() fs.IntVar( - &fetchParallelismFV, + &FetchParallelismFV, FetchParallelismFN, 4, "Control the number of concurrent data fetches for Exchange. Valid range is [1-4]. Default: 4") cobra.CheckErr(fs.MarkHidden(FetchParallelismFN)) } -// --------------------------------------------------------------------------- -// Feature Flags -// --------------------------------------------------------------------------- - -var ( - disableIncrementalsFV bool - disableDeltaFV bool -) - // Adds the hidden '--disable-incrementals' cli flag which, when set, disables // incremental backups. func AddDisableIncrementalsFlag(cmd *cobra.Command) { fs := cmd.Flags() fs.BoolVar( - &disableIncrementalsFV, + &DisableIncrementalsFV, DisableIncrementalsFN, false, "Disable incremental data retrieval in backups.") @@ -116,38 +101,45 @@ func AddDisableIncrementalsFlag(cmd *cobra.Command) { func AddDisableDeltaFlag(cmd *cobra.Command) { fs := cmd.Flags() fs.BoolVar( - &disableDeltaFV, + &DisableDeltaFV, DisableDeltaFN, false, "Disable delta based data retrieval in backups.") cobra.CheckErr(fs.MarkHidden(DisableDeltaFN)) } -var enableImmutableID bool - // Adds the hidden '--enable-immutable-id' cli flag which, when set, enables // immutable IDs for Exchange func AddEnableImmutableIDFlag(cmd *cobra.Command) { fs := cmd.Flags() fs.BoolVar( - &enableImmutableID, + &EnableImmutableIDFV, EnableImmutableIDFN, false, "Enable exchange immutable ID.") cobra.CheckErr(fs.MarkHidden(EnableImmutableIDFN)) } -var disableConcurrencyLimiterFV bool - // AddDisableConcurrencyLimiterFlag adds a hidden cli flag which, when set, // removes concurrency limits when communicating with graph API. This // flag is only relevant for exchange backups for now func AddDisableConcurrencyLimiterFlag(cmd *cobra.Command) { fs := cmd.Flags() fs.BoolVar( - &disableConcurrencyLimiterFV, + &DisableConcurrencyLimiterFV, DisableConcurrencyLimiterFN, false, "Disable concurrency limiter middleware. Default: false") cobra.CheckErr(fs.MarkHidden(DisableConcurrencyLimiterFN)) } + +// AddRunModeFlag adds the hidden --run-mode flag. +func AddRunModeFlag(cmd *cobra.Command, persistent bool) { + fs := cmd.Flags() + if persistent { + fs = cmd.PersistentFlags() + } + + fs.StringVar(&RunModeFV, RunModeFN, "run", "What mode to run: dry, test, run. Defaults to run.") + cobra.CheckErr(fs.MarkHidden(RunModeFN)) +} diff --git a/src/cli/flags/repo.go b/src/cli/flags/repo.go new file mode 100644 index 000000000..67bf6b0db --- /dev/null +++ b/src/cli/flags/repo.go @@ -0,0 +1,18 @@ +package flags + +import ( + "github.com/spf13/cobra" +) + +const BackupFN = "backup" + +var BackupIDFV string + +// AddBackupIDFlag adds the --backup flag. +func AddBackupIDFlag(cmd *cobra.Command, require bool) { + cmd.Flags().StringVar(&BackupIDFV, BackupFN, "", "ID of the backup to retrieve.") + + if require { + cobra.CheckErr(cmd.MarkFlagRequired(BackupFN)) + } +} diff --git a/src/cli/flags/sharepoint.go b/src/cli/flags/sharepoint.go new file mode 100644 index 000000000..31ba29bff --- /dev/null +++ b/src/cli/flags/sharepoint.go @@ -0,0 +1,113 @@ +package flags + +import ( + "github.com/spf13/cobra" +) + +const ( + LibraryFN = "library" + ListFolderFN = "list" + ListItemFN = "list-item" + PageFolderFN = "page-folder" + PageFN = "page" + SiteFN = "site" // site only accepts WebURL values + SiteIDFN = "site-id" // site-id accepts actual site ids +) + +var ( + LibraryFV string + ListFolderFV []string + ListItemFV []string + PageFolderFV []string + PageFV []string + SiteIDFV []string + WebURLFV []string +) + +// AddSharePointDetailsAndRestoreFlags adds flags that are common to both the +// details and restore commands. +func AddSharePointDetailsAndRestoreFlags(cmd *cobra.Command) { + fs := cmd.Flags() + + // libraries + + fs.StringVar( + &LibraryFV, + LibraryFN, "", + "Select only this library; defaults to all libraries.") + fs.StringSliceVar( + &FolderPathFV, + FolderFN, nil, + "Select by folder; defaults to root.") + fs.StringSliceVar( + &FileNameFV, + FileFN, nil, + "Select by file name.") + fs.StringVar( + &FileCreatedAfterFV, + FileCreatedAfterFN, "", + "Select files created after this datetime.") + fs.StringVar( + &FileCreatedBeforeFV, + FileCreatedBeforeFN, "", + "Select files created before this datetime.") + fs.StringVar( + &FileModifiedAfterFV, + FileModifiedAfterFN, "", + "Select files modified after this datetime.") + fs.StringVar( + &FileModifiedBeforeFV, + FileModifiedBeforeFN, "", + "Select files modified before this datetime.") + + // lists + + fs.StringSliceVar( + &ListFolderFV, + ListFolderFN, nil, + "Select lists by name; accepts '"+Wildcard+"' to select all lists.") + cobra.CheckErr(fs.MarkHidden(ListFolderFN)) + fs.StringSliceVar( + &ListItemFV, + ListItemFN, nil, + "Select lists by item name; accepts '"+Wildcard+"' to select all lists.") + cobra.CheckErr(fs.MarkHidden(ListItemFN)) + + // pages + + fs.StringSliceVar( + &PageFolderFV, + PageFolderFN, nil, + "Select pages by folder name; accepts '"+Wildcard+"' to select all pages.") + cobra.CheckErr(fs.MarkHidden(PageFolderFN)) + fs.StringSliceVar( + &PageFV, + PageFN, nil, + "Select pages by item name; accepts '"+Wildcard+"' to select all pages.") + cobra.CheckErr(fs.MarkHidden(PageFN)) +} + +// AddSiteIDFlag adds the --site-id flag, which accepts site ID values. +// This flag is hidden, since we expect users to prefer the --site url +// and do not want to encourage confusion. +func AddSiteIDFlag(cmd *cobra.Command) { + fs := cmd.Flags() + + // note string ARRAY var. IDs naturally contain commas, so we cannot accept + // duplicate values within a flag declaration. ie: --site-id a,b,c does not + // work. Users must call --site-id a --site-id b --site-id c. + fs.StringArrayVar( + &SiteIDFV, + SiteIDFN, nil, + //nolint:lll + "Backup data by site ID; accepts '"+Wildcard+"' to select all sites. Args cannot be comma-delimited and must use multiple flags.") + cobra.CheckErr(fs.MarkHidden(SiteIDFN)) +} + +// AddSiteFlag adds the --site flag, which accepts webURL values. +func AddSiteFlag(cmd *cobra.Command) { + cmd.Flags().StringSliceVar( + &WebURLFV, + SiteFN, nil, + "Backup data by site URL; accepts '"+Wildcard+"' to select all sites.") +} diff --git a/src/cli/options/options_test.go b/src/cli/options/options_test.go deleted file mode 100644 index 8538e3441..000000000 --- a/src/cli/options/options_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package options - -import ( - "testing" - - "github.com/alcionai/clues" - "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 OptionsUnitSuite struct { - tester.Suite -} - -func TestOptionsUnitSuite(t *testing.T) { - suite.Run(t, &OptionsUnitSuite{Suite: tester.NewUnitSuite(t)}) -} - -func (suite *OptionsUnitSuite) TestAddExchangeCommands() { - t := suite.T() - - cmd := &cobra.Command{ - Use: "test", - Run: func(cmd *cobra.Command, args []string) { - assert.True(t, failFastFV, FailFastFN) - assert.True(t, disableIncrementalsFV, DisableIncrementalsFN) - assert.True(t, disableDeltaFV, DisableDeltaFN) - assert.True(t, noStatsFV, NoStatsFN) - assert.True(t, restorePermissionsFV, RestorePermissionsFN) - assert.True(t, skipReduceFV, SkipReduceFN) - assert.Equal(t, 2, fetchParallelismFV, FetchParallelismFN) - assert.True(t, disableConcurrencyLimiterFV, DisableConcurrencyLimiterFN) - }, - } - - // adds no-stats - AddGlobalOperationFlags(cmd) - - AddFailFastFlag(cmd) - AddDisableIncrementalsFlag(cmd) - AddDisableDeltaFlag(cmd) - AddRestorePermissionsFlag(cmd) - AddSkipReduceFlag(cmd) - AddFetchParallelismFlag(cmd) - AddDisableConcurrencyLimiterFlag(cmd) - - // Test arg parsing for few args - cmd.SetArgs([]string{ - "test", - "--" + FailFastFN, - "--" + DisableIncrementalsFN, - "--" + DisableDeltaFN, - "--" + NoStatsFN, - "--" + RestorePermissionsFN, - "--" + SkipReduceFN, - "--" + FetchParallelismFN, "2", - "--" + DisableConcurrencyLimiterFN, - }) - - err := cmd.Execute() - require.NoError(t, err, clues.ToCore(err)) -} diff --git a/src/cli/repo/repo.go b/src/cli/repo/repo.go index 6d36d1608..c6cba55be 100644 --- a/src/cli/repo/repo.go +++ b/src/cli/repo/repo.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/exp/maps" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/pkg/control/repository" @@ -42,8 +43,8 @@ func AddCommands(cmd *cobra.Command) { maintenanceCmd, utils.HideCommand(), utils.MarkPreReleaseCommand()) - utils.AddMaintenanceModeFlag(maintenanceCmd) - utils.AddForceMaintenanceFlag(maintenanceCmd) + flags.AddMaintenanceModeFlag(maintenanceCmd) + flags.AddForceMaintenanceFlag(maintenanceCmd) for _, addRepoTo := range repoCommands { addRepoTo(initCmd) @@ -116,7 +117,7 @@ func maintenanceCmd() *cobra.Command { func handleMaintenanceCmd(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - t, err := getMaintenanceType(utils.MaintenanceModeFV) + t, err := getMaintenanceType(flags.MaintenanceModeFV) if err != nil { return err } @@ -133,7 +134,7 @@ func handleMaintenanceCmd(cmd *cobra.Command, args []string) error { repository.Maintenance{ Type: t, Safety: repository.FullMaintenanceSafety, - Force: utils.ForceMaintenanceFV, + Force: flags.ForceMaintenanceFV, }) if err != nil { return print.Only(ctx, err) diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index feba087a8..2480cf0fa 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -10,7 +10,6 @@ import ( "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/events" @@ -124,7 +123,7 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { cfg.Account.ID(), map[string]any{"command": "init repo"}, cfg.Account.ID(), - options.Control()) + utils.Control()) s3Cfg, err := cfg.Storage.S3Config() if err != nil { @@ -143,7 +142,7 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { return Only(ctx, clues.Wrap(err, "Failed to parse m365 account config")) } - r, err := repository.Initialize(ctx, cfg.Account, cfg.Storage, options.Control()) + r, err := repository.Initialize(ctx, cfg.Account, cfg.Storage, utils.Control()) if err != nil { if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) { return nil @@ -214,7 +213,7 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { return Only(ctx, clues.New(invalidEndpointErr)) } - r, err := repository.ConnectAndSendConnectEvent(ctx, cfg.Account, cfg.Storage, repoID, options.Control()) + r, err := repository.ConnectAndSendConnectEvent(ctx, cfg.Account, cfg.Storage, repoID, utils.Control()) if err != nil { return Only(ctx, clues.Wrap(err, "Failed to connect to the S3 repository")) } diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 514e6102c..be5b83dfc 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" @@ -32,9 +32,9 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command { // general flags fs.SortFlags = false - utils.AddBackupIDFlag(c, true) - utils.AddExchangeDetailsAndRestoreFlags(c) - options.AddFailFastFlag(c) + flags.AddBackupIDFlag(c, true) + flags.AddExchangeDetailsAndRestoreFlags(c) + flags.AddFailFastFlag(c) } return c @@ -81,11 +81,11 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { opts := utils.MakeExchangeOpts(cmd) - if utils.RunModeFV == utils.RunModeFlagTest { + if flags.RunModeFV == flags.RunModeFlagTest { return nil } - if err := utils.ValidateExchangeRestoreFlags(utils.BackupIDFV, opts); err != nil { + if err := utils.ValidateExchangeRestoreFlags(flags.BackupIDFV, opts); err != nil { return err } @@ -102,7 +102,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { sel := utils.IncludeExchangeRestoreDataSelectors(opts) utils.FilterExchangeRestoreInfoSelectors(sel, opts) - ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg) + ro, err := r.NewRestore(ctx, flags.BackupIDFV, sel.Selector, restoreCfg) if err != nil { return Only(ctx, clues.Wrap(err, "Failed to initialize Exchange restore")) } @@ -110,7 +110,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { ds, err := ro.Run(ctx) if err != nil { if errors.Is(err, data.ErrNotFound) { - return Only(ctx, clues.New("Backup or backup details missing for id "+utils.BackupIDFV)) + return Only(ctx, clues.New("Backup or backup details missing for id "+flags.BackupIDFV)) } return Only(ctx, clues.Wrap(err, "Failed to run Exchange restore")) diff --git a/src/cli/restore/exchange_e2e_test.go b/src/cli/restore/exchange_e2e_test.go index 1f4f93601..5512dca4f 100644 --- a/src/cli/restore/exchange_e2e_test.go +++ b/src/cli/restore/exchange_e2e_test.go @@ -12,7 +12,7 @@ import ( "github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli/config" - "github.com/alcionai/corso/src/cli/utils" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/m365/exchange" "github.com/alcionai/corso/src/internal/operations" @@ -135,7 +135,7 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd() { cmd := tester.StubRootCmd( "restore", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID)) + "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID)) cli.BuildCommandTree(cmd) // run the command @@ -162,15 +162,15 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badTimeFlags() { var timeFilter string switch set { case email: - timeFilter = "--" + utils.EmailReceivedAfterFN + timeFilter = "--" + flags.EmailReceivedAfterFN case events: - timeFilter = "--" + utils.EventStartsAfterFN + timeFilter = "--" + flags.EventStartsAfterFN } cmd := tester.StubRootCmd( "restore", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID), + "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID), timeFilter, "smarf") cli.BuildCommandTree(cmd) @@ -198,13 +198,13 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badBoolFlags() { var timeFilter string switch set { case events: - timeFilter = "--" + utils.EventRecursFN + timeFilter = "--" + flags.EventRecursFN } cmd := tester.StubRootCmd( "restore", "exchange", "--config-file", suite.cfgFP, - "--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID), + "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID), timeFilter, "wingbat") cli.BuildCommandTree(cmd) diff --git a/src/cli/restore/exchange_test.go b/src/cli/restore/exchange_test.go index 4f5915c21..955df3267 100644 --- a/src/cli/restore/exchange_test.go +++ b/src/cli/restore/exchange_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" @@ -43,7 +44,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { // normally a persistent flag from the root. // required to ensure a dry run. - utils.AddRunModeFlag(cmd, true) + flags.AddRunModeFlag(cmd, true) c := addExchangeCommands(cmd) require.NotNil(t, c) @@ -59,27 +60,24 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { // Test arg parsing for few args cmd.SetArgs([]string{ "exchange", - "--" + utils.RunModeFN, utils.RunModeFlagTest, - "--" + utils.BackupFN, testdata.BackupInput, - - "--" + utils.ContactFN, testdata.FlgInputs(testdata.ContactInput), - "--" + utils.ContactFolderFN, testdata.FlgInputs(testdata.ContactFldInput), - "--" + utils.ContactNameFN, testdata.ContactNameInput, - - "--" + utils.EmailFN, testdata.FlgInputs(testdata.EmailInput), - "--" + utils.EmailFolderFN, testdata.FlgInputs(testdata.EmailFldInput), - "--" + utils.EmailReceivedAfterFN, testdata.EmailReceivedAfterInput, - "--" + utils.EmailReceivedBeforeFN, testdata.EmailReceivedBeforeInput, - "--" + utils.EmailSenderFN, testdata.EmailSenderInput, - "--" + utils.EmailSubjectFN, testdata.EmailSubjectInput, - - "--" + utils.EventFN, testdata.FlgInputs(testdata.EventInput), - "--" + utils.EventCalendarFN, testdata.FlgInputs(testdata.EventCalInput), - "--" + utils.EventOrganizerFN, testdata.EventOrganizerInput, - "--" + utils.EventRecursFN, testdata.EventRecursInput, - "--" + utils.EventStartsAfterFN, testdata.EventStartsAfterInput, - "--" + utils.EventStartsBeforeFN, testdata.EventStartsBeforeInput, - "--" + utils.EventSubjectFN, testdata.EventSubjectInput, + "--" + flags.RunModeFN, flags.RunModeFlagTest, + "--" + flags.BackupFN, testdata.BackupInput, + "--" + flags.ContactFN, testdata.FlgInputs(testdata.ContactInput), + "--" + flags.ContactFolderFN, testdata.FlgInputs(testdata.ContactFldInput), + "--" + flags.ContactNameFN, testdata.ContactNameInput, + "--" + flags.EmailFN, testdata.FlgInputs(testdata.EmailInput), + "--" + flags.EmailFolderFN, testdata.FlgInputs(testdata.EmailFldInput), + "--" + flags.EmailReceivedAfterFN, testdata.EmailReceivedAfterInput, + "--" + flags.EmailReceivedBeforeFN, testdata.EmailReceivedBeforeInput, + "--" + flags.EmailSenderFN, testdata.EmailSenderInput, + "--" + flags.EmailSubjectFN, testdata.EmailSubjectInput, + "--" + flags.EventFN, testdata.FlgInputs(testdata.EventInput), + "--" + flags.EventCalendarFN, testdata.FlgInputs(testdata.EventCalInput), + "--" + flags.EventOrganizerFN, testdata.EventOrganizerInput, + "--" + flags.EventRecursFN, testdata.EventRecursInput, + "--" + flags.EventStartsAfterFN, testdata.EventStartsAfterInput, + "--" + flags.EventStartsBeforeFN, testdata.EventStartsBeforeInput, + "--" + flags.EventSubjectFN, testdata.EventSubjectInput, }) cmd.SetOut(new(bytes.Buffer)) // drop output @@ -88,7 +86,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() { assert.NoError(t, err, clues.ToCore(err)) opts := utils.MakeExchangeOpts(cmd) - assert.Equal(t, testdata.BackupInput, utils.BackupIDFV) + assert.Equal(t, testdata.BackupInput, flags.BackupIDFV) assert.ElementsMatch(t, testdata.ContactInput, opts.Contact) assert.ElementsMatch(t, testdata.ContactFldInput, opts.ContactFolder) diff --git a/src/cli/restore/onedrive.go b/src/cli/restore/onedrive.go index 85b159370..ad3ac36d0 100644 --- a/src/cli/restore/onedrive.go +++ b/src/cli/restore/onedrive.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" @@ -31,12 +31,10 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command { // More generic (ex: --user) and more frequently used flags take precedence. fs.SortFlags = false - utils.AddBackupIDFlag(c, true) - utils.AddOneDriveDetailsAndRestoreFlags(c) - - // restore permissions - options.AddRestorePermissionsFlag(c) - options.AddFailFastFlag(c) + flags.AddBackupIDFlag(c, true) + flags.AddOneDriveDetailsAndRestoreFlags(c) + flags.AddRestorePermissionsFlag(c) + flags.AddFailFastFlag(c) } return c @@ -82,11 +80,11 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error { opts := utils.MakeOneDriveOpts(cmd) - if utils.RunModeFV == utils.RunModeFlagTest { + if flags.RunModeFV == flags.RunModeFlagTest { return nil } - if err := utils.ValidateOneDriveRestoreFlags(utils.BackupIDFV, opts); err != nil { + if err := utils.ValidateOneDriveRestoreFlags(flags.BackupIDFV, opts); err != nil { return err } @@ -103,7 +101,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error { sel := utils.IncludeOneDriveRestoreDataSelectors(opts) utils.FilterOneDriveRestoreInfoSelectors(sel, opts) - ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg) + ro, err := r.NewRestore(ctx, flags.BackupIDFV, sel.Selector, restoreCfg) if err != nil { return Only(ctx, clues.Wrap(err, "Failed to initialize OneDrive restore")) } @@ -111,7 +109,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error { ds, err := ro.Run(ctx) if err != nil { if errors.Is(err, data.ErrNotFound) { - return Only(ctx, clues.New("Backup or backup details missing for id "+utils.BackupIDFV)) + return Only(ctx, clues.New("Backup or backup details missing for id "+flags.BackupIDFV)) } return Only(ctx, clues.Wrap(err, "Failed to run OneDrive restore")) diff --git a/src/cli/restore/onedrive_test.go b/src/cli/restore/onedrive_test.go index cf119c328..922698c55 100644 --- a/src/cli/restore/onedrive_test.go +++ b/src/cli/restore/onedrive_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" @@ -43,7 +44,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { // normally a persistent flag from the root. // required to ensure a dry run. - utils.AddRunModeFlag(cmd, true) + flags.AddRunModeFlag(cmd, true) c := addOneDriveCommands(cmd) require.NotNil(t, c) @@ -58,15 +59,14 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { cmd.SetArgs([]string{ "onedrive", - "--" + utils.RunModeFN, utils.RunModeFlagTest, - "--" + utils.BackupFN, testdata.BackupInput, - - "--" + utils.FileFN, testdata.FlgInputs(testdata.FileNameInput), - "--" + utils.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), - "--" + utils.FileCreatedAfterFN, testdata.FileCreatedAfterInput, - "--" + utils.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, - "--" + utils.FileModifiedAfterFN, testdata.FileModifiedAfterInput, - "--" + utils.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput, + "--" + flags.RunModeFN, flags.RunModeFlagTest, + "--" + flags.BackupFN, testdata.BackupInput, + "--" + flags.FileFN, testdata.FlgInputs(testdata.FileNameInput), + "--" + flags.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), + "--" + flags.FileCreatedAfterFN, testdata.FileCreatedAfterInput, + "--" + flags.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, + "--" + flags.FileModifiedAfterFN, testdata.FileModifiedAfterInput, + "--" + flags.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput, }) cmd.SetOut(new(bytes.Buffer)) // drop output @@ -75,7 +75,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() { assert.NoError(t, err, clues.ToCore(err)) opts := utils.MakeOneDriveOpts(cmd) - assert.Equal(t, testdata.BackupInput, utils.BackupIDFV) + assert.Equal(t, testdata.BackupInput, flags.BackupIDFV) assert.ElementsMatch(t, testdata.FileNameInput, opts.FileName) assert.ElementsMatch(t, testdata.FolderPathInput, opts.FolderPath) diff --git a/src/cli/restore/sharepoint.go b/src/cli/restore/sharepoint.go index a52f5bb2a..8ab849996 100644 --- a/src/cli/restore/sharepoint.go +++ b/src/cli/restore/sharepoint.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/alcionai/corso/src/cli/options" + "github.com/alcionai/corso/src/cli/flags" . "github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" @@ -31,11 +31,10 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command { // More generic (ex: --site) and more frequently used flags take precedence. fs.SortFlags = false - utils.AddBackupIDFlag(c, true) - utils.AddSharePointDetailsAndRestoreFlags(c) - - options.AddRestorePermissionsFlag(c) - options.AddFailFastFlag(c) + flags.AddBackupIDFlag(c, true) + flags.AddSharePointDetailsAndRestoreFlags(c) + flags.AddRestorePermissionsFlag(c) + flags.AddFailFastFlag(c) } return c @@ -87,11 +86,11 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error { opts := utils.MakeSharePointOpts(cmd) - if utils.RunModeFV == utils.RunModeFlagTest { + if flags.RunModeFV == flags.RunModeFlagTest { return nil } - if err := utils.ValidateSharePointRestoreFlags(utils.BackupIDFV, opts); err != nil { + if err := utils.ValidateSharePointRestoreFlags(flags.BackupIDFV, opts); err != nil { return err } @@ -108,7 +107,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error { sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts) utils.FilterSharePointRestoreInfoSelectors(sel, opts) - ro, err := r.NewRestore(ctx, utils.BackupIDFV, sel.Selector, restoreCfg) + ro, err := r.NewRestore(ctx, flags.BackupIDFV, sel.Selector, restoreCfg) if err != nil { return Only(ctx, clues.Wrap(err, "Failed to initialize SharePoint restore")) } @@ -116,7 +115,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error { ds, err := ro.Run(ctx) if err != nil { if errors.Is(err, data.ErrNotFound) { - return Only(ctx, clues.New("Backup or backup details missing for id "+utils.BackupIDFV)) + return Only(ctx, clues.New("Backup or backup details missing for id "+flags.BackupIDFV)) } return Only(ctx, clues.Wrap(err, "Failed to run SharePoint restore")) diff --git a/src/cli/restore/sharepoint_test.go b/src/cli/restore/sharepoint_test.go index ce7e3c73d..09b056975 100644 --- a/src/cli/restore/sharepoint_test.go +++ b/src/cli/restore/sharepoint_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/internal/tester" @@ -43,7 +44,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { // normally a persistent flag from the root. // required to ensure a dry run. - utils.AddRunModeFlag(cmd, true) + flags.AddRunModeFlag(cmd, true) c := addSharePointCommands(cmd) require.NotNil(t, c) @@ -58,22 +59,19 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { cmd.SetArgs([]string{ "sharepoint", - "--" + utils.RunModeFN, utils.RunModeFlagTest, - "--" + utils.BackupFN, testdata.BackupInput, - - "--" + utils.LibraryFN, testdata.LibraryInput, - "--" + utils.FileFN, testdata.FlgInputs(testdata.FileNameInput), - "--" + utils.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), - "--" + utils.FileCreatedAfterFN, testdata.FileCreatedAfterInput, - "--" + utils.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, - "--" + utils.FileModifiedAfterFN, testdata.FileModifiedAfterInput, - "--" + utils.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput, - - "--" + utils.ListItemFN, testdata.FlgInputs(testdata.ListItemInput), - "--" + utils.ListFolderFN, testdata.FlgInputs(testdata.ListFolderInput), - - "--" + utils.PageFN, testdata.FlgInputs(testdata.PageInput), - "--" + utils.PageFolderFN, testdata.FlgInputs(testdata.PageFolderInput), + "--" + flags.RunModeFN, flags.RunModeFlagTest, + "--" + flags.BackupFN, testdata.BackupInput, + "--" + flags.LibraryFN, testdata.LibraryInput, + "--" + flags.FileFN, testdata.FlgInputs(testdata.FileNameInput), + "--" + flags.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), + "--" + flags.FileCreatedAfterFN, testdata.FileCreatedAfterInput, + "--" + flags.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, + "--" + flags.FileModifiedAfterFN, testdata.FileModifiedAfterInput, + "--" + flags.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput, + "--" + flags.ListItemFN, testdata.FlgInputs(testdata.ListItemInput), + "--" + flags.ListFolderFN, testdata.FlgInputs(testdata.ListFolderInput), + "--" + flags.PageFN, testdata.FlgInputs(testdata.PageInput), + "--" + flags.PageFolderFN, testdata.FlgInputs(testdata.PageFolderInput), }) cmd.SetOut(new(bytes.Buffer)) // drop output @@ -82,7 +80,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() { assert.NoError(t, err, clues.ToCore(err)) opts := utils.MakeSharePointOpts(cmd) - assert.Equal(t, testdata.BackupInput, utils.BackupIDFV) + assert.Equal(t, testdata.BackupInput, flags.BackupIDFV) assert.Equal(t, testdata.LibraryInput, opts.Library) assert.ElementsMatch(t, testdata.FileNameInput, opts.FileName) diff --git a/src/cli/utils/exchange.go b/src/cli/utils/exchange.go index d167c710e..7051d5904 100644 --- a/src/cli/utils/exchange.go +++ b/src/cli/utils/exchange.go @@ -4,53 +4,10 @@ import ( "github.com/alcionai/clues" "github.com/spf13/cobra" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/pkg/selectors" ) -// flag names (id: FN) -const ( - ContactFN = "contact" - ContactFolderFN = "contact-folder" - ContactNameFN = "contact-name" - - EmailFN = "email" - EmailFolderFN = "email-folder" - EmailReceivedAfterFN = "email-received-after" - EmailReceivedBeforeFN = "email-received-before" - EmailSenderFN = "email-sender" - EmailSubjectFN = "email-subject" - - EventFN = "event" - EventCalendarFN = "event-calendar" - EventOrganizerFN = "event-organizer" - EventRecursFN = "event-recurs" - EventStartsAfterFN = "event-starts-after" - EventStartsBeforeFN = "event-starts-before" - EventSubjectFN = "event-subject" -) - -// flag values (ie: FV) -var ( - ContactFV []string - ContactFolderFV []string - ContactNameFV string - - EmailFV []string - EmailFolderFV []string - EmailReceivedAfterFV string - EmailReceivedBeforeFV string - EmailSenderFV string - EmailSubjectFV string - - EventFV []string - EventCalendarFV []string - EventOrganizerFV string - EventRecursFV string - EventStartsAfterFV string - EventStartsBeforeFV string - EventSubjectFV string -) - type ExchangeOpts struct { Users []string @@ -73,113 +30,37 @@ type ExchangeOpts struct { EventStartsBefore string EventSubject string - Populated PopulatedFlags + Populated flags.PopulatedFlags } // populates an ExchangeOpts struct with the command's current flags. func MakeExchangeOpts(cmd *cobra.Command) ExchangeOpts { return ExchangeOpts{ - Users: UserFV, + Users: flags.UserFV, - Contact: ContactFV, - ContactFolder: ContactFolderFV, - ContactName: ContactNameFV, + Contact: flags.ContactFV, + ContactFolder: flags.ContactFolderFV, + ContactName: flags.ContactNameFV, - Email: EmailFV, - EmailFolder: EmailFolderFV, - EmailReceivedAfter: EmailReceivedAfterFV, - EmailReceivedBefore: EmailReceivedBeforeFV, - EmailSender: EmailSenderFV, - EmailSubject: EmailSubjectFV, + Email: flags.EmailFV, + EmailFolder: flags.EmailFolderFV, + EmailReceivedAfter: flags.EmailReceivedAfterFV, + EmailReceivedBefore: flags.EmailReceivedBeforeFV, + EmailSender: flags.EmailSenderFV, + EmailSubject: flags.EmailSubjectFV, - Event: EventFV, - EventCalendar: EventCalendarFV, - EventOrganizer: EventOrganizerFV, - EventRecurs: EventRecursFV, - EventStartsAfter: EventStartsAfterFV, - EventStartsBefore: EventStartsBeforeFV, - EventSubject: EventSubjectFV, + Event: flags.EventFV, + EventCalendar: flags.EventCalendarFV, + EventOrganizer: flags.EventOrganizerFV, + EventRecurs: flags.EventRecursFV, + EventStartsAfter: flags.EventStartsAfterFV, + EventStartsBefore: flags.EventStartsBeforeFV, + EventSubject: flags.EventSubjectFV, - Populated: GetPopulatedFlags(cmd), + Populated: flags.GetPopulatedFlags(cmd), } } -// AddExchangeDetailsAndRestoreFlags adds flags that are common to both the -// details and restore commands. -func AddExchangeDetailsAndRestoreFlags(cmd *cobra.Command) { - fs := cmd.Flags() - - // email flags - fs.StringSliceVar( - &EmailFV, - EmailFN, nil, - "Select email messages by ID; accepts '"+Wildcard+"' to select all emails.") - fs.StringSliceVar( - &EmailFolderFV, - EmailFolderFN, nil, - "Select emails within a folder; accepts '"+Wildcard+"' to select all email folders.") - fs.StringVar( - &EmailSubjectFV, - EmailSubjectFN, "", - "Select emails with a subject containing this value.") - fs.StringVar( - &EmailSenderFV, - EmailSenderFN, "", - "Select emails from a specific sender.") - fs.StringVar( - &EmailReceivedAfterFV, - EmailReceivedAfterFN, "", - "Select emails received after this datetime.") - fs.StringVar( - &EmailReceivedBeforeFV, - EmailReceivedBeforeFN, "", - "Select emails received before this datetime.") - - // event flags - fs.StringSliceVar( - &EventFV, - EventFN, nil, - "Select events by event ID; accepts '"+Wildcard+"' to select all events.") - fs.StringSliceVar( - &EventCalendarFV, - EventCalendarFN, nil, - "Select events under a calendar; accepts '"+Wildcard+"' to select all events.") - fs.StringVar( - &EventSubjectFV, - EventSubjectFN, "", - "Select events with a subject containing this value.") - fs.StringVar( - &EventOrganizerFV, - EventOrganizerFN, "", - "Select events from a specific organizer.") - fs.StringVar( - &EventRecursFV, - EventRecursFN, "", - "Select recurring events. Use `--event-recurs false` to select non-recurring events.") - fs.StringVar( - &EventStartsAfterFV, - EventStartsAfterFN, "", - "Select events starting after this datetime.") - fs.StringVar( - &EventStartsBeforeFV, - EventStartsBeforeFN, "", - "Select events starting before this datetime.") - - // contact flags - fs.StringSliceVar( - &ContactFV, - ContactFN, nil, - "Select contacts by contact ID; accepts '"+Wildcard+"' to select all contacts.") - fs.StringSliceVar( - &ContactFolderFV, - ContactFolderFN, nil, - "Select contacts within a folder; accepts '"+Wildcard+"' to select all contact folders.") - fs.StringVar( - &ContactNameFV, - ContactNameFN, "", - "Select contacts whose contact name contains this value.") -} - // AddExchangeInclude adds the scope of the provided values to the selector's // inclusion set. Any unpopulated slice will be replaced with selectors.Any() // to act as a wildcard. @@ -231,23 +112,23 @@ func ValidateExchangeRestoreFlags(backupID string, opts ExchangeOpts) error { return clues.New("a backup ID is required") } - if _, ok := opts.Populated[EmailReceivedAfterFN]; ok && !IsValidTimeFormat(opts.EmailReceivedAfter) { + if _, ok := opts.Populated[flags.EmailReceivedAfterFN]; ok && !IsValidTimeFormat(opts.EmailReceivedAfter) { return clues.New("invalid time format for email-received-after") } - if _, ok := opts.Populated[EmailReceivedBeforeFN]; ok && !IsValidTimeFormat(opts.EmailReceivedBefore) { + if _, ok := opts.Populated[flags.EmailReceivedBeforeFN]; ok && !IsValidTimeFormat(opts.EmailReceivedBefore) { return clues.New("invalid time format for email-received-before") } - if _, ok := opts.Populated[EventStartsAfterFN]; ok && !IsValidTimeFormat(opts.EventStartsAfter) { + if _, ok := opts.Populated[flags.EventStartsAfterFN]; ok && !IsValidTimeFormat(opts.EventStartsAfter) { return clues.New("invalid time format for event-starts-after") } - if _, ok := opts.Populated[EventStartsBeforeFN]; ok && !IsValidTimeFormat(opts.EventStartsBefore) { + if _, ok := opts.Populated[flags.EventStartsBeforeFN]; ok && !IsValidTimeFormat(opts.EventStartsBefore) { return clues.New("invalid time format for event-starts-before") } - if _, ok := opts.Populated[EventRecursFN]; ok && !IsValidBool(opts.EventRecurs) { + if _, ok := opts.Populated[flags.EventRecursFN]; ok && !IsValidBool(opts.EventRecurs) { return clues.New("invalid format for event-recurs") } diff --git a/src/cli/utils/exchange_test.go b/src/cli/utils/exchange_test.go index c61e8da77..662532743 100644 --- a/src/cli/utils/exchange_test.go +++ b/src/cli/utils/exchange_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/tester" @@ -62,7 +63,7 @@ func (suite *ExchangeUtilsSuite) TestValidateRestoreFlags() { func (suite *ExchangeUtilsSuite) TestIncludeExchangeRestoreDataSelectors() { stub := []string{"id-stub"} many := []string{"fnord", "smarf"} - a := []string{utils.Wildcard} + a := []string{flags.Wildcard} table := []struct { name string diff --git a/src/cli/utils/flags.go b/src/cli/utils/flags.go index ab1503034..66d3e4fcd 100644 --- a/src/cli/utils/flags.go +++ b/src/cli/utils/flags.go @@ -1,233 +1,13 @@ package utils import ( - "fmt" "strconv" - "strings" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" "github.com/alcionai/corso/src/internal/common/dttm" - "github.com/alcionai/corso/src/pkg/control/repository" "github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/selectors" ) -// common flag vars (eg: FV) -var ( - // RunMode describes the type of run, such as: - // flagtest, dry, run. Should default to 'run'. - RunModeFV string - - BackupIDFV string - - FolderPathFV []string - FileNameFV []string - - FileCreatedAfterFV string - FileCreatedBeforeFV string - FileModifiedAfterFV string - FileModifiedBeforeFV string - - LibraryFV string - SiteIDFV []string - WebURLFV []string - - UserFV []string - - // for selection of data by category. eg: `--data email,contacts` - CategoryDataFV []string - - MaintenanceModeFV string - ForceMaintenanceFV bool -) - -// common flag names (eg: FN) -const ( - RunModeFN = "run-mode" - - BackupFN = "backup" - CategoryDataFN = "data" - - SiteFN = "site" // site only accepts WebURL values - SiteIDFN = "site-id" // site-id accepts actual site ids - UserFN = "user" - MailBoxFN = "mailbox" - - LibraryFN = "library" - FileFN = "file" - FolderFN = "folder" - - FileCreatedAfterFN = "file-created-after" - FileCreatedBeforeFN = "file-created-before" - FileModifiedAfterFN = "file-modified-after" - FileModifiedBeforeFN = "file-modified-before" - - // Maintenance stuff. - MaintenanceModeFN = "mode" - ForceMaintenanceFN = "force" -) - -// well-known flag values -const ( - RunModeFlagTest = "flag-test" - RunModeRun = "run" -) - -// AddBackupIDFlag adds the --backup flag. -func AddBackupIDFlag(cmd *cobra.Command, require bool) { - cmd.Flags().StringVar(&BackupIDFV, BackupFN, "", "ID of the backup to retrieve.") - - if require { - cobra.CheckErr(cmd.MarkFlagRequired(BackupFN)) - } -} - -func AddDataFlag(cmd *cobra.Command, allowed []string, hide bool) { - var ( - allowedMsg string - fs = cmd.Flags() - ) - - switch len(allowed) { - case 0: - return - case 1: - allowedMsg = allowed[0] - case 2: - allowedMsg = fmt.Sprintf("%s or %s", allowed[0], allowed[1]) - default: - allowedMsg = fmt.Sprintf( - "%s or %s", - strings.Join(allowed[:len(allowed)-1], ", "), - allowed[len(allowed)-1]) - } - - fs.StringSliceVar( - &CategoryDataFV, - CategoryDataFN, nil, - "Select one or more types of data to backup: "+allowedMsg+".") - - if hide { - cobra.CheckErr(fs.MarkHidden(CategoryDataFN)) - } -} - -// AddRunModeFlag adds the hidden --run-mode flag. -func AddRunModeFlag(cmd *cobra.Command, persistent bool) { - fs := cmd.Flags() - if persistent { - fs = cmd.PersistentFlags() - } - - fs.StringVar(&RunModeFV, RunModeFN, "run", "What mode to run: dry, test, run. Defaults to run.") - cobra.CheckErr(fs.MarkHidden(RunModeFN)) -} - -// AddUserFlag adds the --user flag. -func AddUserFlag(cmd *cobra.Command) { - cmd.Flags().StringSliceVar( - &UserFV, - UserFN, nil, - "Backup a specific user's data; accepts '"+Wildcard+"' to select all users.") - cobra.CheckErr(cmd.MarkFlagRequired(UserFN)) -} - -// AddMailBoxFlag adds the --user and --mailbox flag. -func AddMailBoxFlag(cmd *cobra.Command) { - flags := cmd.Flags() - - flags.StringSliceVar( - &UserFV, - UserFN, nil, - "Backup a specific user's data; accepts '"+Wildcard+"' to select all users.") - - cobra.CheckErr(flags.MarkDeprecated(UserFN, fmt.Sprintf("use --%s instead", MailBoxFN))) - - flags.StringSliceVar( - &UserFV, - MailBoxFN, nil, - "Backup a specific mailbox's data; accepts '"+Wildcard+"' to select all mailbox.") -} - -// AddSiteIDFlag adds the --site-id flag, which accepts site ID values. -// This flag is hidden, since we expect users to prefer the --site url -// and do not want to encourage confusion. -func AddSiteIDFlag(cmd *cobra.Command) { - fs := cmd.Flags() - - // note string ARRAY var. IDs naturally contain commas, so we cannot accept - // duplicate values within a flag declaration. ie: --site-id a,b,c does not - // work. Users must call --site-id a --site-id b --site-id c. - fs.StringArrayVar( - &SiteIDFV, - SiteIDFN, nil, - //nolint:lll - "Backup data by site ID; accepts '"+Wildcard+"' to select all sites. Args cannot be comma-delimited and must use multiple flags.") - cobra.CheckErr(fs.MarkHidden(SiteIDFN)) -} - -// AddSiteFlag adds the --site flag, which accepts webURL values. -func AddSiteFlag(cmd *cobra.Command) { - cmd.Flags().StringSliceVar( - &WebURLFV, - SiteFN, nil, - "Backup data by site URL; accepts '"+Wildcard+"' to select all sites.") -} - -func AddMaintenanceModeFlag(cmd *cobra.Command) { - fs := cmd.Flags() - fs.StringVar( - &MaintenanceModeFV, - MaintenanceModeFN, - repository.CompleteMaintenance.String(), - "Type of maintenance operation to run. Pass '"+ - repository.MetadataMaintenance.String()+"' to run a faster maintenance "+ - "that does minimal clean-up and optimization. Pass '"+ - repository.CompleteMaintenance.String()+"' to fully compact existing "+ - "data and delete unused data.") - cobra.CheckErr(fs.MarkHidden(MaintenanceModeFN)) -} - -func AddForceMaintenanceFlag(cmd *cobra.Command) { - fs := cmd.Flags() - fs.BoolVar( - &ForceMaintenanceFV, - ForceMaintenanceFN, - false, - "Force maintenance. Caution: user must ensure this is not run concurrently on a single repo") - cobra.CheckErr(fs.MarkHidden(ForceMaintenanceFN)) -} - -type PopulatedFlags map[string]struct{} - -func (fs PopulatedFlags) populate(pf *pflag.Flag) { - if pf == nil { - return - } - - if pf.Changed { - fs[pf.Name] = struct{}{} - } -} - -// GetPopulatedFlags returns a map of flags that have been -// populated by the user. Entry keys match the flag's long -// name. Values are empty. -func GetPopulatedFlags(cmd *cobra.Command) PopulatedFlags { - pop := PopulatedFlags{} - - fs := cmd.Flags() - if fs == nil { - return pop - } - - fs.VisitAll(pop.populate) - - return pop -} - // IsValidTimeFormat returns true if the input is recognized as a // supported format by the common time parser. func IsValidTimeFormat(in string) bool { diff --git a/src/cli/utils/onedrive.go b/src/cli/utils/onedrive.go index ff75951c3..16c9c8d8f 100644 --- a/src/cli/utils/onedrive.go +++ b/src/cli/utils/onedrive.go @@ -4,6 +4,7 @@ import ( "github.com/alcionai/clues" "github.com/spf13/cobra" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/pkg/selectors" ) @@ -17,78 +18,43 @@ type OneDriveOpts struct { FileModifiedAfter string FileModifiedBefore string - Populated PopulatedFlags + Populated flags.PopulatedFlags } func MakeOneDriveOpts(cmd *cobra.Command) OneDriveOpts { return OneDriveOpts{ - Users: UserFV, + Users: flags.UserFV, - FileName: FileNameFV, - FolderPath: FolderPathFV, - FileCreatedAfter: FileCreatedAfterFV, - FileCreatedBefore: FileCreatedBeforeFV, - FileModifiedAfter: FileModifiedAfterFV, - FileModifiedBefore: FileModifiedBeforeFV, + FileName: flags.FileNameFV, + FolderPath: flags.FolderPathFV, + FileCreatedAfter: flags.FileCreatedAfterFV, + FileCreatedBefore: flags.FileCreatedBeforeFV, + FileModifiedAfter: flags.FileModifiedAfterFV, + FileModifiedBefore: flags.FileModifiedBeforeFV, - Populated: GetPopulatedFlags(cmd), + Populated: flags.GetPopulatedFlags(cmd), } } -// AddOneDriveDetailsAndRestoreFlags adds flags that are common to both the -// details and restore commands. -func AddOneDriveDetailsAndRestoreFlags(cmd *cobra.Command) { - fs := cmd.Flags() - - fs.StringSliceVar( - &FolderPathFV, - FolderFN, nil, - "Select files by OneDrive folder; defaults to root.") - - fs.StringSliceVar( - &FileNameFV, - FileFN, nil, - "Select files by name.") - - fs.StringVar( - &FileCreatedAfterFV, - FileCreatedAfterFN, "", - "Select files created after this datetime.") - fs.StringVar( - &FileCreatedBeforeFV, - FileCreatedBeforeFN, "", - "Select files created before this datetime.") - - fs.StringVar( - &FileModifiedAfterFV, - FileModifiedAfterFN, "", - "Select files modified after this datetime.") - - fs.StringVar( - &FileModifiedBeforeFV, - FileModifiedBeforeFN, "", - "Select files modified before this datetime.") -} - // ValidateOneDriveRestoreFlags checks common flags for correctness and interdependencies func ValidateOneDriveRestoreFlags(backupID string, opts OneDriveOpts) error { if len(backupID) == 0 { return clues.New("a backup ID is required") } - if _, ok := opts.Populated[FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) { + if _, ok := opts.Populated[flags.FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) { return clues.New("invalid time format for created-after") } - if _, ok := opts.Populated[FileCreatedBeforeFN]; ok && !IsValidTimeFormat(opts.FileCreatedBefore) { + if _, ok := opts.Populated[flags.FileCreatedBeforeFN]; ok && !IsValidTimeFormat(opts.FileCreatedBefore) { return clues.New("invalid time format for created-before") } - if _, ok := opts.Populated[FileModifiedAfterFN]; ok && !IsValidTimeFormat(opts.FileModifiedAfter) { + if _, ok := opts.Populated[flags.FileModifiedAfterFN]; ok && !IsValidTimeFormat(opts.FileModifiedAfter) { return clues.New("invalid time format for modified-after") } - if _, ok := opts.Populated[FileModifiedBeforeFN]; ok && !IsValidTimeFormat(opts.FileModifiedBefore) { + if _, ok := opts.Populated[flags.FileModifiedBeforeFN]; ok && !IsValidTimeFormat(opts.FileModifiedBefore) { return clues.New("invalid time format for modified-before") } diff --git a/src/cli/utils/options.go b/src/cli/utils/options.go new file mode 100644 index 000000000..72bfac0a1 --- /dev/null +++ b/src/cli/utils/options.go @@ -0,0 +1,26 @@ +package utils + +import ( + "github.com/alcionai/corso/src/cli/flags" + "github.com/alcionai/corso/src/pkg/control" +) + +// Control produces the control options based on the user's flags. +func Control() control.Options { + opt := control.Defaults() + + if flags.FailFastFV { + opt.FailureHandling = control.FailFast + } + + opt.DisableMetrics = flags.NoStatsFV + opt.RestorePermissions = flags.RestorePermissionsFV + opt.SkipReduce = flags.SkipReduceFV + opt.ToggleFeatures.DisableIncrementals = flags.DisableIncrementalsFV + opt.ToggleFeatures.DisableDelta = flags.DisableDeltaFV + opt.ToggleFeatures.ExchangeImmutableIDs = flags.EnableImmutableIDFV + opt.ToggleFeatures.DisableConcurrencyLimiter = flags.DisableConcurrencyLimiterFV + opt.Parallelism.ItemFetch = flags.FetchParallelismFV + + return opt +} diff --git a/src/cli/utils/options_test.go b/src/cli/utils/options_test.go new file mode 100644 index 000000000..746558aa1 --- /dev/null +++ b/src/cli/utils/options_test.go @@ -0,0 +1,67 @@ +package utils + +import ( + "testing" + + "github.com/alcionai/clues" + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/alcionai/corso/src/cli/flags" + "github.com/alcionai/corso/src/internal/tester" +) + +type OptionsUnitSuite struct { + tester.Suite +} + +func TestOptionsUnitSuite(t *testing.T) { + suite.Run(t, &OptionsUnitSuite{Suite: tester.NewUnitSuite(t)}) +} + +func (suite *OptionsUnitSuite) TestAddExchangeCommands() { + t := suite.T() + + cmd := &cobra.Command{ + Use: "test", + Run: func(cmd *cobra.Command, args []string) { + assert.True(t, flags.FailFastFV, flags.FailFastFN) + assert.True(t, flags.DisableIncrementalsFV, flags.DisableIncrementalsFN) + assert.True(t, flags.DisableDeltaFV, flags.DisableDeltaFN) + assert.True(t, flags.NoStatsFV, flags.NoStatsFN) + assert.True(t, flags.RestorePermissionsFV, flags.RestorePermissionsFN) + assert.True(t, flags.SkipReduceFV, flags.SkipReduceFN) + assert.Equal(t, 2, flags.FetchParallelismFV, flags.FetchParallelismFN) + assert.True(t, flags.DisableConcurrencyLimiterFV, flags.DisableConcurrencyLimiterFN) + }, + } + + // adds no-stats + flags.AddGlobalOperationFlags(cmd) + + flags.AddFailFastFlag(cmd) + flags.AddDisableIncrementalsFlag(cmd) + flags.AddDisableDeltaFlag(cmd) + flags.AddRestorePermissionsFlag(cmd) + flags.AddSkipReduceFlag(cmd) + flags.AddFetchParallelismFlag(cmd) + flags.AddDisableConcurrencyLimiterFlag(cmd) + + // Test arg parsing for few args + cmd.SetArgs([]string{ + "test", + "--" + flags.FailFastFN, + "--" + flags.DisableIncrementalsFN, + "--" + flags.DisableDeltaFN, + "--" + flags.NoStatsFN, + "--" + flags.RestorePermissionsFN, + "--" + flags.SkipReduceFN, + "--" + flags.FetchParallelismFN, "2", + "--" + flags.DisableConcurrencyLimiterFN, + }) + + err := cmd.Execute() + require.NoError(t, err, clues.ToCore(err)) +} diff --git a/src/cli/utils/sharepoint.go b/src/cli/utils/sharepoint.go index bb37eb532..78b6e947f 100644 --- a/src/cli/utils/sharepoint.go +++ b/src/cli/utils/sharepoint.go @@ -8,25 +8,11 @@ import ( "github.com/alcionai/clues" "github.com/spf13/cobra" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/pkg/logger" "github.com/alcionai/corso/src/pkg/selectors" ) -const ( - ListFolderFN = "list" - ListItemFN = "list-item" - PageFolderFN = "page-folder" - PageFN = "page" -) - -// flag population variables -var ( - ListFolder []string - ListItem []string - PageFolder []string - Page []string -) - type SharePointOpts struct { SiteID []string WebURL []string @@ -45,95 +31,32 @@ type SharePointOpts struct { PageFolder []string Page []string - Populated PopulatedFlags + Populated flags.PopulatedFlags } func MakeSharePointOpts(cmd *cobra.Command) SharePointOpts { return SharePointOpts{ - SiteID: SiteIDFV, - WebURL: WebURLFV, + SiteID: flags.SiteIDFV, + WebURL: flags.WebURLFV, - Library: LibraryFV, - FileName: FileNameFV, - FolderPath: FolderPathFV, - FileCreatedAfter: FileCreatedAfterFV, - FileCreatedBefore: FileCreatedBeforeFV, - FileModifiedAfter: FileModifiedAfterFV, - FileModifiedBefore: FileModifiedBeforeFV, + Library: flags.LibraryFV, + FileName: flags.FileNameFV, + FolderPath: flags.FolderPathFV, + FileCreatedAfter: flags.FileCreatedAfterFV, + FileCreatedBefore: flags.FileCreatedBeforeFV, + FileModifiedAfter: flags.FileModifiedAfterFV, + FileModifiedBefore: flags.FileModifiedBeforeFV, - ListFolder: ListFolder, - ListItem: ListItem, + ListFolder: flags.ListFolderFV, + ListItem: flags.ListItemFV, - Page: Page, - PageFolder: PageFolder, + Page: flags.PageFV, + PageFolder: flags.PageFolderFV, - Populated: GetPopulatedFlags(cmd), + Populated: flags.GetPopulatedFlags(cmd), } } -// AddSharePointDetailsAndRestoreFlags adds flags that are common to both the -// details and restore commands. -func AddSharePointDetailsAndRestoreFlags(cmd *cobra.Command) { - fs := cmd.Flags() - - // libraries - - fs.StringVar( - &LibraryFV, - LibraryFN, "", - "Select only this library; defaults to all libraries.") - fs.StringSliceVar( - &FolderPathFV, - FolderFN, nil, - "Select by folder; defaults to root.") - fs.StringSliceVar( - &FileNameFV, - FileFN, nil, - "Select by file name.") - fs.StringVar( - &FileCreatedAfterFV, - FileCreatedAfterFN, "", - "Select files created after this datetime.") - fs.StringVar( - &FileCreatedBeforeFV, - FileCreatedBeforeFN, "", - "Select files created before this datetime.") - fs.StringVar( - &FileModifiedAfterFV, - FileModifiedAfterFN, "", - "Select files modified after this datetime.") - fs.StringVar( - &FileModifiedBeforeFV, - FileModifiedBeforeFN, "", - "Select files modified before this datetime.") - - // lists - - fs.StringSliceVar( - &ListFolder, - ListFolderFN, nil, - "Select lists by name; accepts '"+Wildcard+"' to select all lists.") - cobra.CheckErr(fs.MarkHidden(ListFolderFN)) - fs.StringSliceVar( - &ListItem, - ListItemFN, nil, - "Select lists by item name; accepts '"+Wildcard+"' to select all lists.") - cobra.CheckErr(fs.MarkHidden(ListItemFN)) - - // pages - - fs.StringSliceVar( - &PageFolder, - PageFolderFN, nil, - "Select pages by folder name; accepts '"+Wildcard+"' to select all pages.") - cobra.CheckErr(fs.MarkHidden(PageFolderFN)) - fs.StringSliceVar( - &Page, - PageFN, nil, - "Select pages by item name; accepts '"+Wildcard+"' to select all pages.") - cobra.CheckErr(fs.MarkHidden(PageFN)) -} - // ValidateSharePointRestoreFlags checks common flags for correctness and interdependencies func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error { if len(backupID) == 0 { @@ -141,7 +64,7 @@ func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error } // ensure url can parse all weburls provided by --site. - if _, ok := opts.Populated[SiteFN]; ok { + if _, ok := opts.Populated[flags.SiteFN]; ok { for _, wu := range opts.WebURL { if _, err := url.Parse(wu); err != nil { return clues.New("invalid site url: " + wu) @@ -149,20 +72,20 @@ func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error } } - if _, ok := opts.Populated[FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) { - return clues.New("invalid time format for " + FileCreatedAfterFN) + if _, ok := opts.Populated[flags.FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) { + return clues.New("invalid time format for " + flags.FileCreatedAfterFN) } - if _, ok := opts.Populated[FileCreatedBeforeFN]; ok && !IsValidTimeFormat(opts.FileCreatedBefore) { - return clues.New("invalid time format for " + FileCreatedBeforeFN) + if _, ok := opts.Populated[flags.FileCreatedBeforeFN]; ok && !IsValidTimeFormat(opts.FileCreatedBefore) { + return clues.New("invalid time format for " + flags.FileCreatedBeforeFN) } - if _, ok := opts.Populated[FileModifiedAfterFN]; ok && !IsValidTimeFormat(opts.FileModifiedAfter) { - return clues.New("invalid time format for " + FileModifiedAfterFN) + if _, ok := opts.Populated[flags.FileModifiedAfterFN]; ok && !IsValidTimeFormat(opts.FileModifiedAfter) { + return clues.New("invalid time format for " + flags.FileModifiedAfterFN) } - if _, ok := opts.Populated[FileModifiedBeforeFN]; ok && !IsValidTimeFormat(opts.FileModifiedBefore) { - return clues.New("invalid time format for " + FileModifiedBeforeFN) + if _, ok := opts.Populated[flags.FileModifiedBeforeFN]; ok && !IsValidTimeFormat(opts.FileModifiedBefore) { + return clues.New("invalid time format for " + flags.FileModifiedBeforeFN) } return nil diff --git a/src/cli/utils/sharepoint_test.go b/src/cli/utils/sharepoint_test.go index 5714adc2a..0e5cbd411 100644 --- a/src/cli/utils/sharepoint_test.go +++ b/src/cli/utils/sharepoint_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/tester" @@ -297,12 +298,12 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { FileCreatedBefore: dttm.Now(), FileModifiedAfter: dttm.Now(), FileModifiedBefore: dttm.Now(), - Populated: utils.PopulatedFlags{ - utils.SiteFN: {}, - utils.FileCreatedAfterFN: {}, - utils.FileCreatedBeforeFN: {}, - utils.FileModifiedAfterFN: {}, - utils.FileModifiedBeforeFN: {}, + Populated: flags.PopulatedFlags{ + flags.SiteFN: struct{}{}, + flags.FileCreatedAfterFN: struct{}{}, + flags.FileCreatedBeforeFN: struct{}{}, + flags.FileModifiedAfterFN: struct{}{}, + flags.FileModifiedBeforeFN: struct{}{}, }, }, expect: assert.NoError, @@ -318,8 +319,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { backupID: "id", opts: utils.SharePointOpts{ WebURL: []string{"slander://:vree.garbles/:"}, - Populated: utils.PopulatedFlags{ - utils.SiteFN: {}, + Populated: flags.PopulatedFlags{ + flags.SiteFN: struct{}{}, }, }, expect: assert.Error, @@ -329,8 +330,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { backupID: "id", opts: utils.SharePointOpts{ FileCreatedAfter: "1235", - Populated: utils.PopulatedFlags{ - utils.FileCreatedAfterFN: {}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedAfterFN: struct{}{}, }, }, expect: assert.Error, @@ -340,8 +341,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { backupID: "id", opts: utils.SharePointOpts{ FileCreatedBefore: "1235", - Populated: utils.PopulatedFlags{ - utils.FileCreatedBeforeFN: {}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedBeforeFN: struct{}{}, }, }, expect: assert.Error, @@ -351,8 +352,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { backupID: "id", opts: utils.SharePointOpts{ FileModifiedAfter: "1235", - Populated: utils.PopulatedFlags{ - utils.FileModifiedAfterFN: {}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedAfterFN: struct{}{}, }, }, expect: assert.Error, @@ -362,8 +363,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() { backupID: "id", opts: utils.SharePointOpts{ FileModifiedBefore: "1235", - Populated: utils.PopulatedFlags{ - utils.FileModifiedBeforeFN: {}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedBeforeFN: struct{}{}, }, }, expect: assert.Error, diff --git a/src/cli/utils/testdata/opts.go b/src/cli/utils/testdata/opts.go index 614434c11..bb42f856a 100644 --- a/src/cli/utils/testdata/opts.go +++ b/src/cli/utils/testdata/opts.go @@ -7,6 +7,7 @@ import ( "github.com/alcionai/clues" + "github.com/alcionai/corso/src/cli/flags" "github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/pkg/backup" @@ -37,8 +38,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EmailReceivedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EmailReceivedAfterFN: struct{}{}, }, } }, @@ -48,8 +49,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EmailReceivedAfter: "", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EmailReceivedAfterFN: struct{}{}, }, } }, @@ -59,8 +60,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EmailReceivedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EmailReceivedBeforeFN: struct{}{}, }, } }, @@ -70,8 +71,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EmailReceivedBefore: "", - Populated: utils.PopulatedFlags{ - utils.EmailReceivedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EmailReceivedBeforeFN: struct{}{}, }, } }, @@ -81,8 +82,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventRecurs: "foo", - Populated: utils.PopulatedFlags{ - utils.EventRecursFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventRecursFN: struct{}{}, }, } }, @@ -92,8 +93,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventRecurs: "", - Populated: utils.PopulatedFlags{ - utils.EventRecursFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventRecursFN: struct{}{}, }, } }, @@ -103,8 +104,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventStartsAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.EventStartsAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventStartsAfterFN: struct{}{}, }, } }, @@ -114,8 +115,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventStartsAfter: "", - Populated: utils.PopulatedFlags{ - utils.EventStartsAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventStartsAfterFN: struct{}{}, }, } }, @@ -125,8 +126,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventStartsBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.EventStartsBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventStartsBeforeFN: struct{}{}, }, } }, @@ -136,8 +137,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { return utils.ExchangeOpts{ EventStartsBefore: "", - Populated: utils.PopulatedFlags{ - utils.EventStartsBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.EventStartsBeforeFN: struct{}{}, }, } }, @@ -441,8 +442,8 @@ var ( return utils.OneDriveOpts{ Users: selectors.Any(), FileCreatedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.FileCreatedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedAfterFN: struct{}{}, }, } }, @@ -452,8 +453,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileCreatedAfter: "", - Populated: utils.PopulatedFlags{ - utils.FileCreatedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedAfterFN: struct{}{}, }, } }, @@ -463,8 +464,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileCreatedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.FileCreatedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedBeforeFN: struct{}{}, }, } }, @@ -474,8 +475,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileCreatedBefore: "", - Populated: utils.PopulatedFlags{ - utils.FileCreatedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileCreatedBeforeFN: struct{}{}, }, } }, @@ -485,8 +486,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileModifiedAfter: "foo", - Populated: utils.PopulatedFlags{ - utils.FileModifiedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedAfterFN: struct{}{}, }, } }, @@ -496,8 +497,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileModifiedAfter: "", - Populated: utils.PopulatedFlags{ - utils.FileModifiedAfterFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedAfterFN: struct{}{}, }, } }, @@ -507,8 +508,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileModifiedBefore: "foo", - Populated: utils.PopulatedFlags{ - utils.FileModifiedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedBeforeFN: struct{}{}, }, } }, @@ -518,8 +519,8 @@ var ( Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { return utils.OneDriveOpts{ FileModifiedBefore: "", - Populated: utils.PopulatedFlags{ - utils.FileModifiedBeforeFN: struct{}{}, + Populated: flags.PopulatedFlags{ + flags.FileModifiedBeforeFN: struct{}{}, }, } }, @@ -751,8 +752,8 @@ var ( // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { // return utils.SharePointOpts{ // FileCreatedBefore: "foo", - // Populated: utils.PopulatedFlags{ - // utils.FileCreatedBeforeFN: struct{}{}, + // Populated: flags.PopulatedFlags{ + // flags.FileCreatedBeforeFN: struct{}{}, // }, // } // }, @@ -762,8 +763,8 @@ var ( // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { // return utils.SharePointOpts{ // FileCreatedBefore: "", - // Populated: utils.PopulatedFlags{ - // utils.FileCreatedBeforeFN: struct{}{}, + // Populated: flags.PopulatedFlags{ + // flags.FileCreatedBeforeFN: struct{}{}, // }, // } // }, diff --git a/src/cli/utils/utils.go b/src/cli/utils/utils.go index e0b4c5276..277f11c5c 100644 --- a/src/cli/utils/utils.go +++ b/src/cli/utils/utils.go @@ -9,7 +9,6 @@ import ( "github.com/spf13/pflag" "github.com/alcionai/corso/src/cli/config" - "github.com/alcionai/corso/src/cli/options" "github.com/alcionai/corso/src/internal/events" "github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/control" @@ -20,10 +19,6 @@ import ( "github.com/alcionai/corso/src/pkg/storage" ) -const ( - Wildcard = "*" -) - func GetAccountAndConnect(ctx context.Context) (repository.Repository, *storage.Storage, *account.Account, error) { cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { @@ -35,7 +30,7 @@ func GetAccountAndConnect(ctx context.Context) (repository.Repository, *storage. repoID = events.RepoIDNotFound } - r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, repoID, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, repoID, Control()) if err != nil { return nil, nil, nil, clues.Wrap(err, "connecting to the "+cfg.Storage.Provider.String()+" repository") }