From a87d80089a78b707d9e4fbd7061e54e7e834688d Mon Sep 17 00:00:00 2001 From: Sebastiaan Pasterkamp <26205277+SebastiaanPasterkamp@users.noreply.github.com> Date: Sun, 2 Jan 2022 15:06:37 +0100 Subject: [PATCH 1/2] Add 'IgnoreDefault' option --- README.md | 22 ++++++++++++++++++++-- parse.go | 10 ++++++++-- parse_test.go | 13 +++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dab2996..7f1fdca 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,10 @@ arg.MustParse(&args) ```shell $ ./example -h -Usage: [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] [--help] INPUT [OUTPUT [OUTPUT ...]] +Usage: [--verbose] [--dataset DATASET] [--optimize OPTIMIZE] [--help] INPUT [OUTPUT [OUTPUT ...]] Positional arguments: - INPUT + INPUT OUTPUT Options: @@ -180,6 +180,24 @@ var args struct { arg.MustParse(&args) ``` +#### Ignoring environment variables and/or default values + +The values in an existing structure can be kept in-tact by ignoring environment +variables and/or default values. + +```go +var args struct { + Test string `arg:"-t,env:TEST" default:"something"` +} + +p, err := arg.NewParser(arg.Config{ + IgnoreEnv: true, + IgnoreDefault: true, +}, &args) + +err = p.Parse(os.Args) +``` + ### Arguments with multiple values ```go var args struct { diff --git a/parse.go b/parse.go index 7588dfb..9f93502 100644 --- a/parse.go +++ b/parse.go @@ -121,6 +121,10 @@ type Config struct { // IgnoreEnv instructs the library not to read environment variables IgnoreEnv bool + + // IgnoreDefault instructs the library not to reset the variables to the + // default values, including pointers to sub commands + IgnoreDefault bool } // Parser represents a set of command line options with destination values @@ -527,7 +531,9 @@ func (p *Parser) process(args []string) error { // instantiate the field to point to a new struct v := p.val(subcmd.dest) - v.Set(reflect.New(v.Type().Elem())) // we already checked that all subcommands are struct pointers + if !p.config.IgnoreDefault || v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) // we already checked that all subcommands are struct pointers + } // add the new options to the set of allowed options specs = append(specs, subcmd.specs...) @@ -659,7 +665,7 @@ func (p *Parser) process(args []string) error { } return errors.New(msg) } - if spec.defaultVal != "" { + if !p.config.IgnoreDefault && spec.defaultVal != "" { err := scalar.ParseValue(p.val(spec.dest), spec.defaultVal) if err != nil { return fmt.Errorf("error processing default value for %s: %v", name, err) diff --git a/parse_test.go b/parse_test.go index 2d0ef7a..aebe5ff 100644 --- a/parse_test.go +++ b/parse_test.go @@ -816,6 +816,19 @@ func TestEnvironmentVariableIgnored(t *testing.T) { assert.Equal(t, "", args.Foo) } +func TestDefaultValuesIgnored(t *testing.T) { + var args struct { + Foo string `default:"bad"` + } + + p, err := NewParser(Config{IgnoreDefault: true}, &args) + require.NoError(t, err) + + err = p.Parse(nil) + assert.NoError(t, err) + assert.Equal(t, "", args.Foo) +} + func TestEnvironmentVariableInSubcommandIgnored(t *testing.T) { var args struct { Sub *struct { From b48371a62f7beed42eadc9b719ea4f059aa24ef2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Pasterkamp <26205277+SebastiaanPasterkamp@users.noreply.github.com> Date: Sun, 5 Jun 2022 17:54:46 +0200 Subject: [PATCH 2/2] Simplify sub-command initialization w/o IgnoreDefault --- parse.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parse.go b/parse.go index 9f93502..a883a10 100644 --- a/parse.go +++ b/parse.go @@ -531,7 +531,7 @@ func (p *Parser) process(args []string) error { // instantiate the field to point to a new struct v := p.val(subcmd.dest) - if !p.config.IgnoreDefault || v.IsNil() { + if v.IsNil() { v.Set(reflect.New(v.Type().Elem())) // we already checked that all subcommands are struct pointers }