AFAIRE
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
1.7 KiB

/*
------------------------------------------------------------------------------------------------------------------------
####### cmdline ####### Copyright (c) 2021 losyme ################################################## MIT License #######
------------------------------------------------------------------------------------------------------------------------
*/
package cmdline
import (
"fmt"
"os"
"strings"
"forge.chapril.org/losyme/errors"
)
type Cmd struct {
flagSet
name string
usage string
run func() error
cmds map[string]*Cmd
}
type CmdOption func(c *Cmd)
func WithRunFn(run func() error) CmdOption {
return func(c *Cmd) {
c.run = run
}
}
func NewCmd(name, usage string, options ...CmdOption) *Cmd {
c := &Cmd{
name: name,
usage: usage,
}
for _, opt := range options {
opt(c)
}
return c
}
func (c *Cmd) printUsage(offset int) {
fmt.Fprintf(os.Stderr, "%s%s - %s\n", strings.Repeat("\t", offset), c.name, c.usage)
c.flagSet.printUsage(offset)
printUsage(c.cmds, offset+1)
}
func (c *Cmd) AddSubCmd(cmd *Cmd) {
if cmd == nil {
return
}
if c.cmds == nil {
c.cmds = make(map[string]*Cmd)
}
c.cmds[cmd.name] = cmd
}
func (c *Cmd) execute(name string, args []string) error {
if len(args) != 0 {
arg := args[0]
if !strings.HasPrefix(arg, "-") {
name += "." + arg
cmd, ok := c.cmds[arg]
if !ok {
return errors.New("command provided but not defined", "cmd", name) /////////////////////////////////////
}
return cmd.execute(name, args[1:])
}
}
if err := c.flags().Parse(args); err != nil {
return err
}
if c.run == nil {
return nil
}
return c.run()
}
/*
######################################################################################################## @(°_°)@ #######
*/