| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package flags
- import (
- "reflect"
- "sort"
- "strings"
- "unsafe"
- )
- type lookup struct {
- shortNames map[string]*Option
- longNames map[string]*Option
- required map[*Option]bool
- commands map[string]*Command
- }
- func newCommand(name string, shortDescription string, longDescription string, data interface{}) *Command {
- return &Command{
- Group: newGroup(shortDescription, longDescription, data),
- Name: name,
- }
- }
- func (c *Command) scanSubCommandHandler(parentg *Group) scanHandler {
- f := func(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
- mtag := newMultiTag(string(sfield.Tag))
- if err := mtag.Parse(); err != nil {
- return true, err
- }
- subcommand := mtag.Get("command")
- if len(subcommand) != 0 {
- ptrval := reflect.NewAt(realval.Type(), unsafe.Pointer(realval.UnsafeAddr()))
- shortDescription := mtag.Get("description")
- longDescription := mtag.Get("long-description")
- if _, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface()); err != nil {
- return true, err
- }
- return true, nil
- }
- return parentg.scanSubGroupHandler(realval, sfield)
- }
- return f
- }
- func (c *Command) scan() error {
- return c.scanType(c.scanSubCommandHandler(c.Group))
- }
- func (c *Command) eachCommand(f func(*Command), recurse bool) {
- f(c)
- for _, cc := range c.commands {
- if recurse {
- cc.eachCommand(f, true)
- } else {
- f(cc)
- }
- }
- }
- func (c *Command) eachActiveGroup(f func(g *Group)) {
- c.eachGroup(f)
- if c.Active != nil {
- c.Active.eachActiveGroup(f)
- }
- }
- func (c *Command) addHelpGroups(showHelp func() error) {
- if !c.hasBuiltinHelpGroup {
- c.addHelpGroup(showHelp)
- c.hasBuiltinHelpGroup = true
- }
- for _, cc := range c.commands {
- cc.addHelpGroups(showHelp)
- }
- }
- func (c *Command) makeLookup() lookup {
- ret := lookup{
- shortNames: make(map[string]*Option),
- longNames: make(map[string]*Option),
- required: make(map[*Option]bool),
- commands: make(map[string]*Command),
- }
- c.eachGroup(func(g *Group) {
- for _, option := range g.options {
- if option.Required && option.canCli() {
- ret.required[option] = true
- }
- if option.ShortName != 0 {
- ret.shortNames[string(option.ShortName)] = option
- }
- if len(option.LongName) > 0 {
- ret.longNames[option.LongName] = option
- }
- }
- })
- for _, subcommand := range c.commands {
- ret.commands[subcommand.Name] = subcommand
- }
- return ret
- }
- func (c *Command) groupByName(name string) *Group {
- if grp := c.Group.groupByName(name); grp != nil {
- return grp
- }
- for _, subc := range c.commands {
- prefix := subc.Name + "."
- if strings.HasPrefix(name, prefix) {
- if grp := subc.groupByName(name[len(prefix):]); grp != nil {
- return grp
- }
- } else if name == subc.Name {
- return subc.Group
- }
- }
- return nil
- }
- type commandList []*Command
- func (c commandList) Less(i, j int) bool {
- return c[i].Name < c[j].Name
- }
- func (c commandList) Len() int {
- return len(c)
- }
- func (c commandList) Swap(i, j int) {
- c[i], c[j] = c[j], c[i]
- }
- func (c *Command) sortedCommands() []*Command {
- ret := make(commandList, len(c.commands))
- copy(ret, c.commands)
- sort.Sort(ret)
- return []*Command(ret)
- }
|