Something went wrong on our end
-
Volker Schukai authoredVolker Schukai authored
api.go 2.47 KiB
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package xflags
import (
"bytes"
"flag"
"fmt"
"io"
"os"
"reflect"
)
// ExecuteWithShadow executes the command line arguments and calls the functions.
func ExecuteWithShadow[C any, D any](cmd C, cnf D) *Settings[C] {
return execute(cmd, cnf, os.Args[0], os.Args[1:])
}
type noShadow struct{}
// Execute executes the command line arguments and calls the functions.
func Execute[C any](cmd C) *Settings[C] {
return execute(cmd, noShadow{}, os.Args[0], os.Args[1:])
}
func (s *Settings[C]) PrintFlagOutput() {
fmt.Println(s.command.flagSet.Output())
}
// execute is the internal implementation of ExecuteWithShadow.
func execute[C any, D any](cmd C, cnf D, name string, args []string) *Settings[C] {
instance := New(name, cmd)
if instance.HasErrors() {
return instance
}
if (reflect.ValueOf(&cnf).Elem().Type() != reflect.TypeOf(noShadow{})) {
instance.SetShadow(cnf)
if instance.HasErrors() {
return instance
}
}
instance.Parse(args)
if instance.HelpRequested() {
for i, err := range instance.errors {
if err == flag.ErrHelp {
instance.errors = append(instance.errors[:i], instance.errors[i+1:]...)
}
}
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
}
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
}