Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func readWithProgress(r io.Reader, setStatus func(st *client.VertexStatus)) (dt
}

func ListTargets(files []File) ([]string, error) {
c, _, err := ParseFiles(files, nil)
c, _, err := ParseFiles(files, nil, nil)
if err != nil {
return nil, err
}
Expand All @@ -194,8 +194,8 @@ func ListTargets(files []File) ([]string, error) {
return dedupSlice(targets), nil
}

func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults map[string]string, ent *EntitlementConf) (map[string]*Target, map[string]*Group, error) {
c, _, err := ParseFiles(files, defaults)
func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults, vars map[string]string, ent *EntitlementConf) (map[string]*Target, map[string]*Group, error) {
c, _, err := ParseFiles(files, defaults, vars)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -334,7 +334,7 @@ func (c Config) matchNames(pattern string) ([]string, error) {
return names, nil
}

func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclparser.ParseMeta, err error) {
func ParseFiles(files []File, defaults, vars map[string]string) (_ *Config, _ *hclparser.ParseMeta, err error) {
defer func() {
err = formatHCLError(err, files)
}()
Expand All @@ -343,7 +343,7 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars
var composeFiles []File
var hclFiles []*hcl.File
for _, f := range files {
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
isCompose, composeErr := validateComposeFile(f.Data, f.Name, vars)
if isCompose {
if composeErr != nil {
return nil, nil, composeErr
Expand All @@ -366,7 +366,7 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars
}

if len(composeFiles) > 0 {
cfg, cmperr := ParseComposeFiles(composeFiles)
cfg, cmperr := ParseComposeFiles(composeFiles, vars)
if cmperr != nil {
return nil, nil, errors.Wrap(cmperr, "failed to parse compose file")
}
Expand All @@ -376,9 +376,14 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars

var pm hclparser.ParseMeta
if len(hclFiles) > 0 {
lookup := func(string) (string, bool) { return "", false }
if envLookupAllowed() {
lookup = os.LookupEnv
lookup := func(key string) (string, bool) {
if v, ok := vars[key]; ok {
return v, true
}
if envLookupAllowed() {
return os.LookupEnv(key)
}
return "", false
}
res, err := hclparser.Parse(hclparser.MergeFiles(hclFiles), hclparser.Opt{
LookupVar: lookup,
Expand Down Expand Up @@ -430,7 +435,7 @@ func dedupeConfig(c Config) Config {
}

func ParseFile(dt []byte, fn string) (*Config, error) {
c, _, err := ParseFiles([]File{{Data: dt, Name: fn}}, nil)
c, _, err := ParseFiles([]File{{Data: dt, Name: fn}}, nil, nil)
return c, err
}

Expand Down
208 changes: 104 additions & 104 deletions bake/bake_test.go

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions bake/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bake
import (
"context"
"fmt"
"maps"
"os"
"path/filepath"
"slices"
Expand All @@ -20,8 +21,8 @@ import (
"go.yaml.in/yaml/v3"
)

func ParseComposeFiles(fs []File) (*Config, error) {
envs, err := composeEnv()
func ParseComposeFiles(fs []File, envOverrides map[string]string) (*Config, error) {
envs, err := composeEnv(envOverrides)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -278,8 +279,8 @@ func loadComposeFiles(cfgs []composetypes.ConfigFile, envs map[string]string, op
})
}

func validateComposeFile(dt []byte, fn string) (bool, error) {
envs, err := composeEnv()
func validateComposeFile(dt []byte, fn string, envOverrides map[string]string) (bool, error) {
envs, err := composeEnv(envOverrides)
if err != nil {
return false, err
}
Expand All @@ -303,7 +304,7 @@ func validateCompose(dt []byte, envs map[string]string) error {
return err
}

func composeEnv() (map[string]string, error) {
func composeEnv(envOverrides map[string]string) (map[string]string, error) {
var env []string
if envLookupAllowed() {
env = os.Environ()
Expand All @@ -315,6 +316,7 @@ func composeEnv() (map[string]string, error) {
return nil, err
}
}
maps.Copy(envs, envOverrides)
return envs, nil
}

Expand Down
16 changes: 8 additions & 8 deletions bake/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ services:
c, err := ParseComposeFiles([]File{{
Name: "docker-compose.yml",
Data: dt,
}})
}}, nil)
require.NoError(t, err)
require.Equal(t, map[string]*string{"FOO": ptrstr("bar")}, c.Targets[0].Args)
}
Expand Down Expand Up @@ -716,7 +716,7 @@ target "default" {
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
isCompose, err := validateComposeFile(tt.dt, tt.fn)
isCompose, err := validateComposeFile(tt.dt, tt.fn, nil)
assert.Equal(t, tt.isCompose, isCompose)
if tt.wantErr {
require.Error(t, err)
Expand Down Expand Up @@ -790,7 +790,7 @@ services:
c, err := ParseComposeFiles([]File{{
Name: "composetypes.yml",
Data: dt,
}})
}}, nil)
require.NoError(t, err)

require.Equal(t, 2, len(c.Targets))
Expand Down Expand Up @@ -943,7 +943,7 @@ services:
`)

chdir(t, tmpdir)
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}})
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}}, nil)
require.NoError(t, err)
}

Expand All @@ -968,7 +968,7 @@ services:
t.Setenv("SYSTEM_VALUE", "abc")

chdir(t, tmpdir)
c, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}})
c, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}}, nil)
require.NoError(t, err)
require.Equal(t, map[string]*string{"TEST_VALUE": ptrstr("abc"), "FOO_VALUE": ptrstr("abc")}, c.Targets[0].Args)
}
Expand All @@ -987,7 +987,7 @@ foo:
`)

chdir(t, tmpdir)
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}})
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}}, nil)
require.NoError(t, err)
}

Expand All @@ -1002,15 +1002,15 @@ services:
`)

chdir(t, tmpdir)
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}})
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: dt}}, nil)
require.Error(t, err)
require.ErrorContains(t, err, `additional properties 'foo' not allowed`)
}

func TestEmptyComposeFile(t *testing.T) {
tmpdir := t.TempDir()
chdir(t, tmpdir)
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: []byte(``)}})
_, err := ParseComposeFiles([]File{{Name: "compose.yml", Data: []byte(``)}}, nil)
require.Error(t, err)
require.ErrorContains(t, err, `empty compose file`) // https://github.com/compose-spec/compose-go/blob/a42e7579d813e64c0c1f598a666358bc0c0a0eb4/loader/loader.go#L542
}
Expand Down
27 changes: 14 additions & 13 deletions bake/hcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "app", c.Targets[0].Name)
Expand All @@ -296,7 +296,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Targets))
Expand Down Expand Up @@ -333,7 +333,7 @@ func TestHCLVarsWithVars(t *testing.T) {
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "app", c.Targets[0].Name)
Expand All @@ -345,7 +345,7 @@ func TestHCLVarsWithVars(t *testing.T) {
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Targets))
Expand Down Expand Up @@ -914,7 +914,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "app", c.Targets[0].Name)
Expand All @@ -925,7 +925,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Targets))
Expand All @@ -949,7 +949,7 @@ func TestHCLMultiFileGlobalAttrs(t *testing.T) {
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "app", c.Targets[0].Name)
Expand Down Expand Up @@ -1133,7 +1133,7 @@ func TestHCLRenameMultiFile(t *testing.T) {
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
{Data: dt3, Name: "c3.hcl"},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 2, len(c.Targets))
Expand Down Expand Up @@ -1351,7 +1351,7 @@ func TestHCLMatrixArgsOverride(t *testing.T) {

c, _, err := ParseFiles([]File{
{Data: dt, Name: "docker-bake.hcl"},
}, map[string]string{"ABC": "11,22,33"})
}, map[string]string{"ABC": "11,22,33"}, nil)
require.NoError(t, err)

require.Equal(t, 3, len(c.Targets))
Expand Down Expand Up @@ -1538,7 +1538,7 @@ services:
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.yml"},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Targets))
Expand All @@ -1561,7 +1561,7 @@ func TestHCLBuiltinVars(t *testing.T) {
{Data: dt, Name: "c1.hcl"},
}, map[string]string{
"BAKE_CMD_CONTEXT": "foo",
})
}, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Targets))
Expand Down Expand Up @@ -1622,7 +1622,7 @@ target "b" {
}]
}`),
},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Groups))
Expand Down Expand Up @@ -1679,7 +1679,7 @@ target "two" {
Name: "bar.json",
Data: []byte(`{"ABC": "ghi", "DEF": "jkl"}`),
},
}, nil)
}, nil, nil)
require.NoError(t, err)

require.Equal(t, 1, len(c.Groups))
Expand Down Expand Up @@ -2341,6 +2341,7 @@ func TestJSONOverridePriority(t *testing.T) {
c, _, err := ParseFiles(
[]File{{Name: "docker-bake.hcl", Data: dt}},
map[string]string{"FOO_JSON": "whatever"},
nil,
)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
Expand Down
31 changes: 29 additions & 2 deletions commands/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const (
type bakeOptions struct {
files []string
overrides []string
vars []string

sbom string
provenance string
Expand Down Expand Up @@ -209,9 +210,13 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
"BAKE_CMD_CONTEXT": cmdContext,
"BAKE_LOCAL_PLATFORM": platforms.Format(platforms.DefaultSpec()),
}
vars, err := parseBakeVars(in.vars)
if err != nil {
return err
}

if in.list != "" {
cfg, pm, err := bake.ParseFiles(files, defaults)
cfg, pm, err := bake.ParseFiles(files, defaults, vars)
if err != nil {
return err
}
Expand All @@ -230,7 +235,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
}
}

tgts, grps, err := bake.ReadTargets(ctx, files, targets, overrides, defaults, &ent)
tgts, grps, err := bake.ReadTargets(ctx, files, targets, overrides, defaults, vars, &ent)
if err != nil {
return err
}
Expand Down Expand Up @@ -516,6 +521,7 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`)
flags.StringArrayVar(&options.vars, "var", nil, `Set a variable value (e.g., "name=value")`)
flags.StringVar(&options.callFunc, "call", "build", `Set method for evaluating build ("check", "outline", "targets")`)
flags.StringArrayVar(&options.allow, "allow", nil, "Allow build to access specified resources")

Expand Down Expand Up @@ -717,6 +723,27 @@ func parseList(input string) (listEntry, error) {
return res, nil
}

func parseBakeVars(values []string) (map[string]string, error) {
if len(values) == 0 {
return nil, nil
}
vars := make(map[string]string, len(values))
for _, value := range values {
if value == "" {
continue
}
key, val, ok := strings.Cut(value, "=")
if !ok {
return nil, errors.Errorf("invalid variable %q, expected key=value", value)
}
if key == "" {
return nil, errors.Errorf("invalid variable %q, key is empty", value)
}
vars[key] = val
}
return vars, nil
}

func printVars(w io.Writer, format string, vars []*hclparser.Variable) error {
slices.SortFunc(vars, func(a, b *hclparser.Variable) int {
return cmp.Compare(a.Name, b.Name)
Expand Down
1 change: 1 addition & 0 deletions docs/reference/buildx_bake.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Build from a file
| [`--push`](#push) | `bool` | | Shorthand for `--set=*.output=type=registry`. Conditional. |
| [`--sbom`](#sbom) | `string` | | Shorthand for `--set=*.attest=type=sbom` |
| [`--set`](#set) | `stringArray` | | Override target value (e.g., `targetpattern.key=value`) |
| `--var` | `stringArray` | | Set a variable value (e.g., `name=value`) |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could have basic examples similar to set



<!---MARKER_GEN_END-->
Expand Down
Loading