@@ -3,6 +3,7 @@ package history
3
3
import (
4
4
"context"
5
5
"io"
6
+ "maps"
6
7
"os"
7
8
"slices"
8
9
@@ -14,14 +15,16 @@ import (
14
15
"github.com/docker/buildx/util/confutil"
15
16
"github.com/docker/buildx/util/desktop/bundle"
16
17
"github.com/docker/cli/cli/command"
18
+ "github.com/moby/buildkit/client"
17
19
"github.com/pkg/errors"
18
20
"github.com/spf13/cobra"
19
21
)
20
22
21
23
type exportOptions struct {
22
24
builder string
23
- ref string
25
+ refs [] string
24
26
output string
27
+ all bool
25
28
}
26
29
27
30
func runExport (ctx context.Context , dockerCli command.Cli , opts exportOptions ) error {
@@ -40,40 +43,56 @@ func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) e
40
43
}
41
44
}
42
45
43
- recs , err := queryRecords (ctx , opts .ref , nodes , & queryOptions {
44
- CompletedOnly : true ,
45
- })
46
- if err != nil {
47
- return err
46
+ if len (opts .refs ) == 0 {
47
+ opts .refs = []string {"" }
48
48
}
49
49
50
- if len (recs ) == 0 {
51
- if opts .ref == "" {
52
- return errors .New ("no records found" )
50
+ var res []historyRecord
51
+ for _ , ref := range opts .refs {
52
+ recs , err := queryRecords (ctx , ref , nodes , & queryOptions {
53
+ CompletedOnly : true ,
54
+ })
55
+ if err != nil {
56
+ return err
53
57
}
54
- return errors .Errorf ("no record found for ref %q" , opts .ref )
55
- }
56
58
57
- if opts .ref == "" {
58
- slices .SortFunc (recs , func (a , b historyRecord ) int {
59
- return b .CreatedAt .AsTime ().Compare (a .CreatedAt .AsTime ())
60
- })
61
- }
59
+ if len (recs ) == 0 {
60
+ if ref == "" {
61
+ return errors .New ("no records found" )
62
+ }
63
+ return errors .Errorf ("no record found for ref %q" , ref )
64
+ }
62
65
63
- recs = recs [:1 ]
66
+ if ref == "" {
67
+ slices .SortFunc (recs , func (a , b historyRecord ) int {
68
+ return b .CreatedAt .AsTime ().Compare (a .CreatedAt .AsTime ())
69
+ })
70
+ }
71
+
72
+ if opts .all {
73
+ res = append (res , recs ... )
74
+ break
75
+ } else {
76
+ res = append (res , recs [0 ])
77
+ }
78
+ }
64
79
65
80
ls , err := localstate .New (confutil .NewConfig (dockerCli ))
66
81
if err != nil {
67
82
return err
68
83
}
69
84
70
- c , err := recs [0 ].node .Driver .Client (ctx )
71
- if err != nil {
72
- return err
85
+ clients := map [* client.Client ]struct {}{}
86
+ for _ , rec := range res {
87
+ c , err := rec .node .Driver .Client (ctx )
88
+ if err != nil {
89
+ return err
90
+ }
91
+ clients [c ] = struct {}{}
73
92
}
74
93
75
- toExport := make ([]* bundle.Record , 0 , len (recs ))
76
- for _ , rec := range recs {
94
+ toExport := make ([]* bundle.Record , 0 , len (res ))
95
+ for _ , rec := range res {
77
96
var defaultPlatform string
78
97
if p := rec .node .Platforms ; len (p ) > 0 {
79
98
defaultPlatform = platforms .FormatAll (platforms .Normalize (p [0 ]))
@@ -110,7 +129,7 @@ func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) e
110
129
}
111
130
}
112
131
113
- return bundle .Export (ctx , c , w , toExport )
132
+ return bundle .Export (ctx , maps . Keys ( clients ) , w , toExport )
114
133
}
115
134
116
135
func exportCmd (dockerCli command.Cli , rootOpts RootOptions ) * cobra.Command {
@@ -119,11 +138,11 @@ func exportCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
119
138
cmd := & cobra.Command {
120
139
Use : "export [OPTIONS] [REF]" ,
121
140
Short : "Export a build into Docker Desktop bundle" ,
122
- Args : cobra .MaximumNArgs (1 ),
123
141
RunE : func (cmd * cobra.Command , args []string ) error {
124
- if len (args ) > 0 {
125
- options . ref = args [ 0 ]
142
+ if options . all && len (args ) > 0 {
143
+ return errors . New ( "cannot specify refs when using --all" )
126
144
}
145
+ options .refs = args
127
146
options .builder = * rootOpts .Builder
128
147
return runExport (cmd .Context (), dockerCli , options )
129
148
},
@@ -132,6 +151,7 @@ func exportCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
132
151
133
152
flags := cmd .Flags ()
134
153
flags .StringVarP (& options .output , "output" , "o" , "" , "Output file path" )
154
+ flags .BoolVar (& options .all , "all" , false , "Export all records for the builder" )
135
155
136
156
return cmd
137
157
}
0 commit comments