@@ -36,7 +36,8 @@ const (
3636)
3737
3838type lsOptions struct {
39- format string
39+ format string
40+ noTrunc bool
4041}
4142
4243func runLs (dockerCli command.Cli , in lsOptions ) error {
@@ -75,7 +76,7 @@ func runLs(dockerCli command.Cli, in lsOptions) error {
7576 return err
7677 }
7778
78- if hasErrors , err := lsPrint (dockerCli , current , builders , in . format ); err != nil {
79+ if hasErrors , err := lsPrint (dockerCli , current , builders , in ); err != nil {
7980 return err
8081 } else if hasErrors {
8182 _ , _ = fmt .Fprintf (dockerCli .Err (), "\n " )
@@ -110,21 +111,23 @@ func lsCmd(dockerCli command.Cli) *cobra.Command {
110111
111112 flags := cmd .Flags ()
112113 flags .StringVar (& options .format , "format" , formatter .TableFormatKey , "Format the output" )
114+ flags .BoolVar (& options .noTrunc , "no-trunc" , false , "Don't truncate output" )
113115
114116 // hide builder persistent flag for this command
115117 cobrautil .HideInheritedFlags (cmd , "builder" )
116118
117119 return cmd
118120}
119121
120- func lsPrint (dockerCli command.Cli , current * store.NodeGroup , builders []* builder.Builder , format string ) (hasErrors bool , _ error ) {
121- if format == formatter .TableFormatKey {
122- format = lsDefaultTableFormat
122+ func lsPrint (dockerCli command.Cli , current * store.NodeGroup , builders []* builder.Builder , in lsOptions ) (hasErrors bool , _ error ) {
123+ if in . format == formatter .TableFormatKey {
124+ in . format = lsDefaultTableFormat
123125 }
124126
125127 ctx := formatter.Context {
126128 Output : dockerCli .Out (),
127- Format : formatter .Format (format ),
129+ Format : formatter .Format (in .format ),
130+ Trunc : ! in .noTrunc ,
128131 }
129132
130133 sort .SliceStable (builders , func (i , j int ) bool {
@@ -141,11 +144,12 @@ func lsPrint(dockerCli command.Cli, current *store.NodeGroup, builders []*builde
141144 render := func (format func (subContext formatter.SubContext ) error ) error {
142145 for _ , b := range builders {
143146 if err := format (& lsContext {
147+ format : ctx .Format ,
148+ trunc : ctx .Trunc ,
144149 Builder : & lsBuilder {
145150 Builder : b ,
146151 Current : b .Name == current .Name ,
147152 },
148- format : ctx .Format ,
149153 }); err != nil {
150154 return err
151155 }
@@ -163,6 +167,7 @@ func lsPrint(dockerCli command.Cli, current *store.NodeGroup, builders []*builde
163167 }
164168 if err := format (& lsContext {
165169 format : ctx .Format ,
170+ trunc : ctx .Trunc ,
166171 Builder : & lsBuilder {
167172 Builder : b ,
168173 Current : b .Name == current .Name ,
@@ -199,6 +204,7 @@ type lsContext struct {
199204 Builder * lsBuilder
200205
201206 format formatter.Format
207+ trunc bool
202208 node builder.Node
203209}
204210
@@ -264,7 +270,17 @@ func (c *lsContext) Platforms() string {
264270 if c .node .Name == "" {
265271 return ""
266272 }
267- return strings .Join (platformutil .FormatInGroups (c .node .Node .Platforms , c .node .Platforms ), ", " )
273+ platforms := platformutil .FormatInGroups (c .node .Node .Platforms , c .node .Platforms )
274+ if c .trunc && c .format .IsTable () {
275+ tplatforms := truncPlatforms (platforms , 4 )
276+ left := len (platforms ) - len (tplatforms )
277+ out := strings .Join (tplatforms , ", " )
278+ if left > 0 {
279+ out += fmt .Sprintf (", (+%d)" , left )
280+ }
281+ return out
282+ }
283+ return strings .Join (platforms , ", " )
268284}
269285
270286func (c * lsContext ) Error () string {
@@ -275,3 +291,51 @@ func (c *lsContext) Error() string {
275291 }
276292 return ""
277293}
294+
295+ func truncPlatforms (platforms []string , max int ) []string {
296+ majorPlatforms := map [string ]struct {}{
297+ "linux/amd64" : {},
298+ "linux/arm64" : {},
299+ "linux/arm/v7" : {},
300+ "linux/mips64" : {},
301+ "linux/ppc64le" : {},
302+ "linux/riscv64" : {},
303+ "linux/s390x" : {},
304+ }
305+ var res []string
306+ var left []string
307+ m := map [string ]struct {}{}
308+ for _ , p := range platforms {
309+ if len (res ) >= max {
310+ break
311+ }
312+ pp := strings .TrimSuffix (p , "*" )
313+ if _ , ok := m [pp ]; ok {
314+ continue
315+ }
316+ if _ , ok := majorPlatforms [pp ]; ok {
317+ res = append (res , p )
318+ m [pp ] = struct {}{}
319+ } else {
320+ left = append (left , p )
321+ }
322+ }
323+ if len (left ) > 0 && len (res ) < max {
324+ cl := max - len (res )
325+ if cl > len (left ) {
326+ cl = len (left )
327+ }
328+ res = append (res , left [:cl ]... )
329+ }
330+ sort .SliceStable (res , func (i , j int ) bool {
331+ ipref := strings .HasSuffix (res [i ], "*" )
332+ jpref := strings .HasSuffix (res [j ], "*" )
333+ if ipref && ! jpref {
334+ return true
335+ } else if ! ipref && jpref {
336+ return false
337+ }
338+ return i < j
339+ })
340+ return res
341+ }
0 commit comments