2023-11-09 23:34:37 -05:00
|
|
|
package cmd
|
|
|
|
|
|
|
|
import "go.fifitido.net/cmd/flags"
|
|
|
|
|
2023-11-10 00:49:44 -05:00
|
|
|
type RunFunc func(args []string)
|
|
|
|
type RunErrFunc func(args []string) error
|
|
|
|
|
2023-11-09 23:34:37 -05:00
|
|
|
type Command struct {
|
|
|
|
Name string
|
|
|
|
ShortDescription string
|
|
|
|
LongDescription string
|
|
|
|
Aliases []string
|
|
|
|
Arguments []*Argument
|
|
|
|
Flags []flags.Flag
|
|
|
|
Subcommands []*Command
|
2023-11-10 00:49:44 -05:00
|
|
|
Run RunFunc
|
|
|
|
RunE RunErrFunc
|
2023-11-09 23:34:37 -05:00
|
|
|
isRoot bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRoot(options ...Option) *Command {
|
|
|
|
cmd := &Command{isRoot: true}
|
|
|
|
cmd.ApplyOptions(options...)
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(name string, options ...Option) *Command {
|
|
|
|
cmd := &Command{Name: name}
|
|
|
|
cmd.ApplyOptions(options...)
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) ApplyOptions(options ...Option) {
|
|
|
|
for _, option := range options {
|
|
|
|
option(c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) Execute(args []string) {
|
2023-11-10 00:58:09 -05:00
|
|
|
if c.isRoot {
|
|
|
|
args = args[1:]
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|
|
|
|
|
2023-11-10 00:58:09 -05:00
|
|
|
if len(args) > 0 {
|
|
|
|
for _, subcommand := range c.Subcommands {
|
|
|
|
if subcommand.Name == args[0] {
|
2023-11-09 23:34:37 -05:00
|
|
|
subcommand.Execute(args[1:])
|
|
|
|
return
|
|
|
|
}
|
2023-11-10 00:58:09 -05:00
|
|
|
|
|
|
|
for _, alias := range subcommand.Aliases {
|
|
|
|
if alias == args[0] {
|
|
|
|
subcommand.Execute(args[1:])
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Run != nil {
|
|
|
|
c.Run(args)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.RunE != nil {
|
|
|
|
if err := c.RunE(args); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|