...

Source file src/github.com/urfave/cli/v2/category.go

Documentation: github.com/urfave/cli/v2

     1  package cli
     2  
     3  import "sort"
     4  
     5  // CommandCategories interface allows for category manipulation
     6  type CommandCategories interface {
     7  	// AddCommand adds a command to a category, creating a new category if necessary.
     8  	AddCommand(category string, command *Command)
     9  	// Categories returns a slice of categories sorted by name
    10  	Categories() []CommandCategory
    11  }
    12  
    13  type commandCategories []*commandCategory
    14  
    15  func newCommandCategories() CommandCategories {
    16  	ret := commandCategories([]*commandCategory{})
    17  	return &ret
    18  }
    19  
    20  func (c *commandCategories) Less(i, j int) bool {
    21  	return lexicographicLess((*c)[i].Name(), (*c)[j].Name())
    22  }
    23  
    24  func (c *commandCategories) Len() int {
    25  	return len(*c)
    26  }
    27  
    28  func (c *commandCategories) Swap(i, j int) {
    29  	(*c)[i], (*c)[j] = (*c)[j], (*c)[i]
    30  }
    31  
    32  func (c *commandCategories) AddCommand(category string, command *Command) {
    33  	for _, commandCategory := range []*commandCategory(*c) {
    34  		if commandCategory.name == category {
    35  			commandCategory.commands = append(commandCategory.commands, command)
    36  			return
    37  		}
    38  	}
    39  	newVal := append(*c,
    40  		&commandCategory{name: category, commands: []*Command{command}})
    41  	*c = newVal
    42  }
    43  
    44  func (c *commandCategories) Categories() []CommandCategory {
    45  	ret := make([]CommandCategory, len(*c))
    46  	for i, cat := range *c {
    47  		ret[i] = cat
    48  	}
    49  	return ret
    50  }
    51  
    52  // CommandCategory is a category containing commands.
    53  type CommandCategory interface {
    54  	// Name returns the category name string
    55  	Name() string
    56  	// VisibleCommands returns a slice of the Commands with Hidden=false
    57  	VisibleCommands() []*Command
    58  }
    59  
    60  type commandCategory struct {
    61  	name     string
    62  	commands []*Command
    63  }
    64  
    65  func (c *commandCategory) Name() string {
    66  	return c.name
    67  }
    68  
    69  func (c *commandCategory) VisibleCommands() []*Command {
    70  	if c.commands == nil {
    71  		c.commands = []*Command{}
    72  	}
    73  
    74  	var ret []*Command
    75  	for _, command := range c.commands {
    76  		if !command.Hidden {
    77  			ret = append(ret, command)
    78  		}
    79  	}
    80  	return ret
    81  }
    82  
    83  // FlagCategories interface allows for category manipulation
    84  type FlagCategories interface {
    85  	// AddFlags adds a flag to a category, creating a new category if necessary.
    86  	AddFlag(category string, fl Flag)
    87  	// VisibleCategories returns a slice of visible flag categories sorted by name
    88  	VisibleCategories() []VisibleFlagCategory
    89  }
    90  
    91  type defaultFlagCategories struct {
    92  	m map[string]*defaultVisibleFlagCategory
    93  }
    94  
    95  func newFlagCategories() FlagCategories {
    96  	return &defaultFlagCategories{
    97  		m: map[string]*defaultVisibleFlagCategory{},
    98  	}
    99  }
   100  
   101  func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
   102  	fc := newFlagCategories()
   103  
   104  	var categorized bool
   105  	for _, fl := range fs {
   106  		if cf, ok := fl.(CategorizableFlag); ok {
   107  			if cat := cf.GetCategory(); cat != "" {
   108  				fc.AddFlag(cat, cf)
   109  				categorized = true
   110  			}
   111  		}
   112  	}
   113  
   114  	if categorized {
   115  		for _, fl := range fs {
   116  			if cf, ok := fl.(CategorizableFlag); ok {
   117  				if cf.GetCategory() == "" {
   118  					fc.AddFlag("", fl)
   119  				}
   120  			}
   121  		}
   122  	}
   123  
   124  	return fc
   125  }
   126  
   127  func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
   128  	if _, ok := f.m[category]; !ok {
   129  		f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
   130  	}
   131  
   132  	f.m[category].m[fl.String()] = fl
   133  }
   134  
   135  func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
   136  	catNames := []string{}
   137  	for name := range f.m {
   138  		catNames = append(catNames, name)
   139  	}
   140  
   141  	sort.Strings(catNames)
   142  
   143  	ret := make([]VisibleFlagCategory, len(catNames))
   144  	for i, name := range catNames {
   145  		ret[i] = f.m[name]
   146  	}
   147  
   148  	return ret
   149  }
   150  
   151  // VisibleFlagCategory is a category containing flags.
   152  type VisibleFlagCategory interface {
   153  	// Name returns the category name string
   154  	Name() string
   155  	// Flags returns a slice of VisibleFlag sorted by name
   156  	Flags() []VisibleFlag
   157  }
   158  
   159  type defaultVisibleFlagCategory struct {
   160  	name string
   161  	m    map[string]Flag
   162  }
   163  
   164  func (fc *defaultVisibleFlagCategory) Name() string {
   165  	return fc.name
   166  }
   167  
   168  func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
   169  	vfNames := []string{}
   170  	for flName, fl := range fc.m {
   171  		if vf, ok := fl.(VisibleFlag); ok {
   172  			if vf.IsVisible() {
   173  				vfNames = append(vfNames, flName)
   174  			}
   175  		}
   176  	}
   177  
   178  	sort.Strings(vfNames)
   179  
   180  	ret := make([]VisibleFlag, len(vfNames))
   181  	for i, flName := range vfNames {
   182  		ret[i] = fc.m[flName].(VisibleFlag)
   183  	}
   184  
   185  	return ret
   186  }
   187  

View as plain text