mirror of https://github.com/docker/buildx.git
3172 - Allow passing env vars with set for docker compose cases
- Related: #3172, #1135 - Example: --set=env.key=value
This commit is contained in:
parent
e3c6618db2
commit
2af52e84ea
38
bake/bake.go
38
bake/bake.go
|
@ -181,7 +181,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
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ func ListTargets(files []File) ([]string, error) {
|
|||
}
|
||||
|
||||
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)
|
||||
c, _, err := ParseFiles(files, overrides, defaults)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ func sliceToMap(env []string) (res map[string]string) {
|
|||
return
|
||||
}
|
||||
|
||||
func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclparser.ParseMeta, err error) {
|
||||
func ParseFiles(files []File, overrides []string, defaults map[string]string) (_ *Config, _ *hclparser.ParseMeta, err error) {
|
||||
defer func() {
|
||||
err = formatHCLError(err, files)
|
||||
}()
|
||||
|
@ -312,8 +312,12 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars
|
|||
var c Config
|
||||
var composeFiles []File
|
||||
var hclFiles []*hcl.File
|
||||
envOverrides, err := parseEnvOverrides(overrides)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, f := range files {
|
||||
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
|
||||
isCompose, composeErr := validateComposeFile(f.Data, f.Name, envOverrides)
|
||||
if isCompose {
|
||||
if composeErr != nil {
|
||||
return nil, nil, composeErr
|
||||
|
@ -336,7 +340,7 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars
|
|||
}
|
||||
|
||||
if len(composeFiles) > 0 {
|
||||
cfg, cmperr := ParseComposeFiles(composeFiles)
|
||||
cfg, cmperr := ParseComposeFiles(composeFiles, envOverrides)
|
||||
if cmperr != nil {
|
||||
return nil, nil, errors.Wrap(cmperr, "failed to parse compose file")
|
||||
}
|
||||
|
@ -374,6 +378,28 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclpars
|
|||
return &c, &pm, nil
|
||||
}
|
||||
|
||||
// Considering overrides are "targetpattern.key=value"
|
||||
// Parse env overrides like example "env.key=value"
|
||||
func parseEnvOverrides(overrides []string) (map[string]string, error) {
|
||||
envs := make(map[string]string)
|
||||
for _, o := range overrides {
|
||||
parts := strings.SplitN(o, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, errors.Errorf("invalid env override %q", o)
|
||||
}
|
||||
key := strings.TrimSpace(parts[0])
|
||||
value := strings.TrimSpace(parts[1])
|
||||
if strings.HasPrefix(key, "env.") {
|
||||
strippedKey := strings.TrimPrefix(key, "env.")
|
||||
if strippedKey == "" || value == "" {
|
||||
return nil, errors.Errorf("invalid env override %q", o)
|
||||
}
|
||||
envs[strippedKey] = value
|
||||
}
|
||||
}
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
func dedupeConfig(c Config) Config {
|
||||
c2 := c
|
||||
c2.Groups = make([]*Group, 0, len(c2.Groups))
|
||||
|
@ -396,7 +422,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
|
||||
}
|
||||
|
||||
|
|
|
@ -1641,7 +1641,7 @@ services:
|
|||
c, _, err := ParseFiles([]File{
|
||||
{Data: dt, Name: "c1.foo"},
|
||||
{Data: dt2, Name: "c2.bar"},
|
||||
}, nil)
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(c.Targets))
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
"gopkg.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
|
||||
}
|
||||
|
@ -199,8 +199,8 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
|
|||
return &c, nil
|
||||
}
|
||||
|
||||
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 true, err
|
||||
}
|
||||
|
@ -233,7 +233,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) {
|
||||
envs := sliceToMap(os.Environ())
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
envs, err = loadDotEnv(envs, wd)
|
||||
|
@ -241,6 +241,12 @@ func composeEnv() (map[string]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
if envOverrides != nil {
|
||||
// Apply envOverrides on envs
|
||||
for key, value := range envOverrides {
|
||||
envs[key] = value
|
||||
}
|
||||
}
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -437,7 +437,33 @@ 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)
|
||||
}
|
||||
|
||||
func TestEnvOverrides(t *testing.T) {
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
overrides := []string{"env.FOO=bar"}
|
||||
|
||||
envOverrides, err := parseEnvOverrides(overrides)
|
||||
require.NoError(t, err)
|
||||
|
||||
dt := []byte(`
|
||||
services:
|
||||
scratch:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
FOO:
|
||||
`)
|
||||
|
||||
chdir(t, tmpdir)
|
||||
c, err := ParseComposeFiles([]File{{
|
||||
Name: "docker-compose.yml",
|
||||
Data: dt,
|
||||
}}, envOverrides)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{"FOO": ptrstr("bar")}, c.Targets[0].Args)
|
||||
}
|
||||
|
@ -664,7 +690,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)
|
||||
|
@ -738,7 +764,7 @@ services:
|
|||
c, err := ParseComposeFiles([]File{{
|
||||
Name: "composetypes.yml",
|
||||
Data: dt,
|
||||
}})
|
||||
}}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 2, len(c.Targets))
|
||||
|
|
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -841,7 +841,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)
|
||||
|
@ -852,7 +852,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))
|
||||
|
@ -876,7 +876,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)
|
||||
|
@ -1060,7 +1060,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))
|
||||
|
@ -1278,7 +1278,7 @@ func TestHCLMatrixArgsOverride(t *testing.T) {
|
|||
|
||||
c, _, err := ParseFiles([]File{
|
||||
{Data: dt, Name: "docker-bake.hcl"},
|
||||
}, map[string]string{"ABC": "11,22,33"})
|
||||
}, nil, map[string]string{"ABC": "11,22,33"})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 3, len(c.Targets))
|
||||
|
@ -1465,7 +1465,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))
|
||||
|
@ -1486,7 +1486,7 @@ func TestHCLBuiltinVars(t *testing.T) {
|
|||
|
||||
c, _, err := ParseFiles([]File{
|
||||
{Data: dt, Name: "c1.hcl"},
|
||||
}, map[string]string{
|
||||
}, nil, map[string]string{
|
||||
"BAKE_CMD_CONTEXT": "foo",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
@ -1549,7 +1549,7 @@ target "b" {
|
|||
}]
|
||||
}`),
|
||||
},
|
||||
}, nil)
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, 1, len(c.Groups))
|
||||
|
@ -1606,7 +1606,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))
|
||||
|
@ -2267,6 +2267,7 @@ func TestJSONOverridePriority(t *testing.T) {
|
|||
t.Setenv("FOO_JSON", "[3,4,5]")
|
||||
c, _, err := ParseFiles(
|
||||
[]File{{Name: "docker-bake.hcl", Data: dt}},
|
||||
nil,
|
||||
map[string]string{"FOO_JSON": "whatever"},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -198,7 +198,7 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
|||
}
|
||||
|
||||
if in.list != "" {
|
||||
cfg, pm, err := bake.ParseFiles(files, defaults)
|
||||
cfg, pm, err := bake.ParseFiles(files, overrides, defaults)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue