cmd/command.go

96 lines
1.5 KiB
Go
Raw Normal View History

package cmd
2023-11-10 13:17:01 -05:00
import (
"os"
"path/filepath"
2023-11-11 19:28:58 -05:00
"go.fifitido.net/cmd/opts"
2023-11-10 13:17:01 -05:00
)
type Command struct {
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
subcommands Set
2023-11-10 13:17:01 -05:00
parent *Command
run func(args []string)
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)
}
}
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])
}
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)
}
func (c *Command) Execute(args []string) {
2023-11-10 00:58:09 -05:00
if c.isRoot {
args = args[1:]
}
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 {
sc, ok := c.subcommands.Get(args[0])
if ok {
sc.Execute(args[1:])
return
}
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-10 13:17:01 -05:00
if c.CanRun() {
c.Run(args)
return
}
2023-11-10 13:17:01 -05:00
c.ShowHelp()
}