Chromium Code Reviews| Index: go/src/infra/tools/cr/lib/subcommand/subcommand.go |
| diff --git a/go/src/infra/tools/cr/lib/subcommand/subcommand.go b/go/src/infra/tools/cr/lib/subcommand/subcommand.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a905907d5f2c3da811103bacd60c7488cd90df02 |
| --- /dev/null |
| +++ b/go/src/infra/tools/cr/lib/subcommand/subcommand.go |
| @@ -0,0 +1,77 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +/* |
| +Library for defining subcommands in a structured way. |
| +*/ |
| + |
| +// Package subcommand provides a simple framework for defining subcommands. |
| +package subcommand |
| + |
| +import ( |
| + "flag" |
| + "fmt" |
| + "os" |
| + "text/tabwriter" |
| +) |
| + |
| +// Subcommand represents a single subcommand, with short and long versions of |
| +// its help (usage) text, a function which adds command-line flags to a |
| +// pre-existing flag.FlagSet, and a function which will be called to actually |
| +// execute the subcommand. |
| +type Subcommand struct { |
| + shortHelp string |
| + longHelp string |
| + flagFn func(*flag.FlagSet) |
| + runFn func(*flag.FlagSet) error |
| +} |
| + |
| +// Subcommands is a map of the string names of all registered subcommands to |
| +// the Subcommand structs holding their vital data. |
| +var Subcommands map[string]*Subcommand |
|
seanmccullough1
2016/05/06 00:43:54
var Subcommands = make(map[string]*Subcommand)
an
agable
2016/05/10 00:34:11
...I could have sworn I tried exactly that, and on
|
| + |
| +// TabulateSubcommands prints out all registered Subcommand names and their |
| +// short help strings. If no formatter is supplied, it uses a sane default. |
|
seanmccullough1
2016/05/06 00:43:54
Might want to mention that it flushes formatter be
agable
2016/05/10 00:34:11
Yeah, removed the parameter.
|
| +func TabulateSubcommands(formatter *tabwriter.Writer) { |
| + if formatter == nil { |
| + formatter = tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) |
| + } |
| + for key, value := range Subcommands { |
| + fmt.Fprintf(formatter, "\t%v\t%v\n", key, value.shortHelp) |
| + } |
| + formatter.Flush() |
| +} |
| + |
| +// New creates a new Subcommand struct and returns a reference to it. |
| +func New(name string, shortHelp string, longHelp string, flagFn func(*flag.FlagSet), runFn func(*flag.FlagSet) error) *Subcommand { |
| + ret := &Subcommand{shortHelp, longHelp, flagFn, runFn} |
| + Subcommands[name] = ret |
|
seanmccullough1
2016/05/06 00:43:54
bonus points: check Subcommands for existence of n
agable
2016/05/10 00:34:11
Done
|
| + return ret |
| +} |
| + |
| +// Help prints the short and long help messages, as well as the autogenerated |
| +// flags documentation. |
| +func (c *Subcommand) Help(flags *flag.FlagSet) { |
| + fmt.Printf("%s\n\n%s\n\n", c.shortHelp, c.longHelp) |
| + flags.PrintDefaults() |
| +} |
| + |
| +// InitFlags adds the subcommand's flags to a FlagSet, if flagFn is defined. |
| +func (c *Subcommand) InitFlags(flags *flag.FlagSet) { |
| + if c.flagFn != nil { |
| + c.flagFn(flags) |
| + } |
| +} |
| + |
| +// Run executes the subcommand's runFn, if it is defined. |
| +func (c *Subcommand) Run(flags *flag.FlagSet) error { |
| + if c.runFn != nil { |
| + return c.runFn(flags) |
| + } |
| + return nil |
| +} |
| + |
| +func init() { |
| + Subcommands = map[string]*Subcommand{} |
| +} |