Add command set and move help and version flags to global flags default set

This commit is contained in:
Evan Fiordeliso 2023-11-11 19:16:05 -05:00
parent 46a6f8d48e
commit 0cecbd6003
6 changed files with 75 additions and 30 deletions

View File

@ -8,13 +8,13 @@ import (
) )
type Command struct { type Command struct {
Name string name string
ShortDescription string shortDescription string
LongDescription string longDescription string
aliases []string aliases []string
arguments []*Argument arguments []*Argument
flags flags.Set flags flags.Set
subcommands []*Command subcommands Set
parent *Command parent *Command
run func(args []string) run func(args []string)
isRoot bool isRoot bool
@ -27,7 +27,7 @@ func NewRoot(options ...Option) *Command {
} }
func New(name string, options ...Option) *Command { func New(name string, options ...Option) *Command {
cmd := &Command{Name: name} cmd := &Command{name: name}
cmd.ApplyOptions(options...) cmd.ApplyOptions(options...)
return cmd return cmd
} }
@ -43,7 +43,7 @@ func (c *Command) CommandPath() string {
return filepath.Base(os.Args[0]) return filepath.Base(os.Args[0])
} }
return c.parent.CommandPath() + " " + c.Name return c.parent.CommandPath() + " " + c.name
} }
func (c *Command) CanRun() bool { func (c *Command) CanRun() bool {
@ -65,18 +65,10 @@ func (c *Command) Execute(args []string) {
} }
if len(args) > 0 { if len(args) > 0 {
for _, subcommand := range c.subcommands { sc, ok := c.subcommands.Get(args[0])
if subcommand.Name == args[0] { if ok {
subcommand.Execute(args[1:]) sc.Execute(args[1:])
return return
}
for _, alias := range subcommand.aliases {
if alias == args[0] {
subcommand.Execute(args[1:])
return
}
}
} }
// TODO: remove when done with flag parsing // TODO: remove when done with flag parsing

View File

@ -1,6 +1,9 @@
package flags package flags
var globalFlags Set var globalFlags = Set{
Bool("help", "h", false, "Show the help menu"),
Bool("version", "v", false, "Show the app version"),
}
func Global(fs ...Flag) { func Global(fs ...Flag) {
globalFlags = append(globalFlags, fs...) globalFlags = append(globalFlags, fs...)

View File

@ -6,8 +6,8 @@ func NewSet() Set {
return Set{} return Set{}
} }
func (s Set) Add(f Flag) Set { func (s *Set) Add(f Flag) {
return append(s, f) *s = append(*s, f)
} }
func (s Set) Get(name string) (Flag, bool) { func (s Set) Get(name string) (Flag, bool) {

15
help.go
View File

@ -9,7 +9,7 @@ import (
func (c *Command) ShowHelp() { func (c *Command) ShowHelp() {
cmdPath := c.CommandPath() cmdPath := c.CommandPath()
fmt.Println(c.LongDescription) fmt.Println(c.longDescription)
fmt.Println() fmt.Println()
fmt.Println("Usage: ") fmt.Println("Usage: ")
fmt.Printf(" %s ", cmdPath) fmt.Printf(" %s ", cmdPath)
@ -34,7 +34,7 @@ func (c *Command) ShowHelp() {
} }
for _, s := range c.subcommands { for _, s := range c.subcommands {
fmt.Println(" " + s.Name + " " + s.ShortDescription) fmt.Println(" " + s.name + " " + s.shortDescription)
} }
} }
@ -46,8 +46,15 @@ func (c *Command) ShowHelp() {
fmt.Println(" " + flags.HelpLine(f, paddedWidth)) fmt.Println(" " + flags.HelpLine(f, paddedWidth))
} }
fmt.Println(" -h, --help Show the help menu") globalFlags := flags.Globals()
fmt.Println(" -v, --version Show the app version") if len(globalFlags) > 0 {
paddedWidth = globalFlags.MaxWidth()
fmt.Println()
fmt.Println("Global flags:")
for _, f := range globalFlags {
fmt.Println(" " + flags.HelpLine(f, paddedWidth))
}
}
if len(c.subcommands) > 0 { if len(c.subcommands) > 0 {
fmt.Println() fmt.Println()

View File

@ -6,13 +6,13 @@ type Option func(*Command)
func WithShortDescription(s string) Option { func WithShortDescription(s string) Option {
return func(c *Command) { return func(c *Command) {
c.ShortDescription = s c.shortDescription = s
} }
} }
func WithLongDescription(s string) Option { func WithLongDescription(s string) Option {
return func(c *Command) { return func(c *Command) {
c.LongDescription = s c.longDescription = s
} }
} }
@ -42,21 +42,24 @@ func WithFlags(fs ...flags.Flag) Option {
func WithSubcommand(s *Command) Option { func WithSubcommand(s *Command) Option {
return func(c *Command) { return func(c *Command) {
c.subcommands = append(c.subcommands, s) c.subcommands.Add(c)
s.parent = c s.parent = c
} }
} }
func WithSubcommands(ss ...*Command) Option { func WithSubcommands(ss ...*Command) Option {
return func(c *Command) { return func(c *Command) {
c.subcommands = append(c.subcommands, ss...) c.subcommands.Add(c)
for _, s := range ss {
s.parent = c
}
} }
} }
func WithParent(p *Command) Option { func WithParent(p *Command) Option {
return func(c *Command) { return func(c *Command) {
c.parent = p c.parent = p
p.subcommands = append(p.subcommands, c) p.subcommands.Add(c)
} }
} }

40
set.go Normal file
View File

@ -0,0 +1,40 @@
package cmd
type Set []*Command
func NewSet() Set {
return Set{}
}
func (s *Set) Add(c *Command) {
*s = append(*s, c)
}
func (s Set) Get(name string) (*Command, bool) {
for _, c := range s {
if c.name == name {
return c, true
}
for _, alias := range c.aliases {
if alias == name {
return c, true
}
}
}
return nil, false
}
func (s Set) MaxNameWidth() int {
max := 0
for _, f := range s {
if w := len(f.name); w > max {
max = w
}
}
return max
}
func (s Set) Len() int {
return len(s)
}