combine cli utils, options; separate flags (#3665)

The goal of this PR is to normalize the cli packages in a way that 1/ showcases clear ownership of data, 2/ minimizes package bloat, and 3/ helps avoid circular import issues.

To achieve this, two primary changes were made.
First, the cli/options package was folded into cli/utils, so that all "shared functionality" is owned by a single package.  Second, all flag values, globals, declarations, and mutator funcs (in the cli layer, logging package was not changed) were extracted from cli/utils and placed into cli/flags.  This divides ownership between the declaration and population of the flags (cli/flags) from the utilization of values derived from flags in command processing (cli/utils).

This PR contains zero logical changes.  Only code
movement and renaming.

---

#### Does this PR need a docs update or release note?

- [x]  No

#### Type of change

- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #3664

#### Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-06-26 22:19:15 -06:00 committed by GitHub
parent 0451e933d5
commit b70d32923b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 996 additions and 970 deletions

View File

@ -9,6 +9,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/alcionai/corso/src/cli/flags"
. "github.com/alcionai/corso/src/cli/print" . "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
@ -58,31 +59,21 @@ func AddCommands(cmd *cobra.Command) {
// common flags and flag attachers for commands // 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) { func addFailedItemsFN(cmd *cobra.Command) {
cmd.Flags().StringVar( cmd.Flags().StringVar(
&listFailedItems, failedItemsFN, "show", &flags.ListFailedItemsFV, flags.FailedItemsFN, "show",
"Toggles showing or hiding the list of items that failed.") "Toggles showing or hiding the list of items that failed.")
} }
func addSkippedItemsFN(cmd *cobra.Command) { func addSkippedItemsFN(cmd *cobra.Command) {
cmd.Flags().StringVar( cmd.Flags().StringVar(
&listSkippedItems, skippedItemsFN, "show", &flags.ListSkippedItemsFV, flags.SkippedItemsFN, "show",
"Toggles showing or hiding the list of items that were skipped.") "Toggles showing or hiding the list of items that were skipped.")
} }
func addRecoveredErrorsFN(cmd *cobra.Command) { func addRecoveredErrorsFN(cmd *cobra.Command) {
cmd.Flags().StringVar( cmd.Flags().StringVar(
&listRecoveredErrors, recoveredErrorsFN, "show", &flags.ListRecoveredErrorsFV, flags.RecoveredErrorsFN, "show",
"Toggles showing or hiding the list of errors which corso recovered from.") "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) 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 return nil
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
@ -31,7 +31,7 @@ const (
const ( const (
exchangeServiceCommand = "exchange" exchangeServiceCommand = "exchange"
exchangeServiceCommandCreateUseSuffix = "--mailbox <email> | '" + utils.Wildcard + "'" exchangeServiceCommandCreateUseSuffix = "--mailbox <email> | '" + flags.Wildcard + "'"
exchangeServiceCommandDeleteUseSuffix = "--backup <backupId>" exchangeServiceCommandDeleteUseSuffix = "--backup <backupId>"
exchangeServiceCommandDetailsUseSuffix = "--backup <backupId>" exchangeServiceCommandDetailsUseSuffix = "--backup <backupId>"
) )
@ -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: // 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. // More generic (ex: --user) and more frequently used flags take precedence.
utils.AddMailBoxFlag(c) flags.AddMailBoxFlag(c)
utils.AddDataFlag(c, []string{dataEmail, dataContacts, dataEvents}, false) flags.AddDataFlag(c, []string{dataEmail, dataContacts, dataEvents}, false)
options.AddFetchParallelismFlag(c) flags.AddFetchParallelismFlag(c)
options.AddFailFastFlag(c) flags.AddFailFastFlag(c)
options.AddDisableIncrementalsFlag(c) flags.AddDisableIncrementalsFlag(c)
options.AddDisableDeltaFlag(c) flags.AddDisableDeltaFlag(c)
options.AddEnableImmutableIDFlag(c) flags.AddEnableImmutableIDFlag(c)
options.AddDisableConcurrencyLimiterFlag(c) flags.AddDisableConcurrencyLimiterFlag(c)
case listCommand: case listCommand:
c, fs = utils.AddCommand(cmd, exchangeListCmd()) c, fs = utils.AddCommand(cmd, exchangeListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) flags.AddBackupIDFlag(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -107,12 +107,12 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + exchangeServiceCommandDetailsUseSuffix c.Use = c.Use + " " + exchangeServiceCommandDetailsUseSuffix
c.Example = exchangeServiceCommandDetailsExamples 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: // 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. // More generic (ex: --user) and more frequently used flags take precedence.
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddExchangeDetailsAndRestoreFlags(c) flags.AddExchangeDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:
c, fs = utils.AddCommand(cmd, exchangeDeleteCmd()) c, fs = utils.AddCommand(cmd, exchangeDeleteCmd())
@ -121,7 +121,7 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + exchangeServiceCommandDeleteUseSuffix c.Use = c.Use + " " + exchangeServiceCommandDeleteUseSuffix
c.Example = exchangeServiceCommandDeleteExamples c.Example = exchangeServiceCommandDeleteExamples
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
} }
return c return c
@ -149,7 +149,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
if err := validateExchangeBackupCreateFlags(utils.UserFV, utils.CategoryDataFV); err != nil { if err := validateExchangeBackupCreateFlags(flags.UserFV, flags.CategoryDataFV); err != nil {
return err return err
} }
@ -160,7 +160,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error {
defer utils.CloseRepo(ctx, r) 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)) ins, err := utils.UsersMap(ctx, *acct, fault.New(true))
if err != nil { if err != nil {
@ -235,7 +235,7 @@ func exchangeListCmd() *cobra.Command {
// lists the history of backup operations // lists the history of backup operations
func listExchangeCmd(cmd *cobra.Command, args []string) error { 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) 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 { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
@ -340,5 +340,5 @@ func exchangeDeleteCmd() *cobra.Command {
// deletes an exchange service backup. // deletes an exchange service backup.
func deleteExchangeCmd(cmd *cobra.Command, args []string) error { func deleteExchangeCmd(cmd *cobra.Command, args []string) error {
return genericDeleteCommand(cmd, utils.BackupIDFV, "Exchange", args) return genericDeleteCommand(cmd, flags.BackupIDFV, "Exchange", args)
} }

View File

@ -16,8 +16,8 @@ import (
"github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli"
"github.com/alcionai/corso/src/cli/config" "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/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/m365/exchange" "github.com/alcionai/corso/src/internal/m365/exchange"
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
@ -469,7 +469,7 @@ func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category p
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "details", "exchange", "backup", "details", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(bID)) "--"+flags.BackupFN, string(bID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder) cmd.SetOut(&suite.recorder)
@ -568,7 +568,7 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd() {
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "exchange", "backup", "delete", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
// run the command // run the command
@ -597,7 +597,7 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd_UnknownID
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "exchange", "backup", "delete", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
// unknown backupIDs should error since the modelStore can't find the backup // unknown backupIDs should error since the modelStore can't find the backup
@ -617,8 +617,8 @@ func buildExchangeBackupCmd(
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "create", "exchange", "backup", "create", "exchange",
"--config-file", configFile, "--config-file", configFile,
"--"+utils.UserFN, user, "--"+flags.UserFN, user,
"--"+utils.CategoryDataFN, category) "--"+flags.CategoryDataFN, category)
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(recorder) cmd.SetOut(recorder)

View File

@ -10,8 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/cli/options" "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/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/internal/version"
@ -43,14 +42,14 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
expectUse + " " + exchangeServiceCommandCreateUseSuffix, expectUse + " " + exchangeServiceCommandCreateUseSuffix,
exchangeCreateCmd().Short, exchangeCreateCmd().Short,
[]string{ []string{
utils.UserFN, flags.UserFN,
utils.CategoryDataFN, flags.CategoryDataFN,
options.DisableIncrementalsFN, flags.DisableIncrementalsFN,
options.DisableDeltaFN, flags.DisableDeltaFN,
options.FailFastFN, flags.FailFastFN,
options.FetchParallelismFN, flags.FetchParallelismFN,
options.SkipReduceFN, flags.SkipReduceFN,
options.NoStatsFN, flags.NoStatsFN,
}, },
createExchangeCmd, createExchangeCmd,
}, },
@ -60,10 +59,10 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
expectUse, expectUse,
exchangeListCmd().Short, exchangeListCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
failedItemsFN, flags.FailedItemsFN,
skippedItemsFN, flags.SkippedItemsFN,
recoveredErrorsFN, flags.RecoveredErrorsFN,
}, },
listExchangeCmd, listExchangeCmd,
}, },
@ -73,23 +72,23 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
expectUse + " " + exchangeServiceCommandDetailsUseSuffix, expectUse + " " + exchangeServiceCommandDetailsUseSuffix,
exchangeDetailsCmd().Short, exchangeDetailsCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
utils.ContactFN, flags.ContactFN,
utils.ContactFolderFN, flags.ContactFolderFN,
utils.ContactNameFN, flags.ContactNameFN,
utils.EmailFN, flags.EmailFN,
utils.EmailFolderFN, flags.EmailFolderFN,
utils.EmailReceivedAfterFN, flags.EmailReceivedAfterFN,
utils.EmailReceivedBeforeFN, flags.EmailReceivedBeforeFN,
utils.EmailSenderFN, flags.EmailSenderFN,
utils.EmailSubjectFN, flags.EmailSubjectFN,
utils.EventFN, flags.EventFN,
utils.EventCalendarFN, flags.EventCalendarFN,
utils.EventOrganizerFN, flags.EventOrganizerFN,
utils.EventRecursFN, flags.EventRecursFN,
utils.EventStartsAfterFN, flags.EventStartsAfterFN,
utils.EventStartsBeforeFN, flags.EventStartsBeforeFN,
utils.EventSubjectFN, flags.EventSubjectFN,
}, },
detailsExchangeCmd, detailsExchangeCmd,
}, },
@ -98,7 +97,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
deleteCommand, deleteCommand,
expectUse + " " + exchangeServiceCommandDeleteUseSuffix, expectUse + " " + exchangeServiceCommandDeleteUseSuffix,
exchangeDeleteCmd().Short, exchangeDeleteCmd().Short,
[]string{utils.BackupFN}, []string{flags.BackupFN},
deleteExchangeCmd, deleteExchangeCmd,
}, },
} }
@ -171,7 +170,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, no data", name: "any users, no data",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
expectIncludeLen: 3, expectIncludeLen: 3,
}, },
{ {
@ -181,7 +180,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, contacts", name: "any users, contacts",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataContacts}, data: []string{dataContacts},
expectIncludeLen: 1, expectIncludeLen: 1,
}, },
@ -193,7 +192,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, email", name: "any users, email",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataEmail}, data: []string{dataEmail},
expectIncludeLen: 1, expectIncludeLen: 1,
}, },
@ -205,7 +204,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, events", name: "any users, events",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataEvents}, data: []string{dataEvents},
expectIncludeLen: 1, expectIncludeLen: 1,
}, },
@ -217,7 +216,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, contacts + email", name: "any users, contacts + email",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataContacts, dataEmail}, data: []string{dataContacts, dataEmail},
expectIncludeLen: 2, expectIncludeLen: 2,
}, },
@ -229,7 +228,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, email + events", name: "any users, email + events",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataEmail, dataEvents}, data: []string{dataEmail, dataEvents},
expectIncludeLen: 2, expectIncludeLen: 2,
}, },
@ -241,7 +240,7 @@ func (suite *ExchangeUnitSuite) TestExchangeBackupCreateSelectors() {
}, },
{ {
name: "any users, events + contacts", name: "any users, events + contacts",
user: []string{utils.Wildcard}, user: []string{flags.Wildcard},
data: []string{dataEvents, dataContacts}, data: []string{dataEvents, dataContacts},
expectIncludeLen: 2, expectIncludeLen: 2,
}, },

View File

@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
@ -25,7 +25,7 @@ import (
const ( const (
oneDriveServiceCommand = "onedrive" oneDriveServiceCommand = "onedrive"
oneDriveServiceCommandCreateUseSuffix = "--user <email> | '" + utils.Wildcard + "'" oneDriveServiceCommandCreateUseSuffix = "--user <email> | '" + flags.Wildcard + "'"
oneDriveServiceCommandDeleteUseSuffix = "--backup <backupId>" oneDriveServiceCommandDeleteUseSuffix = "--backup <backupId>"
oneDriveServiceCommandDetailsUseSuffix = "--backup <backupId>" oneDriveServiceCommandDetailsUseSuffix = "--backup <backupId>"
) )
@ -70,15 +70,15 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + oneDriveServiceCommandCreateUseSuffix c.Use = c.Use + " " + oneDriveServiceCommandCreateUseSuffix
c.Example = oneDriveServiceCommandCreateExamples c.Example = oneDriveServiceCommandCreateExamples
utils.AddUserFlag(c) flags.AddUserFlag(c)
options.AddFailFastFlag(c) flags.AddFailFastFlag(c)
options.AddDisableIncrementalsFlag(c) flags.AddDisableIncrementalsFlag(c)
case listCommand: case listCommand:
c, fs = utils.AddCommand(cmd, oneDriveListCmd()) c, fs = utils.AddCommand(cmd, oneDriveListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) flags.AddBackupIDFlag(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -90,9 +90,9 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + oneDriveServiceCommandDetailsUseSuffix c.Use = c.Use + " " + oneDriveServiceCommandDetailsUseSuffix
c.Example = oneDriveServiceCommandDetailsExamples c.Example = oneDriveServiceCommandDetailsExamples
options.AddSkipReduceFlag(c) flags.AddSkipReduceFlag(c)
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddOneDriveDetailsAndRestoreFlags(c) flags.AddOneDriveDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:
c, fs = utils.AddCommand(cmd, oneDriveDeleteCmd()) c, fs = utils.AddCommand(cmd, oneDriveDeleteCmd())
@ -101,7 +101,7 @@ func addOneDriveCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + oneDriveServiceCommandDeleteUseSuffix c.Use = c.Use + " " + oneDriveServiceCommandDeleteUseSuffix
c.Example = oneDriveServiceCommandDeleteExamples c.Example = oneDriveServiceCommandDeleteExamples
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
} }
return c return c
@ -130,7 +130,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
if err := validateOneDriveBackupCreateFlags(utils.UserFV); err != nil { if err := validateOneDriveBackupCreateFlags(flags.UserFV); err != nil {
return err return err
} }
@ -141,7 +141,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error {
defer utils.CloseRepo(ctx, r) defer utils.CloseRepo(ctx, r)
sel := oneDriveBackupCreateSelectors(utils.UserFV) sel := oneDriveBackupCreateSelectors(flags.UserFV)
ins, err := utils.UsersMap(ctx, *acct, fault.New(true)) ins, err := utils.UsersMap(ctx, *acct, fault.New(true))
if err != nil { if err != nil {
@ -193,7 +193,7 @@ func oneDriveListCmd() *cobra.Command {
// lists the history of backup operations // lists the history of backup operations
func listOneDriveCmd(cmd *cobra.Command, args []string) error { 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) 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 { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
@ -295,5 +295,5 @@ func oneDriveDeleteCmd() *cobra.Command {
// deletes a oneDrive service backup. // deletes a oneDrive service backup.
func deleteOneDriveCmd(cmd *cobra.Command, args []string) error { func deleteOneDriveCmd(cmd *cobra.Command, args []string) error {
return genericDeleteCommand(cmd, utils.BackupIDFV, "OneDrive", args) return genericDeleteCommand(cmd, flags.BackupIDFV, "OneDrive", args)
} }

View File

@ -14,8 +14,8 @@ import (
"github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli"
"github.com/alcionai/corso/src/cli/config" "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/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -108,7 +108,7 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() {
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "create", "onedrive", "backup", "create", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.UserFN, "foo@nothere.com") "--"+flags.UserFN, "foo@nothere.com")
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(&recorder) cmd.SetOut(&recorder)
@ -200,7 +200,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() {
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "onedrive", "backup", "delete", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.recorder)
@ -240,7 +240,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd_unknownID
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "onedrive", "backup", "delete", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
// unknown backupIDs should error since the modelStore can't find the backup // unknown backupIDs should error since the modelStore can't find the backup

View File

@ -10,8 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/cli/options" "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/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/version" "github.com/alcionai/corso/src/internal/version"
@ -43,9 +42,9 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
expectUse + " " + oneDriveServiceCommandCreateUseSuffix, expectUse + " " + oneDriveServiceCommandCreateUseSuffix,
oneDriveCreateCmd().Short, oneDriveCreateCmd().Short,
[]string{ []string{
utils.UserFN, flags.UserFN,
options.DisableIncrementalsFN, flags.DisableIncrementalsFN,
options.FailFastFN, flags.FailFastFN,
}, },
createOneDriveCmd, createOneDriveCmd,
}, },
@ -55,10 +54,10 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
expectUse, expectUse,
oneDriveListCmd().Short, oneDriveListCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
failedItemsFN, flags.FailedItemsFN,
skippedItemsFN, flags.SkippedItemsFN,
recoveredErrorsFN, flags.RecoveredErrorsFN,
}, },
listOneDriveCmd, listOneDriveCmd,
}, },
@ -68,13 +67,13 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
expectUse + " " + oneDriveServiceCommandDetailsUseSuffix, expectUse + " " + oneDriveServiceCommandDetailsUseSuffix,
oneDriveDetailsCmd().Short, oneDriveDetailsCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
utils.FolderFN, flags.FolderFN,
utils.FileFN, flags.FileFN,
utils.FileCreatedAfterFN, flags.FileCreatedAfterFN,
utils.FileCreatedBeforeFN, flags.FileCreatedBeforeFN,
utils.FileModifiedAfterFN, flags.FileModifiedAfterFN,
utils.FileModifiedBeforeFN, flags.FileModifiedBeforeFN,
}, },
detailsOneDriveCmd, detailsOneDriveCmd,
}, },
@ -83,7 +82,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
deleteCommand, deleteCommand,
expectUse + " " + oneDriveServiceCommandDeleteUseSuffix, expectUse + " " + oneDriveServiceCommandDeleteUseSuffix,
oneDriveDeleteCmd().Short, oneDriveDeleteCmd().Short,
[]string{utils.BackupFN}, []string{flags.BackupFN},
deleteOneDriveCmd, deleteOneDriveCmd,
}, },
} }

View File

@ -9,7 +9,7 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"golang.org/x/exp/slices" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
@ -34,7 +34,7 @@ const (
const ( const (
sharePointServiceCommand = "sharepoint" sharePointServiceCommand = "sharepoint"
sharePointServiceCommandCreateUseSuffix = "--site <siteURL> | '" + utils.Wildcard + "'" sharePointServiceCommandCreateUseSuffix = "--site <siteURL> | '" + flags.Wildcard + "'"
sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>" sharePointServiceCommandDeleteUseSuffix = "--backup <backupId>"
sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>" sharePointServiceCommandDetailsUseSuffix = "--backup <backupId>"
) )
@ -84,17 +84,17 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix c.Use = c.Use + " " + sharePointServiceCommandCreateUseSuffix
c.Example = sharePointServiceCommandCreateExamples c.Example = sharePointServiceCommandCreateExamples
utils.AddSiteFlag(c) flags.AddSiteFlag(c)
utils.AddSiteIDFlag(c) flags.AddSiteIDFlag(c)
utils.AddDataFlag(c, []string{dataLibraries}, true) flags.AddDataFlag(c, []string{dataLibraries}, true)
options.AddFailFastFlag(c) flags.AddFailFastFlag(c)
options.AddDisableIncrementalsFlag(c) flags.AddDisableIncrementalsFlag(c)
case listCommand: case listCommand:
c, fs = utils.AddCommand(cmd, sharePointListCmd()) c, fs = utils.AddCommand(cmd, sharePointListCmd())
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, false) flags.AddBackupIDFlag(c, false)
addFailedItemsFN(c) addFailedItemsFN(c)
addSkippedItemsFN(c) addSkippedItemsFN(c)
addRecoveredErrorsFN(c) addRecoveredErrorsFN(c)
@ -106,9 +106,9 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix c.Use = c.Use + " " + sharePointServiceCommandDetailsUseSuffix
c.Example = sharePointServiceCommandDetailsExamples c.Example = sharePointServiceCommandDetailsExamples
options.AddSkipReduceFlag(c) flags.AddSkipReduceFlag(c)
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddSharePointDetailsAndRestoreFlags(c) flags.AddSharePointDetailsAndRestoreFlags(c)
case deleteCommand: case deleteCommand:
c, fs = utils.AddCommand(cmd, sharePointDeleteCmd()) c, fs = utils.AddCommand(cmd, sharePointDeleteCmd())
@ -117,7 +117,7 @@ func addSharePointCommands(cmd *cobra.Command) *cobra.Command {
c.Use = c.Use + " " + sharePointServiceCommandDeleteUseSuffix c.Use = c.Use + " " + sharePointServiceCommandDeleteUseSuffix
c.Example = sharePointServiceCommandDeleteExamples c.Example = sharePointServiceCommandDeleteExamples
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
} }
return c return c
@ -146,7 +146,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error {
return nil 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 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")) 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 { if err != nil {
return Only(ctx, clues.Wrap(err, "Retrieving up sharepoint sites by ID and URL")) 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 { if len(sites) == 0 && len(weburls) == 0 {
return clues.New( return clues.New(
"requires one or more --" + "requires one or more --" +
utils.SiteFN + " urls, or the wildcard --" + flags.SiteFN + " urls, or the wildcard --" +
utils.SiteFN + " *", flags.SiteFN + " *",
) )
} }
@ -214,11 +214,11 @@ func sharePointBackupCreateSelectors(
return selectors.NewSharePointBackup(selectors.None()), nil 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 return includeAllSitesWithCategories(ins, cats), nil
} }
if filters.PathContains(weburls).Compare(utils.Wildcard) { if filters.PathContains(weburls).Compare(flags.Wildcard) {
return includeAllSitesWithCategories(ins, cats), nil return includeAllSitesWithCategories(ins, cats), nil
} }
@ -265,7 +265,7 @@ func sharePointListCmd() *cobra.Command {
// lists the history of backup operations // lists the history of backup operations
func listSharePointCmd(cmd *cobra.Command, args []string) error { 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. // deletes a sharePoint service backup.
func deleteSharePointCmd(cmd *cobra.Command, args []string) error { 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) 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 { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }

View File

@ -14,8 +14,8 @@ import (
"github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli"
"github.com/alcionai/corso/src/cli/config" "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/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -164,7 +164,7 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd() {
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "sharepoint", "backup", "delete", "sharepoint",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.recorder)
@ -205,7 +205,7 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd_unkno
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"backup", "delete", "sharepoint", "backup", "delete", "sharepoint",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
// unknown backupIDs should error since the modelStore can't find the backup // unknown backupIDs should error since the modelStore can't find the backup

View File

@ -10,8 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/cli/options" "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/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/common/idname" "github.com/alcionai/corso/src/internal/common/idname"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -45,9 +44,9 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
expectUse + " " + sharePointServiceCommandCreateUseSuffix, expectUse + " " + sharePointServiceCommandCreateUseSuffix,
sharePointCreateCmd().Short, sharePointCreateCmd().Short,
[]string{ []string{
utils.SiteFN, flags.SiteFN,
options.DisableIncrementalsFN, flags.DisableIncrementalsFN,
options.FailFastFN, flags.FailFastFN,
}, },
createSharePointCmd, createSharePointCmd,
}, },
@ -57,10 +56,10 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
expectUse, expectUse,
sharePointListCmd().Short, sharePointListCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
failedItemsFN, flags.FailedItemsFN,
skippedItemsFN, flags.SkippedItemsFN,
recoveredErrorsFN, flags.RecoveredErrorsFN,
}, },
listSharePointCmd, listSharePointCmd,
}, },
@ -70,14 +69,14 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
expectUse + " " + sharePointServiceCommandDetailsUseSuffix, expectUse + " " + sharePointServiceCommandDetailsUseSuffix,
sharePointDetailsCmd().Short, sharePointDetailsCmd().Short,
[]string{ []string{
utils.BackupFN, flags.BackupFN,
utils.LibraryFN, flags.LibraryFN,
utils.FolderFN, flags.FolderFN,
utils.FileFN, flags.FileFN,
utils.FileCreatedAfterFN, flags.FileCreatedAfterFN,
utils.FileCreatedBeforeFN, flags.FileCreatedBeforeFN,
utils.FileModifiedAfterFN, flags.FileModifiedAfterFN,
utils.FileModifiedBeforeFN, flags.FileModifiedBeforeFN,
}, },
detailsSharePointCmd, detailsSharePointCmd,
}, },
@ -86,7 +85,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
deleteCommand, deleteCommand,
expectUse + " " + sharePointServiceCommandDeleteUseSuffix, expectUse + " " + sharePointServiceCommandDeleteUseSuffix,
sharePointDeleteCmd().Short, sharePointDeleteCmd().Short,
[]string{utils.BackupFN}, []string{flags.BackupFN},
deleteSharePointCmd, deleteSharePointCmd,
}, },
} }
@ -183,13 +182,13 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() {
}, },
{ {
name: "site wildcard", name: "site wildcard",
site: []string{utils.Wildcard}, site: []string{flags.Wildcard},
expect: bothIDs, expect: bothIDs,
expectScopesLen: 2, expectScopesLen: 2,
}, },
{ {
name: "url wildcard", name: "url wildcard",
weburl: []string{utils.Wildcard}, weburl: []string{flags.Wildcard},
expect: bothIDs, expect: bothIDs,
expectScopesLen: 2, expectScopesLen: 2,
}, },
@ -221,7 +220,7 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() {
}, },
{ {
name: "unnecessary site wildcard", name: "unnecessary site wildcard",
site: []string{id1, utils.Wildcard}, site: []string{id1, flags.Wildcard},
weburl: []string{url1, url2}, weburl: []string{url1, url2},
expect: bothIDs, expect: bothIDs,
expectScopesLen: 2, expectScopesLen: 2,
@ -229,7 +228,7 @@ func (suite *SharePointUnitSuite) TestSharePointBackupCreateSelectors() {
{ {
name: "unnecessary url wildcard", name: "unnecessary url wildcard",
site: []string{id1}, site: []string{id1},
weburl: []string{url1, utils.Wildcard}, weburl: []string{url1, flags.Wildcard},
expect: bothIDs, expect: bothIDs,
expectScopesLen: 2, expectScopesLen: 2,
}, },

View File

@ -11,8 +11,8 @@ import (
"github.com/alcionai/corso/src/cli/backup" "github.com/alcionai/corso/src/cli/backup"
"github.com/alcionai/corso/src/cli/config" "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/help"
"github.com/alcionai/corso/src/cli/options"
"github.com/alcionai/corso/src/cli/print" "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/repo" "github.com/alcionai/corso/src/cli/repo"
"github.com/alcionai/corso/src/cli/restore" "github.com/alcionai/corso/src/cli/restore"
@ -44,11 +44,11 @@ func preRun(cc *cobra.Command, args []string) error {
ctx := cc.Context() ctx := cc.Context()
log := logger.Ctx(ctx) log := logger.Ctx(ctx)
flags := utils.GetPopulatedFlags(cc) fs := flags.GetPopulatedFlags(cc)
flagSl := make([]string, 0, len(flags)) flagSl := make([]string, 0, len(fs))
// currently only tracking flag names to avoid pii leakage. // currently only tracking flag names to avoid pii leakage.
for f := range flags { for f := range fs {
flagSl = append(flagSl, f) flagSl = append(flagSl, f)
} }
@ -87,7 +87,7 @@ func preRun(cc *cobra.Command, args []string) error {
cfg.Account.ID(), cfg.Account.ID(),
map[string]any{"command": cc.CommandPath()}, map[string]any{"command": cc.CommandPath()},
cfg.RepoID, cfg.RepoID,
options.Control()) utils.Control())
} }
// handle deprecated user flag in Backup exchange command // handle deprecated user flag in Backup exchange command
@ -138,7 +138,7 @@ func CorsoCommand() *cobra.Command {
func BuildCommandTree(cmd *cobra.Command) { func BuildCommandTree(cmd *cobra.Command) {
// want to order flags explicitly // want to order flags explicitly
cmd.PersistentFlags().SortFlags = false cmd.PersistentFlags().SortFlags = false
utils.AddRunModeFlag(cmd, true) flags.AddRunModeFlag(cmd, true)
cmd.Flags().BoolP("version", "v", false, "current version info") cmd.Flags().BoolP("version", "v", false, "current version info")
cmd.PersistentPreRunE = preRun cmd.PersistentPreRunE = preRun
@ -146,7 +146,7 @@ func BuildCommandTree(cmd *cobra.Command) {
logger.AddLoggingFlags(cmd) logger.AddLoggingFlags(cmd)
observe.AddProgressBarFlags(cmd) observe.AddProgressBarFlags(cmd)
print.AddOutputFlag(cmd) print.AddOutputFlag(cmd)
options.AddGlobalOperationFlags(cmd) flags.AddGlobalOperationFlags(cmd)
cmd.SetUsageTemplate(indentExamplesTemplate(corsoCmd.UsageTemplate())) cmd.SetUsageTemplate(indentExamplesTemplate(corsoCmd.UsageTemplate()))
cmd.CompletionOptions.DisableDefaultCmd = true cmd.CompletionOptions.DisableDefaultCmd = true

124
src/cli/flags/exchange.go Normal file
View File

@ -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.")
}

36
src/cli/flags/flags.go Normal file
View File

@ -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
}

View File

@ -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))
}
}

View File

@ -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.")
}

View File

@ -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))
}

60
src/cli/flags/onedrive.go Normal file
View File

@ -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.")
}

View File

@ -1,65 +1,59 @@
package options package flags
import ( import (
"github.com/spf13/cobra" "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 ( const (
FailFastFN = "fail-fast" DisableConcurrencyLimiterFN = "disable-concurrency-limiter"
FetchParallelismFN = "fetch-parallelism"
NoStatsFN = "no-stats"
RestorePermissionsFN = "restore-permissions"
SkipReduceFN = "skip-reduce"
DisableDeltaFN = "disable-delta" DisableDeltaFN = "disable-delta"
DisableIncrementalsFN = "disable-incrementals" DisableIncrementalsFN = "disable-incrementals"
EnableImmutableIDFN = "enable-immutable-id" 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 ( var (
failFastFV bool DisableConcurrencyLimiterFV bool
fetchParallelismFV int DisableDeltaFV bool
noStatsFV bool DisableIncrementalsFV bool
restorePermissionsFV bool EnableImmutableIDFV bool
skipReduceFV 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. // AddGlobalOperationFlags adds the global operations flag set.
func AddGlobalOperationFlags(cmd *cobra.Command) { func AddGlobalOperationFlags(cmd *cobra.Command) {
fs := cmd.PersistentFlags() 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. // AddFailFastFlag adds a flag to toggle fail-fast error handling behavior.
func AddFailFastFlag(cmd *cobra.Command) { func AddFailFastFlag(cmd *cobra.Command) {
fs := cmd.Flags() 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 // TODO: reveal this flag when fail-fast support is implemented
cobra.CheckErr(fs.MarkHidden(FailFastFN)) cobra.CheckErr(fs.MarkHidden(FailFastFN))
} }
@ -67,14 +61,14 @@ func AddFailFastFlag(cmd *cobra.Command) {
// AddRestorePermissionsFlag adds OneDrive flag for restoring permissions // AddRestorePermissionsFlag adds OneDrive flag for restoring permissions
func AddRestorePermissionsFlag(cmd *cobra.Command) { func AddRestorePermissionsFlag(cmd *cobra.Command) {
fs := cmd.Flags() 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 // AddSkipReduceFlag adds a hidden flag that allows callers to skip the selector
// reduction step. Currently only intended for details commands, not restore. // reduction step. Currently only intended for details commands, not restore.
func AddSkipReduceFlag(cmd *cobra.Command) { func AddSkipReduceFlag(cmd *cobra.Command) {
fs := cmd.Flags() 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)) cobra.CheckErr(fs.MarkHidden(SkipReduceFN))
} }
@ -83,28 +77,19 @@ func AddSkipReduceFlag(cmd *cobra.Command) {
func AddFetchParallelismFlag(cmd *cobra.Command) { func AddFetchParallelismFlag(cmd *cobra.Command) {
fs := cmd.Flags() fs := cmd.Flags()
fs.IntVar( fs.IntVar(
&fetchParallelismFV, &FetchParallelismFV,
FetchParallelismFN, FetchParallelismFN,
4, 4,
"Control the number of concurrent data fetches for Exchange. Valid range is [1-4]. Default: 4") "Control the number of concurrent data fetches for Exchange. Valid range is [1-4]. Default: 4")
cobra.CheckErr(fs.MarkHidden(FetchParallelismFN)) cobra.CheckErr(fs.MarkHidden(FetchParallelismFN))
} }
// ---------------------------------------------------------------------------
// Feature Flags
// ---------------------------------------------------------------------------
var (
disableIncrementalsFV bool
disableDeltaFV bool
)
// Adds the hidden '--disable-incrementals' cli flag which, when set, disables // Adds the hidden '--disable-incrementals' cli flag which, when set, disables
// incremental backups. // incremental backups.
func AddDisableIncrementalsFlag(cmd *cobra.Command) { func AddDisableIncrementalsFlag(cmd *cobra.Command) {
fs := cmd.Flags() fs := cmd.Flags()
fs.BoolVar( fs.BoolVar(
&disableIncrementalsFV, &DisableIncrementalsFV,
DisableIncrementalsFN, DisableIncrementalsFN,
false, false,
"Disable incremental data retrieval in backups.") "Disable incremental data retrieval in backups.")
@ -116,38 +101,45 @@ func AddDisableIncrementalsFlag(cmd *cobra.Command) {
func AddDisableDeltaFlag(cmd *cobra.Command) { func AddDisableDeltaFlag(cmd *cobra.Command) {
fs := cmd.Flags() fs := cmd.Flags()
fs.BoolVar( fs.BoolVar(
&disableDeltaFV, &DisableDeltaFV,
DisableDeltaFN, DisableDeltaFN,
false, false,
"Disable delta based data retrieval in backups.") "Disable delta based data retrieval in backups.")
cobra.CheckErr(fs.MarkHidden(DisableDeltaFN)) cobra.CheckErr(fs.MarkHidden(DisableDeltaFN))
} }
var enableImmutableID bool
// Adds the hidden '--enable-immutable-id' cli flag which, when set, enables // Adds the hidden '--enable-immutable-id' cli flag which, when set, enables
// immutable IDs for Exchange // immutable IDs for Exchange
func AddEnableImmutableIDFlag(cmd *cobra.Command) { func AddEnableImmutableIDFlag(cmd *cobra.Command) {
fs := cmd.Flags() fs := cmd.Flags()
fs.BoolVar( fs.BoolVar(
&enableImmutableID, &EnableImmutableIDFV,
EnableImmutableIDFN, EnableImmutableIDFN,
false, false,
"Enable exchange immutable ID.") "Enable exchange immutable ID.")
cobra.CheckErr(fs.MarkHidden(EnableImmutableIDFN)) cobra.CheckErr(fs.MarkHidden(EnableImmutableIDFN))
} }
var disableConcurrencyLimiterFV bool
// AddDisableConcurrencyLimiterFlag adds a hidden cli flag which, when set, // AddDisableConcurrencyLimiterFlag adds a hidden cli flag which, when set,
// removes concurrency limits when communicating with graph API. This // removes concurrency limits when communicating with graph API. This
// flag is only relevant for exchange backups for now // flag is only relevant for exchange backups for now
func AddDisableConcurrencyLimiterFlag(cmd *cobra.Command) { func AddDisableConcurrencyLimiterFlag(cmd *cobra.Command) {
fs := cmd.Flags() fs := cmd.Flags()
fs.BoolVar( fs.BoolVar(
&disableConcurrencyLimiterFV, &DisableConcurrencyLimiterFV,
DisableConcurrencyLimiterFN, DisableConcurrencyLimiterFN,
false, false,
"Disable concurrency limiter middleware. Default: false") "Disable concurrency limiter middleware. Default: false")
cobra.CheckErr(fs.MarkHidden(DisableConcurrencyLimiterFN)) 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))
}

18
src/cli/flags/repo.go Normal file
View File

@ -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))
}
}

113
src/cli/flags/sharepoint.go Normal file
View File

@ -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.")
}

View File

@ -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))
}

View File

@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"golang.org/x/exp/maps" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/pkg/control/repository" "github.com/alcionai/corso/src/pkg/control/repository"
@ -42,8 +43,8 @@ func AddCommands(cmd *cobra.Command) {
maintenanceCmd, maintenanceCmd,
utils.HideCommand(), utils.HideCommand(),
utils.MarkPreReleaseCommand()) utils.MarkPreReleaseCommand())
utils.AddMaintenanceModeFlag(maintenanceCmd) flags.AddMaintenanceModeFlag(maintenanceCmd)
utils.AddForceMaintenanceFlag(maintenanceCmd) flags.AddForceMaintenanceFlag(maintenanceCmd)
for _, addRepoTo := range repoCommands { for _, addRepoTo := range repoCommands {
addRepoTo(initCmd) addRepoTo(initCmd)
@ -116,7 +117,7 @@ func maintenanceCmd() *cobra.Command {
func handleMaintenanceCmd(cmd *cobra.Command, args []string) error { func handleMaintenanceCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
t, err := getMaintenanceType(utils.MaintenanceModeFV) t, err := getMaintenanceType(flags.MaintenanceModeFV)
if err != nil { if err != nil {
return err return err
} }
@ -133,7 +134,7 @@ func handleMaintenanceCmd(cmd *cobra.Command, args []string) error {
repository.Maintenance{ repository.Maintenance{
Type: t, Type: t,
Safety: repository.FullMaintenanceSafety, Safety: repository.FullMaintenanceSafety,
Force: utils.ForceMaintenanceFV, Force: flags.ForceMaintenanceFV,
}) })
if err != nil { if err != nil {
return print.Only(ctx, err) return print.Only(ctx, err)

View File

@ -10,7 +10,6 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/alcionai/corso/src/cli/config" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/events" "github.com/alcionai/corso/src/internal/events"
@ -124,7 +123,7 @@ func initS3Cmd(cmd *cobra.Command, args []string) error {
cfg.Account.ID(), cfg.Account.ID(),
map[string]any{"command": "init repo"}, map[string]any{"command": "init repo"},
cfg.Account.ID(), cfg.Account.ID(),
options.Control()) utils.Control())
s3Cfg, err := cfg.Storage.S3Config() s3Cfg, err := cfg.Storage.S3Config()
if err != nil { 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")) 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 err != nil {
if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) { if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) {
return nil return nil
@ -214,7 +213,7 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error {
return Only(ctx, clues.New(invalidEndpointErr)) 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 { if err != nil {
return Only(ctx, clues.Wrap(err, "Failed to connect to the S3 repository")) return Only(ctx, clues.Wrap(err, "Failed to connect to the S3 repository"))
} }

View File

@ -6,7 +6,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/common/dttm"
@ -32,9 +32,9 @@ func addExchangeCommands(cmd *cobra.Command) *cobra.Command {
// general flags // general flags
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddExchangeDetailsAndRestoreFlags(c) flags.AddExchangeDetailsAndRestoreFlags(c)
options.AddFailFastFlag(c) flags.AddFailFastFlag(c)
} }
return c return c
@ -81,11 +81,11 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
opts := utils.MakeExchangeOpts(cmd) opts := utils.MakeExchangeOpts(cmd)
if utils.RunModeFV == utils.RunModeFlagTest { if flags.RunModeFV == flags.RunModeFlagTest {
return nil return nil
} }
if err := utils.ValidateExchangeRestoreFlags(utils.BackupIDFV, opts); err != nil { if err := utils.ValidateExchangeRestoreFlags(flags.BackupIDFV, opts); err != nil {
return err return err
} }
@ -102,7 +102,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
sel := utils.IncludeExchangeRestoreDataSelectors(opts) sel := utils.IncludeExchangeRestoreDataSelectors(opts)
utils.FilterExchangeRestoreInfoSelectors(sel, 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 { if err != nil {
return Only(ctx, clues.Wrap(err, "Failed to initialize Exchange restore")) 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) ds, err := ro.Run(ctx)
if err != nil { if err != nil {
if errors.Is(err, data.ErrNotFound) { 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")) return Only(ctx, clues.Wrap(err, "Failed to run Exchange restore"))

View File

@ -12,7 +12,7 @@ import (
"github.com/alcionai/corso/src/cli" "github.com/alcionai/corso/src/cli"
"github.com/alcionai/corso/src/cli/config" "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/common/idname"
"github.com/alcionai/corso/src/internal/m365/exchange" "github.com/alcionai/corso/src/internal/m365/exchange"
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
@ -135,7 +135,7 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd() {
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"restore", "exchange", "restore", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
// run the command // run the command
@ -162,15 +162,15 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badTimeFlags() {
var timeFilter string var timeFilter string
switch set { switch set {
case email: case email:
timeFilter = "--" + utils.EmailReceivedAfterFN timeFilter = "--" + flags.EmailReceivedAfterFN
case events: case events:
timeFilter = "--" + utils.EventStartsAfterFN timeFilter = "--" + flags.EventStartsAfterFN
} }
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"restore", "exchange", "restore", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID), "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID),
timeFilter, "smarf") timeFilter, "smarf")
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -198,13 +198,13 @@ func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badBoolFlags() {
var timeFilter string var timeFilter string
switch set { switch set {
case events: case events:
timeFilter = "--" + utils.EventRecursFN timeFilter = "--" + flags.EventRecursFN
} }
cmd := tester.StubRootCmd( cmd := tester.StubRootCmd(
"restore", "exchange", "restore", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.cfgFP,
"--"+utils.BackupFN, string(suite.backupOps[set].Results.BackupID), "--"+flags.BackupFN, string(suite.backupOps[set].Results.BackupID),
timeFilter, "wingbat") timeFilter, "wingbat")
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "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"
"github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -43,7 +44,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
// normally a persistent flag from the root. // normally a persistent flag from the root.
// required to ensure a dry run. // required to ensure a dry run.
utils.AddRunModeFlag(cmd, true) flags.AddRunModeFlag(cmd, true)
c := addExchangeCommands(cmd) c := addExchangeCommands(cmd)
require.NotNil(t, c) require.NotNil(t, c)
@ -59,27 +60,24 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
// Test arg parsing for few args // Test arg parsing for few args
cmd.SetArgs([]string{ cmd.SetArgs([]string{
"exchange", "exchange",
"--" + utils.RunModeFN, utils.RunModeFlagTest, "--" + flags.RunModeFN, flags.RunModeFlagTest,
"--" + utils.BackupFN, testdata.BackupInput, "--" + flags.BackupFN, testdata.BackupInput,
"--" + flags.ContactFN, testdata.FlgInputs(testdata.ContactInput),
"--" + utils.ContactFN, testdata.FlgInputs(testdata.ContactInput), "--" + flags.ContactFolderFN, testdata.FlgInputs(testdata.ContactFldInput),
"--" + utils.ContactFolderFN, testdata.FlgInputs(testdata.ContactFldInput), "--" + flags.ContactNameFN, testdata.ContactNameInput,
"--" + utils.ContactNameFN, testdata.ContactNameInput, "--" + flags.EmailFN, testdata.FlgInputs(testdata.EmailInput),
"--" + flags.EmailFolderFN, testdata.FlgInputs(testdata.EmailFldInput),
"--" + utils.EmailFN, testdata.FlgInputs(testdata.EmailInput), "--" + flags.EmailReceivedAfterFN, testdata.EmailReceivedAfterInput,
"--" + utils.EmailFolderFN, testdata.FlgInputs(testdata.EmailFldInput), "--" + flags.EmailReceivedBeforeFN, testdata.EmailReceivedBeforeInput,
"--" + utils.EmailReceivedAfterFN, testdata.EmailReceivedAfterInput, "--" + flags.EmailSenderFN, testdata.EmailSenderInput,
"--" + utils.EmailReceivedBeforeFN, testdata.EmailReceivedBeforeInput, "--" + flags.EmailSubjectFN, testdata.EmailSubjectInput,
"--" + utils.EmailSenderFN, testdata.EmailSenderInput, "--" + flags.EventFN, testdata.FlgInputs(testdata.EventInput),
"--" + utils.EmailSubjectFN, testdata.EmailSubjectInput, "--" + flags.EventCalendarFN, testdata.FlgInputs(testdata.EventCalInput),
"--" + flags.EventOrganizerFN, testdata.EventOrganizerInput,
"--" + utils.EventFN, testdata.FlgInputs(testdata.EventInput), "--" + flags.EventRecursFN, testdata.EventRecursInput,
"--" + utils.EventCalendarFN, testdata.FlgInputs(testdata.EventCalInput), "--" + flags.EventStartsAfterFN, testdata.EventStartsAfterInput,
"--" + utils.EventOrganizerFN, testdata.EventOrganizerInput, "--" + flags.EventStartsBeforeFN, testdata.EventStartsBeforeInput,
"--" + utils.EventRecursFN, testdata.EventRecursInput, "--" + flags.EventSubjectFN, testdata.EventSubjectInput,
"--" + utils.EventStartsAfterFN, testdata.EventStartsAfterInput,
"--" + utils.EventStartsBeforeFN, testdata.EventStartsBeforeInput,
"--" + utils.EventSubjectFN, testdata.EventSubjectInput,
}) })
cmd.SetOut(new(bytes.Buffer)) // drop output cmd.SetOut(new(bytes.Buffer)) // drop output
@ -88,7 +86,7 @@ func (suite *ExchangeUnitSuite) TestAddExchangeCommands() {
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))
opts := utils.MakeExchangeOpts(cmd) 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.ContactInput, opts.Contact)
assert.ElementsMatch(t, testdata.ContactFldInput, opts.ContactFolder) assert.ElementsMatch(t, testdata.ContactFldInput, opts.ContactFolder)

View File

@ -6,7 +6,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/dttm" "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. // More generic (ex: --user) and more frequently used flags take precedence.
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddOneDriveDetailsAndRestoreFlags(c) flags.AddOneDriveDetailsAndRestoreFlags(c)
flags.AddRestorePermissionsFlag(c)
// restore permissions flags.AddFailFastFlag(c)
options.AddRestorePermissionsFlag(c)
options.AddFailFastFlag(c)
} }
return c return c
@ -82,11 +80,11 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
opts := utils.MakeOneDriveOpts(cmd) opts := utils.MakeOneDriveOpts(cmd)
if utils.RunModeFV == utils.RunModeFlagTest { if flags.RunModeFV == flags.RunModeFlagTest {
return nil return nil
} }
if err := utils.ValidateOneDriveRestoreFlags(utils.BackupIDFV, opts); err != nil { if err := utils.ValidateOneDriveRestoreFlags(flags.BackupIDFV, opts); err != nil {
return err return err
} }
@ -103,7 +101,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
sel := utils.IncludeOneDriveRestoreDataSelectors(opts) sel := utils.IncludeOneDriveRestoreDataSelectors(opts)
utils.FilterOneDriveRestoreInfoSelectors(sel, 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 { if err != nil {
return Only(ctx, clues.Wrap(err, "Failed to initialize OneDrive restore")) 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) ds, err := ro.Run(ctx)
if err != nil { if err != nil {
if errors.Is(err, data.ErrNotFound) { 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")) return Only(ctx, clues.Wrap(err, "Failed to run OneDrive restore"))

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "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"
"github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -43,7 +44,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
// normally a persistent flag from the root. // normally a persistent flag from the root.
// required to ensure a dry run. // required to ensure a dry run.
utils.AddRunModeFlag(cmd, true) flags.AddRunModeFlag(cmd, true)
c := addOneDriveCommands(cmd) c := addOneDriveCommands(cmd)
require.NotNil(t, c) require.NotNil(t, c)
@ -58,15 +59,14 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
cmd.SetArgs([]string{ cmd.SetArgs([]string{
"onedrive", "onedrive",
"--" + utils.RunModeFN, utils.RunModeFlagTest, "--" + flags.RunModeFN, flags.RunModeFlagTest,
"--" + utils.BackupFN, testdata.BackupInput, "--" + flags.BackupFN, testdata.BackupInput,
"--" + flags.FileFN, testdata.FlgInputs(testdata.FileNameInput),
"--" + utils.FileFN, testdata.FlgInputs(testdata.FileNameInput), "--" + flags.FolderFN, testdata.FlgInputs(testdata.FolderPathInput),
"--" + utils.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), "--" + flags.FileCreatedAfterFN, testdata.FileCreatedAfterInput,
"--" + utils.FileCreatedAfterFN, testdata.FileCreatedAfterInput, "--" + flags.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput,
"--" + utils.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, "--" + flags.FileModifiedAfterFN, testdata.FileModifiedAfterInput,
"--" + utils.FileModifiedAfterFN, testdata.FileModifiedAfterInput, "--" + flags.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput,
"--" + utils.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput,
}) })
cmd.SetOut(new(bytes.Buffer)) // drop output cmd.SetOut(new(bytes.Buffer)) // drop output
@ -75,7 +75,7 @@ func (suite *OneDriveUnitSuite) TestAddOneDriveCommands() {
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))
opts := utils.MakeOneDriveOpts(cmd) 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.FileNameInput, opts.FileName)
assert.ElementsMatch(t, testdata.FolderPathInput, opts.FolderPath) assert.ElementsMatch(t, testdata.FolderPathInput, opts.FolderPath)

View File

@ -6,7 +6,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/print"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/dttm" "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. // More generic (ex: --site) and more frequently used flags take precedence.
fs.SortFlags = false fs.SortFlags = false
utils.AddBackupIDFlag(c, true) flags.AddBackupIDFlag(c, true)
utils.AddSharePointDetailsAndRestoreFlags(c) flags.AddSharePointDetailsAndRestoreFlags(c)
flags.AddRestorePermissionsFlag(c)
options.AddRestorePermissionsFlag(c) flags.AddFailFastFlag(c)
options.AddFailFastFlag(c)
} }
return c return c
@ -87,11 +86,11 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
opts := utils.MakeSharePointOpts(cmd) opts := utils.MakeSharePointOpts(cmd)
if utils.RunModeFV == utils.RunModeFlagTest { if flags.RunModeFV == flags.RunModeFlagTest {
return nil return nil
} }
if err := utils.ValidateSharePointRestoreFlags(utils.BackupIDFV, opts); err != nil { if err := utils.ValidateSharePointRestoreFlags(flags.BackupIDFV, opts); err != nil {
return err return err
} }
@ -108,7 +107,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts) sel := utils.IncludeSharePointRestoreDataSelectors(ctx, opts)
utils.FilterSharePointRestoreInfoSelectors(sel, 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 { if err != nil {
return Only(ctx, clues.Wrap(err, "Failed to initialize SharePoint restore")) 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) ds, err := ro.Run(ctx)
if err != nil { if err != nil {
if errors.Is(err, data.ErrNotFound) { 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")) return Only(ctx, clues.Wrap(err, "Failed to run SharePoint restore"))

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "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"
"github.com/alcionai/corso/src/cli/utils/testdata" "github.com/alcionai/corso/src/cli/utils/testdata"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -43,7 +44,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
// normally a persistent flag from the root. // normally a persistent flag from the root.
// required to ensure a dry run. // required to ensure a dry run.
utils.AddRunModeFlag(cmd, true) flags.AddRunModeFlag(cmd, true)
c := addSharePointCommands(cmd) c := addSharePointCommands(cmd)
require.NotNil(t, c) require.NotNil(t, c)
@ -58,22 +59,19 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
cmd.SetArgs([]string{ cmd.SetArgs([]string{
"sharepoint", "sharepoint",
"--" + utils.RunModeFN, utils.RunModeFlagTest, "--" + flags.RunModeFN, flags.RunModeFlagTest,
"--" + utils.BackupFN, testdata.BackupInput, "--" + flags.BackupFN, testdata.BackupInput,
"--" + flags.LibraryFN, testdata.LibraryInput,
"--" + utils.LibraryFN, testdata.LibraryInput, "--" + flags.FileFN, testdata.FlgInputs(testdata.FileNameInput),
"--" + utils.FileFN, testdata.FlgInputs(testdata.FileNameInput), "--" + flags.FolderFN, testdata.FlgInputs(testdata.FolderPathInput),
"--" + utils.FolderFN, testdata.FlgInputs(testdata.FolderPathInput), "--" + flags.FileCreatedAfterFN, testdata.FileCreatedAfterInput,
"--" + utils.FileCreatedAfterFN, testdata.FileCreatedAfterInput, "--" + flags.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput,
"--" + utils.FileCreatedBeforeFN, testdata.FileCreatedBeforeInput, "--" + flags.FileModifiedAfterFN, testdata.FileModifiedAfterInput,
"--" + utils.FileModifiedAfterFN, testdata.FileModifiedAfterInput, "--" + flags.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput,
"--" + utils.FileModifiedBeforeFN, testdata.FileModifiedBeforeInput, "--" + flags.ListItemFN, testdata.FlgInputs(testdata.ListItemInput),
"--" + flags.ListFolderFN, testdata.FlgInputs(testdata.ListFolderInput),
"--" + utils.ListItemFN, testdata.FlgInputs(testdata.ListItemInput), "--" + flags.PageFN, testdata.FlgInputs(testdata.PageInput),
"--" + utils.ListFolderFN, testdata.FlgInputs(testdata.ListFolderInput), "--" + flags.PageFolderFN, testdata.FlgInputs(testdata.PageFolderInput),
"--" + utils.PageFN, testdata.FlgInputs(testdata.PageInput),
"--" + utils.PageFolderFN, testdata.FlgInputs(testdata.PageFolderInput),
}) })
cmd.SetOut(new(bytes.Buffer)) // drop output cmd.SetOut(new(bytes.Buffer)) // drop output
@ -82,7 +80,7 @@ func (suite *SharePointUnitSuite) TestAddSharePointCommands() {
assert.NoError(t, err, clues.ToCore(err)) assert.NoError(t, err, clues.ToCore(err))
opts := utils.MakeSharePointOpts(cmd) 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.Equal(t, testdata.LibraryInput, opts.Library)
assert.ElementsMatch(t, testdata.FileNameInput, opts.FileName) assert.ElementsMatch(t, testdata.FileNameInput, opts.FileName)

View File

@ -4,53 +4,10 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/alcionai/corso/src/cli/flags"
"github.com/alcionai/corso/src/pkg/selectors" "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 { type ExchangeOpts struct {
Users []string Users []string
@ -73,113 +30,37 @@ type ExchangeOpts struct {
EventStartsBefore string EventStartsBefore string
EventSubject string EventSubject string
Populated PopulatedFlags Populated flags.PopulatedFlags
} }
// populates an ExchangeOpts struct with the command's current flags. // populates an ExchangeOpts struct with the command's current flags.
func MakeExchangeOpts(cmd *cobra.Command) ExchangeOpts { func MakeExchangeOpts(cmd *cobra.Command) ExchangeOpts {
return ExchangeOpts{ return ExchangeOpts{
Users: UserFV, Users: flags.UserFV,
Contact: ContactFV, Contact: flags.ContactFV,
ContactFolder: ContactFolderFV, ContactFolder: flags.ContactFolderFV,
ContactName: ContactNameFV, ContactName: flags.ContactNameFV,
Email: EmailFV, Email: flags.EmailFV,
EmailFolder: EmailFolderFV, EmailFolder: flags.EmailFolderFV,
EmailReceivedAfter: EmailReceivedAfterFV, EmailReceivedAfter: flags.EmailReceivedAfterFV,
EmailReceivedBefore: EmailReceivedBeforeFV, EmailReceivedBefore: flags.EmailReceivedBeforeFV,
EmailSender: EmailSenderFV, EmailSender: flags.EmailSenderFV,
EmailSubject: EmailSubjectFV, EmailSubject: flags.EmailSubjectFV,
Event: EventFV, Event: flags.EventFV,
EventCalendar: EventCalendarFV, EventCalendar: flags.EventCalendarFV,
EventOrganizer: EventOrganizerFV, EventOrganizer: flags.EventOrganizerFV,
EventRecurs: EventRecursFV, EventRecurs: flags.EventRecursFV,
EventStartsAfter: EventStartsAfterFV, EventStartsAfter: flags.EventStartsAfterFV,
EventStartsBefore: EventStartsBeforeFV, EventStartsBefore: flags.EventStartsBeforeFV,
EventSubject: EventSubjectFV, 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 // AddExchangeInclude adds the scope of the provided values to the selector's
// inclusion set. Any unpopulated slice will be replaced with selectors.Any() // inclusion set. Any unpopulated slice will be replaced with selectors.Any()
// to act as a wildcard. // to act as a wildcard.
@ -231,23 +112,23 @@ func ValidateExchangeRestoreFlags(backupID string, opts ExchangeOpts) error {
return clues.New("a backup ID is required") 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") 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") 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") 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") 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") return clues.New("invalid format for event-recurs")
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "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"
"github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -62,7 +63,7 @@ func (suite *ExchangeUtilsSuite) TestValidateRestoreFlags() {
func (suite *ExchangeUtilsSuite) TestIncludeExchangeRestoreDataSelectors() { func (suite *ExchangeUtilsSuite) TestIncludeExchangeRestoreDataSelectors() {
stub := []string{"id-stub"} stub := []string{"id-stub"}
many := []string{"fnord", "smarf"} many := []string{"fnord", "smarf"}
a := []string{utils.Wildcard} a := []string{flags.Wildcard}
table := []struct { table := []struct {
name string name string

View File

@ -1,233 +1,13 @@
package utils package utils
import ( import (
"fmt"
"strconv" "strconv"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/alcionai/corso/src/internal/common/dttm" "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/path"
"github.com/alcionai/corso/src/pkg/selectors" "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 // IsValidTimeFormat returns true if the input is recognized as a
// supported format by the common time parser. // supported format by the common time parser.
func IsValidTimeFormat(in string) bool { func IsValidTimeFormat(in string) bool {

View File

@ -4,6 +4,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/alcionai/corso/src/cli/flags"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
) )
@ -17,78 +18,43 @@ type OneDriveOpts struct {
FileModifiedAfter string FileModifiedAfter string
FileModifiedBefore string FileModifiedBefore string
Populated PopulatedFlags Populated flags.PopulatedFlags
} }
func MakeOneDriveOpts(cmd *cobra.Command) OneDriveOpts { func MakeOneDriveOpts(cmd *cobra.Command) OneDriveOpts {
return OneDriveOpts{ return OneDriveOpts{
Users: UserFV, Users: flags.UserFV,
FileName: FileNameFV, FileName: flags.FileNameFV,
FolderPath: FolderPathFV, FolderPath: flags.FolderPathFV,
FileCreatedAfter: FileCreatedAfterFV, FileCreatedAfter: flags.FileCreatedAfterFV,
FileCreatedBefore: FileCreatedBeforeFV, FileCreatedBefore: flags.FileCreatedBeforeFV,
FileModifiedAfter: FileModifiedAfterFV, FileModifiedAfter: flags.FileModifiedAfterFV,
FileModifiedBefore: FileModifiedBeforeFV, 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 // ValidateOneDriveRestoreFlags checks common flags for correctness and interdependencies
func ValidateOneDriveRestoreFlags(backupID string, opts OneDriveOpts) error { func ValidateOneDriveRestoreFlags(backupID string, opts OneDriveOpts) error {
if len(backupID) == 0 { if len(backupID) == 0 {
return clues.New("a backup ID is required") 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") 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") 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") 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") return clues.New("invalid time format for modified-before")
} }

26
src/cli/utils/options.go Normal file
View File

@ -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
}

View File

@ -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))
}

View File

@ -8,25 +8,11 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/alcionai/corso/src/cli/flags"
"github.com/alcionai/corso/src/pkg/logger" "github.com/alcionai/corso/src/pkg/logger"
"github.com/alcionai/corso/src/pkg/selectors" "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 { type SharePointOpts struct {
SiteID []string SiteID []string
WebURL []string WebURL []string
@ -45,95 +31,32 @@ type SharePointOpts struct {
PageFolder []string PageFolder []string
Page []string Page []string
Populated PopulatedFlags Populated flags.PopulatedFlags
} }
func MakeSharePointOpts(cmd *cobra.Command) SharePointOpts { func MakeSharePointOpts(cmd *cobra.Command) SharePointOpts {
return SharePointOpts{ return SharePointOpts{
SiteID: SiteIDFV, SiteID: flags.SiteIDFV,
WebURL: WebURLFV, WebURL: flags.WebURLFV,
Library: LibraryFV, Library: flags.LibraryFV,
FileName: FileNameFV, FileName: flags.FileNameFV,
FolderPath: FolderPathFV, FolderPath: flags.FolderPathFV,
FileCreatedAfter: FileCreatedAfterFV, FileCreatedAfter: flags.FileCreatedAfterFV,
FileCreatedBefore: FileCreatedBeforeFV, FileCreatedBefore: flags.FileCreatedBeforeFV,
FileModifiedAfter: FileModifiedAfterFV, FileModifiedAfter: flags.FileModifiedAfterFV,
FileModifiedBefore: FileModifiedBeforeFV, FileModifiedBefore: flags.FileModifiedBeforeFV,
ListFolder: ListFolder, ListFolder: flags.ListFolderFV,
ListItem: ListItem, ListItem: flags.ListItemFV,
Page: Page, Page: flags.PageFV,
PageFolder: PageFolder, 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 // ValidateSharePointRestoreFlags checks common flags for correctness and interdependencies
func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error { func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error {
if len(backupID) == 0 { if len(backupID) == 0 {
@ -141,7 +64,7 @@ func ValidateSharePointRestoreFlags(backupID string, opts SharePointOpts) error
} }
// ensure url can parse all weburls provided by --site. // 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 { for _, wu := range opts.WebURL {
if _, err := url.Parse(wu); err != nil { if _, err := url.Parse(wu); err != nil {
return clues.New("invalid site url: " + wu) 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) { if _, ok := opts.Populated[flags.FileCreatedAfterFN]; ok && !IsValidTimeFormat(opts.FileCreatedAfter) {
return clues.New("invalid time format for " + FileCreatedAfterFN) return clues.New("invalid time format for " + flags.FileCreatedAfterFN)
} }
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 " + FileCreatedBeforeFN) return clues.New("invalid time format for " + flags.FileCreatedBeforeFN)
} }
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 " + FileModifiedAfterFN) return clues.New("invalid time format for " + flags.FileModifiedAfterFN)
} }
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 " + FileModifiedBeforeFN) return clues.New("invalid time format for " + flags.FileModifiedBeforeFN)
} }
return nil return nil

View File

@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite" "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"
"github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
@ -297,12 +298,12 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
FileCreatedBefore: dttm.Now(), FileCreatedBefore: dttm.Now(),
FileModifiedAfter: dttm.Now(), FileModifiedAfter: dttm.Now(),
FileModifiedBefore: dttm.Now(), FileModifiedBefore: dttm.Now(),
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.SiteFN: {}, flags.SiteFN: struct{}{},
utils.FileCreatedAfterFN: {}, flags.FileCreatedAfterFN: struct{}{},
utils.FileCreatedBeforeFN: {}, flags.FileCreatedBeforeFN: struct{}{},
utils.FileModifiedAfterFN: {}, flags.FileModifiedAfterFN: struct{}{},
utils.FileModifiedBeforeFN: {}, flags.FileModifiedBeforeFN: struct{}{},
}, },
}, },
expect: assert.NoError, expect: assert.NoError,
@ -318,8 +319,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
WebURL: []string{"slander://:vree.garbles/:"}, WebURL: []string{"slander://:vree.garbles/:"},
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.SiteFN: {}, flags.SiteFN: struct{}{},
}, },
}, },
expect: assert.Error, expect: assert.Error,
@ -329,8 +330,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
FileCreatedAfter: "1235", FileCreatedAfter: "1235",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedAfterFN: {}, flags.FileCreatedAfterFN: struct{}{},
}, },
}, },
expect: assert.Error, expect: assert.Error,
@ -340,8 +341,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
FileCreatedBefore: "1235", FileCreatedBefore: "1235",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedBeforeFN: {}, flags.FileCreatedBeforeFN: struct{}{},
}, },
}, },
expect: assert.Error, expect: assert.Error,
@ -351,8 +352,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
FileModifiedAfter: "1235", FileModifiedAfter: "1235",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedAfterFN: {}, flags.FileModifiedAfterFN: struct{}{},
}, },
}, },
expect: assert.Error, expect: assert.Error,
@ -362,8 +363,8 @@ func (suite *SharePointUtilsSuite) TestValidateSharePointRestoreFlags() {
backupID: "id", backupID: "id",
opts: utils.SharePointOpts{ opts: utils.SharePointOpts{
FileModifiedBefore: "1235", FileModifiedBefore: "1235",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedBeforeFN: {}, flags.FileModifiedBeforeFN: struct{}{},
}, },
}, },
expect: assert.Error, expect: assert.Error,

View File

@ -7,6 +7,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/cli/flags"
"github.com/alcionai/corso/src/cli/utils" "github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/common/dttm" "github.com/alcionai/corso/src/internal/common/dttm"
"github.com/alcionai/corso/src/pkg/backup" "github.com/alcionai/corso/src/pkg/backup"
@ -37,8 +38,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EmailReceivedAfter: "foo", EmailReceivedAfter: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EmailReceivedAfterFN: struct{}{}, flags.EmailReceivedAfterFN: struct{}{},
}, },
} }
}, },
@ -48,8 +49,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EmailReceivedAfter: "", EmailReceivedAfter: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EmailReceivedAfterFN: struct{}{}, flags.EmailReceivedAfterFN: struct{}{},
}, },
} }
}, },
@ -59,8 +60,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EmailReceivedBefore: "foo", EmailReceivedBefore: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EmailReceivedBeforeFN: struct{}{}, flags.EmailReceivedBeforeFN: struct{}{},
}, },
} }
}, },
@ -70,8 +71,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EmailReceivedBefore: "", EmailReceivedBefore: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EmailReceivedBeforeFN: struct{}{}, flags.EmailReceivedBeforeFN: struct{}{},
}, },
} }
}, },
@ -81,8 +82,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventRecurs: "foo", EventRecurs: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventRecursFN: struct{}{}, flags.EventRecursFN: struct{}{},
}, },
} }
}, },
@ -92,8 +93,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventRecurs: "", EventRecurs: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventRecursFN: struct{}{}, flags.EventRecursFN: struct{}{},
}, },
} }
}, },
@ -103,8 +104,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventStartsAfter: "foo", EventStartsAfter: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventStartsAfterFN: struct{}{}, flags.EventStartsAfterFN: struct{}{},
}, },
} }
}, },
@ -114,8 +115,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventStartsAfter: "", EventStartsAfter: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventStartsAfterFN: struct{}{}, flags.EventStartsAfterFN: struct{}{},
}, },
} }
}, },
@ -125,8 +126,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventStartsBefore: "foo", EventStartsBefore: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventStartsBeforeFN: struct{}{}, flags.EventStartsBeforeFN: struct{}{},
}, },
} }
}, },
@ -136,8 +137,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts { Opts: func(t *testing.T, wantedVersion int) utils.ExchangeOpts {
return utils.ExchangeOpts{ return utils.ExchangeOpts{
EventStartsBefore: "", EventStartsBefore: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.EventStartsBeforeFN: struct{}{}, flags.EventStartsBeforeFN: struct{}{},
}, },
} }
}, },
@ -441,8 +442,8 @@ var (
return utils.OneDriveOpts{ return utils.OneDriveOpts{
Users: selectors.Any(), Users: selectors.Any(),
FileCreatedAfter: "foo", FileCreatedAfter: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedAfterFN: struct{}{}, flags.FileCreatedAfterFN: struct{}{},
}, },
} }
}, },
@ -452,8 +453,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileCreatedAfter: "", FileCreatedAfter: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedAfterFN: struct{}{}, flags.FileCreatedAfterFN: struct{}{},
}, },
} }
}, },
@ -463,8 +464,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileCreatedBefore: "foo", FileCreatedBefore: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedBeforeFN: struct{}{}, flags.FileCreatedBeforeFN: struct{}{},
}, },
} }
}, },
@ -474,8 +475,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileCreatedBefore: "", FileCreatedBefore: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileCreatedBeforeFN: struct{}{}, flags.FileCreatedBeforeFN: struct{}{},
}, },
} }
}, },
@ -485,8 +486,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileModifiedAfter: "foo", FileModifiedAfter: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedAfterFN: struct{}{}, flags.FileModifiedAfterFN: struct{}{},
}, },
} }
}, },
@ -496,8 +497,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileModifiedAfter: "", FileModifiedAfter: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedAfterFN: struct{}{}, flags.FileModifiedAfterFN: struct{}{},
}, },
} }
}, },
@ -507,8 +508,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileModifiedBefore: "foo", FileModifiedBefore: "foo",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedBeforeFN: struct{}{}, flags.FileModifiedBeforeFN: struct{}{},
}, },
} }
}, },
@ -518,8 +519,8 @@ var (
Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
return utils.OneDriveOpts{ return utils.OneDriveOpts{
FileModifiedBefore: "", FileModifiedBefore: "",
Populated: utils.PopulatedFlags{ Populated: flags.PopulatedFlags{
utils.FileModifiedBeforeFN: struct{}{}, flags.FileModifiedBeforeFN: struct{}{},
}, },
} }
}, },
@ -751,8 +752,8 @@ var (
// Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
// return utils.SharePointOpts{ // return utils.SharePointOpts{
// FileCreatedBefore: "foo", // FileCreatedBefore: "foo",
// Populated: utils.PopulatedFlags{ // Populated: flags.PopulatedFlags{
// utils.FileCreatedBeforeFN: struct{}{}, // flags.FileCreatedBeforeFN: struct{}{},
// }, // },
// } // }
// }, // },
@ -762,8 +763,8 @@ var (
// Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts { // Opts: func(t *testing.T, wantedVersion int) utils.OneDriveOpts {
// return utils.SharePointOpts{ // return utils.SharePointOpts{
// FileCreatedBefore: "", // FileCreatedBefore: "",
// Populated: utils.PopulatedFlags{ // Populated: flags.PopulatedFlags{
// utils.FileCreatedBeforeFN: struct{}{}, // flags.FileCreatedBeforeFN: struct{}{},
// }, // },
// } // }
// }, // },

View File

@ -9,7 +9,6 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/alcionai/corso/src/cli/config" "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/internal/events"
"github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control"
@ -20,10 +19,6 @@ import (
"github.com/alcionai/corso/src/pkg/storage" "github.com/alcionai/corso/src/pkg/storage"
) )
const (
Wildcard = "*"
)
func GetAccountAndConnect(ctx context.Context) (repository.Repository, *storage.Storage, *account.Account, error) { func GetAccountAndConnect(ctx context.Context) (repository.Repository, *storage.Storage, *account.Account, error) {
cfg, err := config.GetConfigRepoDetails(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
@ -35,7 +30,7 @@ func GetAccountAndConnect(ctx context.Context) (repository.Repository, *storage.
repoID = events.RepoIDNotFound 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 { if err != nil {
return nil, nil, nil, clues.Wrap(err, "connecting to the "+cfg.Storage.Provider.String()+" repository") return nil, nil, nil, clues.Wrap(err, "connecting to the "+cfg.Storage.Provider.String()+" repository")
} }