|
|
|
@ -1,10 +1,12 @@
|
|
|
|
|
package cli
|
|
|
|
|
|
|
|
|
|
import "sort"
|
|
|
|
|
|
|
|
|
|
// CommandCategories interface allows for category manipulation
|
|
|
|
|
type CommandCategories interface {
|
|
|
|
|
// AddCommand adds a command to a category, creating a new category if necessary.
|
|
|
|
|
AddCommand(category string, command *Command)
|
|
|
|
|
// categories returns a copy of the category slice
|
|
|
|
|
// Categories returns a slice of categories sorted by name
|
|
|
|
|
Categories() []CommandCategory
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -78,47 +80,81 @@ func (c *commandCategory) VisibleCommands() []*Command {
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FlagCategories is a slice of *FlagCategory.
|
|
|
|
|
type FlagCategories []*FlagCategory
|
|
|
|
|
|
|
|
|
|
// FlagCategory is a category containing flags.
|
|
|
|
|
type FlagCategory struct {
|
|
|
|
|
Name string
|
|
|
|
|
Flags []Flag
|
|
|
|
|
// FlagCategories interface allows for category manipulation
|
|
|
|
|
type FlagCategories interface {
|
|
|
|
|
// AddFlags adds a flag to a category, creating a new category if necessary.
|
|
|
|
|
AddFlag(category string, fl Flag)
|
|
|
|
|
// VisibleCategories returns a slice of visible flag categories sorted by name
|
|
|
|
|
VisibleCategories() []VisibleFlagCategory
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f FlagCategories) Less(i, j int) bool {
|
|
|
|
|
return lexicographicLess(f[i].Name, f[j].Name)
|
|
|
|
|
type defaultFlagCategories struct {
|
|
|
|
|
m map[string]*defaultVisibleFlagCategory
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f FlagCategories) Len() int {
|
|
|
|
|
return len(f)
|
|
|
|
|
func newFlagCategories() FlagCategories {
|
|
|
|
|
return &defaultFlagCategories{
|
|
|
|
|
m: map[string]*defaultVisibleFlagCategory{},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f FlagCategories) Swap(i, j int) {
|
|
|
|
|
f[i], f[j] = f[j], f[i]
|
|
|
|
|
func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
|
|
|
|
|
if _, ok := f.m[category]; !ok {
|
|
|
|
|
f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f.m[category].m[fl.String()] = fl
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddFlags adds a command to a category.
|
|
|
|
|
func (f FlagCategories) AddFlag(category string, flag Flag) FlagCategories {
|
|
|
|
|
for _, flagCategory := range f {
|
|
|
|
|
if flagCategory.Name == category {
|
|
|
|
|
flagCategory.Flags = append(flagCategory.Flags, flag)
|
|
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
|
|
|
|
|
catNames := []string{}
|
|
|
|
|
for name := range f.m {
|
|
|
|
|
catNames = append(catNames, name)
|
|
|
|
|
}
|
|
|
|
|
return append(f, &FlagCategory{Name: category, Flags: []Flag{flag}})
|
|
|
|
|
|
|
|
|
|
sort.Strings(catNames)
|
|
|
|
|
|
|
|
|
|
ret := make([]VisibleFlagCategory, len(catNames))
|
|
|
|
|
for i, name := range catNames {
|
|
|
|
|
ret[i] = f.m[name]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// VisibleFlags returns a slice of the Flags with Hidden=false
|
|
|
|
|
func (c *FlagCategory) VisibleFlags() []VisibleFlag {
|
|
|
|
|
ret := []VisibleFlag{}
|
|
|
|
|
for _, fl := range c.Flags {
|
|
|
|
|
// VisibleFlagCategory is a category containing flags.
|
|
|
|
|
type VisibleFlagCategory interface {
|
|
|
|
|
// Name returns the category name string
|
|
|
|
|
Name() string
|
|
|
|
|
// Flags returns a slice of VisibleFlag sorted by name
|
|
|
|
|
Flags() []VisibleFlag
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type defaultVisibleFlagCategory struct {
|
|
|
|
|
name string
|
|
|
|
|
m map[string]Flag
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (fc *defaultVisibleFlagCategory) Name() string {
|
|
|
|
|
return fc.name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
|
|
|
|
|
vfNames := []string{}
|
|
|
|
|
for flName, fl := range fc.m {
|
|
|
|
|
if vf, ok := fl.(VisibleFlag); ok {
|
|
|
|
|
if vf.IsVisible() {
|
|
|
|
|
ret = append(ret, vf)
|
|
|
|
|
vfNames = append(vfNames, flName)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sort.Strings(vfNames)
|
|
|
|
|
|
|
|
|
|
ret := make([]VisibleFlag, len(vfNames))
|
|
|
|
|
for i, flName := range vfNames {
|
|
|
|
|
ret[i] = fc.m[flName].(VisibleFlag)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|