-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto-skip: add support for arg matrices (#3444)
Adds support for the expansion of `BUILD` arguments when multiple values are specified for a given argument. Addresses: earthly/earthly#3045
- Loading branch information
1 parent
c43f15d
commit a457e73
Showing
8 changed files
with
140 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1 @@ | ||
package earthfile2llb | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBuildArgMatrix(t *testing.T) { | ||
var tests = []struct { | ||
in []string | ||
out [][]string | ||
}{ | ||
{[]string{}, [][]string{nil}}, | ||
{[]string{"a=1"}, [][]string{{"a=1"}}}, | ||
{[]string{"a=1", "a=2", "a=3"}, [][]string{{"a=1"}, {"a=2"}, {"a=3"}}}, | ||
{[]string{"a=1", "b=2"}, [][]string{{"a=1", "b=2"}}}, | ||
{[]string{"a=1", "a=3", "b=2"}, [][]string{{"a=1", "b=2"}, {"a=3", "b=2"}}}, | ||
{[]string{"a=1", "a=3", "b=2", "b=4"}, [][]string{{"a=1", "b=2"}, {"a=1", "b=4"}, {"a=3", "b=2"}, {"a=3", "b=4"}}}, | ||
{[]string{"a=1", "b=2", "a=3", "b=4"}, [][]string{{"a=1", "b=2"}, {"a=1", "b=4"}, {"a=3", "b=2"}, {"a=3", "b=4"}}}, | ||
{[]string{"a=1", "b=2", "a=3", "b=4", "c=10"}, [][]string{{"a=1", "b=2", "c=10"}, {"a=1", "b=4", "c=10"}, {"a=3", "b=2", "c=10"}, {"a=3", "b=4", "c=10"}}}, | ||
{[]string{"a=1", "a=3", "a=7", "c=10"}, [][]string{{"a=1", "c=10"}, {"a=3", "c=10"}, {"a=7", "c=10"}}}, | ||
} | ||
|
||
for _, tt := range tests { | ||
ans, err := buildArgMatrix(tt.in) | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.out, ans) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
VERSION 0.7 | ||
|
||
PROJECT earthly-technologies/core | ||
|
||
FROM alpine | ||
|
||
foo: | ||
ARG NAME | ||
ARG SENDER | ||
RUN echo "Hello $NAME. From $SENDER" | ||
|
||
arg-matrix: | ||
BUILD +foo --NAME=Bob --NAME=John --NAME=Bill --NAME=Sarah --SENDER=Todd --SENDER=Owen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package flagutil | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
type argGroup struct { | ||
key string | ||
values []*string | ||
} | ||
|
||
// BuildArgMatrix builds a 2-dimensional slice of arguments that contains all | ||
// combinations | ||
func BuildArgMatrix(args []string) ([][]string, error) { | ||
groupedArgs := make([]argGroup, 0, len(args)) | ||
for _, arg := range args { | ||
k, v, err := parseKeyValue(arg) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
found := false | ||
for i, g := range groupedArgs { | ||
if g.key == k { | ||
groupedArgs[i].values = append(groupedArgs[i].values, v) | ||
found = true | ||
break | ||
} | ||
} | ||
if !found { | ||
groupedArgs = append(groupedArgs, argGroup{ | ||
key: k, | ||
values: []*string{v}, | ||
}) | ||
} | ||
} | ||
return crossProduct(groupedArgs, nil), nil | ||
} | ||
|
||
func crossProduct(ga []argGroup, prefix []string) [][]string { | ||
if len(ga) == 0 { | ||
return [][]string{prefix} | ||
} | ||
var ret [][]string | ||
for _, v := range ga[0].values { | ||
newPrefix := prefix[:] | ||
var kv string | ||
if v == nil { | ||
kv = ga[0].key | ||
} else { | ||
kv = fmt.Sprintf("%s=%s", ga[0].key, *v) | ||
} | ||
newPrefix = append(newPrefix, kv) | ||
|
||
cp := crossProduct(ga[1:], newPrefix) | ||
ret = append(ret, cp...) | ||
} | ||
return ret | ||
} | ||
|
||
func parseKeyValue(arg string) (string, *string, error) { | ||
var name string | ||
splitArg := strings.SplitN(arg, "=", 2) | ||
if len(splitArg) < 1 { | ||
return "", nil, errors.Errorf("invalid build arg %s", splitArg) | ||
} | ||
name = splitArg[0] | ||
var value *string | ||
if len(splitArg) == 2 { | ||
value = &splitArg[1] | ||
} | ||
return name, value, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package flagutil | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBuildArgMatrix(t *testing.T) { | ||
var tests = []struct { | ||
in []string | ||
out [][]string | ||
}{ | ||
{[]string{}, [][]string{nil}}, | ||
{[]string{"a=1"}, [][]string{{"a=1"}}}, | ||
{[]string{"a=1", "a=2", "a=3"}, [][]string{{"a=1"}, {"a=2"}, {"a=3"}}}, | ||
{[]string{"a=1", "b=2"}, [][]string{{"a=1", "b=2"}}}, | ||
{[]string{"a=1", "a=3", "b=2"}, [][]string{{"a=1", "b=2"}, {"a=3", "b=2"}}}, | ||
{[]string{"a=1", "a=3", "b=2", "b=4"}, [][]string{{"a=1", "b=2"}, {"a=1", "b=4"}, {"a=3", "b=2"}, {"a=3", "b=4"}}}, | ||
{[]string{"a=1", "b=2", "a=3", "b=4"}, [][]string{{"a=1", "b=2"}, {"a=1", "b=4"}, {"a=3", "b=2"}, {"a=3", "b=4"}}}, | ||
{[]string{"a=1", "b=2", "a=3", "b=4", "c=10"}, [][]string{{"a=1", "b=2", "c=10"}, {"a=1", "b=4", "c=10"}, {"a=3", "b=2", "c=10"}, {"a=3", "b=4", "c=10"}}}, | ||
{[]string{"a=1", "a=3", "a=7", "c=10"}, [][]string{{"a=1", "c=10"}, {"a=3", "c=10"}, {"a=7", "c=10"}}}, | ||
} | ||
|
||
for _, tt := range tests { | ||
ans, err := BuildArgMatrix(tt.in) | ||
assert.NoError(t, err) | ||
assert.Equal(t, tt.out, ans) | ||
} | ||
} |