119 lines
1.9 KiB
Go
119 lines
1.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"go.fifitido.net/cmd/opt"
|
|
)
|
|
|
|
type Command struct {
|
|
Name string
|
|
version string
|
|
ShortDescription string
|
|
LongDescription string
|
|
Aliases []string
|
|
Args []*Argument
|
|
Opts opt.Set
|
|
Subcommands Set
|
|
Parent *Command
|
|
run func(args []string)
|
|
isRoot bool
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
func (c *Command) Root() *Command {
|
|
if c.isRoot {
|
|
return c
|
|
}
|
|
|
|
return c.Parent.Root()
|
|
}
|
|
|
|
func (c *Command) IsRoot() bool {
|
|
return c.isRoot
|
|
}
|
|
|
|
func (c *Command) CommandPath() string {
|
|
if c.Parent == nil {
|
|
return ""
|
|
}
|
|
|
|
parentPath := c.Parent.CommandPath()
|
|
if parentPath == "" {
|
|
return c.Name
|
|
}
|
|
|
|
return c.Parent.CommandPath() + " " + c.Name
|
|
}
|
|
|
|
func (c *Command) CanRun() bool {
|
|
return c.run != nil
|
|
}
|
|
|
|
func (c *Command) Run(args []string) {
|
|
c.run(args)
|
|
}
|
|
|
|
func (c *Command) Execute(args []string) {
|
|
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()
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
c.ShowHelp()
|
|
os.Exit(1)
|
|
}
|
|
|
|
versionOpt, ok := opt.Globals().GetBool("version")
|
|
if ok && versionOpt.Value() {
|
|
c.ShowVersion()
|
|
return
|
|
}
|
|
|
|
helpOpt, ok := opt.Globals().GetBool("help")
|
|
if ok && helpOpt.Value() {
|
|
c.ShowHelp()
|
|
return
|
|
}
|
|
|
|
if c.CanRun() {
|
|
c.Run(restArgs)
|
|
return
|
|
}
|
|
|
|
c.ShowHelp()
|
|
}
|
|
|
|
func (c *Command) ShowVersion() {
|
|
rootName := c.Root().Name
|
|
fmt.Printf("%s %s\n", rootName, c.version)
|
|
}
|