From 8d3db9c1e12aa99afca212428ab1a1c98306f035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Wed, 17 Apr 2024 01:20:14 +0200 Subject: [PATCH] cli: Add JSON output option for pull --check & compare This will make it easier for other higher level tools (Plasma Discover for example) to read the output of those commands. --- lib/src/cli.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/src/cli.rs b/lib/src/cli.rs index af78d3dd..5de38481 100644 --- a/lib/src/cli.rs +++ b/lib/src/cli.rs @@ -10,10 +10,11 @@ use camino::{Utf8Path, Utf8PathBuf}; use cap_std::fs::Dir; use cap_std_ext::cap_std; use cap_std_ext::prelude::CapStdExtDirExt; -use clap::{Parser, Subcommand}; +use clap::{builder::ArgPredicate, Parser, Subcommand}; use fn_error_context::context; use io_lifetimes::AsFd; use ostree::{gio, glib}; +use serde_json; use std::borrow::Cow; use std::collections::BTreeMap; use std::ffi::OsString; @@ -178,6 +179,10 @@ pub(crate) enum ContainerOpts { /// Image reference, e.g. ostree-remote-image:someremote:registry:quay.io/exampleos/exampleos:latest #[clap(value_parser = parse_imgref)] imgref_new: OstreeImageReference, + + /// Use JSON as output format. + #[clap(long)] + json: bool, }, } @@ -234,6 +239,10 @@ pub(crate) enum ContainerImageOpts { /// the new manifest. #[clap(long)] check: Option, + + /// Use JSON as output format. Only applies to the --check option. + #[clap(long, requires_if(ArgPredicate::IsPresent, "check"))] + json: bool, }, /// Output metadata about an already stored container image. @@ -717,6 +726,7 @@ async fn container_store( proxyopts: ContainerProxyOpts, quiet: bool, check: Option, + json: bool, ) -> Result<()> { let mut imp = ImageImporter::new(repo, imgref, proxyopts.into()).await?; let prep = match imp.prepare().await? { @@ -739,7 +749,11 @@ async fn container_store( } if let Some(previous_state) = prep.previous_state.as_ref() { let diff = ManifestDiff::new(&previous_state.manifest, &prep.manifest); - diff.print(); + if json { + println!("{:#?}", serde_json::to_string(&diff)); + } else { + diff.print(); + } } print_layer_status(&prep); let printer = (!quiet).then(|| { @@ -965,9 +979,10 @@ async fn run_from_opt(opt: Opt) -> Result<()> { proxyopts, quiet, check, + json, } => { let repo = parse_repo(&repo)?; - container_store(&repo, &imgref, proxyopts, quiet, check).await + container_store(&repo, &imgref, proxyopts, quiet, check, json).await } ContainerImageOpts::History { repo, imgref } => { let repo = parse_repo(&repo)?; @@ -1177,12 +1192,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> { ContainerOpts::Compare { imgref_old, imgref_new, + json, } => { let (manifest_old, _) = crate::container::fetch_manifest(&imgref_old).await?; let (manifest_new, _) = crate::container::fetch_manifest(&imgref_new).await?; let manifest_diff = crate::container::ManifestDiff::new(&manifest_old, &manifest_new); - manifest_diff.print(); + if json { + println!("{:#?}", serde_json::to_string(&manifest_diff)); + } else { + manifest_diff.print(); + } Ok(()) } },