Skip to content

Commit 70a92e3

Browse files
committed
output cross images as json
1 parent 05c7284 commit 70a92e3

File tree

1 file changed

+73
-39
lines changed

1 file changed

+73
-39
lines changed

src/bin/commands/images.rs

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ pub struct ListImages {
2626
/// Container engine (such as docker or podman).
2727
#[clap(long)]
2828
pub engine: Option<String>,
29+
/// Output format
30+
#[clap(long, default_value = "human")]
31+
pub format: OutputFormat,
2932
/// Only list images for specific target(s). By default, list all targets.
3033
pub targets: Vec<String>,
3134
}
@@ -36,6 +39,25 @@ impl ListImages {
3639
}
3740
}
3841

42+
#[derive(Clone, Debug)]
43+
pub enum OutputFormat {
44+
Human,
45+
Json,
46+
}
47+
48+
impl clap::ValueEnum for OutputFormat {
49+
fn value_variants<'a>() -> &'a [Self] {
50+
&[Self::Human, Self::Json]
51+
}
52+
53+
fn to_possible_value<'a>(&self) -> Option<clap::PossibleValue<'a>> {
54+
match self {
55+
OutputFormat::Human => Some(clap::PossibleValue::new("human")),
56+
OutputFormat::Json => Some(clap::PossibleValue::new("json")),
57+
}
58+
}
59+
}
60+
3961
#[derive(Args, Debug)]
4062
pub struct RemoveImages {
4163
/// If not provided, remove all images.
@@ -118,7 +140,7 @@ impl Images {
118140
}
119141
}
120142

121-
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
143+
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, serde::Serialize)]
122144
struct Image {
123145
repository: String,
124146
tag: String,
@@ -258,7 +280,9 @@ fn get_image_target(
258280
}
259281

260282
pub fn list_images(
261-
ListImages { targets, .. }: ListImages,
283+
ListImages {
284+
targets, format, ..
285+
}: ListImages,
262286
engine: &docker::Engine,
263287
msg_info: &mut MessageInfo,
264288
) -> cross::Result<()> {
@@ -281,45 +305,55 @@ pub fn list_images(
281305
let mut keys: Vec<&str> = map.keys().map(|k| k.as_ref()).collect();
282306
keys.sort_unstable();
283307

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);
308+
match format {
309+
OutputFormat::Json => {
310+
msg_info.info(format_args!("{}", serde_json::to_string(&map)?))?;
311+
}
312+
OutputFormat::Human => {
313+
let print_string =
314+
|col1: &str, col2: &str, fill: char, info: &mut MessageInfo| -> cross::Result<()> {
315+
let mut row = String::new();
316+
row.push('|');
317+
row.push(fill);
318+
row.push_str(col1);
319+
let spaces = max_target_len.max(col1.len()) + 1 - col1.len();
320+
for _ in 0..spaces {
321+
row.push(fill);
322+
}
323+
row.push('|');
324+
row.push(fill);
325+
row.push_str(col2);
326+
let spaces = max_image_len.max(col2.len()) + 1 - col2.len();
327+
for _ in 0..spaces {
328+
row.push(fill);
329+
}
330+
row.push('|');
331+
info.print(row)
332+
};
333+
334+
if targets.len() != 1 {
335+
print_string("Targets", "Images", ' ', msg_info)?;
336+
print_string("-------", "------", '-', msg_info)?;
300337
}
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-
}
309338

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)?;
339+
let print_single = |_: &str,
340+
image: &Image,
341+
info: &mut MessageInfo|
342+
-> cross::Result<()> { info.print(image) };
343+
let print_table =
344+
|target: &str, image: &Image, info: &mut MessageInfo| -> cross::Result<()> {
345+
let name = image.name();
346+
print_string(target, &name, ' ', info)
347+
};
348+
349+
for target in keys {
350+
for image in map.get(target).expect("map must have key").iter() {
351+
if targets.len() == 1 {
352+
print_single(target, image, msg_info)?;
353+
} else {
354+
print_table(target, image, msg_info)?;
355+
}
356+
}
323357
}
324358
}
325359
}

0 commit comments

Comments
 (0)