mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #5636 - ebroto:issue_5041, r=phansch
multiple_crate_versions: skip dev and build deps changelog: multiple_crate_versions: skip dev and build deps Closes #5041
This commit is contained in:
commit
182ac89f16
@ -76,7 +76,8 @@ fn create_test(lint: &LintData) -> io::Result<()> {
|
|||||||
|
|
||||||
path.push("src");
|
path.push("src");
|
||||||
fs::create_dir(&path)?;
|
fs::create_dir(&path)?;
|
||||||
write_file(path.join("main.rs"), get_test_file_contents(lint_name))?;
|
let header = format!("// compile-flags: --crate-name={}", lint_name);
|
||||||
|
write_file(path.join("main.rs"), get_test_file_contents(lint_name, Some(&header)))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -90,7 +91,7 @@ fn create_test(lint: &LintData) -> io::Result<()> {
|
|||||||
create_project_layout(lint.name, &test_dir, "pass", "This file should not trigger the lint")
|
create_project_layout(lint.name, &test_dir, "pass", "This file should not trigger the lint")
|
||||||
} else {
|
} else {
|
||||||
let test_path = format!("tests/ui/{}.rs", lint.name);
|
let test_path = format!("tests/ui/{}.rs", lint.name);
|
||||||
let test_contents = get_test_file_contents(lint.name);
|
let test_contents = get_test_file_contents(lint.name, None);
|
||||||
write_file(lint.project_root.join(test_path), test_contents)
|
write_file(lint.project_root.join(test_path), test_contents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,8 +120,8 @@ fn to_camel_case(name: &str) -> String {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_test_file_contents(lint_name: &str) -> String {
|
fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
|
||||||
format!(
|
let mut contents = format!(
|
||||||
"#![warn(clippy::{})]
|
"#![warn(clippy::{})]
|
||||||
|
|
||||||
fn main() {{
|
fn main() {{
|
||||||
@ -128,7 +129,13 @@ fn main() {{
|
|||||||
}}
|
}}
|
||||||
",
|
",
|
||||||
lint_name
|
lint_name
|
||||||
)
|
);
|
||||||
|
|
||||||
|
if let Some(header) = header_commands {
|
||||||
|
contents = format!("{}\n{}", header, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
contents
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
|
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
//! lint on multiple versions of a crate being used
|
//! lint on multiple versions of a crate being used
|
||||||
|
|
||||||
use crate::utils::{run_lints, span_lint};
|
use crate::utils::{run_lints, span_lint};
|
||||||
|
use rustc_hir::def_id::LOCAL_CRATE;
|
||||||
use rustc_hir::{Crate, CRATE_HIR_ID};
|
use rustc_hir::{Crate, CRATE_HIR_ID};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::source_map::DUMMY_SP;
|
use rustc_span::source_map::DUMMY_SP;
|
||||||
|
|
||||||
|
use cargo_metadata::{DependencyKind, MetadataCommand, Node, Package, PackageId};
|
||||||
|
use if_chain::if_chain;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -39,32 +42,61 @@ impl LateLintPass<'_, '_> for MultipleCrateVersions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = if let Ok(metadata) = cargo_metadata::MetadataCommand::new().exec() {
|
let metadata = if let Ok(metadata) = MetadataCommand::new().exec() {
|
||||||
metadata
|
metadata
|
||||||
} else {
|
} else {
|
||||||
span_lint(cx, MULTIPLE_CRATE_VERSIONS, DUMMY_SP, "could not read cargo metadata");
|
span_lint(cx, MULTIPLE_CRATE_VERSIONS, DUMMY_SP, "could not read cargo metadata");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let local_name = cx.tcx.crate_name(LOCAL_CRATE).as_str();
|
||||||
let mut packages = metadata.packages;
|
let mut packages = metadata.packages;
|
||||||
packages.sort_by(|a, b| a.name.cmp(&b.name));
|
packages.sort_by(|a, b| a.name.cmp(&b.name));
|
||||||
|
|
||||||
for (name, group) in &packages.into_iter().group_by(|p| p.name.clone()) {
|
if_chain! {
|
||||||
let group: Vec<cargo_metadata::Package> = group.collect();
|
if let Some(resolve) = &metadata.resolve;
|
||||||
|
if let Some(local_id) = packages
|
||||||
|
.iter()
|
||||||
|
.find_map(|p| if p.name == *local_name { Some(&p.id) } else { None });
|
||||||
|
then {
|
||||||
|
for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
|
||||||
|
let group: Vec<&Package> = group.collect();
|
||||||
|
|
||||||
if group.len() > 1 {
|
if group.len() <= 1 {
|
||||||
let mut versions: Vec<_> = group.into_iter().map(|p| p.version).collect();
|
continue;
|
||||||
versions.sort();
|
}
|
||||||
let versions = versions.iter().join(", ");
|
|
||||||
|
|
||||||
span_lint(
|
if group.iter().all(|p| is_normal_dep(&resolve.nodes, local_id, &p.id)) {
|
||||||
cx,
|
let mut versions: Vec<_> = group.into_iter().map(|p| &p.version).collect();
|
||||||
MULTIPLE_CRATE_VERSIONS,
|
versions.sort();
|
||||||
DUMMY_SP,
|
let versions = versions.iter().join(", ");
|
||||||
&format!("multiple versions for dependency `{}`: {}", name, versions),
|
|
||||||
);
|
span_lint(
|
||||||
|
cx,
|
||||||
|
MULTIPLE_CRATE_VERSIONS,
|
||||||
|
DUMMY_SP,
|
||||||
|
&format!("multiple versions for dependency `{}`: {}", name, versions),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_normal_dep(nodes: &[Node], local_id: &PackageId, dep_id: &PackageId) -> bool {
|
||||||
|
fn depends_on(node: &Node, dep_id: &PackageId) -> bool {
|
||||||
|
node.deps.iter().any(|dep| {
|
||||||
|
dep.pkg == *dep_id
|
||||||
|
&& dep
|
||||||
|
.dep_kinds
|
||||||
|
.iter()
|
||||||
|
.any(|info| matches!(info.kind, DependencyKind::Normal))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes
|
||||||
|
.iter()
|
||||||
|
.filter(|node| depends_on(node, dep_id))
|
||||||
|
.any(|node| node.id == *local_id || is_normal_dep(nodes, local_id, &node.id))
|
||||||
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=cargo_common_metadata
|
||||||
#![warn(clippy::cargo_common_metadata)]
|
#![warn(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=cargo_common_metadata
|
||||||
#![warn(clippy::cargo_common_metadata)]
|
#![warn(clippy::cargo_common_metadata)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
# Should not lint for dev or build dependencies. See issue 5041.
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "multiple_crate_versions"
|
||||||
|
version = "0.1.0"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
# One of the versions of winapi is only a dev dependency: allowed
|
||||||
|
[dependencies]
|
||||||
|
ctrlc = "=3.1.0"
|
||||||
|
[dev-dependencies]
|
||||||
|
ansi_term = "=0.11.0"
|
||||||
|
|
||||||
|
# Both versions of winapi are a build dependency: allowed
|
||||||
|
[build-dependencies]
|
||||||
|
ctrlc = "=3.1.0"
|
||||||
|
ansi_term = "=0.11.0"
|
@ -0,0 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=multiple_crate_versions
|
||||||
|
#![warn(clippy::multiple_crate_versions)]
|
||||||
|
|
||||||
|
fn main() {}
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=multiple_crate_versions
|
||||||
#![warn(clippy::multiple_crate_versions)]
|
#![warn(clippy::multiple_crate_versions)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=multiple_crate_versions
|
||||||
#![warn(clippy::multiple_crate_versions)]
|
#![warn(clippy::multiple_crate_versions)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=wildcard_dependencies
|
||||||
#![warn(clippy::wildcard_dependencies)]
|
#![warn(clippy::wildcard_dependencies)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// compile-flags: --crate-name=wildcard_dependencies
|
||||||
#![warn(clippy::wildcard_dependencies)]
|
#![warn(clippy::wildcard_dependencies)]
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user