From 8858d71d28d68a0063f3ccab1fbf378d69afc78b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 16 Nov 2019 16:12:09 +0100 Subject: [PATCH 1/6] Put back output-format option for show-coverage --- src/librustdoc/config.rs | 59 +++++++++++++++++++++++++---- src/librustdoc/core.rs | 2 + src/librustdoc/html/render.rs | 3 +- src/librustdoc/html/render/cache.rs | 1 + 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 33b3e800374e3..99a55f3c68282 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -1,5 +1,6 @@ use std::collections::BTreeMap; use std::ffi::OsStr; +use std::convert::TryFrom; use std::fmt; use std::path::PathBuf; @@ -24,6 +25,33 @@ use crate::opts; use crate::passes::{self, Condition, DefaultPassOption}; use crate::theme; +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum OutputFormat { + Json, + HTML, +} + +impl OutputFormat { + pub fn is_json(&self) -> bool { + match *self { + OutputFormat::Json => true, + _ => false, + } + } +} + +impl TryFrom<&str> for OutputFormat { + type Error = String; + + fn try_from(value: &str) -> Result { + match value { + "json" => Ok(OutputFormat::Json), + "html" => Ok(OutputFormat::HTML), + _ => Err(format!("unknown output format `{}`", value)), + } + } +} + /// Configuration options for rustdoc. #[derive(Clone)] pub struct Options { @@ -115,6 +143,8 @@ pub struct Options { pub crate_version: Option, /// Collected options specific to outputting final pages. pub render_options: RenderOptions, + /// Output format rendering (used only for "show-coverage" option for the moment) + pub output_format: Option, } impl fmt::Debug for Options { @@ -425,14 +455,6 @@ impl Options { } } - match matches.opt_str("w").as_ref().map(|s| &**s) { - Some("html") | None => {} - Some(s) => { - diag.struct_err(&format!("unknown output format: {}", s)).emit(); - return Err(1); - } - } - let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s)); if let Some(ref index_page) = index_page { if !index_page.is_file() { @@ -469,6 +491,23 @@ impl Options { } }; + let output_format = match matches.opt_str("output-format") { + Some(s) => match OutputFormat::try_from(s.as_str()) { + Ok(o) => { + if o.is_json() && !show_coverage { + diag.struct_err("json output format isn't supported for doc generation") + .emit(); + return Err(1); + } + Some(o) + } + Err(e) => { + diag.struct_err(&e).emit(); + return Err(1); + } + } + None => None, + }; let crate_name = matches.opt_str("crate-name"); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); @@ -553,6 +592,7 @@ impl Options { generate_search_filter, generate_redirect_pages, }, + output_format, }) } @@ -568,6 +608,9 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for flag in deprecated_flags.iter() { if matches.opt_present(flag) { + if *flag == "output-format" && matches.opt_present("show-coverage") { + continue; + } let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated", flag)); err.warn( diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8bc34e949f175..b9ae3d53afc04 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -228,6 +228,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt mut manual_passes, display_warnings, render_options, + output_format, .. } = options; @@ -385,6 +386,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let mut renderinfo = RenderInfo::default(); renderinfo.access_levels = access_levels; + renderinfo.output_format = output_format; let mut ctxt = DocContext { tcx, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4dd2a6562a4cd..016054c688ddc 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -60,7 +60,7 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy}; -use crate::config::RenderOptions; +use crate::config::{OutputFormat, RenderOptions}; use crate::docfs::{DocFS, ErrorStorage, PathError}; use crate::doctree; use crate::html::escape::Escape; @@ -270,6 +270,7 @@ pub struct RenderInfo { pub deref_trait_did: Option, pub deref_mut_trait_did: Option, pub owned_box_did: Option, + pub output_format: Option, } // Helper structs for rendering items/sidebars and carrying along contextual diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index a0a35e4ce4b85..4198369eca8f5 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -139,6 +139,7 @@ impl Cache { deref_trait_did, deref_mut_trait_did, owned_box_did, + .. } = renderinfo; let external_paths = From 10492c392af127074d13593ae0dd5067286e8e15 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 16 Nov 2019 16:12:29 +0100 Subject: [PATCH 2/6] Add support for json output in show-coverage option --- .../passes/calculate_doc_coverage.rs | 67 ++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index d4a7f3313a49b..0ca5a956bdb69 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -1,4 +1,5 @@ use crate::clean; +use crate::config::OutputFormat; use crate::core::DocContext; use crate::fold::{self, DocFolder}; use crate::passes::Pass; @@ -6,6 +7,7 @@ use crate::passes::Pass; use rustc_ast::attr; use rustc_span::symbol::sym; use rustc_span::FileName; +use serialize::json::{ToJson, Json}; use std::collections::BTreeMap; use std::ops; @@ -16,8 +18,8 @@ pub const CALCULATE_DOC_COVERAGE: Pass = Pass { description: "counts the number of items with and without documentation", }; -fn calculate_doc_coverage(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate { - let mut calc = CoverageCalculator::default(); +fn calculate_doc_coverage( krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate { + let mut calc = CoverageCalculator::new(ctx.renderinfo.borrow().output_format); let krate = calc.fold_crate(krate); calc.print_results(); @@ -64,13 +66,72 @@ impl ops::AddAssign for ItemCount { } } -#[derive(Default)] struct CoverageCalculator { items: BTreeMap, + output_format: Option, +} + +fn limit_filename_len(filename: String) -> String { + // if a filename is too long, shorten it so we don't blow out the table + // FIXME(misdreavus): this needs to count graphemes, and probably also track + // double-wide characters... + if filename.len() > 35 { + "...".to_string() + &filename[filename.len() - 32..] + } else { + filename + } +} + +impl ToJson for CoverageCalculator { + fn to_json(&self) -> Json { + let mut total = ItemCount::default(); + let mut entries = BTreeMap::default(); + + entries.insert("files".to_owned(), Json::Array(self.items + .iter() + .filter_map(|(file, &count)| { + count.percentage().map(|percent| { + (limit_filename_len(file.to_string()), count, percent) + }) + }) + .map(|(name, count, percentage)| { + let mut fields = BTreeMap::default(); + + fields.insert("documented".to_owned(), Json::U64(count.with_docs)); + fields.insert("total".to_owned(), Json::U64(count.total)); + fields.insert("percentage".to_owned(), Json::F64(percentage)); + + total += count; + + let mut obj = BTreeMap::default(); + obj.insert(name, Json::Object(fields)); + + Json::Object(obj) + }) + .collect::>())); + let mut fields = BTreeMap::default(); + fields.insert("documented".to_owned(), Json::U64(total.with_docs)); + fields.insert("total".to_owned(), Json::U64(total.total)); + fields.insert("percentage".to_owned(), Json::F64(total.percentage().unwrap_or(0.0))); + + entries.insert("total".to_owned(), Json::Object(fields)); + Json::Object(entries) + } } impl CoverageCalculator { + fn new(output_format: Option) -> CoverageCalculator { + CoverageCalculator { + items: Default::default(), + output_format, + } + } + fn print_results(&self) { + if self.output_format.map(|o| o.is_json()).unwrap_or_else(|| false) { + println!("{}", self.to_json().pretty()); + return; + } let mut total = ItemCount::default(); fn print_table_line() { From 15babed8b7936e03ed4cd57afd5c91c44dc4f0be Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 16 Nov 2019 16:23:27 +0100 Subject: [PATCH 3/6] add tests for rustdoc output-format json --- src/test/rustdoc-ui/coverage/json.rs | 27 ++++++++++++++++++++ src/test/rustdoc-ui/coverage/json.stdout | 7 +++++ src/test/rustdoc/output-format-fail-check.rs | 5 ++++ 3 files changed, 39 insertions(+) create mode 100644 src/test/rustdoc-ui/coverage/json.rs create mode 100644 src/test/rustdoc-ui/coverage/json.stdout create mode 100644 src/test/rustdoc/output-format-fail-check.rs diff --git a/src/test/rustdoc-ui/coverage/json.rs b/src/test/rustdoc-ui/coverage/json.rs new file mode 100644 index 0000000000000..8b80244f825c4 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/json.rs @@ -0,0 +1,27 @@ +// build-pass +// compile-flags:-Z unstable-options --show-coverage + +pub mod foo { + /// Hello! + pub struct Foo; + /// Bar + pub enum Bar { A } +} + +/// X +pub struct X; + +/// Bar +pub mod bar { + /// bar + pub struct Bar; + /// X + pub enum X { Y } +} + +/// yolo +pub enum Yolo { X } + +pub struct Xo { + x: T, +} diff --git a/src/test/rustdoc-ui/coverage/json.stdout b/src/test/rustdoc-ui/coverage/json.stdout new file mode 100644 index 0000000000000..be56a8c0ffafa --- /dev/null +++ b/src/test/rustdoc-ui/coverage/json.stdout @@ -0,0 +1,7 @@ ++-------------------------------------+------------+------------+------------+ +| File | Documented | Total | Percentage | ++-------------------------------------+------------+------------+------------+ +| ...test/rustdoc-ui/coverage/json.rs | 7 | 13 | 53.8% | ++-------------------------------------+------------+------------+------------+ +| Total | 7 | 13 | 53.8% | ++-------------------------------------+------------+------------+------------+ diff --git a/src/test/rustdoc/output-format-fail-check.rs b/src/test/rustdoc/output-format-fail-check.rs new file mode 100644 index 0000000000000..a78811078be29 --- /dev/null +++ b/src/test/rustdoc/output-format-fail-check.rs @@ -0,0 +1,5 @@ +// compile-flags:-Z unstable-options --output-format +// should-fail + +/// toudoum! +pub struct SomeStruct; From f1070b152546827e599cdee1f64c55faaf8bf082 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 17 Feb 2020 13:53:27 +0100 Subject: [PATCH 4/6] Replace ToJson with serde --- src/librustdoc/config.rs | 16 ++-- .../passes/calculate_doc_coverage.rs | 90 ++++++------------- src/test/rustdoc-ui/coverage/html.rs | 4 + src/test/rustdoc-ui/coverage/html.stderr | 2 + src/test/rustdoc-ui/coverage/json.rs | 2 +- src/test/rustdoc-ui/coverage/json.stdout | 8 +- .../coverage}/output-format-fail-check.rs | 1 - .../coverage/output-format-fail-check.stderr | 6 ++ 8 files changed, 51 insertions(+), 78 deletions(-) create mode 100644 src/test/rustdoc-ui/coverage/html.rs create mode 100644 src/test/rustdoc-ui/coverage/html.stderr rename src/test/{rustdoc => rustdoc-ui/coverage}/output-format-fail-check.rs (85%) create mode 100644 src/test/rustdoc-ui/coverage/output-format-fail-check.stderr diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 99a55f3c68282..58c8a7d82bfb5 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use std::ffi::OsStr; use std::convert::TryFrom; +use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; @@ -28,12 +28,12 @@ use crate::theme; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum OutputFormat { Json, - HTML, + Html, } impl OutputFormat { pub fn is_json(&self) -> bool { - match *self { + match self { OutputFormat::Json => true, _ => false, } @@ -46,7 +46,7 @@ impl TryFrom<&str> for OutputFormat { fn try_from(value: &str) -> Result { match value { "json" => Ok(OutputFormat::Json), - "html" => Ok(OutputFormat::HTML), + "html" => Ok(OutputFormat::Html), _ => Err(format!("unknown output format `{}`", value)), } } @@ -498,6 +498,12 @@ impl Options { diag.struct_err("json output format isn't supported for doc generation") .emit(); return Err(1); + } else if !o.is_json() && show_coverage { + diag.struct_err( + "html output format isn't supported for the --show-coverage option", + ) + .emit(); + return Err(1); } Some(o) } @@ -505,7 +511,7 @@ impl Options { diag.struct_err(&e).emit(); return Err(1); } - } + }, None => None, }; let crate_name = matches.opt_str("crate-name"); diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 0ca5a956bdb69..f48224512ba4f 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -7,7 +7,8 @@ use crate::passes::Pass; use rustc_ast::attr; use rustc_span::symbol::sym; use rustc_span::FileName; -use serialize::json::{ToJson, Json}; +use serde::Serialize; +use serde_json; use std::collections::BTreeMap; use std::ops; @@ -18,16 +19,16 @@ pub const CALCULATE_DOC_COVERAGE: Pass = Pass { description: "counts the number of items with and without documentation", }; -fn calculate_doc_coverage( krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate { - let mut calc = CoverageCalculator::new(ctx.renderinfo.borrow().output_format); +fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate { + let mut calc = CoverageCalculator::new(); let krate = calc.fold_crate(krate); - calc.print_results(); + calc.print_results(ctx.renderinfo.borrow().output_format); krate } -#[derive(Default, Copy, Clone)] +#[derive(Default, Copy, Clone, Serialize)] struct ItemCount { total: u64, with_docs: u64, @@ -68,68 +69,37 @@ impl ops::AddAssign for ItemCount { struct CoverageCalculator { items: BTreeMap, - output_format: Option, } fn limit_filename_len(filename: String) -> String { - // if a filename is too long, shorten it so we don't blow out the table - // FIXME(misdreavus): this needs to count graphemes, and probably also track - // double-wide characters... - if filename.len() > 35 { - "...".to_string() + &filename[filename.len() - 32..] + let nb_chars = filename.chars().count(); + if nb_chars > 35 { + "...".to_string() + + &filename[filename.char_indices().nth(nb_chars - 32).map(|x| x.0).unwrap_or(0)..] } else { filename } } -impl ToJson for CoverageCalculator { - fn to_json(&self) -> Json { - let mut total = ItemCount::default(); - let mut entries = BTreeMap::default(); - - entries.insert("files".to_owned(), Json::Array(self.items - .iter() - .filter_map(|(file, &count)| { - count.percentage().map(|percent| { - (limit_filename_len(file.to_string()), count, percent) - }) - }) - .map(|(name, count, percentage)| { - let mut fields = BTreeMap::default(); - - fields.insert("documented".to_owned(), Json::U64(count.with_docs)); - fields.insert("total".to_owned(), Json::U64(count.total)); - fields.insert("percentage".to_owned(), Json::F64(percentage)); - - total += count; - - let mut obj = BTreeMap::default(); - obj.insert(name, Json::Object(fields)); - - Json::Object(obj) - }) - .collect::>())); - let mut fields = BTreeMap::default(); - fields.insert("documented".to_owned(), Json::U64(total.with_docs)); - fields.insert("total".to_owned(), Json::U64(total.total)); - fields.insert("percentage".to_owned(), Json::F64(total.percentage().unwrap_or(0.0))); - - entries.insert("total".to_owned(), Json::Object(fields)); - Json::Object(entries) +impl CoverageCalculator { + fn new() -> CoverageCalculator { + CoverageCalculator { items: Default::default() } } -} -impl CoverageCalculator { - fn new(output_format: Option) -> CoverageCalculator { - CoverageCalculator { - items: Default::default(), - output_format, - } + fn to_json(&self) -> String { + serde_json::to_string( + &self + .items + .iter() + .map(|(k, v)| (k.to_string(), v)) + .collect::>(), + ) + .expect("failed to convert JSON data to string") } - fn print_results(&self) { - if self.output_format.map(|o| o.is_json()).unwrap_or_else(|| false) { - println!("{}", self.to_json().pretty()); + fn print_results(&self, output_format: Option) { + if output_format.map(|o| o.is_json()).unwrap_or_else(|| false) { + println!("{}", self.to_json()); return; } let mut total = ItemCount::default(); @@ -154,15 +124,7 @@ impl CoverageCalculator { for (file, &count) in &self.items { if let Some(percentage) = count.percentage() { - let mut name = file.to_string(); - // if a filename is too long, shorten it so we don't blow out the table - // FIXME(misdreavus): this needs to count graphemes, and probably also track - // double-wide characters... - if name.len() > 35 { - name = "...".to_string() + &name[name.len() - 32..]; - } - - print_table_record(&name, count, percentage); + print_table_record(&limit_filename_len(file.to_string()), count, percentage); total += count; } diff --git a/src/test/rustdoc-ui/coverage/html.rs b/src/test/rustdoc-ui/coverage/html.rs new file mode 100644 index 0000000000000..181cb4c5061a7 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/html.rs @@ -0,0 +1,4 @@ +// compile-flags:-Z unstable-options --output-format html --show-coverage + +/// Foo +pub struct Xo; diff --git a/src/test/rustdoc-ui/coverage/html.stderr b/src/test/rustdoc-ui/coverage/html.stderr new file mode 100644 index 0000000000000..adca375d4bce5 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/html.stderr @@ -0,0 +1,2 @@ +error: html output format isn't supported for the --show-coverage option + diff --git a/src/test/rustdoc-ui/coverage/json.rs b/src/test/rustdoc-ui/coverage/json.rs index 8b80244f825c4..b1220b32e9194 100644 --- a/src/test/rustdoc-ui/coverage/json.rs +++ b/src/test/rustdoc-ui/coverage/json.rs @@ -1,5 +1,5 @@ // build-pass -// compile-flags:-Z unstable-options --show-coverage +// compile-flags:-Z unstable-options --output-format json --show-coverage pub mod foo { /// Hello! diff --git a/src/test/rustdoc-ui/coverage/json.stdout b/src/test/rustdoc-ui/coverage/json.stdout index be56a8c0ffafa..63b22a7d94b00 100644 --- a/src/test/rustdoc-ui/coverage/json.stdout +++ b/src/test/rustdoc-ui/coverage/json.stdout @@ -1,7 +1 @@ -+-------------------------------------+------------+------------+------------+ -| File | Documented | Total | Percentage | -+-------------------------------------+------------+------------+------------+ -| ...test/rustdoc-ui/coverage/json.rs | 7 | 13 | 53.8% | -+-------------------------------------+------------+------------+------------+ -| Total | 7 | 13 | 53.8% | -+-------------------------------------+------------+------------+------------+ +{"$DIR/json.rs":{"total":13,"with_docs":7}} diff --git a/src/test/rustdoc/output-format-fail-check.rs b/src/test/rustdoc-ui/coverage/output-format-fail-check.rs similarity index 85% rename from src/test/rustdoc/output-format-fail-check.rs rename to src/test/rustdoc-ui/coverage/output-format-fail-check.rs index a78811078be29..30b525df76359 100644 --- a/src/test/rustdoc/output-format-fail-check.rs +++ b/src/test/rustdoc-ui/coverage/output-format-fail-check.rs @@ -1,5 +1,4 @@ // compile-flags:-Z unstable-options --output-format -// should-fail /// toudoum! pub struct SomeStruct; diff --git a/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr b/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr new file mode 100644 index 0000000000000..9e9aa0e050163 --- /dev/null +++ b/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr @@ -0,0 +1,6 @@ +warning: the 'output-format' flag is considered deprecated + | + = warning: see issue #44136 for more information + +error: too many file operands + From 1c01646e6f1ed540fa1be66f3389181ad5644778 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Feb 2020 17:20:32 +0100 Subject: [PATCH 5/6] Extend json detection in runtest --- src/tools/compiletest/src/runtest.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ac808b1f14e13..86621e8812b4c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3204,7 +3204,9 @@ impl<'test> TestCx<'test> { let json = cflags.contains("--error-format json") || cflags.contains("--error-format pretty-json") || cflags.contains("--error-format=json") - || cflags.contains("--error-format=pretty-json"); + || cflags.contains("--error-format=pretty-json") + || cflags.contains("--output-format json") + || cflags.contains("--output-format=json"); let mut normalized = output.to_string(); From b6466273ba3d019433a8665fb337bfedeaf209ef Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 2 Mar 2020 13:20:32 +0100 Subject: [PATCH 6/6] remove output-format test --- src/test/rustdoc-ui/coverage/output-format-fail-check.rs | 4 ---- .../rustdoc-ui/coverage/output-format-fail-check.stderr | 6 ------ 2 files changed, 10 deletions(-) delete mode 100644 src/test/rustdoc-ui/coverage/output-format-fail-check.rs delete mode 100644 src/test/rustdoc-ui/coverage/output-format-fail-check.stderr diff --git a/src/test/rustdoc-ui/coverage/output-format-fail-check.rs b/src/test/rustdoc-ui/coverage/output-format-fail-check.rs deleted file mode 100644 index 30b525df76359..0000000000000 --- a/src/test/rustdoc-ui/coverage/output-format-fail-check.rs +++ /dev/null @@ -1,4 +0,0 @@ -// compile-flags:-Z unstable-options --output-format - -/// toudoum! -pub struct SomeStruct; diff --git a/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr b/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr deleted file mode 100644 index 9e9aa0e050163..0000000000000 --- a/src/test/rustdoc-ui/coverage/output-format-fail-check.stderr +++ /dev/null @@ -1,6 +0,0 @@ -warning: the 'output-format' flag is considered deprecated - | - = warning: see issue #44136 for more information - -error: too many file operands -