diff --git a/bake/hcl_test.go b/bake/hcl_test.go index 140293c5..f053d24a 100644 --- a/bake/hcl_test.go +++ b/bake/hcl_test.go @@ -565,3 +565,37 @@ func TestHCLFunctionInAttr(t *testing.T) { require.Equal(t, c.Targets[0].Name, "app") require.Equal(t, "FOO <> [baz]", c.Targets[0].Args["v1"]) } + +func TestHCLCombineCompose(t *testing.T) { + dt := []byte(` + target "app" { + context = "dir" + args = { + v1 = "foo" + } + } + `) + dt2 := []byte(` +version: "3" + +services: + app: + build: + dockerfile: Dockerfile-alternate + args: + v2: "bar" +`) + + c, err := ParseFiles([]File{ + {Data: dt, Name: "c1.hcl"}, + {Data: dt2, Name: "c2.yml"}, + }) + require.NoError(t, err) + + require.Equal(t, 1, len(c.Targets)) + require.Equal(t, c.Targets[0].Name, "app") + require.Equal(t, "foo", c.Targets[0].Args["v1"]) + require.Equal(t, "bar", c.Targets[0].Args["v2"]) + require.Equal(t, "dir", *c.Targets[0].Context) + require.Equal(t, "Dockerfile-alternate", *c.Targets[0].Dockerfile) +} diff --git a/bake/hclparser/hclparser.go b/bake/hclparser/hclparser.go index 43ff4e87..46c2316f 100644 --- a/bake/hclparser/hclparser.go +++ b/bake/hclparser/hclparser.go @@ -435,9 +435,21 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics { continue } - setLabel(vv, b.Labels[0]) + lblIndex := setLabel(vv, b.Labels[0]) oldValue, exists := t.values[b.Labels[0]] + if !exists && lblIndex != -1 { + if v.Elem().Field(t.idx).Type().Kind() == reflect.Slice { + for i := 0; i < v.Elem().Field(t.idx).Len(); i++ { + if b.Labels[0] == v.Elem().Field(t.idx).Index(i).Elem().Field(lblIndex).String() { + exists = true + oldValue = value{Value: v.Elem().Field(t.idx).Index(i), idx: i} + break + } + } + } + + } if exists { if m := oldValue.Value.MethodByName("Merge"); m.IsValid() { m.Call([]reflect.Value{vv}) @@ -460,15 +472,16 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics { return nil } -func setLabel(v reflect.Value, lbl string) { +func setLabel(v reflect.Value, lbl string) int { // cache field index? numFields := v.Elem().Type().NumField() for i := 0; i < numFields; i++ { for _, t := range strings.Split(v.Elem().Type().Field(i).Tag.Get("hcl"), ",") { if t == "label" { v.Elem().Field(i).Set(reflect.ValueOf(lbl)) - return + return i } } } + return -1 }