Skip to content

Commit a2c9d10

Browse files
bors[bot]ysimonson
andcommitted
3419: Linter to check that all common metadata is included r=flip1995 a=ysimonson Addresses rust-lang#1793 This is not ready to be merged yet. First the associated changes to `cargo_metadata` need to be merged: oli-obk/cargo_metadata#55 Co-authored-by: Yusuf Simonson <[email protected]>
2 parents 7e0ddef + 866caab commit a2c9d10

File tree

6 files changed

+122
-3
lines changed

6 files changed

+122
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ All notable changes to this project will be documented in this file.
628628
[`box_vec`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#box_vec
629629
[`boxed_local`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#boxed_local
630630
[`builtin_type_shadow`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#builtin_type_shadow
631+
[`cargo_common_metadata`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cargo_common_metadata
631632
[`cast_lossless`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cast_lossless
632633
[`cast_possible_truncation`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cast_possible_truncation
633634
[`cast_possible_wrap`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cast_possible_wrap

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ rustc_tools_util = { version = "0.1.0", path = "rustc_tools_util"}
4747

4848
[dev-dependencies]
4949
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
50-
cargo_metadata = "0.6"
50+
cargo_metadata = "0.6.2"
5151
compiletest_rs = "0.3.16"
5252
lazy_static = "1.0"
5353
serde_derive = "1.0"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in
99

1010
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
1111

12-
[There are 287 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
12+
[There are 288 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
1313

1414
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1515

clippy_lints/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ keywords = ["clippy", "lint", "plugin"]
1717
edition = "2018"
1818

1919
[dependencies]
20-
cargo_metadata = "0.6"
20+
cargo_metadata = "0.6.2"
2121
itertools = "0.7"
2222
lazy_static = "1.0.2"
2323
matches = "0.1.7"
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution.
3+
//
4+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7+
// option. This file may not be copied, modified, or distributed
8+
// except according to those terms.
9+
10+
//! lint on missing cargo common metadata
11+
12+
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
13+
use crate::rustc::{declare_tool_lint, lint_array};
14+
use crate::syntax::{ast::*, source_map::DUMMY_SP};
15+
use crate::utils::span_lint;
16+
17+
use cargo_metadata;
18+
19+
/// **What it does:** Checks to see if all common metadata is defined in
20+
/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
21+
///
22+
/// **Why is this bad?** It will be more difficult for users to discover the
23+
/// purpose of the crate, and key information related to it.
24+
///
25+
/// **Known problems:** None.
26+
///
27+
/// **Example:**
28+
/// ```toml
29+
/// # This `Cargo.toml` is missing an authors field:
30+
/// [package]
31+
/// name = "clippy"
32+
/// version = "0.0.212"
33+
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
34+
/// repository = "https://github.com/rust-lang-nursery/rust-clippy"
35+
/// readme = "README.md"
36+
/// license = "MIT/Apache-2.0"
37+
/// keywords = ["clippy", "lint", "plugin"]
38+
/// categories = ["development-tools", "development-tools::cargo-plugins"]
39+
/// ```
40+
declare_clippy_lint! {
41+
pub CARGO_COMMON_METADATA,
42+
cargo,
43+
"common metadata is defined in `Cargo.toml`"
44+
}
45+
46+
fn warning(cx: &EarlyContext<'_>, message: &str) {
47+
span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);
48+
}
49+
50+
fn missing_warning(cx: &EarlyContext<'_>, package: &cargo_metadata::Package, field: &str) {
51+
let message = format!("package `{}` is missing `{}` metadata", package.name, field);
52+
warning(cx, &message);
53+
}
54+
55+
fn is_empty_str(value: &Option<String>) -> bool {
56+
match value {
57+
None => true,
58+
Some(value) if value.is_empty() => true,
59+
_ => false
60+
}
61+
}
62+
63+
fn is_empty_vec(value: &[String]) -> bool {
64+
// This works because empty iterators return true
65+
value.iter().all(|v| v.is_empty())
66+
}
67+
68+
pub struct Pass;
69+
70+
impl LintPass for Pass {
71+
fn get_lints(&self) -> LintArray {
72+
lint_array!(CARGO_COMMON_METADATA)
73+
}
74+
}
75+
76+
impl EarlyLintPass for Pass {
77+
fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &Crate) {
78+
let metadata = if let Ok(metadata) = cargo_metadata::metadata_deps(None, true) {
79+
metadata
80+
} else {
81+
warning(cx, "could not read cargo metadata");
82+
return;
83+
};
84+
85+
for package in metadata.packages {
86+
if is_empty_vec(&package.authors) {
87+
missing_warning(cx, &package, "package.authors");
88+
}
89+
90+
if is_empty_str(&package.description) {
91+
missing_warning(cx, &package, "package.description");
92+
}
93+
94+
if is_empty_str(&package.license) {
95+
missing_warning(cx, &package, "package.license");
96+
}
97+
98+
if is_empty_str(&package.repository) {
99+
missing_warning(cx, &package, "package.repository");
100+
}
101+
102+
if is_empty_str(&package.readme) {
103+
missing_warning(cx, &package, "package.readme");
104+
}
105+
106+
if is_empty_vec(&package.keywords) {
107+
missing_warning(cx, &package, "package.keywords");
108+
}
109+
110+
if is_empty_vec(&package.categories) {
111+
missing_warning(cx, &package, "package.categories");
112+
}
113+
}
114+
}
115+
}

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub mod blacklisted_name;
9696
pub mod block_in_if_condition;
9797
pub mod booleans;
9898
pub mod bytecount;
99+
pub mod cargo_common_metadata;
99100
pub mod collapsible_if;
100101
pub mod const_static_lifetime;
101102
pub mod copies;
@@ -444,6 +445,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
444445
reg.register_late_lint_pass(box double_comparison::Pass);
445446
reg.register_late_lint_pass(box question_mark::Pass);
446447
reg.register_late_lint_pass(box suspicious_trait_impl::SuspiciousImpl);
448+
reg.register_early_lint_pass(box cargo_common_metadata::Pass);
447449
reg.register_early_lint_pass(box multiple_crate_versions::Pass);
448450
reg.register_early_lint_pass(box wildcard_dependencies::Pass);
449451
reg.register_late_lint_pass(box map_unit_fn::Pass);
@@ -985,6 +987,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
985987
]);
986988

987989
reg.register_lint_group("clippy::cargo", Some("clippy_cargo"), vec![
990+
cargo_common_metadata::CARGO_COMMON_METADATA,
988991
multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
989992
wildcard_dependencies::WILDCARD_DEPENDENCIES,
990993
]);

0 commit comments

Comments
 (0)