mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00
bake: add list-variables option
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
parent
7460f049f2
commit
233b869c63
29
bake/bake.go
29
bake/bake.go
@ -177,7 +177,7 @@ func readWithProgress(r io.Reader, setStatus func(st *client.VertexStatus)) (dt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ListTargets(files []File) ([]string, error) {
|
func ListTargets(files []File) ([]string, error) {
|
||||||
c, err := ParseFiles(files, nil)
|
c, _, err := ParseFiles(files, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -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) {
|
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 {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ func sliceToMap(env []string) (res map[string]string) {
|
|||||||
return
|
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() {
|
defer func() {
|
||||||
err = formatHCLError(err, files)
|
err = formatHCLError(err, files)
|
||||||
}()
|
}()
|
||||||
@ -310,7 +310,7 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
|
isCompose, composeErr := validateComposeFile(f.Data, f.Name)
|
||||||
if isCompose {
|
if isCompose {
|
||||||
if composeErr != nil {
|
if composeErr != nil {
|
||||||
return nil, composeErr
|
return nil, nil, composeErr
|
||||||
}
|
}
|
||||||
composeFiles = append(composeFiles, f)
|
composeFiles = append(composeFiles, f)
|
||||||
}
|
}
|
||||||
@ -318,13 +318,13 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
hf, isHCL, err := ParseHCLFile(f.Data, f.Name)
|
hf, isHCL, err := ParseHCLFile(f.Data, f.Name)
|
||||||
if isHCL {
|
if isHCL {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
hclFiles = append(hclFiles, hf)
|
hclFiles = append(hclFiles, hf)
|
||||||
} else if composeErr != nil {
|
} 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 {
|
} else {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,23 +332,24 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
if len(composeFiles) > 0 {
|
if len(composeFiles) > 0 {
|
||||||
cfg, cmperr := ParseComposeFiles(composeFiles)
|
cfg, cmperr := ParseComposeFiles(composeFiles)
|
||||||
if cmperr != nil {
|
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 = mergeConfig(c, *cfg)
|
||||||
c = dedupeConfig(c)
|
c = dedupeConfig(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pm hclparser.ParseMeta
|
||||||
if len(hclFiles) > 0 {
|
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,
|
LookupVar: os.LookupEnv,
|
||||||
Vars: defaults,
|
Vars: defaults,
|
||||||
ValidateLabel: validateTargetName,
|
ValidateLabel: validateTargetName,
|
||||||
}, &c)
|
}, &c)
|
||||||
if err.HasErrors() {
|
if err.HasErrors() {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, renamed := range renamed {
|
for _, renamed := range res.Renamed {
|
||||||
for oldName, newNames := range renamed {
|
for oldName, newNames := range renamed {
|
||||||
newNames = dedupSlice(newNames)
|
newNames = dedupSlice(newNames)
|
||||||
if len(newNames) == 1 && oldName == newNames[0] {
|
if len(newNames) == 1 && oldName == newNames[0] {
|
||||||
@ -361,9 +362,10 @@ func ParseFiles(files []File, defaults map[string]string) (_ *Config, err error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = dedupeConfig(c)
|
c = dedupeConfig(c)
|
||||||
|
pm = *res
|
||||||
}
|
}
|
||||||
|
|
||||||
return &c, nil
|
return &c, &pm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dedupeConfig(c Config) Config {
|
func dedupeConfig(c Config) Config {
|
||||||
@ -388,7 +390,8 @@ func dedupeConfig(c Config) Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ParseFile(dt []byte, fn string) (*Config, error) {
|
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 {
|
type Config struct {
|
||||||
|
@ -1528,7 +1528,7 @@ services:
|
|||||||
v2: "bar"
|
v2: "bar"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.foo"},
|
{Data: dt, Name: "c1.foo"},
|
||||||
{Data: dt2, Name: "c2.bar"},
|
{Data: dt2, Name: "c2.bar"},
|
||||||
}, nil)
|
}, nil)
|
||||||
|
@ -273,7 +273,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -285,7 +285,7 @@ func TestHCLMultiFileSharedVariables(t *testing.T) {
|
|||||||
|
|
||||||
t.Setenv("FOO", "def")
|
t.Setenv("FOO", "def")
|
||||||
|
|
||||||
c, err = ParseFiles([]File{
|
c, _, err = ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -322,7 +322,7 @@ func TestHCLVarsWithVars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -334,7 +334,7 @@ func TestHCLVarsWithVars(t *testing.T) {
|
|||||||
|
|
||||||
t.Setenv("BASE", "new")
|
t.Setenv("BASE", "new")
|
||||||
|
|
||||||
c, err = ParseFiles([]File{
|
c, _, err = ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -612,7 +612,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {
|
|||||||
FOO="def"
|
FOO="def"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -623,7 +623,7 @@ func TestHCLMultiFileAttrs(t *testing.T) {
|
|||||||
|
|
||||||
t.Setenv("FOO", "ghi")
|
t.Setenv("FOO", "ghi")
|
||||||
|
|
||||||
c, err = ParseFiles([]File{
|
c, _, err = ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -647,7 +647,7 @@ func TestHCLMultiFileGlobalAttrs(t *testing.T) {
|
|||||||
FOO = "def"
|
FOO = "def"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -830,7 +830,7 @@ func TestHCLRenameMultiFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.hcl"},
|
{Data: dt2, Name: "c2.hcl"},
|
||||||
{Data: dt3, Name: "c3.hcl"},
|
{Data: dt3, Name: "c3.hcl"},
|
||||||
@ -1050,7 +1050,7 @@ func TestHCLMatrixArgsOverride(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "docker-bake.hcl"},
|
{Data: dt, Name: "docker-bake.hcl"},
|
||||||
}, map[string]string{"ABC": "11,22,33"})
|
}, map[string]string{"ABC": "11,22,33"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -1236,7 +1236,7 @@ services:
|
|||||||
v2: "bar"
|
v2: "bar"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
{Data: dt2, Name: "c2.yml"},
|
{Data: dt2, Name: "c2.yml"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@ -1258,7 +1258,7 @@ func TestHCLBuiltinVars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{Data: dt, Name: "c1.hcl"},
|
{Data: dt, Name: "c1.hcl"},
|
||||||
}, map[string]string{
|
}, map[string]string{
|
||||||
"BAKE_CMD_CONTEXT": "foo",
|
"BAKE_CMD_CONTEXT": "foo",
|
||||||
@ -1272,7 +1272,7 @@ func TestHCLBuiltinVars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCombineHCLAndJSONTargets(t *testing.T) {
|
func TestCombineHCLAndJSONTargets(t *testing.T) {
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{
|
{
|
||||||
Name: "docker-bake.hcl",
|
Name: "docker-bake.hcl",
|
||||||
Data: []byte(`
|
Data: []byte(`
|
||||||
@ -1348,7 +1348,7 @@ target "b" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCombineHCLAndJSONVars(t *testing.T) {
|
func TestCombineHCLAndJSONVars(t *testing.T) {
|
||||||
c, err := ParseFiles([]File{
|
c, _, err := ParseFiles([]File{
|
||||||
{
|
{
|
||||||
Name: "docker-bake.hcl",
|
Name: "docker-bake.hcl",
|
||||||
Data: []byte(`
|
Data: []byte(`
|
||||||
|
@ -25,9 +25,11 @@ type Opt struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type variable struct {
|
type variable struct {
|
||||||
Name string `json:"-" hcl:"name,label"`
|
Name string `json:"-" hcl:"name,label"`
|
||||||
Default *hcl.Attribute `json:"default,omitempty" hcl:"default,optional"`
|
Default *hcl.Attribute `json:"default,omitempty" hcl:"default,optional"`
|
||||||
Body hcl.Body `json:"-" hcl:",body"`
|
Description string `json:"description,omitempty" hcl:"description,optional"`
|
||||||
|
Body hcl.Body `json:"-" hcl:",body"`
|
||||||
|
Remain hcl.Body `json:"-" hcl:",remain"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type functionDef struct {
|
type functionDef struct {
|
||||||
@ -534,7 +536,18 @@ func (p *parser) resolveBlockNames(block *hcl.Block) ([]string, error) {
|
|||||||
return names, nil
|
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{}{}
|
reserved := map[string]struct{}{}
|
||||||
schema, _ := gohcl.ImpliedBodySchema(val)
|
schema, _ := gohcl.ImpliedBodySchema(val)
|
||||||
|
|
||||||
@ -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 {
|
for k := range p.vars {
|
||||||
if err := p.resolveValue(p.ectx, k); err != nil {
|
if err := p.resolveValue(p.ectx, k); err != nil {
|
||||||
if diags, ok := err.(hcl.Diagnostics); ok {
|
if diags, ok := err.(hcl.Diagnostics); ok {
|
||||||
@ -651,6 +665,21 @@ func Parse(b hcl.Body, opt Opt, val interface{}) (map[string]map[string][]string
|
|||||||
r := p.vars[k].Body.MissingItemRange()
|
r := p.vars[k].Body.MissingItemRange()
|
||||||
return nil, wrapErrorDiagnostic("Invalid value", err, &r, &r)
|
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 {
|
for k := range p.funcs {
|
||||||
@ -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.
|
// wrapErrorDiagnostic wraps an error into a hcl.Diagnostics object.
|
||||||
|
@ -111,21 +111,19 @@ func (mb mergedBodies) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
|
|||||||
diags = append(diags, thisDiags...)
|
diags = append(diags, thisDiags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if thisAttrs != nil {
|
for name, attr := range thisAttrs {
|
||||||
for name, attr := range thisAttrs {
|
if existing := attrs[name]; existing != nil {
|
||||||
if existing := attrs[name]; existing != nil {
|
diags = diags.Append(&hcl.Diagnostic{
|
||||||
diags = diags.Append(&hcl.Diagnostic{
|
Severity: hcl.DiagError,
|
||||||
Severity: hcl.DiagError,
|
Summary: "Duplicate argument",
|
||||||
Summary: "Duplicate argument",
|
Detail: fmt.Sprintf(
|
||||||
Detail: fmt.Sprintf(
|
"Argument %q was already set at %s",
|
||||||
"Argument %q was already set at %s",
|
name, existing.NameRange.String(),
|
||||||
name, existing.NameRange.String(),
|
),
|
||||||
),
|
Subject: thisAttrs[name].NameRange.Ptr(),
|
||||||
Subject: thisAttrs[name].NameRange.Ptr(),
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
attrs[name] = attr
|
|
||||||
}
|
}
|
||||||
|
attrs[name] = attr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/platforms"
|
"github.com/containerd/platforms"
|
||||||
"github.com/docker/buildx/bake"
|
"github.com/docker/buildx/bake"
|
||||||
|
"github.com/docker/buildx/bake/hclparser"
|
||||||
"github.com/docker/buildx/build"
|
"github.com/docker/buildx/build"
|
||||||
"github.com/docker/buildx/builder"
|
"github.com/docker/buildx/builder"
|
||||||
"github.com/docker/buildx/controller/pb"
|
"github.com/docker/buildx/controller/pb"
|
||||||
@ -39,6 +40,7 @@ type bakeOptions struct {
|
|||||||
overrides []string
|
overrides []string
|
||||||
printOnly bool
|
printOnly bool
|
||||||
listTargets bool
|
listTargets bool
|
||||||
|
listVars bool
|
||||||
sbom string
|
sbom string
|
||||||
provenance string
|
provenance string
|
||||||
|
|
||||||
@ -161,19 +163,19 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
if progressMode != progressui.QuietMode && progressMode != progressui.RawJSONMode {
|
||||||
if progressMode != progressui.QuietMode && progressMode != progressui.RawJSONMode {
|
desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term)
|
||||||
desktop.PrintBuildDetails(os.Stderr, printer.BuildRefs(), term)
|
|
||||||
}
|
|
||||||
if resp != nil && len(in.metadataFile) > 0 {
|
|
||||||
dt := make(map[string]interface{})
|
|
||||||
for t, r := range resp {
|
|
||||||
dt[t] = decodeExporterResponse(r.ExporterResponse)
|
|
||||||
}
|
}
|
||||||
if warnings := printer.Warnings(); len(warnings) > 0 && confutil.MetadataWarningsEnabled() {
|
if resp != nil && len(in.metadataFile) > 0 {
|
||||||
dt["buildx.build.warnings"] = warnings
|
dt := make(map[string]interface{})
|
||||||
|
for t, r := range resp {
|
||||||
|
dt[t] = decodeExporterResponse(r.ExporterResponse)
|
||||||
|
}
|
||||||
|
if warnings := printer.Warnings(); len(warnings) > 0 && confutil.MetadataWarningsEnabled() {
|
||||||
|
dt["buildx.build.warnings"] = warnings
|
||||||
|
}
|
||||||
|
err = writeMetadataFile(in.metadataFile, dt)
|
||||||
}
|
}
|
||||||
err = writeMetadataFile(in.metadataFile, dt)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -193,8 +195,8 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
|||||||
"BAKE_LOCAL_PLATFORM": platforms.Format(platforms.DefaultSpec()),
|
"BAKE_LOCAL_PLATFORM": platforms.Format(platforms.DefaultSpec()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if in.listTargets {
|
if in.listTargets || in.listVars {
|
||||||
cfg, err := bake.ParseFiles(files, defaults)
|
cfg, pm, err := bake.ParseFiles(files, defaults)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -204,7 +206,11 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return printTargetList(dockerCli.Out(), cfg)
|
if in.listTargets {
|
||||||
|
return printTargetList(dockerCli.Out(), cfg)
|
||||||
|
} else if in.listVars {
|
||||||
|
return printVars(dockerCli.Out(), pm.AllVariables)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tgts, grps, err := bake.ReadTargets(ctx, files, targets, overrides, defaults)
|
tgts, grps, err := bake.ReadTargets(ctx, files, targets, overrides, defaults)
|
||||||
@ -439,6 +445,7 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
|
|||||||
flags.BoolVar(&options.exportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`)
|
flags.BoolVar(&options.exportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`)
|
||||||
flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
|
flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
|
||||||
flags.BoolVar(&options.listTargets, "list-targets", false, "List available targets")
|
flags.BoolVar(&options.listTargets, "list-targets", false, "List available targets")
|
||||||
|
flags.BoolVar(&options.listVars, "list-variables", false, "List defined variables")
|
||||||
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`)
|
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`)
|
||||||
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
|
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
|
||||||
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
|
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
|
||||||
@ -503,6 +510,27 @@ func readBakeFiles(ctx context.Context, nodes []builder.Node, url string, names
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printVars(w io.Writer, vars []*hclparser.Variable) error {
|
||||||
|
slices.SortFunc(vars, func(a, b *hclparser.Variable) int {
|
||||||
|
return cmp.Compare(a.Name, b.Name)
|
||||||
|
})
|
||||||
|
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
|
||||||
|
defer tw.Flush()
|
||||||
|
|
||||||
|
tw.Write([]byte("VARIABLE\tVALUE\tDESCRIPTION\n"))
|
||||||
|
|
||||||
|
for _, v := range vars {
|
||||||
|
var value string
|
||||||
|
if v.Value != nil {
|
||||||
|
value = *v.Value
|
||||||
|
} else {
|
||||||
|
value = "<null>"
|
||||||
|
}
|
||||||
|
fmt.Fprintf(tw, "%s\t%s\t%s\n", v.Name, value, v.Description)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func printTargetList(w io.Writer, cfg *bake.Config) error {
|
func printTargetList(w io.Writer, cfg *bake.Config) error {
|
||||||
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
|
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
|
||||||
defer tw.Flush()
|
defer tw.Flush()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user