mirror of
https://github.com/rust-lang/cargo.git
synced 2026-03-24 20:10:25 +00:00
feat(lint): lint also workspace dependencies
This has a future performance that version requirments in `[workspace.dependencies]` shoud avoid reparse
This commit is contained in:
@@ -1340,6 +1340,13 @@ impl<'gctx> Workspace<'gctx> {
|
||||
|
||||
if self.gctx.cli_unstable().cargo_lints {
|
||||
// Calls to lint functions go in here
|
||||
implicit_minimum_version_req(
|
||||
self.root_maybe().into(),
|
||||
self.root_manifest(),
|
||||
&cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
}
|
||||
|
||||
// This is a short term hack to allow `blanket_hint_mostly_unused`
|
||||
|
||||
@@ -7,12 +7,14 @@ use annotate_snippets::Level;
|
||||
use annotate_snippets::Patch;
|
||||
use annotate_snippets::Snippet;
|
||||
use cargo_platform::Platform;
|
||||
use cargo_util_schemas::manifest::TomlDependency;
|
||||
use cargo_util_schemas::manifest::TomlToolLints;
|
||||
use toml::de::DeValue;
|
||||
|
||||
use crate::CargoResult;
|
||||
use crate::GlobalContext;
|
||||
use crate::core::Manifest;
|
||||
use crate::core::MaybePackage;
|
||||
use crate::core::Package;
|
||||
use crate::util::OptVersionReq;
|
||||
use crate::util::lints::Lint;
|
||||
@@ -98,6 +100,14 @@ pub fn implicit_minimum_version_req(
|
||||
ManifestFor::Package(pkg) => {
|
||||
lint_package(pkg, manifest_path, lint_level, reason, error_count, gctx)
|
||||
}
|
||||
ManifestFor::Workspace(maybe_pkg) => lint_workspace(
|
||||
maybe_pkg,
|
||||
manifest_path,
|
||||
lint_level,
|
||||
reason,
|
||||
error_count,
|
||||
gctx,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +161,72 @@ pub fn lint_package(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn lint_workspace(
|
||||
maybe_pkg: &MaybePackage,
|
||||
manifest_path: String,
|
||||
lint_level: LintLevel,
|
||||
reason: LintLevelReason,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
let document = maybe_pkg.document();
|
||||
let contents = maybe_pkg.contents();
|
||||
let toml = match maybe_pkg {
|
||||
MaybePackage::Package(p) => p.manifest().normalized_toml(),
|
||||
MaybePackage::Virtual(vm) => vm.normalized_toml(),
|
||||
};
|
||||
let dep_iter = toml
|
||||
.workspace
|
||||
.as_ref()
|
||||
.and_then(|ws| ws.dependencies.as_ref())
|
||||
.into_iter()
|
||||
.flat_map(|deps| deps.iter())
|
||||
.map(|(name, dep)| {
|
||||
let name = name.as_str();
|
||||
let ver = match dep {
|
||||
TomlDependency::Simple(ver) => ver,
|
||||
TomlDependency::Detailed(detailed) => {
|
||||
let Some(ver) = detailed.version.as_ref() else {
|
||||
return (name, OptVersionReq::Any);
|
||||
};
|
||||
ver
|
||||
}
|
||||
};
|
||||
let req = semver::VersionReq::parse(ver)
|
||||
.map(Into::into)
|
||||
.unwrap_or(OptVersionReq::Any);
|
||||
(name, req)
|
||||
});
|
||||
|
||||
for (name_in_toml, version_req) in dep_iter {
|
||||
let Some(suggested_req) = get_suggested_version_req(&version_req) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let key_path = ["workspace", "dependencies", name_in_toml];
|
||||
|
||||
let Some(span) = span_of_version_req(document, &key_path) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let report = report(
|
||||
lint_level,
|
||||
reason,
|
||||
span,
|
||||
contents,
|
||||
&manifest_path,
|
||||
&suggested_req,
|
||||
);
|
||||
|
||||
if lint_level.is_error() {
|
||||
*error_count += 1;
|
||||
}
|
||||
gctx.shell().print_report(&report, lint_level.force())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn span_of_version_req<'doc>(
|
||||
document: &'doc toml::Spanned<toml::de::DeTable<'static>>,
|
||||
path: &[&str],
|
||||
|
||||
@@ -23,6 +23,8 @@ pub const LINTS: &[Lint] = &[
|
||||
pub enum ManifestFor<'a> {
|
||||
/// Lint runs for a specific package.
|
||||
Package(&'a Package),
|
||||
/// Lint runs for workspace-level config.
|
||||
Workspace(&'a MaybePackage),
|
||||
}
|
||||
|
||||
impl ManifestFor<'_> {
|
||||
@@ -33,6 +35,7 @@ impl ManifestFor<'_> {
|
||||
p.manifest().edition(),
|
||||
p.manifest().unstable_features(),
|
||||
),
|
||||
ManifestFor::Workspace(p) => lint.level(pkg_lints, p.edition(), p.unstable_features()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +46,12 @@ impl<'a> From<&'a Package> for ManifestFor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a MaybePackage> for ManifestFor<'a> {
|
||||
fn from(value: &'a MaybePackage) -> ManifestFor<'a> {
|
||||
ManifestFor::Workspace(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn analyze_cargo_lints_table(
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
|
||||
@@ -1029,6 +1029,17 @@ workspace = true
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints"])
|
||||
.with_stderr_data(str![[r#"
|
||||
[WARNING] dependency version requirement without an explicit minimum version
|
||||
--> Cargo.toml:7:7
|
||||
|
|
||||
7 | dep = "1"
|
||||
| ^^^ missing full version components
|
||||
|
|
||||
[HELP] consider specifying full `major.minor.patch` version components
|
||||
|
|
||||
7 | dep = "1.0.0"
|
||||
| ++++
|
||||
= [NOTE] `cargo::implicit_minimum_version_req` is set to `warn` in `[lints]`
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] 1 package to latest compatible version
|
||||
[DOWNLOADING] crates ...
|
||||
@@ -1075,6 +1086,17 @@ edition = "2021"
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints"])
|
||||
.with_stderr_data(str![[r#"
|
||||
[WARNING] dependency version requirement without an explicit minimum version
|
||||
--> Cargo.toml:7:7
|
||||
|
|
||||
7 | dep = "1"
|
||||
| ^^^ missing full version components
|
||||
|
|
||||
[HELP] consider specifying full `major.minor.patch` version components
|
||||
|
|
||||
7 | dep = "1.0.0"
|
||||
| ++++
|
||||
= [NOTE] `cargo::implicit_minimum_version_req` is set to `warn` in `[lints]`
|
||||
[CHECKING] member v0.0.0 ([ROOT]/foo/member)
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
|
||||
|
||||
@@ -1122,6 +1144,17 @@ workspace = true
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints"])
|
||||
.with_stderr_data(str![[r#"
|
||||
[WARNING] dependency version requirement without an explicit minimum version
|
||||
--> Cargo.toml:7:7
|
||||
|
|
||||
7 | dep = "1"
|
||||
| ^^^ missing full version components
|
||||
|
|
||||
[HELP] consider specifying full `major.minor.patch` version components
|
||||
|
|
||||
7 | dep = "1.0.0"
|
||||
| ++++
|
||||
= [NOTE] `cargo::implicit_minimum_version_req` is set to `warn` in `[lints]`
|
||||
[WARNING] dependency version requirement without an explicit minimum version
|
||||
--> member/Cargo.toml:7:7
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user