From a6ab226516f2f0f75f52bf581be34c8062043ebd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 4 Nov 2024 21:45:12 +0100 Subject: [PATCH] Do not run `include_file_outside_project` lint if crate is `publish = false` --- .../src/include_file_outside_project.rs | 38 ++++++++++++++++--- clippy_lints/src/lib.rs | 2 +- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/include_file_outside_project.rs b/clippy_lints/src/include_file_outside_project.rs index 123de6afe4a0..e7600e84f517 100644 --- a/clippy_lints/src/include_file_outside_project.rs +++ b/clippy_lints/src/include_file_outside_project.rs @@ -5,9 +5,12 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{FileName, Span, sym}; +use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::macros::root_macro_call_first_node; +use cargo_metadata::MetadataCommand; + use std::path::{Path, PathBuf}; declare_clippy_lint! { @@ -42,15 +45,34 @@ declare_clippy_lint! { pub(crate) struct IncludeFileOutsideProject { cargo_manifest_dir: Option, warned_spans: FxHashSet, + can_check_crate: bool, } impl_lint_pass!(IncludeFileOutsideProject => [INCLUDE_FILE_OUTSIDE_PROJECT]); impl IncludeFileOutsideProject { - pub(crate) fn new() -> Self { + pub(crate) fn new(conf: &'static Conf) -> Self { + let mut can_check_crate = true; + if !conf.cargo_ignore_publish { + match MetadataCommand::new().no_deps().exec() { + Ok(metadata) => { + for package in &metadata.packages { + // only run the lint if publish is `None` (`publish = true` or skipped entirely) + // or if the vector isn't empty (`publish = ["something"]`) + if !matches!(package.publish.as_deref(), Some([]) | None) { + can_check_crate = false; + break; + } + } + }, + Err(_) => can_check_crate = false, + } + } + Self { - cargo_manifest_dir: std::env::var("CARGO_MANIFEST_DIR").ok().map(|dir| PathBuf::from(dir)), + cargo_manifest_dir: std::env::var("CARGO_MANIFEST_DIR").ok().map(PathBuf::from), warned_spans: FxHashSet::default(), + can_check_crate, } } @@ -72,12 +94,12 @@ impl IncludeFileOutsideProject { } } - fn is_part_of_project_dir(&self, file_path: &PathBuf) -> bool { + fn is_part_of_project_dir(&self, file_path: &Path) -> bool { if let Some(ref cargo_manifest_dir) = self.cargo_manifest_dir { // Check if both paths start with the same thing. let mut file_iter = file_path.iter(); - for cargo_item in cargo_manifest_dir.iter() { + for cargo_item in cargo_manifest_dir { match file_iter.next() { Some(file_path) if file_path == cargo_item => {}, _ => { @@ -141,6 +163,9 @@ impl IncludeFileOutsideProject { impl LateLintPass<'_> for IncludeFileOutsideProject { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) { + if !self.can_check_crate { + return; + } if !expr.span.from_expansion() { self.check_hir_id(cx, expr.span, expr.hir_id); } else if let ExprKind::Lit(lit) = &expr.kind @@ -156,12 +181,15 @@ impl LateLintPass<'_> for IncludeFileOutsideProject { fn check_item(&mut self, cx: &LateContext<'_>, item: &'_ Item<'_>) { // Interestingly enough, `include!` content is not considered expanded. Which allows us // to easily filter out items we're not interested into. - if !item.span.from_expansion() { + if self.can_check_crate && !item.span.from_expansion() { self.check_hir_id(cx, item.span, item.hir_id()); } } fn check_attributes(&mut self, cx: &LateContext<'_>, attrs: &[Attribute]) { + if !self.can_check_crate { + return; + } for attr in attrs { if let Some(attr) = attr.meta() { self.check_attribute(cx, &attr); diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 5bf0a6946c2f..74981b5ebcd6 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -951,7 +951,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf))); store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp)); store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)); - store.register_late_pass(|_| Box::new(include_file_outside_project::IncludeFileOutsideProject::new())); + store.register_late_pass(move |_| Box::new(include_file_outside_project::IncludeFileOutsideProject::new(conf))); store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf))); // add lints here, do not remove this comment, it's used in `new_lint` }