diff options
Diffstat (limited to 'cmd/errors.go')
| -rw-r--r-- | cmd/errors.go | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/cmd/errors.go b/cmd/errors.go index 07a1d05..0252fed 100644 --- a/cmd/errors.go +++ b/cmd/errors.go @@ -20,19 +20,59 @@ package cmd import ( + "fmt" + "os" + "github.com/pkg/errors" "github.com/google/fscrypt/util" ) -// Common errors used across commands +// Common errors used across tools var ( - ErrUnknownVersion = errors.New("unknown (missing version tag)") + ErrUnknownVersion = errors.New("unknown version (missing version tag)") ErrCanceled = errors.New("operation canceled by user") ErrMustForce = errors.New("operation must be forced") ErrNotRoot = errors.New("operation must be run as root") ) +// Error return codes +var ( + FailureCode = 1 + UsageFailureCode = 2 +) + +// UsageError is an error type used to denote that a command was incorrectly +// specified. Returning this type from an Action will cause print the command's +// usage to os.Stdout before exiting with UsageFailureCode. +type UsageError string + +func (u UsageError) Error() string { return string(u) } + +// CheckExpectedArgs returns a UsageError if the number of arguements in the +// context does not match expectedArgs. If atMost is set, the number of args +// is allowed to be less than expectedArgs. +func CheckExpectedArgs(ctx *Context, expectedArgs int, atMost bool) error { + // Check the number of arguements and build the message. + nArgs := len(ctx.Args) + message := "expected" + if atMost { + if nArgs <= expectedArgs { + return nil + } + message += " at most" + } else { + if nArgs == expectedArgs { + return nil + } + } + // We have the wrong number of arguments + message += fmt.Sprintf(" %s, got %s", + Pluralize(expectedArgs, "argument"), + Pluralize(nArgs, "argument")) + return UsageError(message) +} + // CheckIfRoot returns an error if the current user is not the root user. func CheckIfRoot() error { if id := util.CurrentUserID(); id != 0 { @@ -40,3 +80,37 @@ func CheckIfRoot() error { } return nil } + +// CheckRequiredFlags returns a UsageError if all of the required flags are not +// set. Only StringFlags are currently supported. +func CheckRequiredFlags(flags []*StringFlag) error { + for _, flag := range flags { + if flag.Value == "" { + return UsageError(fmt.Sprintf("required flag %s not set", flag)) + } + } + return nil +} + +// processError TODO(joerichey) +func (ctx *Context) processError(err error) { + if err == nil { + return + } + + fmt.Fprintf(os.Stderr, "%s: %s\n", ctx.FullName(), err) + // Usage Errors should print the usage information + if _, ok := err.(UsageError); ok { + ExecuteTemplate(os.Stderr, TemplateUsage, ctx) + os.Exit(UsageFailureCode) + return + } + + // Errors with a help text should print it out. + if helpText := ctx.getHelp(err); helpText != "" { + fmt.Fprintln(os.Stderr) + fmt.Fprintln(os.Stderr, wrapText(helpText, 0)) + } + os.Exit(FailureCode) + return +} |