cmd/command.go

119 lines
1.9 KiB
Go
Raw Normal View History

package cmd
2023-11-10 13:17:01 -05:00
import (
"fmt"
2023-11-10 13:17:01 -05:00
"os"
2023-11-12 17:19:34 -05:00
"go.fifitido.net/cmd/opt"
2023-11-10 13:17:01 -05:00
)
type Command struct {
Name string
2023-11-16 23:01:54 -05:00
version 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)
isRoot bool
}
2023-11-16 23:01:54 -05:00
func NewRoot(name string, version string, options ...Option) *Command {
cmd := &Command{Name: name, version: version, 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-11 19:17:46 -05:00
}
2023-11-13 17:00:49 -05:00
func (c *Command) IsRoot() bool {
return c.isRoot
}
2023-11-10 13:17:01 -05:00
func (c *Command) CommandPath() string {
if c.Parent == nil {
return ""
2023-11-10 13:17:01 -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)
}
func (c *Command) Execute(args []string) {
2023-11-10 00:58:09 -05:00
if c.isRoot {
args = args[1:]
}
if len(args) > 0 {
sc, ok := c.Subcommands.Get(args[0])
if ok {
sc.Execute(args[1:])
return
}
}
parser := opt.NewParser(args, c.Opts, false)
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-16 23:01:54 -05:00
versionOpt, ok := opt.Globals().GetBool("version")
if ok && versionOpt.Value() {
c.ShowVersion()
return
}
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-10 13:17:01 -05:00
if c.CanRun() {
2023-11-11 20:49:38 -05:00
c.Run(restArgs)
return
}
2023-11-10 13:17:01 -05:00
c.ShowHelp()
}
2023-11-16 23:01:54 -05:00
func (c *Command) ShowVersion() {
rootName := c.Root().Name
fmt.Printf("%s %s\n", rootName, c.version)
}