diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 83b455117..6621c8464 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/pflag" "github.com/alcionai/corso/cli/config" + "github.com/alcionai/corso/cli/options" "github.com/alcionai/corso/cli/print" "github.com/alcionai/corso/cli/utils" "github.com/alcionai/corso/pkg/logger" @@ -43,6 +44,7 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { "data", nil, "Select one or more types of data to backup: "+dataEmail+", "+dataContacts+", or "+dataEvents) + options.AddOperationFlags(c) case listCommand: c, _ = utils.AddCommand(parent, exchangeListCmd) case detailsCommand: @@ -98,7 +100,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { sel := exchangeBackupCreateSelectors(exchangeAll, user, exchangeData) - bo, err := r.NewBackup(ctx, sel) + bo, err := r.NewBackup(ctx, sel, options.OperationOptions()) if err != nil { return errors.Wrap(err, "Failed to initialize Exchange backup") } diff --git a/src/cli/cli.go b/src/cli/cli.go index b61f1a377..a7e43fcea 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -27,8 +27,8 @@ var corsoCmd = &cobra.Command{ // the root-level flags var ( - version bool cfgFile string + version bool ) func init() { diff --git a/src/cli/options/options.go b/src/cli/options/options.go new file mode 100644 index 000000000..c0cbf6ce4 --- /dev/null +++ b/src/cli/options/options.go @@ -0,0 +1,23 @@ +package options + +import ( + "github.com/alcionai/corso/internal/operations" + "github.com/spf13/cobra" +) + +var ( + fastFail bool +) + +// AddFlags adds the operation option flags +func AddOperationFlags(parent *cobra.Command) { + fs := parent.Flags() + fs.BoolVar(&fastFail, "fast-fail", false, "stop processing immediately if any error occurs") + // TODO: reveal this flag when fail-fast support is implemented + cobra.CheckErr(fs.MarkHidden("fast-fail")) +} + +// OperationOptions produces the operation options based on the user's flags. +func OperationOptions() operations.Options { + return operations.NewOptions(fastFail) +} diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 3fea01832..b558cdd1d 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/pflag" "github.com/alcionai/corso/cli/config" + "github.com/alcionai/corso/cli/options" "github.com/alcionai/corso/cli/utils" "github.com/alcionai/corso/pkg/logger" "github.com/alcionai/corso/pkg/repository" @@ -37,6 +38,7 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { fs.StringVar(&backupID, "backup", "", "ID of the backup to restore") cobra.CheckErr(c.MarkFlagRequired("backup")) fs.StringVar(&user, "user", "", "ID of the user whose exchange data will get restored") + options.AddOperationFlags(c) } return c } @@ -86,7 +88,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { } defer utils.CloseRepo(ctx, r) - ro, err := r.NewRestore(ctx, backupID, exchangeRestoreSelectors(user, emailFolder, email)) + ro, err := r.NewRestore(ctx, backupID, exchangeRestoreSelectors(user, emailFolder, email), options.OperationOptions()) if err != nil { return errors.Wrap(err, "Failed to initialize Exchange restore") } diff --git a/src/internal/operations/operation.go b/src/internal/operations/operation.go index 5165496ee..3153378ad 100644 --- a/src/internal/operations/operation.go +++ b/src/internal/operations/operation.go @@ -38,8 +38,14 @@ type operation struct { // Options configure some parameters of the operation type Options struct { + FailFast bool `json:"failFast"` // todo: collision handling - // todo: fast fail vs best attempt +} + +func NewOptions(failFast bool) Options { + return Options{ + FailFast: failFast, + } } func newOperation( diff --git a/src/pkg/repository/repository.go b/src/pkg/repository/repository.go index 53fdbc709..71fbab84a 100644 --- a/src/pkg/repository/repository.go +++ b/src/pkg/repository/repository.go @@ -128,10 +128,10 @@ func (r *Repository) Close(ctx context.Context) error { } // NewBackup generates a BackupOperation runner. -func (r Repository) NewBackup(ctx context.Context, selector selectors.Selector) (operations.BackupOperation, error) { +func (r Repository) NewBackup(ctx context.Context, selector selectors.Selector, opts operations.Options) (operations.BackupOperation, error) { return operations.NewBackupOperation( ctx, - operations.Options{}, + opts, r.dataLayer, store.NewKopiaStore(r.modelStore), r.Account, @@ -139,10 +139,15 @@ func (r Repository) NewBackup(ctx context.Context, selector selectors.Selector) } // NewRestore generates a restoreOperation runner. -func (r Repository) NewRestore(ctx context.Context, backupID string, sel selectors.Selector) (operations.RestoreOperation, error) { +func (r Repository) NewRestore( + ctx context.Context, + backupID string, + sel selectors.Selector, + opts operations.Options, +) (operations.RestoreOperation, error) { return operations.NewRestoreOperation( ctx, - operations.Options{}, + opts, r.dataLayer, store.NewKopiaStore(r.modelStore), r.Account, diff --git a/src/pkg/repository/repository_test.go b/src/pkg/repository/repository_test.go index 5525b6766..5b1809fea 100644 --- a/src/pkg/repository/repository_test.go +++ b/src/pkg/repository/repository_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/internal/operations" ctesting "github.com/alcionai/corso/internal/testing" "github.com/alcionai/corso/pkg/account" "github.com/alcionai/corso/pkg/repository" @@ -171,7 +172,7 @@ func (suite *RepositoryIntegrationSuite) TestNewBackup() { r, err := repository.Initialize(ctx, acct, st) require.NoError(t, err) - bo, err := r.NewBackup(ctx, selectors.Selector{}) + bo, err := r.NewBackup(ctx, selectors.Selector{}, operations.Options{}) require.NoError(t, err) require.NotNil(t, bo) } @@ -190,7 +191,7 @@ func (suite *RepositoryIntegrationSuite) TestNewRestore() { r, err := repository.Initialize(ctx, acct, st) require.NoError(t, err) - ro, err := r.NewRestore(ctx, "backup-id", selectors.Selector{}) + ro, err := r.NewRestore(ctx, "backup-id", selectors.Selector{}, operations.Options{}) require.NoError(t, err) require.NotNil(t, ro) }