about summary refs log tree commit diff
path: root/clippy_lints
diff options
context:
space:
mode:
authorYusuf Simonson <simonson@gmail.com>2018-11-13 08:43:30 -0500
committerYusuf Simonson <simonson@gmail.com>2018-11-13 08:43:30 -0500
commit866caabb7a1308ee263992414def2074b00db514 (patch)
tree11d3446cbe9dc5d5397b3624fe658119e2b35034 /clippy_lints
parent3bb88775de5a6f8f5c5743dd11af6c820122ccc7 (diff)
downloadrust-866caabb7a1308ee263992414def2074b00db514.tar.gz
rust-866caabb7a1308ee263992414def2074b00db514.zip
Check for common metadata
Diffstat (limited to 'clippy_lints')
-rw-r--r--clippy_lints/Cargo.toml2
-rw-r--r--clippy_lints/src/cargo_common_metadata.rs115
-rw-r--r--clippy_lints/src/lib.rs3
3 files changed, 119 insertions, 1 deletions
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index 8907dd3659c..fa1b22784bd 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -17,7 +17,7 @@ keywords = ["clippy", "lint", "plugin"]
 edition = "2018"
 
 [dependencies]
-cargo_metadata = "0.6"
+cargo_metadata = "0.6.2"
 itertools = "0.7"
 lazy_static = "1.0.2"
 matches = "0.1.7"
diff --git a/clippy_lints/src/cargo_common_metadata.rs b/clippy_lints/src/cargo_common_metadata.rs
new file mode 100644
index 00000000000..1a053de27d1
--- /dev/null
+++ b/clippy_lints/src/cargo_common_metadata.rs
@@ -0,0 +1,115 @@
+// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! lint on missing cargo common metadata
+
+use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
+use crate::rustc::{declare_tool_lint, lint_array};
+use crate::syntax::{ast::*, source_map::DUMMY_SP};
+use crate::utils::span_lint;
+
+use cargo_metadata;
+
+/// **What it does:** Checks to see if all common metadata is defined in
+/// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata
+///
+/// **Why is this bad?** It will be more difficult for users to discover the
+/// purpose of the crate, and key information related to it.
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```toml
+/// # This `Cargo.toml` is missing an authors field:
+/// [package]
+/// name = "clippy"
+/// version = "0.0.212"
+/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
+/// repository = "https://github.com/rust-lang-nursery/rust-clippy"
+/// readme = "README.md"
+/// license = "MIT/Apache-2.0"
+/// keywords = ["clippy", "lint", "plugin"]
+/// categories = ["development-tools", "development-tools::cargo-plugins"]
+/// ```
+declare_clippy_lint! {
+    pub CARGO_COMMON_METADATA,
+    cargo,
+    "common metadata is defined in `Cargo.toml`"
+}
+
+fn warning(cx: &EarlyContext<'_>, message: &str) {
+    span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);
+}
+
+fn missing_warning(cx: &EarlyContext<'_>, package: &cargo_metadata::Package, field: &str) {
+    let message = format!("package `{}` is missing `{}` metadata", package.name, field);
+    warning(cx, &message);
+}
+
+fn is_empty_str(value: &Option<String>) -> bool {
+    match value {
+        None => true,
+        Some(value) if value.is_empty() => true,
+        _ => false
+    }
+}
+
+fn is_empty_vec(value: &[String]) -> bool {
+    // This works because empty iterators return true
+    value.iter().all(|v| v.is_empty())
+}
+
+pub struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(CARGO_COMMON_METADATA)
+    }
+}
+
+impl EarlyLintPass for Pass {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &Crate) {
+        let metadata = if let Ok(metadata) = cargo_metadata::metadata_deps(None, true) {
+            metadata
+        } else {
+            warning(cx, "could not read cargo metadata");
+            return;
+        };
+
+        for package in metadata.packages {
+            if is_empty_vec(&package.authors) {
+                missing_warning(cx, &package, "package.authors");
+            }
+
+            if is_empty_str(&package.description) {
+                missing_warning(cx, &package, "package.description");
+            }
+
+            if is_empty_str(&package.license) {
+                missing_warning(cx, &package, "package.license");
+            }
+
+            if is_empty_str(&package.repository) {
+                missing_warning(cx, &package, "package.repository");
+            }
+
+            if is_empty_str(&package.readme) {
+                missing_warning(cx, &package, "package.readme");
+            }
+
+            if is_empty_vec(&package.keywords) {
+                missing_warning(cx, &package, "package.keywords");
+            }
+
+            if is_empty_vec(&package.categories) {
+                missing_warning(cx, &package, "package.categories");
+            }
+        }
+    }
+}
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index c93e9d57d67..6ebe9df6a1e 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -96,6 +96,7 @@ pub mod blacklisted_name;
 pub mod block_in_if_condition;
 pub mod booleans;
 pub mod bytecount;
+pub mod cargo_common_metadata;
 pub mod collapsible_if;
 pub mod const_static_lifetime;
 pub mod copies;
@@ -444,6 +445,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
     reg.register_late_lint_pass(box double_comparison::Pass);
     reg.register_late_lint_pass(box question_mark::Pass);
     reg.register_late_lint_pass(box suspicious_trait_impl::SuspiciousImpl);
+    reg.register_early_lint_pass(box cargo_common_metadata::Pass);
     reg.register_early_lint_pass(box multiple_crate_versions::Pass);
     reg.register_early_lint_pass(box wildcard_dependencies::Pass);
     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) {
     ]);
 
     reg.register_lint_group("clippy::cargo", Some("clippy_cargo"), vec![
+        cargo_common_metadata::CARGO_COMMON_METADATA,
         multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
         wildcard_dependencies::WILDCARD_DEPENDENCIES,
     ]);