// Copyright 2022 schukai GmbH // SPDX-License-Identifier: AGPL-3.0 package xflags import ( "flag" "fmt" "reflect" "strings" ) func (s *Settings[C]) Execute() *Settings[C] { s.mu.Lock() defer s.mu.Unlock() if len(s.errors) > 0 { return s } if s.command == nil { s.errors = append(s.errors, MissingCommandError) return s } if !s.command.flagSet.Parsed() { s.errors = append(s.errors, NotParsedError) } else { s.wasExecuted = callCmdFunctions(s, s.command.commands) } return s } func callCmdFunctions[C any](settings *Settings[C], commands []*cmd[C]) bool { wasExecuted := false shouldExecute := false var availableCommands []string currentCommand := "" for _, command := range commands { if command.flagSet.Parsed() { shouldExecute = true currentCommand = command.name if len(command.commands) > 0 { r := callCmdFunctions(settings, command.commands) if r { wasExecuted = true } } if !wasExecuted { f := reflect.ValueOf(&command.settings.definitions).MethodByName(command.functionName) if f.IsValid() { m := command.settings in := []reflect.Value{reflect.ValueOf(m)} f.Call(in) wasExecuted = true } } break } else { availableCommands = append(availableCommands, command.name) } } if shouldExecute { if !wasExecuted { settings.errors = append(settings.errors, newMissingFunctionError(currentCommand)) return false } return true } if len(availableCommands) > 0 { if settings.hint == "" { settings.hint = fmt.Sprintf("Did you mean: %v?", strings.Join(availableCommands, ", ")) } settings.errors = append(settings.errors, MissingCommandError) } return false } // HelpRequested indicates if the help flag was set. func (s *Settings[C]) HelpRequested() bool { s.mu.Lock() defer s.mu.Unlock() for _, err := range s.errors { if err == flag.ErrHelp { return true } } return false } // MissingCommand returns true if the command was not found func (s *Settings[C]) MissingCommand() bool { s.mu.Lock() defer s.mu.Unlock() for _, err := range s.errors { if err == MissingCommandError { return true } } return false } // WasExecuted returns true if the call function was executed func (s *Settings[C]) WasExecuted() bool { s.mu.Lock() defer s.mu.Unlock() return s.wasExecuted }