Skip to content

Commit 11c85b2

Browse files
committed
bake: list flag json format support
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 4121583 commit 11c85b2

File tree

2 files changed

+98
-17
lines changed

2 files changed

+98
-17
lines changed

bake/hclparser/hclparser.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,9 @@ func (p *parser) validateVariables(vars map[string]*variable, ectx *hcl.EvalCont
579579
}
580580

581581
type Variable struct {
582-
Name string
583-
Description string
584-
Value *string
582+
Name string `json:"name"`
583+
Description string `json:"description,omitempty"`
584+
Value *string `json:"value,omitempty"`
585585
}
586586

587587
type ParseMeta struct {

commands/bake.go

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/moby/buildkit/util/progress/progressui"
3838
"github.com/pkg/errors"
3939
"github.com/spf13/cobra"
40+
"github.com/tonistiigi/go-csvvalue"
4041
"go.opentelemetry.io/otel/attribute"
4142
)
4243

@@ -200,13 +201,15 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
200201
if err = printer.Wait(); err != nil {
201202
return err
202203
}
203-
switch in.list {
204+
list, err := parseList(in.list)
205+
if err != nil {
206+
return err
207+
}
208+
switch list.Type {
204209
case "targets":
205-
return printTargetList(dockerCli.Out(), cfg)
210+
return printTargetList(dockerCli.Out(), list.Format, cfg)
206211
case "variables":
207-
return printVars(dockerCli.Out(), pm.AllVariables)
208-
default:
209-
return errors.Errorf("invalid list mode %q", in.list)
212+
return printVars(dockerCli.Out(), list.Format, pm.AllVariables)
210213
}
211214
}
212215

@@ -577,10 +580,70 @@ func readBakeFiles(ctx context.Context, nodes []builder.Node, url string, names
577580
return
578581
}
579582

580-
func printVars(w io.Writer, vars []*hclparser.Variable) error {
583+
type listEntry struct {
584+
Type string
585+
Format string
586+
}
587+
588+
func parseList(input string) (listEntry, error) {
589+
res := listEntry{}
590+
591+
fields, err := csvvalue.Fields(input, nil)
592+
if err != nil {
593+
return res, err
594+
}
595+
596+
if len(fields) == 1 && fields[0] == input && !strings.HasPrefix(input, "type=") {
597+
res.Type = input
598+
}
599+
600+
if res.Type == "" {
601+
for _, field := range fields {
602+
key, value, ok := strings.Cut(field, "=")
603+
if !ok {
604+
return res, errors.Errorf("invalid value %s", field)
605+
}
606+
key = strings.TrimSpace(strings.ToLower(key))
607+
switch key {
608+
case "type":
609+
res.Type = value
610+
case "format":
611+
res.Format = value
612+
default:
613+
return res, errors.Errorf("unexpected key '%s' in '%s'", key, field)
614+
}
615+
}
616+
}
617+
if res.Format == "" {
618+
res.Format = "table"
619+
}
620+
621+
switch res.Type {
622+
case "targets", "variables":
623+
default:
624+
return res, errors.Errorf("invalid list type %q", res.Type)
625+
}
626+
627+
switch res.Format {
628+
case "table", "json":
629+
default:
630+
return res, errors.Errorf("invalid list format %q", res.Format)
631+
}
632+
633+
return res, nil
634+
}
635+
636+
func printVars(w io.Writer, format string, vars []*hclparser.Variable) error {
581637
slices.SortFunc(vars, func(a, b *hclparser.Variable) int {
582638
return cmp.Compare(a.Name, b.Name)
583639
})
640+
641+
if format == "json" {
642+
enc := json.NewEncoder(w)
643+
enc.SetIndent("", " ")
644+
return enc.Encode(vars)
645+
}
646+
584647
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
585648
defer tw.Flush()
586649

@@ -598,12 +661,7 @@ func printVars(w io.Writer, vars []*hclparser.Variable) error {
598661
return nil
599662
}
600663

601-
func printTargetList(w io.Writer, cfg *bake.Config) error {
602-
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
603-
defer tw.Flush()
604-
605-
tw.Write([]byte("TARGET\tDESCRIPTION\n"))
606-
664+
func printTargetList(w io.Writer, format string, cfg *bake.Config) error {
607665
type targetOrGroup struct {
608666
name string
609667
target *bake.Target
@@ -622,6 +680,20 @@ func printTargetList(w io.Writer, cfg *bake.Config) error {
622680
return cmp.Compare(a.name, b.name)
623681
})
624682

683+
var tw *tabwriter.Writer
684+
if format == "table" {
685+
tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
686+
defer tw.Flush()
687+
tw.Write([]byte("TARGET\tDESCRIPTION\n"))
688+
}
689+
690+
type targetList struct {
691+
Name string `json:"name"`
692+
Description string `json:"description,omitempty"`
693+
Group bool `json:"group,omitempty"`
694+
}
695+
var targetsList []targetList
696+
625697
for _, tgt := range list {
626698
if strings.HasPrefix(tgt.name, "_") {
627699
// convention for a private target
@@ -630,9 +702,9 @@ func printTargetList(w io.Writer, cfg *bake.Config) error {
630702
var descr string
631703
if tgt.target != nil {
632704
descr = tgt.target.Description
705+
targetsList = append(targetsList, targetList{Name: tgt.name, Description: descr})
633706
} else if tgt.group != nil {
634707
descr = tgt.group.Description
635-
636708
if len(tgt.group.Targets) > 0 {
637709
slices.Sort(tgt.group.Targets)
638710
names := strings.Join(tgt.group.Targets, ", ")
@@ -642,8 +714,17 @@ func printTargetList(w io.Writer, cfg *bake.Config) error {
642714
descr = names
643715
}
644716
}
717+
targetsList = append(targetsList, targetList{Name: tgt.name, Description: descr, Group: true})
718+
}
719+
if format == "table" {
720+
fmt.Fprintf(tw, "%s\t%s\n", tgt.name, descr)
645721
}
646-
fmt.Fprintf(tw, "%s\t%s\n", tgt.name, descr)
722+
}
723+
724+
if format == "json" {
725+
enc := json.NewEncoder(w)
726+
enc.SetIndent("", " ")
727+
return enc.Encode(targetsList)
647728
}
648729

649730
return nil

0 commit comments

Comments
 (0)