| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package fairwind
- import (
- "encoding/json"
- "fmt"
- "os"
- "reflect"
- "strings"
- )
- type CommandHandler func(Parameters) error
- type Parameter struct {
- Kind reflect.Kind
- Required bool
- Value reflect.Value `json:"-"`
- }
- type Parameters map[string]*Parameter
- type Command struct {
- Name string
- Documentation string
- Parameters Parameters
- Handler CommandHandler `json:"-"`
- Commands []Command
- }
- func (this *Command) Execute() {
- parts := os.Args[1:]
- if len(parts) == 0 {
- this.manual()
- return
- }
- currentCommand := this
- index := -1
- for i, part := range parts {
- if strings.Contains(part, "--") {
- index = i
- break
- }
- found := false
- for _, iteratedCommand := range currentCommand.Commands {
- if iteratedCommand.Name != part {
- continue
- }
- currentCommand = &iteratedCommand
- found = true
- break
- }
- if !found {
- fmt.Println("Command not found")
- os.Exit(1)
- }
- }
- parameters := Parameters{}
- fail := false
- if index >= 0 {
- for i := index; i < len(parts); i++ {
- part := parts[i]
- keyValue := strings.Split(part, "=")
- if len(keyValue) != 2 {
- fmt.Printf("Invalid argument: %s\n", part)
- os.Exit(1)
- }
- key := keyValue[0]
- value := keyValue[1]
- parameter, ok := currentCommand.Parameters[key]
- if !ok {
- fmt.Printf("Invalid argument: %s=%s\n", key, value)
- fail = true
- continue
- }
- switch parameter.Kind {
- case reflect.String:
- parameters[key[2:]] = &Parameter{
- Value: reflect.ValueOf(value),
- }
- }
- }
- }
- if fail {
- os.Exit(1)
- }
- for key, parameter := range currentCommand.Parameters {
- if !parameter.Required {
- continue
- }
- _, ok := parameters[key[2:]]
- if !ok {
- fmt.Printf("Argument required: %s\n", key)
- fail = true
- }
- }
- if fail {
- os.Exit(1)
- }
- if currentCommand.Handler == nil {
- fmt.Println("Handler for command not set")
- os.Exit(1)
- }
- err := currentCommand.Handler(parameters)
- if err != nil {
- fmt.Printf("Execution error: %v\n", err)
- os.Exit(1)
- }
- }
- func (this *Command) manual() {
- buffer, err := json.Marshal(this)
- if err != nil {
- fmt.Printf("Execution error: %v\n", err)
- os.Exit(1)
- }
- fmt.Println(string(buffer))
- }
|