Skip to content

Commit 85fa1bf

Browse files
authored
acc: Do env var substitution in EnvMatrix values (#2678)
## Changes When a $VAR reference is used in value of EnvMatrix, it'll be replaced with its value if there is such variable previously defined. ## Why It's useful to define variables in terms of other variables. For example you can define "$MYCLI=$CLI --someparam". I'm using it to define CLI command that either runs from bundle root or another directory. ## Tests Unit tests + acceptance test.
1 parent 8b7aa37 commit 85fa1bf

5 files changed

Lines changed: 109 additions & 4 deletions

File tree

acceptance/acceptance_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,16 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
486486
for _, keyvalue := range customEnv {
487487
items := strings.SplitN(keyvalue, "=", 2)
488488
require.Len(t, items, 2)
489-
cmd.Env = append(cmd.Env, keyvalue)
490-
repls.Set(items[1], "["+items[0]+"]")
489+
key := items[0]
490+
value := items[1]
491+
newValue, newValueWithPlaceholders := internal.SubstituteEnv(value, cmd.Env)
492+
if value != newValue {
493+
t.Logf("Substituted %s %#v -> %#v (%#v)", key, value, newValue, newValueWithPlaceholders)
494+
}
495+
cmd.Env = append(cmd.Env, key+"="+newValue)
496+
repls.Set(newValue, "["+key+"]")
497+
// newValue won't match because parts of it were already replaced; we adding it anyway just in case but we need newValueWithPlaceholders:
498+
repls.Set(newValueWithPlaceholders, "["+key+"]")
491499
}
492500

493501
absDir, err := filepath.Abs(dir)

acceptance/internal/util.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package internal
2+
3+
import (
4+
"regexp"
5+
"strings"
6+
)
7+
8+
func SubstituteEnv(value string, env []string) (actual, placeholder string) {
9+
actual = value
10+
placeholder = value
11+
12+
for _, e := range env {
13+
parts := strings.SplitN(e, "=", 2)
14+
if len(parts) == 2 {
15+
key, val := parts[0], parts[1]
16+
re := regexp.MustCompile(`\$` + key + `\b`)
17+
actual = re.ReplaceAllString(actual, val)
18+
placeholder = re.ReplaceAllString(placeholder, "["+key+"]")
19+
}
20+
}
21+
22+
return actual, placeholder
23+
}

acceptance/internal/util_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package internal
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestSubstituteEnv(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
value string
11+
env []string
12+
expected string
13+
placeholder string
14+
}{
15+
{
16+
name: "simple substitution",
17+
value: "$CLI",
18+
env: []string{"CLI=/bin/true"},
19+
expected: "/bin/true",
20+
placeholder: "[CLI]",
21+
},
22+
{
23+
name: "multiple variables",
24+
value: "$HOME/$USER",
25+
env: []string{"HOME=/home", "USER=john"},
26+
expected: "/home/john",
27+
placeholder: "[HOME]/[USER]",
28+
},
29+
{
30+
name: "no variables",
31+
value: "hello world",
32+
env: []string{"FOO=bar"},
33+
expected: "hello world",
34+
},
35+
{
36+
name: "undefined variable",
37+
value: "$UNDEFINED",
38+
env: []string{"FOO=bar"},
39+
expected: "$UNDEFINED",
40+
},
41+
{
42+
name: "partial substitution",
43+
value: "$FOO$BAR",
44+
env: []string{"FOO=hello"},
45+
expected: "hello$BAR",
46+
placeholder: "[FOO]$BAR",
47+
},
48+
{
49+
name: "overlapping variable names",
50+
value: "$VAR $VARNAME",
51+
env: []string{"VAR=value", "VARNAME=longer"},
52+
expected: "value longer",
53+
placeholder: "[VAR] [VARNAME]",
54+
},
55+
{
56+
name: "only one of overlapping variables provided",
57+
value: "$VAR $VARNAME",
58+
env: []string{"VAR=value"},
59+
expected: "value $VARNAME",
60+
placeholder: "[VAR] $VARNAME",
61+
},
62+
}
63+
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
actual, placeholder := SubstituteEnv(tt.value, tt.env)
67+
if actual != tt.expected {
68+
t.Errorf("SubstituteEnv() actual = %q, want %q", actual, tt.expected)
69+
}
70+
if tt.placeholder != "" && placeholder != tt.placeholder {
71+
t.Errorf("SubstituteEnv() placeholder = %q, want %q", placeholder, tt.placeholder)
72+
}
73+
})
74+
}
75+
}

acceptance/selftest/envmatrix/inner/script

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[ "$FIRST" = "one" ] || [ "$FIRST" = "two" ]
22
[ "$SECOND" = "variantA" ] || [ "$SECOND" = "variantB" ]
3-
[ "$THIRD" = "three" ]
43

54
echo "FIRST=$FIRST"
65
echo "SECOND=$SECOND"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[EnvMatrix]
22
FIRST = ["overriden-in-inner"]
3-
THIRD = ["three"]
3+
THIRD = ["three $FIRST"]

0 commit comments

Comments
 (0)