diff --git a/src/bin/cargo/main.rs b/src/bin/cargo/main.rs index 41252a61296..765da1cd486 100644 --- a/src/bin/cargo/main.rs +++ b/src/bin/cargo/main.rs @@ -1,4 +1,5 @@ use cargo::core::features; +use cargo::util::context::WarningHandling; use cargo::util::network::http::http_handle; use cargo::util::network::http::needs_custom_http_transport; use cargo::util::{self, CargoResult, closest_msg, command_prelude}; @@ -315,6 +316,11 @@ fn execute_subcommand( None => ProcessBuilder::new(&cargo_exe), }; cmd.env(cargo::CARGO_ENV, cargo_exe).args(args); + if let Ok(handling) = gctx.warning_handling() { + if handling != WarningHandling::Warn { + cmd.env("CARGO_BUILD_WARNINGS", handling.as_str()); + } + } if let Some(client) = gctx.jobserver_from_env() { cmd.inherit_jobserver(client); } diff --git a/src/cargo/util/context/schema.rs b/src/cargo/util/context/schema.rs index 68d4c1ef351..f3eaa16f71a 100644 --- a/src/cargo/util/context/schema.rs +++ b/src/cargo/util/context/schema.rs @@ -237,6 +237,16 @@ pub enum WarningHandling { Deny, } +impl WarningHandling { + pub fn as_str(self) -> &'static str { + match self { + WarningHandling::Warn => "warn", + WarningHandling::Allow => "allow", + WarningHandling::Deny => "deny", + } + } +} + /// Configuration for `build.target`. /// /// Accepts in the following forms: diff --git a/tests/testsuite/warning_override.rs b/tests/testsuite/warning_override.rs index b1d8ce0a058..fbe8603f42f 100644 --- a/tests/testsuite/warning_override.rs +++ b/tests/testsuite/warning_override.rs @@ -527,3 +527,51 @@ fn cap_lints_allow() { "#]]) .run(); } + +#[cargo_test] +fn config_before_subcommand_forwarded() { + let clippy_mock = project() + .at("cargo-clippy-mock") + .file( + "Cargo.toml", + &cargo_test_support::basic_manifest("cargo-clippy-mock", "0.0.1"), + ) + .file( + "src/main.rs", + r#" + fn main() { + let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string()); + let mut cmd = std::process::Command::new(cargo); + cmd.arg("check"); + cmd.args(std::env::args().skip(2)); + let status = cmd.status().unwrap(); + std::process::exit(status.code().unwrap_or(1)); + } + "#, + ) + .build(); + clippy_mock.cargo("build").run(); + + let p = make_project_with_rustc_warning(); + + let mut path = + std::env::split_paths(&std::env::var_os("PATH").unwrap_or_default()).collect::>(); + path.push(clippy_mock.target_debug_dir()); + let path = std::env::join_paths(path.iter()).unwrap(); + + p.cargo("") + .arg("--config") + .arg("build.warnings='deny'") + .arg("clippy-mock") + .env("PATH", &path) + .with_status(101) + .with_stderr_data(str![[r#" +[CHECKING] foo v0.0.1 ([ROOT]/foo) +[WARNING] unused variable: `x` +... +[ERROR] `foo` (bin "foo") generated 1 warning (run `cargo fix --bin "foo" -p foo` to apply 1 suggestion) +[ERROR] warnings are denied by `build.warnings` configuration + +"#]]) + .run(); +}