Skip to content

Commit

Permalink
Merge pull request #2556 from tonistiigi/bake-call
Browse files Browse the repository at this point in the history
bake: add call methods support and printing
  • Loading branch information
tonistiigi committed Jul 3, 2024
2 parents 8535c6b + 153e5ed commit c51004e
Show file tree
Hide file tree
Showing 10 changed files with 552 additions and 90 deletions.
54 changes: 37 additions & 17 deletions bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,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)
if err != nil {
return nil, err
}
Expand All @@ -192,7 +192,7 @@ func ListTargets(files []File) ([]string, error) {
}

func ReadTargets(ctx context.Context, files []File, targets, overrides []string, defaults map[string]string) (map[string]*Target, map[string]*Group, error) {
c, err := ParseFiles(files, defaults)
c, _, err := ParseFiles(files, defaults)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -298,7 +298,7 @@ func sliceToMap(env []string) (res map[string]string) {
return
}

func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error) {
func ParseFiles(files []File, defaults map[string]string) (_ *Config, _ *hclparser.ParseMeta, err error) {
defer func() {
err = formatHCLError(err, files)
}()
Expand All @@ -310,45 +310,46 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
if isCompose {
if composeErr != nil {
return nil, composeErr
return nil, nil, composeErr
}
composeFiles = append(composeFiles, f)
}
if !isCompose {
hf, isHCL, err := ParseHCLFile(f.Data, f.Name)
if isHCL {
if err != nil {
return nil, err
return nil, nil, err
}
hclFiles = append(hclFiles, hf)
} else if composeErr != nil {
return nil, errors.Wrapf(err, "failed to parse %s: parsing yaml: %v, parsing hcl", f.Name, composeErr)
return nil, nil, errors.Wrapf(err, "failed to parse %s: parsing yaml: %v, parsing hcl", f.Name, composeErr)
} else {
return nil, err
return nil, nil, err
}
}
}

if len(composeFiles) > 0 {
cfg, cmperr := ParseComposeFiles(composeFiles)
if cmperr != nil {
return nil, errors.Wrap(cmperr, "failed to parse compose file")
return nil, nil, errors.Wrap(cmperr, "failed to parse compose file")
}
c = mergeConfig(c, *cfg)
c = dedupeConfig(c)
}

var pm hclparser.ParseMeta
if len(hclFiles) > 0 {
renamed, err := hclparser.Parse(hclparser.MergeFiles(hclFiles), hclparser.Opt{
res, err := hclparser.Parse(hclparser.MergeFiles(hclFiles), hclparser.Opt{
LookupVar: os.LookupEnv,
Vars: defaults,
ValidateLabel: validateTargetName,
}, &c)
if err.HasErrors() {
return nil, err
return nil, nil, err
}

for _, renamed := range renamed {
for _, renamed := range res.Renamed {
for oldName, newNames := range renamed {
newNames = dedupSlice(newNames)
if len(newNames) == 1 && oldName == newNames[0] {
Expand All @@ -361,9 +362,10 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
}
}
c = dedupeConfig(c)
pm = *res
}

return &c, nil
return &c, &pm, nil
}

func dedupeConfig(c Config) Config {
Expand All @@ -388,7 +390,8 @@ func dedupeConfig(c Config) Config {
}

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

type Config struct {
Expand Down Expand Up @@ -669,13 +672,15 @@ func (c Config) target(name string, visited map[string]*Target, overrides map[st
}

type Group struct {
Name string `json:"-" hcl:"name,label" cty:"name"`
Targets []string `json:"targets" hcl:"targets" cty:"targets"`
Name string `json:"-" hcl:"name,label" cty:"name"`
Description string `json:"description,omitempty" hcl:"description,optional" cty:"description"`
Targets []string `json:"targets" hcl:"targets" cty:"targets"`
// Target // TODO?
}

type Target struct {
Name string `json:"-" hcl:"name,label" cty:"name"`
Name string `json:"-" hcl:"name,label" cty:"name"`
Description string `json:"description,omitempty" hcl:"description,optional" cty:"description"`

// Inherits is the only field that cannot be overridden with --set
Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional" cty:"inherits"`
Expand All @@ -702,7 +707,8 @@ type Target struct {
NoCacheFilter []string `json:"no-cache-filter,omitempty" hcl:"no-cache-filter,optional" cty:"no-cache-filter"`
ShmSize *string `json:"shm-size,omitempty" hcl:"shm-size,optional"`
Ulimits []string `json:"ulimits,omitempty" hcl:"ulimits,optional"`
// IMPORTANT: if you add more fields here, do not forget to update newOverrides and docs/bake-reference.md.
Call *string `json:"call,omitempty" hcl:"call,optional" cty:"call"`
// IMPORTANT: if you add more fields here, do not forget to update newOverrides/AddOverrides and docs/bake-reference.md.

// linked is a private field to mark a target used as a linked one
linked bool
Expand Down Expand Up @@ -776,6 +782,9 @@ func (t *Target) Merge(t2 *Target) {
if t2.Target != nil {
t.Target = t2.Target
}
if t2.Call != nil {
t.Call = t2.Call
}
if t2.Annotations != nil { // merge
t.Annotations = append(t.Annotations, t2.Annotations...)
}
Expand Down Expand Up @@ -819,6 +828,9 @@ func (t *Target) Merge(t2 *Target) {
if t2.Ulimits != nil { // merge
t.Ulimits = append(t.Ulimits, t2.Ulimits...)
}
if t2.Description != "" {
t.Description = t2.Description
}
t.Inherits = append(t.Inherits, t2.Inherits...)
}

Expand Down Expand Up @@ -863,6 +875,8 @@ func (t *Target) AddOverrides(overrides map[string]Override) error {
t.CacheTo = o.ArrValue
case "target":
t.Target = &value
case "call":
t.Call = &value
case "secrets":
t.Secrets = o.ArrValue
case "ssh":
Expand Down Expand Up @@ -1298,6 +1312,12 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
bo.Target = *t.Target
}

if t.Call != nil {
bo.PrintFunc = &build.PrintFunc{
Name: *t.Call,
}
}

cacheImports, err := buildflags.ParseCacheEntry(t.CacheFrom)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion bake/bake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1528,7 +1528,7 @@ services:
v2: "bar"
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.foo"},
{Data: dt2, Name: "c2.bar"},
}, nil)
Expand Down
26 changes: 13 additions & 13 deletions bake/hcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {
}
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand All @@ -285,7 +285,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {

t.Setenv("FOO", "def")

c, err = ParseFiles([]File{
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand Down Expand Up @@ -322,7 +322,7 @@ func TestHCLVarsWithVars(t *testing.T) {
}
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand All @@ -334,7 +334,7 @@ func TestHCLVarsWithVars(t *testing.T) {

t.Setenv("BASE", "new")

c, err = ParseFiles([]File{
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand Down Expand Up @@ -612,7 +612,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {
FOO="def"
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand All @@ -623,7 +623,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {

t.Setenv("FOO", "ghi")

c, err = ParseFiles([]File{
c, _, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand All @@ -647,7 +647,7 @@ func TestHCLMultiFileGlobalAttrs(t *testing.T) {
FOO = "def"
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
Expand Down Expand Up @@ -830,7 +830,7 @@ func TestHCLRenameMultiFile(t *testing.T) {
}
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
{Data: dt3, Name: "c3.hcl"},
Expand Down Expand Up @@ -1050,7 +1050,7 @@ func TestHCLMatrixArgsOverride(t *testing.T) {
}
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "docker-bake.hcl"},
}, map[string]string{"ABC": "11,22,33"})
require.NoError(t, err)
Expand Down Expand Up @@ -1236,7 +1236,7 @@ services:
v2: "bar"
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.yml"},
}, nil)
Expand All @@ -1258,7 +1258,7 @@ func TestHCLBuiltinVars(t *testing.T) {
}
`)

c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
}, map[string]string{
"BAKE_CMD_CONTEXT": "foo",
Expand All @@ -1272,7 +1272,7 @@ func TestHCLBuiltinVars(t *testing.T) {
}

func TestCombineHCLAndJSONTargets(t *testing.T) {
c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{
Name: "docker-bake.hcl",
Data: []byte(`
Expand Down Expand Up @@ -1348,7 +1348,7 @@ target "b" {
}

func TestCombineHCLAndJSONVars(t *testing.T) {
c, err := ParseFiles([]File{
c, _, err := ParseFiles([]File{
{
Name: "docker-bake.hcl",
Data: []byte(`
Expand Down
42 changes: 37 additions & 5 deletions bake/hclparser/hclparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ type Opt struct {
}

type variable struct {
Name string `json:"-" hcl:"name,label"`
Default *hcl.Attribute `json:"default,omitempty" hcl:"default,optional"`
Body hcl.Body `json:"-" hcl:",body"`
Name string `json:"-" hcl:"name,label"`
Default *hcl.Attribute `json:"default,omitempty" hcl:"default,optional"`
Description string `json:"description,omitempty" hcl:"description,optional"`
Body hcl.Body `json:"-" hcl:",body"`
Remain hcl.Body `json:"-" hcl:",remain"`
}

type functionDef struct {
Expand Down Expand Up @@ -534,7 +536,18 @@ func (p *parser) resolveBlockNames(block *hcl.Block) ([]string, error) {
return names, nil
}

func Parse(b hcl.Body, opt Opt, val interface{}) (map[string]map[string][]string, hcl.Diagnostics) {
type Variable struct {
Name string
Description string
Value *string
}

type ParseMeta struct {
Renamed map[string]map[string][]string
AllVariables []*Variable
}

func Parse(b hcl.Body, opt Opt, val interface{}) (*ParseMeta, hcl.Diagnostics) {
reserved := map[string]struct{}{}
schema, _ := gohcl.ImpliedBodySchema(val)

Expand Down Expand Up @@ -643,6 +656,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) (map[string]map[string][]string
}
}

vars := make([]*Variable, 0, len(p.vars))
for k := range p.vars {
if err := p.resolveValue(p.ectx, k); err != nil {
if diags, ok := err.(hcl.Diagnostics); ok {
Expand All @@ -651,6 +665,21 @@ func Parse(b hcl.Body, opt Opt, val interface{}) (map[string]map[string][]string
r := p.vars[k].Body.MissingItemRange()
return nil, wrapErrorDiagnostic("Invalid value", err, &r, &r)
}
v := &Variable{
Name: p.vars[k].Name,
Description: p.vars[k].Description,
}
if vv := p.ectx.Variables[k]; !vv.IsNull() {
var s string
switch vv.Type() {
case cty.String:
s = vv.AsString()
case cty.Bool:
s = strconv.FormatBool(vv.True())
}
v.Value = &s
}
vars = append(vars, v)
}

for k := range p.funcs {
Expand Down Expand Up @@ -795,7 +824,10 @@ func Parse(b hcl.Body, opt Opt, val interface{}) (map[string]map[string][]string
}
}

return renamed, nil
return &ParseMeta{
Renamed: renamed,
AllVariables: vars,
}, nil
}

// wrapErrorDiagnostic wraps an error into a hcl.Diagnostics object.
Expand Down
Loading

0 comments on commit c51004e

Please sign in to comment.