Skip to content

Commit

Permalink
Add system env variable expansion to envVars function
Browse files Browse the repository at this point in the history
The function `envVars` has been updated to enable the application to also read system environment variables, in addition to CLI and env file variables. This change includes an update of the function's comment to reflect the new behavior, and the addition of new test cases to validate the feature. CLI variables override env file variables, which in turn override system environment variables if they share the same name.
  • Loading branch information
umputun committed Mar 24, 2024
1 parent 8dafea0 commit 3e407e6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
12 changes: 9 additions & 3 deletions cmd/spot/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,16 @@ func setAdHocSSH(opts options, pbook *config.PlayBook) (*config.PlayBook, error)
return pbook, nil
}

// envVars returns a map of environment variables from the cli and env file, cli vars override env file vars if duplicated
// envVars returns a map of environment variables from the cli, env file, and system env.
// cli vars override env file vars, which in turn override system env vars if duplicated.
func envVars(vars map[string]string, envFile string) (map[string]string, error) {
res := make(map[string]string)

expandEnv := func(value string) string {
// expand environment variables denoted by $var or ${var}
return os.Expand(value, os.Getenv)
}

// load env file vars
envFileData := struct {
Vars map[string]string `yaml:"vars"`
Expand All @@ -465,13 +471,13 @@ func envVars(vars map[string]string, envFile string) (map[string]string, error)
log.Printf("[WARN] can't parse env file %q: %v", envFile, err)
}
for k, v := range envFileData.Vars {
res[k] = v
res[k] = expandEnv(v)
}
}

// cli vars override env file vars
for k, v := range vars {
res[k] = v
res[k] = expandEnv(v)
}

return res, nil
Expand Down
36 changes: 29 additions & 7 deletions cmd/spot/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,9 @@ func Test_targetsForTask(t *testing.T) {
}

func TestEnvVars(t *testing.T) {
os.Setenv("ENV_VAR", "envValue")
defer os.Unsetenv("ENV_VAR")

tests := []struct {
name string
cliVars map[string]string
Expand Down Expand Up @@ -755,34 +758,53 @@ func TestEnvVars(t *testing.T) {
},
expectedError: false,
},
{
name: "system env var replacement",
cliVars: map[string]string{
"key1": "$ENV_VAR",
"key2": "${ENV_VAR}",
"key3": "${ENV_VAR_NOT_FOUND}",
},
envFileData: "",
expectedVars: map[string]string{
"key1": "envValue",
"key2": "envValue",
"key3": "",
},
expectedError: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

envFile := "/tmp/env-not-exist.yaml"
if tt.envFileData != "" {
// create a temp file
file, err := os.CreateTemp("", "*.yaml")
if err != nil {
t.Fatalf("could not create temp file: %v", err)
}
defer os.Remove(file.Name())
defer os.Remove(file.Name()) // Clean up

// write data to temp file
if _, err = file.WriteString(tt.envFileData); err != nil {
t.Fatalf("could not write to temp file: %v", err)
}

// close file
if err = file.Close(); err != nil {
t.Fatalf("could not close temp file: %v", err)
}
envFile = file.Name()
}
// get environment variables

actualVars, err := envVars(tt.cliVars, envFile)
assert.Equal(t, tt.expectedError, err != nil)
if err != nil && !tt.expectedError {
t.Errorf("envVars() error = %v, expectedError %v", err, tt.expectedError)
return
}
if err == nil && tt.expectedError {
t.Errorf("envVars() expected error, got none")
return
}

assert.Equal(t, tt.expectedVars, actualVars)
})
}
Expand Down

0 comments on commit 3e407e6

Please sign in to comment.