1
1
use std:: collections:: { BTreeMap , BTreeSet } ;
2
2
3
+ use clap:: builder:: PossibleValue ;
3
4
use clap:: { Args , Subcommand } ;
4
5
use cross:: docker:: { self , CROSS_CUSTOM_DOCKERFILE_IMAGE_PREFIX } ;
5
6
use cross:: shell:: MessageInfo ;
@@ -26,6 +27,9 @@ pub struct ListImages {
26
27
/// Container engine (such as docker or podman).
27
28
#[ clap( long) ]
28
29
pub engine : Option < String > ,
30
+ /// Output format
31
+ #[ clap( long, default_value = "human" ) ]
32
+ pub format : OutputFormat ,
29
33
/// Only list images for specific target(s). By default, list all targets.
30
34
pub targets : Vec < String > ,
31
35
}
@@ -36,6 +40,25 @@ impl ListImages {
36
40
}
37
41
}
38
42
43
+ #[ derive( Clone , Debug ) ]
44
+ pub enum OutputFormat {
45
+ Human ,
46
+ Json ,
47
+ }
48
+
49
+ impl clap:: ValueEnum for OutputFormat {
50
+ fn value_variants < ' a > ( ) -> & ' a [ Self ] {
51
+ & [ Self :: Human , Self :: Json ]
52
+ }
53
+
54
+ fn to_possible_value ( & self ) -> Option < PossibleValue > {
55
+ match self {
56
+ OutputFormat :: Human => Some ( PossibleValue :: new ( "human" ) ) ,
57
+ OutputFormat :: Json => Some ( PossibleValue :: new ( "json" ) ) ,
58
+ }
59
+ }
60
+ }
61
+
39
62
#[ derive( Args , Debug ) ]
40
63
pub struct RemoveImages {
41
64
/// If not provided, remove all images.
@@ -118,7 +141,7 @@ impl Images {
118
141
}
119
142
}
120
143
121
- #[ derive( Debug , PartialOrd , Ord , PartialEq , Eq ) ]
144
+ #[ derive( Debug , PartialOrd , Ord , PartialEq , Eq , serde :: Serialize ) ]
122
145
struct Image {
123
146
repository : String ,
124
147
tag : String ,
@@ -258,7 +281,9 @@ fn get_image_target(
258
281
}
259
282
260
283
pub fn list_images (
261
- ListImages { targets, .. } : ListImages ,
284
+ ListImages {
285
+ targets, format, ..
286
+ } : ListImages ,
262
287
engine : & docker:: Engine ,
263
288
msg_info : & mut MessageInfo ,
264
289
) -> cross:: Result < ( ) > {
@@ -281,45 +306,55 @@ pub fn list_images(
281
306
let mut keys: Vec < & str > = map. keys ( ) . map ( |k| k. as_ref ( ) ) . collect ( ) ;
282
307
keys. sort_unstable ( ) ;
283
308
284
- let print_string =
285
- |col1 : & str , col2 : & str , fill : char , info : & mut MessageInfo | -> cross:: Result < ( ) > {
286
- let mut row = String :: new ( ) ;
287
- row. push ( '|' ) ;
288
- row. push ( fill) ;
289
- row. push_str ( col1) ;
290
- let spaces = max_target_len. max ( col1. len ( ) ) + 1 - col1. len ( ) ;
291
- for _ in 0 ..spaces {
292
- row. push ( fill) ;
293
- }
294
- row. push ( '|' ) ;
295
- row. push ( fill) ;
296
- row. push_str ( col2) ;
297
- let spaces = max_image_len. max ( col2. len ( ) ) + 1 - col2. len ( ) ;
298
- for _ in 0 ..spaces {
299
- row. push ( fill) ;
309
+ match format {
310
+ OutputFormat :: Json => {
311
+ msg_info. info ( format_args ! ( "{}" , serde_json:: to_string( & map) ?) ) ?;
312
+ }
313
+ OutputFormat :: Human => {
314
+ let print_string =
315
+ |col1 : & str , col2 : & str , fill : char , info : & mut MessageInfo | -> cross:: Result < ( ) > {
316
+ let mut row = String :: new ( ) ;
317
+ row. push ( '|' ) ;
318
+ row. push ( fill) ;
319
+ row. push_str ( col1) ;
320
+ let spaces = max_target_len. max ( col1. len ( ) ) + 1 - col1. len ( ) ;
321
+ for _ in 0 ..spaces {
322
+ row. push ( fill) ;
323
+ }
324
+ row. push ( '|' ) ;
325
+ row. push ( fill) ;
326
+ row. push_str ( col2) ;
327
+ let spaces = max_image_len. max ( col2. len ( ) ) + 1 - col2. len ( ) ;
328
+ for _ in 0 ..spaces {
329
+ row. push ( fill) ;
330
+ }
331
+ row. push ( '|' ) ;
332
+ info. print ( row)
333
+ } ;
334
+
335
+ if targets. len ( ) != 1 {
336
+ print_string ( "Targets" , "Images" , ' ' , msg_info) ?;
337
+ print_string ( "-------" , "------" , '-' , msg_info) ?;
300
338
}
301
- row. push ( '|' ) ;
302
- info. print ( row)
303
- } ;
304
-
305
- if targets. len ( ) != 1 {
306
- print_string ( "Targets" , "Images" , ' ' , msg_info) ?;
307
- print_string ( "-------" , "------" , '-' , msg_info) ?;
308
- }
309
339
310
- let print_single =
311
- |_: & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > { info. print ( image) } ;
312
- let print_table = |target : & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > {
313
- let name = image. name ( ) ;
314
- print_string ( target, & name, ' ' , info)
315
- } ;
316
-
317
- for target in keys {
318
- for image in map. get ( target) . expect ( "map must have key" ) . iter ( ) {
319
- if targets. len ( ) == 1 {
320
- print_single ( target, image, msg_info) ?;
321
- } else {
322
- print_table ( target, image, msg_info) ?;
340
+ let print_single = |_: & str ,
341
+ image : & Image ,
342
+ info : & mut MessageInfo |
343
+ -> cross:: Result < ( ) > { info. print ( image) } ;
344
+ let print_table =
345
+ |target : & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > {
346
+ let name = image. name ( ) ;
347
+ print_string ( target, & name, ' ' , info)
348
+ } ;
349
+
350
+ for target in keys {
351
+ for image in map. get ( target) . expect ( "map must have key" ) . iter ( ) {
352
+ if targets. len ( ) == 1 {
353
+ print_single ( target, image, msg_info) ?;
354
+ } else {
355
+ print_table ( target, image, msg_info) ?;
356
+ }
357
+ }
323
358
}
324
359
}
325
360
}
0 commit comments