2023-11-09 23:34:37 -05:00
|
|
|
package cmd
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
import (
|
2023-11-11 21:18:18 -05:00
|
|
|
"fmt"
|
2023-11-10 13:17:01 -05:00
|
|
|
"os"
|
2023-11-09 23:34:37 -05:00
|
|
|
|
2023-11-12 17:19:34 -05:00
|
|
|
"go.fifitido.net/cmd/opt"
|
2023-11-10 13:17:01 -05:00
|
|
|
)
|
2023-11-10 00:49:44 -05:00
|
|
|
|
2023-11-09 23:34:37 -05:00
|
|
|
type Command struct {
|
2023-11-12 23:54:52 -05:00
|
|
|
Name string
|
|
|
|
ShortDescription string
|
|
|
|
LongDescription string
|
|
|
|
Aliases []string
|
|
|
|
Args []*Argument
|
|
|
|
Opts opt.Set
|
|
|
|
Subcommands Set
|
|
|
|
Parent *Command
|
2023-11-10 13:17:01 -05:00
|
|
|
run func(args []string)
|
2023-11-09 23:34:37 -05:00
|
|
|
isRoot bool
|
|
|
|
}
|
|
|
|
|
2023-11-12 23:54:52 -05:00
|
|
|
func NewRoot(name string, options ...Option) *Command {
|
|
|
|
cmd := &Command{Name: name, isRoot: true}
|
2023-11-09 23:34:37 -05:00
|
|
|
cmd.ApplyOptions(options...)
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(name string, options ...Option) *Command {
|
2023-11-12 23:54:52 -05:00
|
|
|
cmd := &Command{Name: name}
|
2023-11-09 23:34:37 -05:00
|
|
|
cmd.ApplyOptions(options...)
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) ApplyOptions(options ...Option) {
|
|
|
|
for _, option := range options {
|
|
|
|
option(c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-11 19:17:46 -05:00
|
|
|
func (c *Command) Root() *Command {
|
|
|
|
if c.isRoot {
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-11-12 23:54:52 -05:00
|
|
|
return c.Parent.Root()
|
2023-11-11 19:17:46 -05:00
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
func (c *Command) CommandPath() string {
|
2023-11-12 23:54:52 -05:00
|
|
|
if c.Parent == nil {
|
|
|
|
return ""
|
2023-11-10 13:17:01 -05:00
|
|
|
}
|
|
|
|
|
2023-11-12 23:54:52 -05:00
|
|
|
parentPath := c.Parent.CommandPath()
|
|
|
|
if parentPath == "" {
|
|
|
|
return c.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.Parent.CommandPath() + " " + c.Name
|
2023-11-10 13:17:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) CanRun() bool {
|
|
|
|
return c.run != nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) Run(args []string) {
|
|
|
|
c.run(args)
|
|
|
|
}
|
|
|
|
|
2023-11-09 23:34:37 -05:00
|
|
|
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-13 13:20:43 -05:00
|
|
|
if len(args) > 0 {
|
|
|
|
sc, ok := c.Subcommands.Get(args[0])
|
|
|
|
if ok {
|
|
|
|
sc.Execute(args[1:])
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2023-11-09 23:34:37 -05:00
|
|
|
|
2023-11-12 23:54:52 -05:00
|
|
|
parser := opt.NewParser(args, c.Opts, false)
|
2023-11-11 21:18:18 -05:00
|
|
|
restArgs, err := parser.Parse()
|
2023-11-11 20:49:38 -05:00
|
|
|
if err != nil {
|
2023-11-11 21:29:56 -05:00
|
|
|
fmt.Println(err.Error())
|
2023-11-11 20:49:38 -05:00
|
|
|
c.ShowHelp()
|
2023-11-11 21:29:56 -05:00
|
|
|
os.Exit(1)
|
2023-11-11 20:49:38 -05:00
|
|
|
}
|
|
|
|
|
2023-11-12 17:19:34 -05:00
|
|
|
helpOpt, ok := opt.Globals().GetBool("help")
|
2023-11-11 20:49:38 -05:00
|
|
|
if ok && helpOpt.Value() {
|
|
|
|
c.ShowHelp()
|
|
|
|
return
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
if c.CanRun() {
|
2023-11-11 20:49:38 -05:00
|
|
|
c.Run(restArgs)
|
2023-11-09 23:34:37 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
c.ShowHelp()
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|