bake: fix skipped group when already visited by another one

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 0b8dde1071)
pull/1022/head
CrazyMax 3 years ago
parent 5fac64c2c4
commit 10fe8f380c
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7

@ -414,12 +414,12 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
} }
func (c Config) ResolveGroup(name string) []string { func (c Config) ResolveGroup(name string) []string {
return c.group(name, map[string]struct{}{}) return dedupString(c.group(name, map[string][]string{}))
} }
func (c Config) group(name string, visited map[string]struct{}) []string { func (c Config) group(name string, visited map[string][]string) []string {
if _, ok := visited[name]; ok { if _, ok := visited[name]; ok {
return nil return visited[name]
} }
var g *Group var g *Group
for _, group := range c.Groups { for _, group := range c.Groups {
@ -431,7 +431,7 @@ func (c Config) group(name string, visited map[string]struct{}) []string {
if g == nil { if g == nil {
return []string{name} return []string{name}
} }
visited[name] = struct{}{} visited[name] = []string{}
targets := make([]string, 0, len(g.Targets)) targets := make([]string, 0, len(g.Targets))
for _, t := range g.Targets { for _, t := range g.Targets {
tgroup := c.group(t, visited) tgroup := c.group(t, visited)
@ -441,6 +441,7 @@ func (c Config) group(name string, visited map[string]struct{}) []string {
targets = append(targets, t) targets = append(targets, t)
} }
} }
visited[name] = targets
return targets return targets
} }

@ -1045,3 +1045,79 @@ func TestTargetName(t *testing.T) {
}) })
} }
} }
func TestNestedGroupsWithSameTarget(t *testing.T) {
ctx := context.TODO()
f := File{
Name: "docker-bake.hcl",
Data: []byte(`
group "a" {
targets = ["b", "c"]
}
group "b" {
targets = ["d"]
}
group "c" {
targets = ["b"]
}
target "d" {
context = "."
dockerfile = "./testdockerfile"
}
group "e" {
targets = ["a", "f"]
}
target "f" {
context = "./foo"
}`)}
cases := []struct {
name string
targets []string
ntargets int
}{
{
name: "a",
targets: []string{"b", "c"},
ntargets: 1,
},
{
name: "b",
targets: []string{"d"},
ntargets: 1,
},
{
name: "c",
targets: []string{"b"},
ntargets: 1,
},
{
name: "d",
targets: []string{"d"},
ntargets: 1,
},
{
name: "e",
targets: []string{"a", "f"},
ntargets: 2,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
m, g, err := ReadTargets(ctx, []File{f}, []string{tt.name}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, tt.targets, g[0].Targets)
require.Equal(t, tt.ntargets, len(m))
require.Equal(t, ".", *m["d"].Context)
require.Equal(t, "./testdockerfile", *m["d"].Dockerfile)
})
}
}

Loading…
Cancel
Save