aboutsummaryrefslogtreecommitdiff
path: root/cmd/errors.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/errors.go')
-rw-r--r--cmd/errors.go78
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
+}