diff --git a/bake/bake.go b/bake/bake.go index c810933a..5f931572 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -134,7 +134,7 @@ func ReadTargets(ctx context.Context, files []File, targets, overrides []string, gt = append(gt, target) } } - g = []*Group{{Targets: dedupString(gt)}} + g = []*Group{{Targets: dedupSlice(gt)}} } for name, t := range m { @@ -146,7 +146,7 @@ func ReadTargets(ctx context.Context, files []File, targets, overrides []string, return m, g, nil } -func dedupString(s []string) []string { +func dedupSlice(s []string) []string { if len(s) == 0 { return s } @@ -161,6 +161,24 @@ func dedupString(s []string) []string { return res } +func dedupMap(ms ...map[string]string) map[string]string { + if len(ms) == 0 { + return nil + } + res := map[string]string{} + for _, m := range ms { + if len(m) == 0 { + continue + } + for k, v := range m { + if _, ok := res[k]; !ok { + res[k] = v + } + } + } + return res +} + func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error) { defer func() { err = formatHCLError(err, files) @@ -418,7 +436,7 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error) } func (c Config) ResolveGroup(name string) []string { - return dedupString(c.group(name, map[string][]string{})) + return dedupSlice(c.group(name, map[string][]string{})) } func (c Config) group(name string, visited map[string][]string) []string { diff --git a/bake/compose.go b/bake/compose.go index d7476256..1f0a3b5d 100644 --- a/bake/compose.go +++ b/bake/compose.go @@ -151,10 +151,12 @@ type xbake struct { Pull *bool `yaml:"pull,omitempty"` NoCache *bool `yaml:"no-cache,omitempty"` NoCacheFilter stringArray `yaml:"no-cache-filter,omitempty"` + Contexts stringMap `yaml:"contexts,omitempty"` // don't forget to update documentation if you add a new field: // docs/guides/bake/compose-file.md#extension-field-with-x-bake } +type stringMap map[string]string type stringArray []string func (sa *stringArray) UnmarshalYAML(unmarshal func(interface{}) error) error { @@ -188,25 +190,25 @@ func (t *Target) composeExtTarget(exts map[string]interface{}) error { } if len(xb.Tags) > 0 { - t.Tags = dedupString(append(t.Tags, xb.Tags...)) + t.Tags = dedupSlice(append(t.Tags, xb.Tags...)) } if len(xb.CacheFrom) > 0 { - t.CacheFrom = dedupString(append(t.CacheFrom, xb.CacheFrom...)) + t.CacheFrom = dedupSlice(append(t.CacheFrom, xb.CacheFrom...)) } if len(xb.CacheTo) > 0 { - t.CacheTo = dedupString(append(t.CacheTo, xb.CacheTo...)) + t.CacheTo = dedupSlice(append(t.CacheTo, xb.CacheTo...)) } if len(xb.Secrets) > 0 { - t.Secrets = dedupString(append(t.Secrets, xb.Secrets...)) + t.Secrets = dedupSlice(append(t.Secrets, xb.Secrets...)) } if len(xb.SSH) > 0 { - t.SSH = dedupString(append(t.SSH, xb.SSH...)) + t.SSH = dedupSlice(append(t.SSH, xb.SSH...)) } if len(xb.Platforms) > 0 { - t.Platforms = dedupString(append(t.Platforms, xb.Platforms...)) + t.Platforms = dedupSlice(append(t.Platforms, xb.Platforms...)) } if len(xb.Outputs) > 0 { - t.Outputs = dedupString(append(t.Outputs, xb.Outputs...)) + t.Outputs = dedupSlice(append(t.Outputs, xb.Outputs...)) } if xb.Pull != nil { t.Pull = xb.Pull @@ -215,7 +217,10 @@ func (t *Target) composeExtTarget(exts map[string]interface{}) error { t.NoCache = xb.NoCache } if len(xb.NoCacheFilter) > 0 { - t.NoCacheFilter = dedupString(append(t.NoCacheFilter, xb.NoCacheFilter...)) + t.NoCacheFilter = dedupSlice(append(t.NoCacheFilter, xb.NoCacheFilter...)) + } + if len(xb.Contexts) > 0 { + t.Contexts = dedupMap(t.Contexts, xb.Contexts) } return nil diff --git a/bake/compose_test.go b/bake/compose_test.go index 15bbfa7f..4f370c29 100644 --- a/bake/compose_test.go +++ b/bake/compose_test.go @@ -267,6 +267,8 @@ services: CT_ECR: foo CT_TAG: bar x-bake: + contexts: + alpine: docker-image://alpine:3.13 tags: - ct-addon:foo - ct-addon:alp @@ -308,6 +310,7 @@ services: require.Equal(t, c.Targets[0].CacheFrom, []string{"user/app:cache", "type=local,src=path/to/cache"}) require.Equal(t, c.Targets[0].CacheTo, []string{"user/app:cache", "type=local,dest=path/to/cache"}) require.Equal(t, c.Targets[0].Pull, newBool(true)) + require.Equal(t, c.Targets[0].Contexts, map[string]string{"alpine": "docker-image://alpine:3.13"}) require.Equal(t, c.Targets[1].Tags, []string{"ct-fake-aws:bar"}) require.Equal(t, c.Targets[1].Secrets, []string{"id=mysecret,src=/local/secret", "id=mysecret2,src=/local/secret2"}) require.Equal(t, c.Targets[1].SSH, []string{"default"}) diff --git a/docs/guides/bake/compose-file.md b/docs/guides/bake/compose-file.md index 5086de6c..5d40a8c7 100644 --- a/docs/guides/bake/compose-file.md +++ b/docs/guides/bake/compose-file.md @@ -209,6 +209,7 @@ Complete list of valid fields for `x-bake`: * `cache-from` * `cache-to` +* `contexts` * `no-cache` * `no-cache-filter` * `output`