2023-11-09 23:34:37 -05:00
|
|
|
package cmd
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2023-11-09 23:34:37 -05:00
|
|
|
|
2023-11-11 19:28:58 -05:00
|
|
|
"go.fifitido.net/cmd/opts"
|
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-11 19:16:05 -05:00
|
|
|
name string
|
|
|
|
shortDescription string
|
|
|
|
longDescription string
|
2023-11-10 13:17:01 -05:00
|
|
|
aliases []string
|
|
|
|
arguments []*Argument
|
2023-11-11 19:28:58 -05:00
|
|
|
opts opts.Set
|
2023-11-11 19:16:05 -05:00
|
|
|
subcommands Set
|
2023-11-10 13:17:01 -05:00
|
|
|
parent *Command
|
|
|
|
run func(args []string)
|
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 {
|
2023-11-11 19:16:05 -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
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.parent.Root()
|
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
func (c *Command) CommandPath() string {
|
|
|
|
if c.parent == nil {
|
|
|
|
return filepath.Base(os.Args[0])
|
|
|
|
}
|
|
|
|
|
2023-11-11 19:16:05 -05:00
|
|
|
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-11 19:28:58 -05:00
|
|
|
if err := c.opts.Parse(args); err != nil {
|
2023-11-10 14:59:37 -05:00
|
|
|
c.ShowHelp()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-11-10 00:58:09 -05:00
|
|
|
if len(args) > 0 {
|
2023-11-11 19:16:05 -05:00
|
|
|
sc, ok := c.subcommands.Get(args[0])
|
|
|
|
if ok {
|
|
|
|
sc.Execute(args[1:])
|
|
|
|
return
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|
2023-11-10 13:17:01 -05:00
|
|
|
|
2023-11-11 19:28:58 -05:00
|
|
|
// TODO: remove when done with option parsing
|
2023-11-10 13:17:01 -05:00
|
|
|
if args[0] == "--help" {
|
|
|
|
c.ShowHelp()
|
|
|
|
return
|
|
|
|
}
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
if c.CanRun() {
|
2023-11-09 23:34:37 -05:00
|
|
|
c.Run(args)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-11-10 13:17:01 -05:00
|
|
|
c.ShowHelp()
|
2023-11-09 23:34:37 -05:00
|
|
|
}
|