diff --git a/docs/src/man/bootc-status.md b/docs/src/man/bootc-status.md index f6807ca09..de2442972 100644 --- a/docs/src/man/bootc-status.md +++ b/docs/src/man/bootc-status.md @@ -4,7 +4,7 @@ bootc-status - Display status # SYNOPSIS -**bootc status** \[**\--json**\] \[**\--booted**\] +**bootc status** \[**\--format**\] \[**\--booted**\] \[**-h**\|**\--help**\] # DESCRIPTION @@ -19,9 +19,16 @@ The exact API format is not currently declared stable. # OPTIONS -**\--json** +**\--format**=*FORMAT* -: Output in JSON format +: The output format\ + +\ +*Possible values:* + +> - yaml: Output in YAML format +> +> - json: Output in JSON format **\--booted** diff --git a/lib/src/cli.rs b/lib/src/cli.rs index 360b499eb..7346b2472 100644 --- a/lib/src/cli.rs +++ b/lib/src/cli.rs @@ -12,6 +12,7 @@ use camino::Utf8PathBuf; use cap_std_ext::cap_std; use cap_std_ext::cap_std::fs::Dir; use clap::Parser; +use clap::ValueEnum; use fn_error_context::context; use ostree::gio; use ostree_container::store::PrepareResult; @@ -107,13 +108,28 @@ pub(crate) struct EditOpts { pub(crate) quiet: bool, } +#[derive(Debug, Clone, ValueEnum, PartialEq, Eq)] +#[clap(rename_all = "lowercase")] +pub(crate) enum OutputFormat { + /// Output in YAML format. + YAML, + /// Output in JSON format. + JSON, +} + /// Perform an status operation #[derive(Debug, Parser, PartialEq, Eq)] pub(crate) struct StatusOpts { /// Output in JSON format. - #[clap(long)] + /// + /// Superceded by the `format` option. + #[clap(long, hide = true)] pub(crate) json: bool, + /// The output format. + #[clap(long)] + pub(crate) format: Option, + /// Only display status for the booted deployment. #[clap(long)] pub(crate) booted: bool, @@ -773,6 +789,7 @@ fn test_parse_opts() { Opt::parse_including_static(["bootc", "status"]), Opt::Status(StatusOpts { json: false, + format: None, booted: false }) )); diff --git a/lib/src/status.rs b/lib/src/status.rs index 009ecea37..c64a05594 100644 --- a/lib/src/status.rs +++ b/lib/src/status.rs @@ -12,6 +12,7 @@ use ostree_ext::oci_spec::image::ImageConfiguration; use ostree_ext::ostree; use ostree_ext::sysroot::SysrootLock; +use crate::cli::OutputFormat; use crate::spec::{BootEntry, BootOrder, Host, HostSpec, HostStatus, HostType, ImageStatus}; use crate::spec::{ImageReference, ImageSignature}; @@ -317,11 +318,18 @@ pub(crate) async fn status(opts: super::cli::StatusOpts) -> Result<()> { // Filter to just the serializable status structures. let out = std::io::stdout(); let mut out = out.lock(); - if opts.json { - serde_json::to_writer(&mut out, &host).context("Writing to stdout")?; - } else { - serde_yaml::to_writer(&mut out, &host).context("Writing to stdout")?; + let format = opts.format.unwrap_or_else(|| { + if opts.json { + OutputFormat::JSON + } else { + OutputFormat::YAML + } + }); + match format { + OutputFormat::JSON => serde_json::to_writer(&mut out, &host).map_err(anyhow::Error::new), + OutputFormat::YAML => serde_yaml::to_writer(&mut out, &host).map_err(anyhow::Error::new), } + .context("Writing to stdout")?; Ok(()) } diff --git a/tests/booted/001-test-status.nu b/tests/booted/001-test-status.nu index 49ce8c469..0d7d559cf 100644 --- a/tests/booted/001-test-status.nu +++ b/tests/booted/001-test-status.nu @@ -1,8 +1,10 @@ use std assert use tap.nu -tap begin "verify bootc status --json looks sane" +tap begin "verify bootc status output formats" let st = bootc status --json | from json assert equal $st.apiVersion org.containers.bootc/v1alpha1 +let st = bootc status --format=yaml | from yaml +assert equal $st.apiVersion org.containers.bootc/v1alpha1 tap ok