diff --git a/api.go b/api.go index 7ef0727cf2e842a0ef6624f08a5bccf6fd359672..bec82e07f40cbd3c5087ab292807955de14db55d 100644 --- a/api.go +++ b/api.go @@ -6,10 +6,52 @@ package xflags import ( "bytes" "flag" + "fmt" "io" + "os" "reflect" ) +// Execute executes the command line arguments and calls the functions. +func Execute[C any, D any](cmd C, cnf D) *Settings[C] { + return execute(cmd, cnf, os.Args[0], os.Args[1:]) +} + +func (s *Settings[C]) PrintFlagOutput() { + fmt.Println(s.command.flagSet.Output()) +} + +// execute is the internal implementation of Execute. +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 + } + + 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:]...) + } + } + instance.PrintFlagOutput() + return instance + } + + if instance.HasErrors() { + return instance + } + + instance.Execute() + 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. diff --git a/api_test.go b/api_test.go index c235b036700d3635af79c81004e1b0b6fb14b494..6b841c83ea7af51701b85ad57bf27e7b591edf1c 100644 --- a/api_test.go +++ b/api_test.go @@ -8,22 +8,31 @@ import ( "testing" ) -//func TestUsage(t *testing.T) { -// -// commands := New("root", CmdTest1{}) -// args := []string{"-h"} -// -// commands.Parse(args) -// -// assert.False(t, commands.HasErrors()) -// if commands.HasErrors() { -// t.Log(commands.Errors()) -// } -// -// usage := commands.Usage() -// assert.NotEmpty(t, usage) -// -//} +func TestUsage(t *testing.T) { + + commands := New("root", CmdTest1{}) + args := []string{"-h"} + + commands.Parse(args) + + assert.True(t, commands.HelpRequested()) + + usage := commands.GetDefaults() + assert.Equal(t, " -a\tMessage A\n -x int\n \tMessage X\n", usage) + +} +func TestExecute(t *testing.T) { + instance := execute("root", CmdTest1{}, "test", []string{"-a", "hello", "-x", "1"}) + assert.NotNil(t, instance) +} + +func TestExecuteHelp(t *testing.T) { + cnf := struct { + }{} + instance := execute(CmdTest1{}, &cnf, "test", []string{"-h"}) + assert.False(t, instance.HasErrors()) + +} func TestNewIntWithError(t *testing.T) { @@ -47,17 +56,17 @@ func TestNew(t *testing.T) { } type CmdTest1 struct { - A bool `short:"a"` + A bool `short:"a" description:"Message A"` Sub1 struct { - B bool `short:"b"` + B bool `short:"b" description:"Message B"` Sub2 struct { - C bool `short:"c"` + C bool `short:"c" description:"Message C"` Sub3 struct { - D bool `short:"d"` + D bool `short:"d" description:"Message D"` } `command:"sub3"` } `command:"sub2"` } `command:"sub1"` - aa int `short:"x"` + aa int `short:"x" description:"Message X"` } func TestCommand2(t *testing.T) { diff --git a/parse.go b/parse.go index 5d10b058602a102721e5ea63ec4185a0db7dc163..9a5b7206f02b5aab32180c839894161d1d0715db 100644 --- a/parse.go +++ b/parse.go @@ -3,7 +3,10 @@ package xflags -import "os" +import ( + "flag" + "os" +) // ParseOsArgs parses the os.Args. func (s *Settings[C]) ParseOsArgs() *Settings[C] { @@ -38,3 +41,14 @@ func (s *Settings[C]) Parse(args []string) *Settings[C] { return s } + +func (s *Settings[C]) HelpRequested() bool { + + for _, err := range s.errors { + if err == flag.ErrHelp { + return true + } + } + + return false +}