| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /* |
| 6 Library for defining subcommands in a structured way. |
| 7 */ |
| 8 |
| 9 // Package subcommand provides a simple framework for defining subcommands. |
| 10 package subcommand |
| 11 |
| 12 import ( |
| 13 "flag" |
| 14 "fmt" |
| 15 "os" |
| 16 "sort" |
| 17 "text/tabwriter" |
| 18 ) |
| 19 |
| 20 // Subcommand represents a single subcommand, with short and long versions of |
| 21 // its help (usage) text, a function which adds command-line flags to a |
| 22 // pre-existing flag.FlagSet, and a function which will be called to actually |
| 23 // execute the subcommand. |
| 24 type Subcommand struct { |
| 25 shortHelp string |
| 26 longHelp string |
| 27 flagFn func(*flag.FlagSet) |
| 28 runFn func(*flag.FlagSet) error |
| 29 } |
| 30 |
| 31 // Help prints the short and long help messages, as well as the autogenerated |
| 32 // flags documentation. |
| 33 func (c *Subcommand) Help(flags *flag.FlagSet) { |
| 34 fmt.Printf("%s\n\n%s\n\n", c.shortHelp, c.longHelp) |
| 35 flags.PrintDefaults() |
| 36 } |
| 37 |
| 38 // InitFlags adds the subcommand's flags to a FlagSet, if flagFn is defined. |
| 39 func (c *Subcommand) InitFlags(flags *flag.FlagSet) { |
| 40 if c.flagFn != nil { |
| 41 c.flagFn(flags) |
| 42 } |
| 43 } |
| 44 |
| 45 // Run executes the subcommand's runFn, if it is defined. |
| 46 func (c *Subcommand) Run(flags *flag.FlagSet) error { |
| 47 if c.runFn != nil { |
| 48 return c.runFn(flags) |
| 49 } |
| 50 return nil |
| 51 } |
| 52 |
| 53 // Private registry holding a map of subcommands. Users of this library only |
| 54 // have access to a default instance of the registry via the New and Tabulate |
| 55 // functions, but tests can instantiate one directly. |
| 56 type registry struct { |
| 57 subcommands map[string]*Subcommand |
| 58 } |
| 59 |
| 60 func (r *registry) new(name string, shortHelp string, longHelp string, flagFn fu
nc(*flag.FlagSet), runFn func(*flag.FlagSet) error) *Subcommand { |
| 61 if _, ok := r.subcommands[name]; ok { |
| 62 panic(fmt.Errorf("attempted to double-register subcommand %q", n
ame)) |
| 63 } |
| 64 ret := &Subcommand{shortHelp, longHelp, flagFn, runFn} |
| 65 r.subcommands[name] = ret |
| 66 return ret |
| 67 } |
| 68 |
| 69 func (r *registry) get(name string) *Subcommand { |
| 70 s, ok := r.subcommands[name] |
| 71 if !ok { |
| 72 return nil |
| 73 } |
| 74 return s |
| 75 } |
| 76 |
| 77 func (r *registry) tabulate() { |
| 78 colwriter := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) |
| 79 keys := make([]string, 0, len(r.subcommands)) |
| 80 for key := range r.subcommands { |
| 81 keys = append(keys, key) |
| 82 } |
| 83 sort.Strings(keys) |
| 84 for _, key := range keys { |
| 85 fmt.Fprintf(colwriter, "\t%v\t%v\n", key, r.subcommands[key].sho
rtHelp) |
| 86 } |
| 87 colwriter.Flush() |
| 88 } |
| 89 |
| 90 var defaultRegistry = ®istry{make(map[string]*Subcommand)} |
| 91 |
| 92 // New creates, registers, and returns a new Subcommand struct. |
| 93 // Panics if you attempt to register a second command with the same name. |
| 94 func New(name string, shortHelp string, longHelp string, flagFn func(*flag.FlagS
et), runFn func(*flag.FlagSet) error) *Subcommand { |
| 95 return defaultRegistry.new(name, shortHelp, longHelp, flagFn, runFn) |
| 96 } |
| 97 |
| 98 // Get returns a Subcommand struct which has been previously registered. |
| 99 func Get(name string) *Subcommand { |
| 100 return defaultRegistry.get(name) |
| 101 } |
| 102 |
| 103 // Tabulate prints out all registered Subcommand names and their |
| 104 // short help strings. |
| 105 func Tabulate() { |
| 106 defaultRegistry.tabulate() |
| 107 } |
| OLD | NEW |