// Copyright 2022 schukai GmbH // SPDX-License-Identifier: AGPL-3.0 package xflags import ( "bytes" "flag" "fmt" "io" "os" "reflect" ) type dummyCopyArg struct{} func (n dummyCopyArg) Copy(_ map[string]any) {} // Execute executes the command line arguments and calls the functions. func Execute[C any](cmd C, cpy ...Copyable) *Settings[C] { if cpy == nil { return execute(cmd, dummyCopyArg{}, os.Args[0], os.Args[1:]) } if len(cpy) > 1 { panic("too many arguments") } return execute(cmd, cpy[0], os.Args[0], os.Args[1:]) } // PrintFlagOutput prints the flag output to the standard output. func (s *Settings[C]) PrintFlagOutput() { fmt.Println(s.command.flagSet.Output()) } // GetFlagOutput returns the flag output. func (s *Settings[C]) GetFlagOutput() { fmt.Println(s.command.flagSet.Output()) } // execute is the internal implementation of Execute. func execute[C any, D Copyable](cmd C, proxy D, name string, args []string) *Settings[C] { instance := New(name, cmd) if instance.HasErrors() { return instance } if (reflect.ValueOf(&proxy).Elem().Type() != reflect.TypeOf(dummyCopyArg{})) { instance.SetMappedObject(proxy) if instance.HasErrors() { return instance } } instance.Parse(args) if instance.HelpRequested() { return instance } if instance.HasErrors() { return instance } instance.Execute() if instance.HasErrors() { return instance } return instance } // New creates a new instance of the settings. // name should be the name of the command and comes from the first argument of the command line. // os.Args[0] is a good choice. func New[C any](name string, definitions C) *Settings[C] { s := &Settings[C]{ config: config{ errorHandling: flag.ContinueOnError, }, } if reflect.TypeOf(definitions).Kind() != reflect.Struct { s.errors = append(s.errors, newUnsupportedReflectKindError(reflect.TypeOf(definitions))) return s } s.mapping = make(map[string]any) buf := bytes.NewBufferString("") s.flagOutput = io.Writer(buf) s.definitions = definitions s.initCommands(name) return s } // Output returns the writer where the flag package writes its output. func (s *Settings[C]) Output() string { return s.flagOutput.(*bytes.Buffer).String() } // Args Returns not parsed arguments. func (s *Settings[C]) Args() []string { return s.args } // GetDefaults returns the default values of the settings. func (s *Settings[C]) GetDefaults() string { mem := s.flagOutput s.flagOutput.(*bytes.Buffer).Reset() s.command.flagSet.PrintDefaults() r := s.flagOutput.(*bytes.Buffer).String() s.flagOutput = mem return r } func (s *Settings[C]) GetMap() map[string]any { return s.mapping }