corso/src/cli/restore/restore.go
Abin Simon bfea3dea34 Add autocompletion for cli commands and flags
This add autocompletion for all flags and commands in the cli.
To use this you'll have to source the completions file generated by
`corso completion [bash|zsh|fish|powershell]`.

You can do that by doing the following (example for bash):

``` bash
corso completion bash > /tmp/corso_completions
source /tmp/corso_completions
```
2023-11-16 18:43:14 +05:30

138 lines
3.7 KiB
Go

package restore
import (
"context"
"github.com/alcionai/clues"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/alcionai/corso/src/cli/flags"
. "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/pkg/count"
"github.com/alcionai/corso/src/pkg/selectors"
)
var restoreCommands = []func(cmd *cobra.Command) *cobra.Command{
addExchangeCommands,
addOneDriveCommands,
addSharePointCommands,
addGroupsCommands,
}
// AddCommands attaches all `corso restore * *` commands to the parent.
func AddCommands(cmd *cobra.Command) {
subCommand := restoreCmd()
cmd.AddCommand(subCommand)
for _, addRestoreTo := range restoreCommands {
sc := addRestoreTo(subCommand)
flags.AddAllProviderFlags(sc)
flags.AddAllStorageFlags(sc)
}
}
const restoreCommand = "restore"
// FIXME: this command doesn't build docs, and so these examples
// are not visible within the website.
//
//nolint:lll
const restoreCommandExamples = `# Restore email inbox messages to their original location
corso restore exchange \
--backup 1234abcd-12ab-cd34-56de-1234abcd \
--email-folder '/inbox' \
--destination '/'
# Restore a specific OneDrive folder to the top-level destination named "recovered_june_releases"
corso restore onedrive \
--backup 1234abcd-12ab-cd34-56de-1234abcd \
--folder '/work/corso_june_releases' \
--destination /recovered_june_releases
# Restore a calendar event, making a copy if the event already exists.
corso restore exchange \
--backup 1234abcd-12ab-cd34-56de-1234abcd \
--event-calendar 'Company Events' \
--event abdef0101 \
--collisions copy
# Restore a SharePoint library in-place, replacing any conflicting files.
corso restore sharepoint \
--backup 1234abcd-12ab-cd34-56de-1234abcd \
--library documents \
--destination '/' \
--collisions replace`
// The restore category of commands.
// `corso restore [<subcommand>] [<flag>...]`
func restoreCmd() *cobra.Command {
return &cobra.Command{
Use: restoreCommand,
Short: "Restore your service data",
Long: `Restore the data stored in one of your M365 services.`,
RunE: handleRestoreCmd,
Args: utils.SubcommandsRequiredWithSuggestions,
Example: restoreCommandExamples,
}
}
// Handler for flat calls to `corso restore`.
// Produces the same output as `corso restore --help`.
func handleRestoreCmd(cmd *cobra.Command, args []string) error {
return cmd.Help()
}
// ---------------------------------------------------------------------------
// common handlers
// ---------------------------------------------------------------------------
func runRestore(
ctx context.Context,
cmd *cobra.Command,
urco utils.RestoreCfgOpts,
sel selectors.Selector,
backupID, serviceName string,
) error {
if err := utils.ValidateRestoreConfigFlags(urco); err != nil {
return Only(ctx, err)
}
r, _, err := utils.GetAccountAndConnect(ctx, cmd, sel.PathService())
if err != nil {
return Only(ctx, err)
}
defer utils.CloseRepo(ctx, r)
ro, err := r.NewRestore(ctx, backupID, sel, utils.MakeRestoreConfig(ctx, urco))
if err != nil {
return Only(ctx, clues.Wrap(err, "Failed to initialize "+serviceName+" restore"))
}
ds, err := ro.Run(ctx)
if err != nil {
if errors.Is(err, data.ErrNotFound) {
return Only(ctx, clues.New("Backup or backup details missing for id "+flags.BackupIDFV))
}
return Only(ctx, clues.Wrap(err, "Failed to run "+serviceName+" restore"))
}
Info(ctx, "Restore Complete")
skipped := ro.Counter.Get(count.CollisionSkip)
if skipped > 0 {
Infof(ctx, "Skipped %d items due to collision", skipped)
}
dis := ds.Items()
Outf(ctx, "Restored %d items", len(dis))
dis.MaybePrintEntries(ctx)
return nil
}