Skip to content

Commit

Permalink
Lint [workspace.dependencies] (#673)
Browse files Browse the repository at this point in the history
This PR adds 2 new lints:

- `workspace-duplicates` - Will be triggered if >1 direct workspace
dependencies that resolve to the same crate are not using a shared
`[workspace.dependencies]` entry
- `unused-workspace-dependency` - Will be triggered if a workspace
dependency is not actually used

This also improves the output for the `wildcards` lint to show the span
information for the actual crate manifest where the wildcard dependency
is declared, rather than the synthesized one used previous to this
change.

Resolves: #436 
Resolves: #525
  • Loading branch information
Jake-Shadle authored Jun 26, 2024
1 parent cd9a0d1 commit 6344cc5
Show file tree
Hide file tree
Showing 52 changed files with 2,758 additions and 504 deletions.
42 changes: 11 additions & 31 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ askalono = { version = "0.4", default-features = false }
bitvec = { version = "1.0", features = ["alloc"] }
# Much nicer paths
camino = "1.1"
cfg-expr = "0.15"
# Allows us to do eg cargo metadata operations without relying on an external cargo
#cargo = { version = "0.71", optional = true }
# Argument parsing, kept aligned with cargo
Expand All @@ -75,9 +76,11 @@ goblin = { version = "0.8", default-features = false, features = [
# We need to figure out HOME/CARGO_HOME in some cases
home = "0.5"
# Provides graphs on top of cargo_metadata
krates = { version = "0.16", features = ["targets"] }
krates = { version = "0.17", features = ["targets"] }
# Log macros
log = "0.4"
# Faster char searching
memchr = "2.7"
# Nicer sync primitives
parking_lot = "0.12"
# Moar brrrr
Expand Down Expand Up @@ -112,7 +115,7 @@ time = { version = "0.3", default-features = false, features = [
"macros",
] }
# Deserialization of configuration files and crate manifests
toml-span = { version = "0.2", features = ["reporting"] }
toml-span = { version = "0.3", features = ["reporting"] }
# Small fast hash crate
twox-hash = { version = "1.5", default-features = false }
# Url parsing/manipulation
Expand All @@ -138,7 +141,7 @@ fs_extra = "1.3"
insta = { version = "1.21", features = ["json"] }
tame-index = { version = "0.12", features = ["local-builder"] }
time = { version = "0.3", features = ["serde"] }
toml-span = { version = "0.2", features = ["serde"] }
toml-span = { version = "0.3", features = ["serde"] }
# We use this for creating fake crate directories for crawling license files on disk
tempfile = "3.1.0"
# divan = "0.1"
Expand Down
7 changes: 7 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ disallowed-types = [

{ path = "ring::digest::SHA1_FOR_LEGACY_USE_ONLY", reason = "SHA-1 is cryptographically broken, and we are building new code so should not use it" },
]
disallowed-macros = [
"std::print",
"std::println",
"std::eprint",
"std::eprintln",
"std::dbg",
]
14 changes: 7 additions & 7 deletions examples/06_advisories/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions examples/06_advisories/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ dirs = "4.0"
# Failure has an unsound advisory (and is unmaintained)
failure = "=0.1.8"

# const-cstr is unmaintained
# https://github.com/rustsec/advisory-db/blob/463e8405f85bb74eef17149f7e704b07723ce46e/crates/const-cstr/RUSTSEC-2023-0020.md
const-cstr = "0.3"
# atty is unmaintained
# https://github.com/rustsec/advisory-db/blob/8eb99abe8c369b48bbd4ca04133e1f05be22a778/crates/static_type_map/RUSTSEC-2022-0023.md
static_type_map = "0.3"

# The advisory applies to 0.10.0-alpha.1 >= && < 0.10.0-alpha.4
# https://github.com/RustSec/advisory-db/blob/c71cfec8c3fe313c9445a9ab0ae9b7faedda850a/crates/lettre/RUSTSEC-2020-0069.md
Expand Down
12 changes: 3 additions & 9 deletions src/advisories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ pub fn check<R, S>(
let mut ignore_yanked_hits: BitVec = BitVec::repeat(false, ctx.cfg.ignore_yanked.len());

// Emit diagnostics for any advisories found that matched crates in the graph
for (krate, krate_index, advisory) in &report.advisories {
for (krate, advisory) in &report.advisories {
let diag = ctx.diag_for_advisory(
krate,
*krate_index,
&advisory.metadata,
Some(&advisory.versions),
|index| {
Expand All @@ -89,14 +88,9 @@ pub fn check<R, S>(
}

for (krate, status) in yanked {
let Some(ind) = ctx.krates.nid_for_kid(&krate.id) else {
log::warn!("failed to locate node id for '{krate}'");
continue;
};

if let Some(e) = status {
if ctx.cfg.yanked.value != LintLevel::Allow {
sink.push(ctx.diag_for_index_failure(krate, ind, e));
sink.push(ctx.diag_for_index_failure(krate, e));
}
} else {
// Check to see if the user has added an ignore for the yanked
Expand All @@ -113,7 +107,7 @@ pub fn check<R, S>(
sink.push(ctx.diag_for_yanked_ignore(krate, i));
ignore_yanked_hits.as_mut_bitslice().set(i, true);
} else {
sink.push(ctx.diag_for_yanked(krate, ind));
sink.push(ctx.diag_for_yanked(krate));
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/advisories/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl<'de> Deserialize<'de> for Config {
v.set(ValueInner::String(s));
}
ValueInner::Table(tab) => {
if tab.contains_key(&"id".into()) {
if tab.contains_key("id") {
v.set(ValueInner::Table(tab));
match IgnoreId::deserialize(&mut v) {
Ok(iid) => u.push(Spanned::with_span(iid, v.span)),
Expand Down Expand Up @@ -994,15 +994,15 @@ expansions = [
let toml_span::value::ValueInner::Table(mut tab) = tv.take() else {
unreachable!()
};
let mut expansions = tab.remove(&"expansions".into()).unwrap();
let mut expansions = tab.remove("expansions").unwrap();
let toml_span::value::ValueInner::Array(exp) = expansions.take() else {
unreachable!()
};

use toml_span::Deserialize as _;

let mut files = crate::diag::Files::new();
let cfg_id = files.add("expansions.toml", toml.into());
let cfg_id = files.add("expansions.toml", toml);

let mut output = String::new();

Expand Down
33 changes: 16 additions & 17 deletions src/advisories/diags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ impl<'a> crate::CheckCtx<'a, super::cfg::ValidConfig> {
pub(crate) fn diag_for_advisory<F>(
&self,
krate: &crate::Krate,
krate_index: krates::NodeId,
advisory: &Metadata,
versions: Option<&Versions>,
mut on_ignore: F,
Expand Down Expand Up @@ -179,9 +178,11 @@ impl<'a> crate::CheckCtx<'a, super::cfg::ValidConfig> {
let diag = pack.push(
Diagnostic::new(severity)
.with_message(advisory.title.clone())
.with_labels(vec![self
.krate_spans
.label_for_index(krate_index.index(), message)])
.with_labels(vec![Label::primary(
self.krate_spans.lock_id,
self.krate_spans.lock_span(&krate.id).total,
)
.with_message(message)])
.with_code(code)
.with_notes(notes),
);
Expand All @@ -193,11 +194,7 @@ impl<'a> crate::CheckCtx<'a, super::cfg::ValidConfig> {
pack
}

pub(crate) fn diag_for_yanked(
&self,
krate: &crate::Krate,
krate_index: krates::NodeId,
) -> Pack {
pub(crate) fn diag_for_yanked(&self, krate: &crate::Krate) -> Pack {
let mut pack = Pack::with_kid(Check::Advisories, krate.id.clone());
pack.push(
Diagnostic::new(self.cfg.yanked.value.into())
Expand All @@ -206,9 +203,11 @@ impl<'a> crate::CheckCtx<'a, super::cfg::ValidConfig> {
krate.name
))
.with_code(Code::Yanked)
.with_labels(vec![self
.krate_spans
.label_for_index(krate_index.index(), "yanked version")]),
.with_labels(vec![Label::primary(
self.krate_spans.lock_id,
self.krate_spans.lock_span(&krate.id).total,
)
.with_message("yanked version")]),
);

pack
Expand All @@ -229,13 +228,13 @@ impl<'a> crate::CheckCtx<'a, super::cfg::ValidConfig> {
pub(crate) fn diag_for_index_failure<D: std::fmt::Display>(
&self,
krate: &crate::Krate,
krate_index: krates::NodeId,
error: D,
) -> Pack {
let mut labels = vec![self.krate_spans.label_for_index(
krate_index.index(),
"crate whose registry we failed to query",
)];
let mut labels = vec![Label::secondary(
self.krate_spans.lock_id,
self.krate_spans.lock_span(&krate.id).total,
)
.with_message("crate whose registry we failed to query")];

// Don't show the config location if it's the default, since it just points
// to the beginning and confuses users
Expand Down
8 changes: 4 additions & 4 deletions src/advisories/helpers/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ fn fetch_via_cli(url: &str, db_path: &Path) -> anyhow::Result<()> {
}

pub struct Report<'db, 'k> {
pub advisories: Vec<(&'k Krate, krates::NodeId, &'db rustsec::Advisory)>,
pub advisories: Vec<(&'k Krate, &'db rustsec::Advisory)>,
/// For backwards compatibility with cargo-audit, we optionally serialize the
/// reports to JSON and output them in addition to the normal cargo-deny
/// diagnostics
Expand Down Expand Up @@ -599,7 +599,7 @@ impl<'db, 'k> Report<'db, 'k> {
return None;
}

Some((km.krate, km.node_id, advisory))
Some((km.krate, advisory))
})
})
.collect();
Expand All @@ -608,7 +608,7 @@ impl<'db, 'k> Report<'db, 'k> {
let mut warnings = std::collections::BTreeMap::<_, Vec<rustsec::Warning>>::new();
let mut vulns = Vec::new();

for (krate, _nid, advisory) in &db_advisories {
for (krate, advisory) in &db_advisories {
let package = rustsec::package::Package {
// :(
name: krate.name.parse().unwrap(),
Expand Down Expand Up @@ -687,7 +687,7 @@ impl<'db, 'k> Report<'db, 'k> {
advisories.append(&mut db_advisories);
}

advisories.sort_by(|a, b| a.1.cmp(&b.1));
advisories.sort_by(|a, b| a.0.cmp(b.0));

Self {
advisories,
Expand Down
Loading

0 comments on commit 6344cc5

Please sign in to comment.