planner/plan/command/command.go

84 lines
1.4 KiB
Go
Raw Normal View History

2024-10-29 07:22:28 +01:00
package command
2024-10-31 07:26:03 +01:00
import (
2024-11-04 09:49:41 +01:00
"errors"
"fmt"
2024-11-05 07:21:43 +01:00
"strings"
2024-10-31 07:26:03 +01:00
)
2024-10-30 07:25:05 +01:00
2024-11-04 09:49:41 +01:00
var (
2024-11-06 07:29:29 +01:00
ErrWrongCommand = errors.New("wrong command")
ErrInvalidArg = errors.New("invalid argument")
2024-10-30 07:25:05 +01:00
)
2024-11-06 07:29:29 +01:00
type ArgSet struct {
Main string
Flags map[string]string
}
func (as *ArgSet) HasFlag(name string) bool {
_, ok := as.Flags[name]
return ok
}
func (as *ArgSet) Flag(name string) string {
return as.Flags[name]
}
func (as *ArgSet) SetFlag(name, value string) {
as.Flags[name] = value
}
2024-11-04 09:49:41 +01:00
type Command interface {
2024-11-06 07:29:29 +01:00
Parse(args []string) (*ArgSet, error)
Do(args *ArgSet) error
2024-10-29 07:22:28 +01:00
}
type CLI struct {
2024-11-04 09:49:41 +01:00
Commands []Command
2024-10-30 07:25:05 +01:00
}
2024-11-04 09:49:41 +01:00
func (cli *CLI) Run(args []string) error {
for _, c := range cli.Commands {
2024-11-06 07:29:29 +01:00
as, err := c.Parse(args)
switch {
case errors.Is(err, ErrWrongCommand):
continue
case err != nil:
2024-11-04 09:49:41 +01:00
return err
2024-11-06 07:29:29 +01:00
default:
return c.Do(as)
2024-10-31 07:26:03 +01:00
}
}
2024-11-05 07:21:43 +01:00
return fmt.Errorf("could not find matching command")
}
2024-11-06 07:29:29 +01:00
func ParseArgs(args []string) (*ArgSet, error) {
2024-11-05 07:21:43 +01:00
flags := make(map[string]string)
2024-11-06 07:29:29 +01:00
main := make([]string, 0)
var inMain bool
2024-11-05 07:21:43 +01:00
for i := 0; i < len(args); i++ {
if strings.HasPrefix(args[i], "-") {
2024-11-06 07:29:29 +01:00
inMain = false
2024-11-05 07:21:43 +01:00
if i+1 >= len(args) {
2024-11-06 07:29:29 +01:00
return &ArgSet{}, fmt.Errorf("flag wihout value")
2024-11-05 07:21:43 +01:00
}
flags[strings.TrimPrefix(args[i], "-")] = args[i+1]
i++
continue
}
2024-11-06 07:29:29 +01:00
if !inMain && len(main) > 0 {
return &ArgSet{}, fmt.Errorf("two mains")
2024-11-05 07:21:43 +01:00
}
2024-11-06 07:29:29 +01:00
inMain = true
main = append(main, args[i])
2024-11-05 07:21:43 +01:00
}
2024-11-06 07:29:29 +01:00
return &ArgSet{
Main: strings.Join(main, " "),
Flags: flags,
}, nil
2024-10-30 07:25:05 +01:00
}