Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print colored warnings when build script panics #8017

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use std::collections::hash_map::{Entry, HashMap};
use std::collections::{BTreeSet, HashSet};
use std::path::{Path, PathBuf};
use std::str;
use std::sync::Arc;
use std::sync::{Arc, Mutex};

const CARGO_WARNING: &str = "cargo:warning=";

/// Contains the parsed output of a custom build script.
#[derive(Clone, Debug, Hash, Default)]
Expand Down Expand Up @@ -343,9 +345,13 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
state.running(&cmd);
let timestamp = paths::set_invocation_time(&script_run_dir)?;
let prefix = format!("[{} {}] ", id.name(), id.version());
let mut warnings_in_case_of_panic = Vec::new();
let output = cmd
.exec_with_streaming(
&mut |stdout| {
if stdout.starts_with(CARGO_WARNING) {
warnings_in_case_of_panic.push(stdout[CARGO_WARNING.len()..].to_owned());
}
if extra_verbose {
state.stdout(format!("{}{}", prefix, stdout));
}
Expand All @@ -359,7 +365,19 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoRes
},
true,
)
.chain_err(|| format!("failed to run custom build command for `{}`", pkg_name))?;
.chain_err(|| format!("failed to run custom build command for `{}`", pkg_name));

if let Err(error) = output {
insert_warnings_in_build_outputs(
build_script_outputs,
id,
metadata_hash,
warnings_in_case_of_panic,
);
return Err(error);
}

let output = output.unwrap();

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

fn insert_warnings_in_build_outputs(
build_script_outputs: Arc<Mutex<BuildScriptOutputs>>,
id: PackageId,
metadata_hash: Metadata,
warnings: Vec<String>,
) {
let build_output_with_only_warnings = BuildOutput {
warnings,
..BuildOutput::default()
};
build_script_outputs
.lock()
.unwrap()
.insert(id, metadata_hash, build_output_with_only_warnings);
}

impl BuildOutput {
pub fn parse_file(
path: &Path,
Expand Down
33 changes: 33 additions & 0 deletions tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2980,6 +2980,39 @@ warning: bar
.run();
}

#[cargo_test]
fn warnings_emitted_when_build_script_panics() {
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.5.0"
authors = []
build = "build.rs"
"#,
)
.file("src/lib.rs", "")
.file(
"build.rs",
r#"
fn main() {
println!("cargo:warning=foo");
println!("cargo:warning=bar");
panic!();
}
"#,
)
.build();

p.cargo("build")
.with_status(101)
.with_stdout("")
.with_stderr_contains("warning: foo\nwarning: bar")
.run();
}

#[cargo_test]
fn warnings_hidden_for_upstream() {
Package::new("bar", "0.1.0")
Expand Down