mirror of
https://github.com/rust-lang/cargo
synced 2024-09-13 04:51:31 +00:00
Combine rustc and cargo's diagnostic summaries
This works by introspecting rustc's error output, using the JSON format to determine whether it's a warning or error, then skipping it altogether if it's a summary of the diagnostics printed. Before: ``` src/main.rs:1:10: warning: trait objects without an explicit `dyn` are deprecated src/main.rs:1:1: error[E0601]: `main` function not found in crate `wrong` src/main.rs:1:9: error[E0038]: the trait `Clone` cannot be made into an object error: aborting due to 2 previous errors; 1 warning emitted error: could not compile `wrong` ``` After: ``` $ cargo check --message-format short src/main.rs:1:10: warning: trait objects without an explicit `dyn` are deprecated src/main.rs:1:1: error[E0601]: `main` function not found in crate `wrong` src/main.rs:1:9: error[E0038]: the trait `Clone` cannot be made into an object error: could not compile `wrong` due to 2 previous errors; 1 warning emitted ```
This commit is contained in:
parent
768b5658c2
commit
9c7cc545d7
|
@ -51,6 +51,7 @@ pub struct FutureBreakageItem {
|
|||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Diagnostic {
|
||||
pub rendered: String,
|
||||
pub level: String,
|
||||
}
|
||||
|
||||
/// The filename in the top-level `target` directory where we store
|
||||
|
|
|
@ -333,7 +333,20 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
|
|||
},
|
||||
)
|
||||
.map_err(verbose_if_simple_exit_code)
|
||||
.with_context(|| format!("could not compile `{}`", name))?;
|
||||
.with_context(|| {
|
||||
// adapted from rustc_errors/src/lib.rs
|
||||
let warnings = match output_options.warnings_seen {
|
||||
0 => String::new(),
|
||||
1 => "; 1 warning emitted".to_string(),
|
||||
count => format!("; {} warnings emitted", count),
|
||||
};
|
||||
let errors = match output_options.errors_seen {
|
||||
0 => String::new(),
|
||||
1 => " due to previous error".to_string(),
|
||||
count => format!(" due to {} previous errors", count),
|
||||
};
|
||||
format!("could not compile `{}`{}{}", name, errors, warnings)
|
||||
})?;
|
||||
}
|
||||
|
||||
if rustc_dep_info_loc.exists() {
|
||||
|
@ -1161,6 +1174,8 @@ struct OutputOptions {
|
|||
/// Other types of messages are processed regardless
|
||||
/// of the value of this flag
|
||||
show_warnings: bool,
|
||||
warnings_seen: usize,
|
||||
errors_seen: usize,
|
||||
}
|
||||
|
||||
impl OutputOptions {
|
||||
|
@ -1177,6 +1192,8 @@ impl OutputOptions {
|
|||
color,
|
||||
cache_cell,
|
||||
show_warnings: true,
|
||||
warnings_seen: 0,
|
||||
errors_seen: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1244,7 +1261,18 @@ fn on_stderr_line_inner(
|
|||
}
|
||||
};
|
||||
|
||||
let count_diagnostic = |level, options: &mut OutputOptions| {
|
||||
if level == "warning" {
|
||||
options.warnings_seen += 1;
|
||||
} else if level == "error" {
|
||||
options.errors_seen += 1;
|
||||
}
|
||||
};
|
||||
|
||||
if let Ok(report) = serde_json::from_str::<FutureIncompatReport>(compiler_message.get()) {
|
||||
for item in &report.future_incompat_report {
|
||||
count_diagnostic(&*item.diagnostic.level, options);
|
||||
}
|
||||
state.future_incompat_report(report.future_incompat_report);
|
||||
return Ok(true);
|
||||
}
|
||||
|
@ -1265,8 +1293,14 @@ fn on_stderr_line_inner(
|
|||
#[derive(serde::Deserialize)]
|
||||
struct CompilerMessage {
|
||||
rendered: String,
|
||||
message: String,
|
||||
level: String,
|
||||
}
|
||||
if let Ok(mut error) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
|
||||
if error.level == "error" && error.message.starts_with("aborting due to") {
|
||||
// Skip this line; we'll print our own summary at the end.
|
||||
return Ok(true);
|
||||
}
|
||||
// state.stderr will add a newline
|
||||
if error.rendered.ends_with('\n') {
|
||||
error.rendered.pop();
|
||||
|
@ -1281,6 +1315,7 @@ fn on_stderr_line_inner(
|
|||
.expect("strip should never fail")
|
||||
};
|
||||
if options.show_warnings {
|
||||
count_diagnostic(&error.level, options);
|
||||
state.stderr(rendered)?;
|
||||
}
|
||||
return Ok(true);
|
||||
|
@ -1368,6 +1403,14 @@ fn on_stderr_line_inner(
|
|||
return Ok(true);
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
struct CompilerMessage {
|
||||
level: String,
|
||||
}
|
||||
if let Ok(message) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
|
||||
count_diagnostic(&message.level, options);
|
||||
}
|
||||
|
||||
let msg = machine_message::FromCompiler {
|
||||
package_id,
|
||||
manifest_path,
|
||||
|
@ -1399,6 +1442,8 @@ fn replay_output_cache(
|
|||
color,
|
||||
cache_cell: None,
|
||||
show_warnings,
|
||||
warnings_seen: 0,
|
||||
errors_seen: 0,
|
||||
};
|
||||
Work::new(move |state| {
|
||||
if !path.exists() {
|
||||
|
|
|
@ -588,12 +588,7 @@ fn cargo_compile_with_invalid_code() {
|
|||
|
||||
p.cargo("build")
|
||||
.with_status(101)
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[ERROR] could not compile `foo`
|
||||
|
||||
To learn more, run the command again with --verbose.\n",
|
||||
)
|
||||
.with_stderr_contains("[ERROR] could not compile `foo` due to previous error\n")
|
||||
.run();
|
||||
assert!(p.root().join("Cargo.lock").is_file());
|
||||
}
|
||||
|
|
|
@ -1458,7 +1458,7 @@ fn build_deps_not_for_normal() {
|
|||
.with_stderr_contains("[..]can't find crate for `aaaaa`[..]")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[ERROR] could not compile `foo`
|
||||
[ERROR] could not compile `foo` due to previous error
|
||||
|
||||
Caused by:
|
||||
process didn't exit successfully: [..]
|
||||
|
|
|
@ -803,8 +803,7 @@ fn short_message_format() {
|
|||
.with_stderr_contains(
|
||||
"\
|
||||
src/lib.rs:1:27: error[E0308]: mismatched types
|
||||
error: aborting due to previous error
|
||||
error: could not compile `foo`
|
||||
error: could not compile `foo` due to previous error
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
|
|
@ -28,7 +28,7 @@ fn do_not_fix_broken_builds() {
|
|||
p.cargo("fix --allow-no-vcs")
|
||||
.env("__CARGO_FIX_YOLO", "1")
|
||||
.with_status(101)
|
||||
.with_stderr_contains("[ERROR] could not compile `foo`")
|
||||
.with_stderr_contains("[ERROR] could not compile `foo` due to previous error")
|
||||
.run();
|
||||
assert!(p.read_file("src/lib.rs").contains("let mut x = 3;"));
|
||||
}
|
||||
|
@ -833,8 +833,6 @@ fn prepare_for_unstable() {
|
|||
[ERROR] cannot migrate src/lib.rs to edition {next}
|
||||
Edition {next} is unstable and not allowed in this release, consider trying the nightly release channel.
|
||||
error: could not compile `foo`
|
||||
|
||||
To learn more, run the command again with --verbose.
|
||||
", next=next))
|
||||
.run();
|
||||
|
||||
|
|
|
@ -742,9 +742,7 @@ fn compile_failure() {
|
|||
found at `[..]target`
|
||||
|
||||
Caused by:
|
||||
could not compile `foo`
|
||||
|
||||
To learn more, run the command again with --verbose.
|
||||
could not compile `foo` due to previous error
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
|
Loading…
Reference in a new issue