feature: accept custom Environment map

This commit is contained in:
Bruno Reis 2023-08-06 16:28:23 -07:00
parent 75ffe0d6b8
commit c14b278ccf
2 changed files with 41 additions and 4 deletions

View File

@ -141,6 +141,9 @@ type Config struct {
// Out is where help text, usage text, and failure messages are printed (defaults to os.Stdout) // Out is where help text, usage text, and failure messages are printed (defaults to os.Stdout)
Out io.Writer Out io.Writer
// Environment is a map of environment variables to override those in the process environment, or provide values to those not in the process environment.
Environment map[string]string
} }
// Parser represents a set of command line options with destination values // Parser represents a set of command line options with destination values
@ -531,7 +534,17 @@ func (p *Parser) captureEnvVars(specs []*spec, wasPresent map[*spec]bool) error
continue continue
} }
value, found := os.LookupEnv(spec.env) var value string
var found bool
if !p.config.IgnoreEnv {
value, found = os.LookupEnv(spec.env)
}
if p.config.Environment != nil {
value, found = p.config.Environment[spec.env]
}
if !found { if !found {
continue continue
} }
@ -584,7 +597,7 @@ func (p *Parser) process(args []string) error {
copy(specs, curCmd.specs) copy(specs, curCmd.specs)
// deal with environment vars // deal with environment vars
if !p.config.IgnoreEnv { if !p.config.IgnoreEnv || p.config.Environment != nil {
err := p.captureEnvVars(specs, wasPresent) err := p.captureEnvVars(specs, wasPresent)
if err != nil { if err != nil {
return err return err
@ -640,7 +653,7 @@ func (p *Parser) process(args []string) error {
} }
// capture environment vars for these new options // capture environment vars for these new options
if !p.config.IgnoreEnv { if !p.config.IgnoreEnv || p.config.Environment != nil {
err := p.captureEnvVars(subcmd.specs, wasPresent) err := p.captureEnvVars(subcmd.specs, wasPresent)
if err != nil { if err != nil {
return err return err

View File

@ -39,7 +39,13 @@ func parseWithEnv(tb testing.TB, cmdline string, env []string, dest interface{})
} }
func parseWithEnvErr(tb testing.TB, cmdline string, env []string, dest interface{}) (*Parser, error) { func parseWithEnvErr(tb testing.TB, cmdline string, env []string, dest interface{}) (*Parser, error) {
p, err := NewParser(Config{}, dest) tb.Helper()
return parseWithConfigEnvErr(tb, Config{}, cmdline, env, dest)
}
func parseWithConfigEnvErr(tb testing.TB, config Config, cmdline string, env []string, dest interface{}) (*Parser, error) {
tb.Helper()
p, err := NewParser(config, dest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -669,6 +675,24 @@ func TestEnvironmentVariable(t *testing.T) {
assert.Equal(t, "bar", args.Foo) assert.Equal(t, "bar", args.Foo)
} }
func TestEnvironmentVariableViaCustomEnvironment(t *testing.T) {
var args struct {
Foo string `arg:"env"`
}
_, err := parseWithConfigEnvErr(t, Config{Environment: map[string]string{"FOO": "bar"}}, "", nil, &args)
require.NoError(t, err)
assert.Equal(t, "bar", args.Foo)
}
func TestEnvironmentVariableOverriddenByCustomEnvironment(t *testing.T) {
var args struct {
Foo string `arg:"env"`
}
_, err := parseWithConfigEnvErr(t, Config{Environment: map[string]string{"FOO": "bar"}}, "", []string{"FOO=foo"}, &args)
require.NoError(t, err)
assert.Equal(t, "bar", args.Foo)
}
func TestEnvironmentVariableNotPresent(t *testing.T) { func TestEnvironmentVariableNotPresent(t *testing.T) {
var args struct { var args struct {
NotPresent string `arg:"env"` NotPresent string `arg:"env"`