diff options
Diffstat (limited to 'cmd/fscrypt/fscrypt.go')
| -rw-r--r-- | cmd/fscrypt/fscrypt.go | 117 |
1 files changed, 113 insertions, 4 deletions
diff --git a/cmd/fscrypt/fscrypt.go b/cmd/fscrypt/fscrypt.go index 191d4fb..d3185fa 100644 --- a/cmd/fscrypt/fscrypt.go +++ b/cmd/fscrypt/fscrypt.go @@ -1,5 +1,6 @@ /* - * fscrypt.go - Stub file which currently just prints out the time + * fscrypt.go - File which starts up and runs the application. Initializes + * information about the application like the name, version, author, etc... * * Copyright 2017 Google Inc. * Author: Joe Richey (joerichey@google.com) @@ -19,16 +20,124 @@ /* fscrypt is a comprehensive command line tool for managing filesystem encryption. - -It currently just tells the time. */ package main import ( "fmt" + "io/ioutil" + "log" + "os" "time" + + "github.com/urfave/cli" +) + +var ( + // Current version of the program (set by Makefile) + version string + // Formatted build time (set by Makefile) + buildTime string + // Authors to display in the info command + Authors = []cli.Author{{ + Name: "Joe Richey", + Email: "joerichey@google.com", + }} ) func main() { - fmt.Printf("The time is now: %v\n", time.Now()) + cli.AppHelpTemplate = appHelpTemplate + cli.CommandHelpTemplate = commandHelpTemplate + cli.SubcommandHelpTemplate = subcommandHelpTemplate + + // Create our command line application + app := cli.NewApp() + app.Usage = shortUsage + app.Authors = Authors + app.Copyright = apache2GoogleCopyright + + // Grab the version and compilation time passed in from the Makefile. + app.Version = version + app.Compiled, _ = time.Parse(time.UnixDate, buildTime) + app.OnUsageError = onUsageError + + // Setup global flags + cli.HelpFlag = helpFlag + cli.VersionFlag = versionFlag + cli.VersionPrinter = func(c *cli.Context) { + cli.HelpPrinter(c.App.Writer, versionInfoTemplate, c.App) + } + app.Flags = universalFlags + + // We hide the help subcommand so that "fscrypt <command> --help" works + // and "fscrypt <command> help" does not. + app.HideHelp = true + + // Initialize command list and setup all of the commands. + app.Action = defaultAction + app.Commands = []cli.Command{Setup, Encrypt, Unlock} + for i := range app.Commands { + setupCommand(&app.Commands[i]) + } + + app.Run(os.Args) +} + +// setupCommand performs some common setup for each command. This includes +// hiding the help, formating the description, adding in the necessary +// flags, setting up error handlers, etc... Note that the command is modified +// in place and its subcommands are also setup. +func setupCommand(command *cli.Command) { + command.Description = wrapText(command.Description, indentLength) + command.HideHelp = true + command.Flags = append(command.Flags, universalFlags...) + + if command.Action == nil { + command.Action = defaultAction + } + + // Setup function handlers + command.OnUsageError = onUsageError + if len(command.Subcommands) == 0 { + command.Before = setupOutputs + } else { + // Cleanup subcommands (if applicable) + for i := range command.Subcommands { + setupCommand(&command.Subcommands[i]) + } + } +} + +// setupOutputs makes sure our logs, errors, and output are going to the correct +// io.Writers and that we haven't over-specified our flags. We only print the +// logs when using verbose, and only print normal stuff when not using quiet. +func setupOutputs(c *cli.Context) error { + log.SetOutput(ioutil.Discard) + c.App.Writer = ioutil.Discard + + if verboseFlag.Value { + log.SetOutput(os.Stdout) + } + if !quietFlag.Value { + c.App.Writer = os.Stdout + } + return nil +} + +// defaultAction will be run when no command is specified. +func defaultAction(c *cli.Context) error { + // Always default to showing the help + if helpFlag.Value { + cli.ShowAppHelp(c) + return nil + } + + // Only exit when not calling with the help command + var message string + if args := c.Args(); args.Present() { + message = fmt.Sprintf("command \"%s\" not found", args.First()) + } else { + message = "no command was specified" + } + return &usageError{c, message} } |