Skip to content

Commit 03d7154

Browse files
committed
Auto merge of #8017 - aleksator:3672_color_build_script_warnings_on_panic, r=ehuss
Print colored warnings when build script panics Fixes #3672
2 parents 526aacc + 590c803 commit 03d7154

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

src/cargo/core/compiler/custom_build.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use std::collections::hash_map::{Entry, HashMap};
1111
use std::collections::{BTreeSet, HashSet};
1212
use std::path::{Path, PathBuf};
1313
use std::str;
14-
use std::sync::Arc;
14+
use std::sync::{Arc, Mutex};
15+
16+
const CARGO_WARNING: &str = "cargo:warning=";
1517

1618
/// Contains the parsed output of a custom build script.
1719
#[derive(Clone, Debug, Hash, Default)]
@@ -343,9 +345,13 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
343345
state.running(&cmd);
344346
let timestamp = paths::set_invocation_time(&script_run_dir)?;
345347
let prefix = format!("[{} {}] ", id.name(), id.version());
348+
let mut warnings_in_case_of_panic = Vec::new();
346349
let output = cmd
347350
.exec_with_streaming(
348351
&mut |stdout| {
352+
if stdout.starts_with(CARGO_WARNING) {
353+
warnings_in_case_of_panic.push(stdout[CARGO_WARNING.len()..].to_owned());
354+
}
349355
if extra_verbose {
350356
state.stdout(format!("{}{}", prefix, stdout));
351357
}
@@ -359,7 +365,19 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
359365
},
360366
true,
361367
)
362-
.chain_err(|| format!("failed to run custom build command for `{}`", pkg_name))?;
368+
.chain_err(|| format!("failed to run custom build command for `{}`", pkg_name));
369+
370+
if let Err(error) = output {
371+
insert_warnings_in_build_outputs(
372+
build_script_outputs,
373+
id,
374+
metadata_hash,
375+
warnings_in_case_of_panic,
376+
);
377+
return Err(error);
378+
}
379+
380+
let output = output.unwrap();
363381

364382
// After the build command has finished running, we need to be sure to
365383
// remember all of its output so we can later discover precisely what it
@@ -429,6 +447,22 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
429447
Ok(job)
430448
}
431449

450+
fn insert_warnings_in_build_outputs(
451+
build_script_outputs: Arc<Mutex<BuildScriptOutputs>>,
452+
id: PackageId,
453+
metadata_hash: Metadata,
454+
warnings: Vec<String>,
455+
) {
456+
let build_output_with_only_warnings = BuildOutput {
457+
warnings,
458+
..BuildOutput::default()
459+
};
460+
build_script_outputs
461+
.lock()
462+
.unwrap()
463+
.insert(id, metadata_hash, build_output_with_only_warnings);
464+
}
465+
432466
impl BuildOutput {
433467
pub fn parse_file(
434468
path: &Path,

tests/testsuite/build_script.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,6 +2980,39 @@ warning: bar
29802980
.run();
29812981
}
29822982

2983+
#[cargo_test]
2984+
fn warnings_emitted_when_build_script_panics() {
2985+
let p = project()
2986+
.file(
2987+
"Cargo.toml",
2988+
r#"
2989+
[project]
2990+
name = "foo"
2991+
version = "0.5.0"
2992+
authors = []
2993+
build = "build.rs"
2994+
"#,
2995+
)
2996+
.file("src/lib.rs", "")
2997+
.file(
2998+
"build.rs",
2999+
r#"
3000+
fn main() {
3001+
println!("cargo:warning=foo");
3002+
println!("cargo:warning=bar");
3003+
panic!();
3004+
}
3005+
"#,
3006+
)
3007+
.build();
3008+
3009+
p.cargo("build")
3010+
.with_status(101)
3011+
.with_stdout("")
3012+
.with_stderr_contains("warning: foo\nwarning: bar")
3013+
.run();
3014+
}
3015+
29833016
#[cargo_test]
29843017
fn warnings_hidden_for_upstream() {
29853018
Package::new("bar", "0.1.0")

0 commit comments

Comments
 (0)