Skip to content

Commit

Permalink
Implement [future-incompat-report] config section
Browse files Browse the repository at this point in the history
Currently, I've just implemented the `always` and `never` frequencies
from the RFC, which don't require tracking any additional state.
  • Loading branch information
Aaron1011 committed Aug 19, 2021
1 parent b64c96b commit 88679e0
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 9 deletions.
28 changes: 22 additions & 6 deletions src/cargo/core/compiler/job_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,21 @@ impl<'cfg> DrainState<'cfg> {
if !bcx.config.cli_unstable().future_incompat_report {
return;
}
let should_display_message = match bcx.config.future_incompat_config() {
Ok(config) => config.should_display_message(),
Err(e) => {
crate::display_warning_with_error(
"failed to read future-incompat config from disk",
&e,
&mut bcx.config.shell(),
);
true
}
};

if self.per_package_future_incompat_reports.is_empty() {
// Explicitly passing a command-line flag overrides
// `should_display_message` from the config file
if bcx.build_config.future_incompat_report {
drop(
bcx.config
Expand All @@ -907,11 +921,13 @@ impl<'cfg> DrainState<'cfg> {
.map(|pid| pid.to_string())
.collect();

drop(bcx.config.shell().warn(&format!(
"the following packages contain code that will be rejected by a future \
version of Rust: {}",
package_vers.join(", ")
)));
if should_display_message || bcx.build_config.future_incompat_report {
drop(bcx.config.shell().warn(&format!(
"the following packages contain code that will be rejected by a future \
version of Rust: {}",
package_vers.join(", ")
)));
}

let on_disk_reports =
OnDiskReports::save_report(bcx.ws, &self.per_package_future_incompat_reports);
Expand All @@ -925,7 +941,7 @@ impl<'cfg> DrainState<'cfg> {
future-incompatibilities -Z future-incompat-report --id {}`",
report_id
)));
} else {
} else if should_display_message {
drop(bcx.config.shell().note(&format!(
"to see what the problems were, use the option \
`--future-incompat-report`, or run `cargo report \
Expand Down
38 changes: 38 additions & 0 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ pub struct Config {
package_cache_lock: RefCell<Option<(Option<FileLock>, usize)>>,
/// Cached configuration parsed by Cargo
http_config: LazyCell<CargoHttpConfig>,
future_incompat_config: LazyCell<CargoFutureIncompatConfig>,
net_config: LazyCell<CargoNetConfig>,
build_config: LazyCell<CargoBuildConfig>,
target_cfgs: LazyCell<Vec<(String, TargetCfgConfig)>>,
Expand Down Expand Up @@ -275,6 +276,7 @@ impl Config {
updated_sources: LazyCell::new(),
package_cache_lock: RefCell::new(None),
http_config: LazyCell::new(),
future_incompat_config: LazyCell::new(),
net_config: LazyCell::new(),
build_config: LazyCell::new(),
target_cfgs: LazyCell::new(),
Expand Down Expand Up @@ -1436,6 +1438,11 @@ impl Config {
.try_borrow_with(|| self.get::<CargoHttpConfig>("http"))
}

pub fn future_incompat_config(&self) -> CargoResult<&CargoFutureIncompatConfig> {
self.future_incompat_config
.try_borrow_with(|| self.get::<CargoFutureIncompatConfig>("future-incompat-report"))
}

pub fn net_config(&self) -> CargoResult<&CargoNetConfig> {
self.net_config
.try_borrow_with(|| self.get::<CargoNetConfig>("net"))
Expand Down Expand Up @@ -2034,6 +2041,37 @@ pub struct CargoHttpConfig {
pub ssl_version: Option<SslVersionConfig>,
}

#[derive(Debug, Default, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub struct CargoFutureIncompatConfig {
frequency: Option<CargoFutureIncompatFrequencyConfig>,
}

#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum CargoFutureIncompatFrequencyConfig {
Always,
Never,
}

impl CargoFutureIncompatConfig {
pub fn should_display_message(&self) -> bool {
use CargoFutureIncompatFrequencyConfig::*;

let frequency = self.frequency.as_ref().unwrap_or(&Always);
match frequency {
Always => true,
Never => false,
}
}
}

impl Default for CargoFutureIncompatFrequencyConfig {
fn default() -> Self {
Self::Always
}
}

/// Configuration for `ssl-version` in `http` section
/// There are two ways to configure:
///
Expand Down
12 changes: 12 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,18 @@ the `--future-incompat-report` flag. The developer should then update their
dependencies to a version where the issue is fixed, or work with the
developers of the dependencies to help resolve the issue.

This feature can be configured through a `[future-incompat-report]`
section in `.cargo/config`. Currently, the supported options are:

```
[future-incompat-report]
frequency = FREQUENCY
```

The supported values for `FREQUENCY` are 'always` and 'never', which control
whether or not a message is printed out at the end of `cargo build` / `cargo check`.


### patch-in-config
* Original Pull Request: [#9204](https://github.com/rust-lang/cargo/pull/9204)
* Tracking Issue: [#9269](https://github.com/rust-lang/cargo/issues/9269)
Expand Down
2 changes: 1 addition & 1 deletion tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub fn write_config_at(path: impl AsRef<Path>, contents: &str) {
fs::write(path, contents).unwrap();
}

fn write_config_toml(config: &str) {
pub fn write_config_toml(config: &str) {
write_config_at(paths::root().join(".cargo/config.toml"), config);
}

Expand Down
37 changes: 35 additions & 2 deletions tests/testsuite/future_incompat_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! So we pick some random lint that will likely always be the same
//! over time.
use super::config::write_config_toml;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, is_nightly, project, Project};

Expand Down Expand Up @@ -115,14 +116,46 @@ fn test_single_crate() {
let p = simple_project();

for command in &["build", "check", "rustc", "test"] {
p.cargo(command).arg("-Zfuture-incompat-report")
let check_has_future_compat = || {
p.cargo(command).arg("-Zfuture-incompat-report")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-Zfuture-incompat-test")
.with_stderr_contains(FUTURE_OUTPUT)
.with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
.with_stderr_does_not_contain("[..]incompatibility[..]")
.run();
};

// Check that we show a message with no [future-incompat-report] config section
write_config_toml("");
check_has_future_compat();

// Check that we show a message with `frequence = "always"`
write_config_toml(
"\
[future-incompat-report]
frequency = 'always'
",
);
check_has_future_compat();

// Check that we do not show a message with `frequency = "never"`
write_config_toml(
"\
[future-incompat-report]
frequency = 'never'
",
);
p.cargo(command)
.arg("-Zfuture-incompat-report")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-Zfuture-incompat-test")
.with_stderr_contains(FUTURE_OUTPUT)
.with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
.with_stderr_does_not_contain("[..]rejected[..]")
.with_stderr_does_not_contain("[..]incompatibility[..]")
.run();

// Check that passing `--future-incompat-report` overrides `frequency = 'never'`
p.cargo(command).arg("-Zfuture-incompat-report").arg("-Zunstable-options").arg("--future-incompat-report")
.masquerade_as_nightly_cargo()
.env("RUSTFLAGS", "-Zfuture-incompat-test")
Expand Down

0 comments on commit 88679e0

Please sign in to comment.