## Description A basic mechanism to show a warning for the help output of pre-release commands ## Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No ## Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🧹 Tech Debt/Cleanup ## Issue(s) ## Test Plan <!-- How will this be tested prior to merging.--> - [x] 💪 Manual - [ ] ⚡ Unit test - [ ] 💚 E2E
139 lines
3.3 KiB
Go
139 lines
3.3 KiB
Go
package utils
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/pflag"
|
|
|
|
"github.com/alcionai/corso/src/pkg/path"
|
|
"github.com/alcionai/corso/src/pkg/repository"
|
|
"github.com/alcionai/corso/src/pkg/selectors"
|
|
)
|
|
|
|
// common flag names
|
|
const (
|
|
BackupFN = "backup"
|
|
DataFN = "data"
|
|
SiteFN = "site"
|
|
UserFN = "user"
|
|
)
|
|
|
|
const (
|
|
Wildcard = "*"
|
|
)
|
|
|
|
// RequireProps validates the existence of the properties
|
|
// in the map. Expects the format map[propName]propVal.
|
|
func RequireProps(props map[string]string) error {
|
|
for name, val := range props {
|
|
if len(val) == 0 {
|
|
return errors.New(name + " is required to perform this command")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CloseRepo handles closing a repo.
|
|
func CloseRepo(ctx context.Context, r repository.Repository) {
|
|
if err := r.Close(ctx); err != nil {
|
|
fmt.Print("Error closing repository:", err)
|
|
}
|
|
}
|
|
|
|
// HasNoFlagsAndShownHelp shows the Help output if no flags
|
|
// were provided to the command. Returns true if the help
|
|
// was shown.
|
|
// Use for when the non-flagged usage of a command
|
|
// (ex: corso backup restore exchange) is expected to no-op.
|
|
func HasNoFlagsAndShownHelp(cmd *cobra.Command) bool {
|
|
if cmd.Flags().NFlag() == 0 {
|
|
cobra.CheckErr(cmd.Help())
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
type cmdCfg struct {
|
|
hidden bool
|
|
preRelese bool
|
|
}
|
|
|
|
type cmdOpt func(*cmdCfg)
|
|
|
|
func (cc *cmdCfg) populate(opts ...cmdOpt) {
|
|
for _, opt := range opts {
|
|
opt(cc)
|
|
}
|
|
}
|
|
|
|
func HideCommand() cmdOpt {
|
|
return func(cc *cmdCfg) {
|
|
cc.hidden = true
|
|
}
|
|
}
|
|
|
|
func MarkPreReleaseCommand() cmdOpt {
|
|
return func(cc *cmdCfg) {
|
|
cc.hidden = true
|
|
cc.preRelese = true
|
|
}
|
|
}
|
|
|
|
// AddCommand adds a clone of the subCommand to the parent,
|
|
// and returns both the clone and its pflags.
|
|
func AddCommand(parent, c *cobra.Command, opts ...cmdOpt) (*cobra.Command, *pflag.FlagSet) {
|
|
cc := &cmdCfg{}
|
|
cc.populate(opts...)
|
|
|
|
parent.AddCommand(c)
|
|
c.Hidden = cc.hidden
|
|
|
|
if cc.preRelese {
|
|
// There is a default deprecated message that always shows so we do some terminal magic to overwrite it
|
|
c.Deprecated = "\n\033[1F\033[K" +
|
|
"==================================================================================================\n" +
|
|
"\tWARNING!!! THIS IS A PRE-RELEASE COMMAND THAT MAY NOT FUNCTION PROPERLY, OR AT ALL\n" +
|
|
"==================================================================================================\n"
|
|
}
|
|
|
|
c.Flags().SortFlags = false
|
|
|
|
return c, c.Flags()
|
|
}
|
|
|
|
// separates the provided folders into two sets: folders that use a pathContains
|
|
// comparison (the default), and folders that use a pathPrefix comparison.
|
|
// Any element beginning with a path.PathSeparator (ie: '/') is moved to the prefix
|
|
// comparison set. If folders is nil, returns only containsFolders with the any matcher.
|
|
func splitFoldersIntoContainsAndPrefix(folders []string) ([]string, []string) {
|
|
var (
|
|
containsFolders = []string{}
|
|
prefixFolders = []string{}
|
|
)
|
|
|
|
if len(folders) == 0 {
|
|
return selectors.Any(), nil
|
|
}
|
|
|
|
// separate folder selection inputs by behavior.
|
|
// any input beginning with a '/' character acts as a prefix match.
|
|
for _, f := range folders {
|
|
if len(f) == 0 {
|
|
continue
|
|
}
|
|
|
|
if f[0] == path.PathSeparator {
|
|
prefixFolders = append(prefixFolders, f)
|
|
} else {
|
|
containsFolders = append(containsFolders, f)
|
|
}
|
|
}
|
|
|
|
return containsFolders, prefixFolders
|
|
}
|