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

Deprecate several fields #606

Merged
merged 4 commits into from
Feb 21, 2024
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
78 changes: 71 additions & 7 deletions src/advisories/cfg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
cfg::{PackageSpecOrExtended, Reason, ValidationContext},
diag::{Diagnostic, FileId, Label},
LintLevel, PathBuf, Spanned,
LintLevel, PathBuf, Span, Spanned,
};
use rustsec::advisory;
use time::Duration;
Expand Down Expand Up @@ -44,6 +44,7 @@ pub struct Config {
/// use the '.' separator instead of ',' which is used by some locales and
/// supported in the RFC3339 format, but not by this implementation
pub maximum_db_staleness: Spanned<Duration>,
deprecated: Vec<Span>,
}

impl Default for Config {
Expand All @@ -62,6 +63,7 @@ impl Default for Config {
git_fetch_with_cli: None,
disable_yank_checking: false,
maximum_db_staleness: Spanned::new(Duration::seconds_f64(NINETY_DAYS)),
deprecated: Vec::new(),
}
}
}
Expand Down Expand Up @@ -97,13 +99,20 @@ impl<'de> toml_span::Deserialize<'de> for Config {
} else {
Vec::new()
};
let vulnerability = th.optional("vulnerability").unwrap_or(LintLevel::Deny);
let unmaintained = th.optional("unmaintained").unwrap_or(LintLevel::Warn);
let unsound = th.optional("unsound").unwrap_or(LintLevel::Warn);

use crate::cfg::deprecated;

let mut fdeps = Vec::new();

let vulnerability =
deprecated(&mut th, "vulnerability", &mut fdeps).unwrap_or(LintLevel::Deny);
let unmaintained =
deprecated(&mut th, "unmaintained", &mut fdeps).unwrap_or(LintLevel::Warn);
let unsound = deprecated(&mut th, "unsound", &mut fdeps).unwrap_or(LintLevel::Warn);
let yanked = th
.optional_s("yanked")
.unwrap_or(Spanned::new(LintLevel::Warn));
let notice = th.optional("notice").unwrap_or(LintLevel::Warn);
let notice = deprecated(&mut th, "notice", &mut fdeps).unwrap_or(LintLevel::Warn);
let (ignore, ignore_yanked) = if let Some((_, mut ignore)) = th.take("ignore") {
let mut u = Vec::new();
let mut y = Vec::new();
Expand Down Expand Up @@ -152,7 +161,38 @@ impl<'de> toml_span::Deserialize<'de> for Config {
} else {
(Vec::new(), Vec::new())
};
let severity_threshold = th.parse_opt("severity-threshold");
let st = |th: &mut TableHelper<'_>, fdeps: &mut Vec<Span>| {
let (k, mut v) = th.take("severity-threshold")?;

fdeps.push(k.span);
let s = match v.take_string(Some(
"https://docs.rs/rustsec/latest/rustsec/advisory/enum.Severity.html",
)) {
Ok(s) => s,
Err(err) => {
th.errors.push(err);
return None;
}
};

match s.parse() {
Ok(st) => Some(st),
Err(err) => {
th.errors.push(
(
toml_span::ErrorKind::Custom(
format!("failed to parse rustsec::Severity: {err}").into(),
),
v.span,
)
.into(),
);
None
}
}
};

let severity_threshold = st(&mut th, &mut fdeps);
let git_fetch_with_cli = th.optional("git-fetch-with-cli");
let disable_yank_checking = th.optional("disable-yank-checking").unwrap_or_default();
let maximum_db_staleness = if let Some((_, mut val)) = th.take("maximum-db-staleness") {
Expand Down Expand Up @@ -199,6 +239,7 @@ impl<'de> toml_span::Deserialize<'de> for Config {
git_fetch_with_cli,
disable_yank_checking,
maximum_db_staleness,
deprecated: fdeps,
})
}
}
Expand Down Expand Up @@ -226,6 +267,23 @@ impl crate::cfg::UnvalidatedConfig for Config {
}
}

use crate::diag::general::{Deprecated, DeprecationReason};

// Output any deprecations, we'll remove the fields at the same time we
// remove all the logic they drive
for dep in self.deprecated {
ctx.push(
Deprecated {
reason: DeprecationReason::WillBeRemoved(Some(
"https://github.com/EmbarkStudios/cargo-deny/pull/606",
)),
key: dep,
file_id: ctx.cfg_id,
}
.into(),
);
}

ValidConfig {
file_id: ctx.cfg_id,
db_path: self.db_path,
Expand Down Expand Up @@ -450,7 +508,13 @@ mod test {
#[test]
fn deserializes_advisories_cfg() {
let cd = ConfigData::<Advisories>::load("tests/cfg/advisories.toml");
let validated = cd.validate(|a| a.advisories);
let validated = cd.validate_with_diags(
|a| a.advisories,
|files, diags| {
let diags = write_diagnostics(files, diags.into_iter());
insta::assert_snapshot!(diags);
},
);

insta::assert_json_snapshot!(validated);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
source: src/advisories/cfg.rs
expression: validated
---
{
"file_id": 1,
"db_path": "~/.cargo/advisory-dbs",
"db_urls": [
"https://github.com/RustSec/advisory-db"
],
"ignore": [
"RUSTSEC-0000-0000"
],
"ignore_yanked": [
{
"spec": {
"name": "crate",
"version-req": "=0.1"
},
"reason": null,
"use-instead": null
},
{
"spec": {
"name": "yanked",
"version-req": null
},
"reason": "a new version has not been released",
"use-instead": null
}
],
"vulnerability": "deny",
"unmaintained": "warn",
"unsound": "warn",
"yanked": "warn",
"notice": "warn",
"severity_threshold": "medium",
"git_fetch_with_cli": false,
"disable_yank_checking": false,
"maximum_db_staleness": [
466560000,
0
]
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
---
source: src/advisories/cfg.rs
expression: validated
expression: diags
---
{
"file_id": 1,
"db_path": "~/.cargo/advisory-dbs",
"db_urls": [
"https://github.com/RustSec/advisory-db"
],
"ignore": [
"RUSTSEC-0000-0000"
],
"ignore_yanked": [
{
"spec": {
"name": "crate",
"version-req": "=0.1"
},
"reason": null,
"use-instead": null
},
{
"spec": {
"name": "yanked",
"version-req": null
},
"reason": "a new version has not been released",
"use-instead": null
}
],
"vulnerability": "deny",
"unmaintained": "warn",
"unsound": "warn",
"yanked": "warn",
"notice": "warn",
"severity_threshold": "medium",
"git_fetch_with_cli": false,
"disable_yank_checking": false,
"maximum_db_staleness": [
466560000,
0
]
}
warning[deprecated]: this key will be removed in a future update, see https://github.com/EmbarkStudios/cargo-deny/pull/606 for details
┌─ tests/cfg/advisories.toml:4:1
4 │ vulnerability = "deny"
│ ^^^^^^^^^^^^^

warning[deprecated]: this key will be removed in a future update, see https://github.com/EmbarkStudios/cargo-deny/pull/606 for details
┌─ tests/cfg/advisories.toml:5:1
5 │ unmaintained = "warn"
│ ^^^^^^^^^^^^

warning[deprecated]: this key will be removed in a future update, see https://github.com/EmbarkStudios/cargo-deny/pull/606 for details
┌─ tests/cfg/advisories.toml:6:1
6 │ unsound = "warn"
│ ^^^^^^^

warning[deprecated]: this key will be removed in a future update, see https://github.com/EmbarkStudios/cargo-deny/pull/606 for details
┌─ tests/cfg/advisories.toml:8:1
8 │ notice = "warn"
│ ^^^^^^

warning[deprecated]: this key will be removed in a future update, see https://github.com/EmbarkStudios/cargo-deny/pull/606 for details
┌─ tests/cfg/advisories.toml:14:1
14 │ severity-threshold = "medium"
│ ^^^^^^^^^^^^^^^^^^


24 changes: 24 additions & 0 deletions src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,27 @@ impl<'de> toml_span::Deserialize<'de> for Reason {
Ok(Self(r))
}
}

/// Deserialize a field from the table if it exists, but append the key's span
/// so it can be marked as deprecated
pub fn deprecated<'de, T>(
th: &mut toml_span::de_helpers::TableHelper<'de>,
field: &'static str,
spans: &mut Vec<Span>,
) -> Option<T>
where
T: toml_span::Deserialize<'de>,
{
let Some((k, mut v)) = th.take(field) else {
return None;
};
spans.push(k.span);

match T::deserialize(&mut v) {
Ok(v) => Some(v),
Err(mut err) => {
th.errors.append(&mut err.errors);
None
}
}
}
26 changes: 21 additions & 5 deletions src/diag/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,39 @@ impl From<Code> for String {
}

pub enum DeprecationReason {
WillBeRemoved,
WillBeRemoved(Option<&'static str>),
Moved(&'static str),
Renamed(&'static str),
MovedAndRenamed {
table: &'static str,
key: &'static str,
},
Removed(&'static str),
}

impl fmt::Display for DeprecationReason {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::WillBeRemoved => f.write_str("the key will be removed in a future update"),
Self::Moved(tab) => write!(f, "the key has been moved to [{tab}]"),
Self::Renamed(nname) => write!(f, "the key has been renamed to '{nname}'"),
Self::WillBeRemoved(url) => {
if let Some(url) = url {
write!(
f,
"this key will be removed in a future update, see {url} for details"
)
} else {
f.write_str("this key will be removed in a future update")
}
}
Self::Moved(tab) => write!(f, "this key has been moved to [{tab}]"),
Self::Renamed(nname) => write!(f, "this key has been renamed to '{nname}'"),
Self::MovedAndRenamed { table, key } => {
write!(f, "the key been moved to [{table}] and renamed to '{key}'")
write!(f, "this key been moved to [{table}] and renamed to '{key}'")
}
Self::Removed(url) => {
write!(
f,
"this key has been removed, see {url} for migration information"
)
}
}
}
Expand Down
Loading