mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
Lint for multiple versions of dependencies
This commit is contained in:
parent
1742229ebb
commit
7de706b34b
6 changed files with 86 additions and 0 deletions
|
@ -17,6 +17,7 @@ We have a bunch of lint categories to allow you to choose how much clippy is sup
|
|||
* `clippy_style` (code that should be written in a more idiomatic way)
|
||||
* `clippy_complexity` (code that does something simple but in a complex way)
|
||||
* `clippy_perf` (code that can be written in a faster way)
|
||||
* `clippy_cargo` (checks against the cargo manifest)
|
||||
* **`clippy_correctness`** (code that is just outright wrong or very very useless)
|
||||
|
||||
More to come, please [file an issue](https://github.com/rust-lang-nursery/rust-clippy/issues) if you have ideas!
|
||||
|
|
|
@ -16,6 +16,7 @@ license = "MPL-2.0"
|
|||
keywords = ["clippy", "lint", "plugin"]
|
||||
|
||||
[dependencies]
|
||||
cargo_metadata = "0.5"
|
||||
itertools = "0.7"
|
||||
lazy_static = "1.0"
|
||||
matches = "0.1.2"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#![feature(iterator_find_map)]
|
||||
|
||||
|
||||
extern crate cargo_metadata;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_typeck;
|
||||
|
@ -81,6 +82,9 @@ macro_rules! declare_clippy_lint {
|
|||
{ pub $name:tt, restriction, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description }
|
||||
};
|
||||
{ pub $name:tt, cargo, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description }
|
||||
};
|
||||
{ pub $name:tt, nursery, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description }
|
||||
};
|
||||
|
@ -158,6 +162,7 @@ pub mod minmax;
|
|||
pub mod misc;
|
||||
pub mod misc_early;
|
||||
pub mod missing_doc;
|
||||
pub mod multiple_crate_versions;
|
||||
pub mod mut_mut;
|
||||
pub mod mut_reference;
|
||||
pub mod mutex_atomic;
|
||||
|
@ -412,6 +417,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||
reg.register_late_lint_pass(box question_mark::QuestionMarkPass);
|
||||
reg.register_late_lint_pass(box suspicious_trait_impl::SuspiciousImpl);
|
||||
reg.register_late_lint_pass(box redundant_field_names::RedundantFieldNames);
|
||||
reg.register_early_lint_pass(box multiple_crate_versions::Pass);
|
||||
reg.register_late_lint_pass(box map_unit_fn::Pass);
|
||||
reg.register_late_lint_pass(box infallible_destructuring_match::Pass);
|
||||
|
||||
|
@ -895,6 +901,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||
vec::USELESS_VEC,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_cargo", vec![
|
||||
multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_nursery", vec![
|
||||
attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
fallible_impl_from::FALLIBLE_IMPL_FROM,
|
||||
|
|
72
clippy_lints/src/multiple_crate_versions.rs
Normal file
72
clippy_lints/src/multiple_crate_versions.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
//! lint on multiple versions of a crate being used
|
||||
|
||||
use rustc::lint::*;
|
||||
use syntax::ast::*;
|
||||
|
||||
use cargo_metadata;
|
||||
use itertools::Itertools;
|
||||
|
||||
/// **What it does:** Checks to see if multiple versions of a crate are being
|
||||
/// used.
|
||||
///
|
||||
/// **Why is this bad?** This bloats the size of targets, and can lead to
|
||||
/// confusing error messages when structs or traits are used interchangeably
|
||||
/// between different versions of a crate.
|
||||
///
|
||||
/// **Known problems:** Because this can be caused purely by the dependencies
|
||||
/// themselves, it's not always possible to fix this issue.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```toml
|
||||
/// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning.
|
||||
/// [dependencies]
|
||||
/// ctrlc = "3.1.0"
|
||||
/// ansi_term = "0.11.0"
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub MULTIPLE_CRATE_VERSIONS,
|
||||
cargo,
|
||||
"multiple versions of the same crate being used"
|
||||
}
|
||||
|
||||
pub struct Pass;
|
||||
|
||||
impl LintPass for Pass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MULTIPLE_CRATE_VERSIONS)
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for Pass {
|
||||
fn check_crate(&mut self, cx: &EarlyContext, krate: &Crate) {
|
||||
let metadata = match cargo_metadata::metadata_deps(None, true) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(_) => {
|
||||
cx.span_lint(
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
krate.span,
|
||||
"could not read cargo metadata"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut packages = metadata.packages;
|
||||
packages.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
|
||||
for (name, group) in &packages.into_iter().group_by(|p| p.name.clone()) {
|
||||
let group: Vec<cargo_metadata::Package> = group.collect();
|
||||
|
||||
if group.len() > 1 {
|
||||
let versions = group.into_iter().map(|p| p.version).join(", ");
|
||||
|
||||
cx.span_lint(
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
krate.span,
|
||||
&format!("multiple versions for dependency `{}`: {}", name, versions),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ lint_levels = {
|
|||
"restriction": 'Allow',
|
||||
"pedantic": 'Allow',
|
||||
"nursery": 'Allow',
|
||||
"cargo": 'Allow',
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ def main(print_only=False, check=False):
|
|||
"perf": [],
|
||||
"restriction": [],
|
||||
"pedantic": [],
|
||||
"cargo": [],
|
||||
"nursery": [],
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue