mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:49:50 +00:00
Respect file exclusions in ruff server
(#11590)
## Summary Closes https://github.com/astral-sh/ruff/issues/11587. ## Test Plan - Added a lint error to `test_server.py` in `vscode-ruff`. - Validated that, prior to this change, diagnostics appeared in the file. - Validated that, with this change, no diagnostics were shown. - Validated that, with this change, no diagnostics were fixed on-save.
This commit is contained in:
parent
531ae5227c
commit
204c59e353
11 changed files with 235 additions and 43 deletions
|
@ -1,3 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use ruff_linter::{
|
||||
linter::{FixerResult, LinterResult},
|
||||
packaging::detect_package_root,
|
||||
|
@ -5,8 +9,8 @@ use ruff_linter::{
|
|||
};
|
||||
use ruff_notebook::SourceValue;
|
||||
use ruff_source_file::LineIndex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::borrow::Cow;
|
||||
use ruff_workspace::resolver::match_any_exclusion;
|
||||
use ruff_workspace::FileResolverSettings;
|
||||
|
||||
use crate::{
|
||||
edit::{Replacement, ToRangeExt},
|
||||
|
@ -20,12 +24,29 @@ pub(crate) type Fixes = FxHashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>;
|
|||
|
||||
pub(crate) fn fix_all(
|
||||
query: &DocumentQuery,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<Fixes> {
|
||||
let document_path = query.file_path();
|
||||
let source_kind = query.make_source_kind();
|
||||
|
||||
// If the document is excluded, return an empty list of fixes.
|
||||
if let Some(exclusion) = match_any_exclusion(
|
||||
document_path,
|
||||
&file_resolver_settings.exclude,
|
||||
&file_resolver_settings.extend_exclude,
|
||||
Some(&linter_settings.exclude),
|
||||
None,
|
||||
) {
|
||||
tracing::debug!(
|
||||
"Ignored path via `{}`: {}",
|
||||
exclusion,
|
||||
document_path.display()
|
||||
);
|
||||
return Ok(Fixes::default());
|
||||
}
|
||||
|
||||
let package = detect_package_root(
|
||||
document_path
|
||||
.parent()
|
||||
|
|
|
@ -16,6 +16,8 @@ use ruff_python_index::Indexer;
|
|||
use ruff_python_parser::AsMode;
|
||||
use ruff_source_file::{LineIndex, Locator};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use ruff_workspace::resolver::match_any_exclusion;
|
||||
use ruff_workspace::FileResolverSettings;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -60,12 +62,29 @@ pub(crate) type Diagnostics = FxHashMap<lsp_types::Url, Vec<lsp_types::Diagnosti
|
|||
|
||||
pub(crate) fn check(
|
||||
query: &DocumentQuery,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> Diagnostics {
|
||||
let document_path = query.file_path();
|
||||
let source_kind = query.make_source_kind();
|
||||
|
||||
// If the document is excluded, return an empty list of diagnostics.
|
||||
if let Some(exclusion) = match_any_exclusion(
|
||||
document_path,
|
||||
&file_resolver_settings.exclude,
|
||||
&file_resolver_settings.extend_exclude,
|
||||
Some(&linter_settings.exclude),
|
||||
None,
|
||||
) {
|
||||
tracing::debug!(
|
||||
"Ignored path via `{}`: {}",
|
||||
exclusion,
|
||||
document_path.display()
|
||||
);
|
||||
return Diagnostics::default();
|
||||
}
|
||||
|
||||
let package = detect_package_root(
|
||||
document_path
|
||||
.parent()
|
||||
|
|
|
@ -10,6 +10,7 @@ pub(super) fn generate_diagnostics(snapshot: &DocumentSnapshot) -> Diagnostics {
|
|||
if snapshot.client_settings().lint() {
|
||||
crate::lint::check(
|
||||
snapshot.query(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
use lsp_server::ErrorCode;
|
||||
use lsp_types::{self as types, request as req};
|
||||
use rustc_hash::FxHashSet;
|
||||
use types::{CodeActionKind, CodeActionOrCommand};
|
||||
|
||||
use crate::edit::WorkspaceEditTracker;
|
||||
use crate::lint::{fixes_for_diagnostics, DiagnosticFix};
|
||||
use crate::server::api::LSPResult;
|
||||
|
@ -5,10 +10,6 @@ use crate::server::SupportedCodeAction;
|
|||
use crate::server::{client::Notifier, Result};
|
||||
use crate::session::DocumentSnapshot;
|
||||
use crate::DIAGNOSTIC_NAME;
|
||||
use lsp_server::ErrorCode;
|
||||
use lsp_types::{self as types, request as req};
|
||||
use rustc_hash::FxHashSet;
|
||||
use types::{CodeActionKind, CodeActionOrCommand};
|
||||
|
||||
use super::code_action_resolve::{resolve_edit_for_fix_all, resolve_edit_for_organize_imports};
|
||||
|
||||
|
@ -156,6 +157,7 @@ fn fix_all(snapshot: &DocumentSnapshot) -> crate::Result<CodeActionOrCommand> {
|
|||
Some(resolve_edit_for_fix_all(
|
||||
document,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)?),
|
||||
|
@ -192,6 +194,7 @@ fn notebook_fix_all(snapshot: &DocumentSnapshot) -> crate::Result<CodeActionOrCo
|
|||
Some(resolve_edit_for_fix_all(
|
||||
document,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)?),
|
||||
|
@ -228,6 +231,7 @@ fn organize_imports(snapshot: &DocumentSnapshot) -> crate::Result<CodeActionOrCo
|
|||
Some(resolve_edit_for_organize_imports(
|
||||
document,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)?),
|
||||
|
@ -264,6 +268,7 @@ fn notebook_organize_imports(snapshot: &DocumentSnapshot) -> crate::Result<CodeA
|
|||
Some(resolve_edit_for_organize_imports(
|
||||
document,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)?),
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use lsp_server::ErrorCode;
|
||||
use lsp_types::{self as types, request as req};
|
||||
|
||||
use ruff_linter::codes::Rule;
|
||||
use ruff_linter::settings::LinterSettings;
|
||||
use ruff_workspace::FileResolverSettings;
|
||||
|
||||
use crate::edit::WorkspaceEditTracker;
|
||||
use crate::fix::Fixes;
|
||||
use crate::server::api::LSPResult;
|
||||
|
@ -7,10 +14,6 @@ use crate::server::SupportedCodeAction;
|
|||
use crate::server::{client::Notifier, Result};
|
||||
use crate::session::{DocumentQuery, DocumentSnapshot, ResolvedClientCapabilities};
|
||||
use crate::PositionEncoding;
|
||||
use lsp_server::ErrorCode;
|
||||
use lsp_types::{self as types, request as req};
|
||||
use ruff_linter::codes::Rule;
|
||||
use ruff_linter::settings::LinterSettings;
|
||||
|
||||
pub(crate) struct CodeActionResolve;
|
||||
|
||||
|
@ -22,7 +25,7 @@ impl super::BackgroundDocumentRequestHandler for CodeActionResolve {
|
|||
fn document_url(params: &types::CodeAction) -> Cow<types::Url> {
|
||||
let uri: lsp_types::Url = serde_json::from_value(params.data.clone().unwrap_or_default())
|
||||
.expect("code actions should have a URI in their data fields");
|
||||
std::borrow::Cow::Owned(uri)
|
||||
Cow::Owned(uri)
|
||||
}
|
||||
fn run_with_snapshot(
|
||||
snapshot: DocumentSnapshot,
|
||||
|
@ -54,6 +57,7 @@ impl super::BackgroundDocumentRequestHandler for CodeActionResolve {
|
|||
resolve_edit_for_fix_all(
|
||||
query,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
query.settings().file_resolver(),
|
||||
query.settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
|
@ -64,6 +68,7 @@ impl super::BackgroundDocumentRequestHandler for CodeActionResolve {
|
|||
resolve_edit_for_organize_imports(
|
||||
query,
|
||||
snapshot.resolved_client_capabilities(),
|
||||
query.settings().file_resolver(),
|
||||
query.settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
|
@ -84,12 +89,13 @@ impl super::BackgroundDocumentRequestHandler for CodeActionResolve {
|
|||
pub(super) fn resolve_edit_for_fix_all(
|
||||
query: &DocumentQuery,
|
||||
client_capabilities: &ResolvedClientCapabilities,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<types::WorkspaceEdit> {
|
||||
let mut tracker = WorkspaceEditTracker::new(client_capabilities);
|
||||
tracker.set_fixes_for_document(
|
||||
fix_all_edit(query, linter_settings, encoding)?,
|
||||
fix_all_edit(query, file_resolver_settings, linter_settings, encoding)?,
|
||||
query.version(),
|
||||
)?;
|
||||
Ok(tracker.into_workspace_edit())
|
||||
|
@ -97,21 +103,23 @@ pub(super) fn resolve_edit_for_fix_all(
|
|||
|
||||
pub(super) fn fix_all_edit(
|
||||
query: &DocumentQuery,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<Fixes> {
|
||||
crate::fix::fix_all(query, linter_settings, encoding)
|
||||
crate::fix::fix_all(query, file_resolver_settings, linter_settings, encoding)
|
||||
}
|
||||
|
||||
pub(super) fn resolve_edit_for_organize_imports(
|
||||
query: &DocumentQuery,
|
||||
client_capabilities: &ResolvedClientCapabilities,
|
||||
linter_settings: &ruff_linter::settings::LinterSettings,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<types::WorkspaceEdit> {
|
||||
let mut tracker = WorkspaceEditTracker::new(client_capabilities);
|
||||
tracker.set_fixes_for_document(
|
||||
organize_imports_edit(query, linter_settings, encoding)?,
|
||||
organize_imports_edit(query, file_resolver_settings, linter_settings, encoding)?,
|
||||
query.version(),
|
||||
)?;
|
||||
Ok(tracker.into_workspace_edit())
|
||||
|
@ -119,6 +127,7 @@ pub(super) fn resolve_edit_for_organize_imports(
|
|||
|
||||
pub(super) fn organize_imports_edit(
|
||||
query: &DocumentQuery,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<Fixes> {
|
||||
|
@ -130,5 +139,5 @@ pub(super) fn organize_imports_edit(
|
|||
.into_iter()
|
||||
.collect();
|
||||
|
||||
crate::fix::fix_all(query, &linter_settings, encoding)
|
||||
crate::fix::fix_all(query, file_resolver_settings, &linter_settings, encoding)
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
|||
Command::FixAll => {
|
||||
let fixes = super::code_action_resolve::fix_all_edit(
|
||||
snapshot.query(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
|
@ -81,6 +82,7 @@ impl super::SyncRequestHandler for ExecuteCommand {
|
|||
Command::OrganizeImports => {
|
||||
let fixes = super::code_action_resolve::organize_imports_edit(
|
||||
snapshot.query(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().linter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
use std::path::Path;
|
||||
|
||||
use lsp_types::{self as types, request as req};
|
||||
use types::TextEdit;
|
||||
|
||||
use ruff_python_ast::PySourceType;
|
||||
use ruff_source_file::LineIndex;
|
||||
use ruff_workspace::resolver::match_any_exclusion;
|
||||
use ruff_workspace::{FileResolverSettings, FormatterSettings};
|
||||
|
||||
use crate::edit::{Replacement, ToRangeExt};
|
||||
use crate::fix::Fixes;
|
||||
use crate::server::api::LSPResult;
|
||||
use crate::server::{client::Notifier, Result};
|
||||
use crate::session::DocumentSnapshot;
|
||||
use crate::{PositionEncoding, TextDocument};
|
||||
use lsp_types::{self as types, request as req};
|
||||
use ruff_python_ast::PySourceType;
|
||||
use ruff_source_file::LineIndex;
|
||||
use ruff_workspace::FormatterSettings;
|
||||
use types::TextEdit;
|
||||
|
||||
pub(crate) struct Format;
|
||||
|
||||
|
@ -39,6 +44,8 @@ pub(super) fn format_full_document(snapshot: &DocumentSnapshot) -> Result<Fixes>
|
|||
if let Some(changes) = format_text_document(
|
||||
text_document,
|
||||
snapshot.query().source_type(),
|
||||
snapshot.query().file_path(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().formatter(),
|
||||
snapshot.encoding(),
|
||||
true,
|
||||
|
@ -50,6 +57,8 @@ pub(super) fn format_full_document(snapshot: &DocumentSnapshot) -> Result<Fixes>
|
|||
if let Some(changes) = format_text_document(
|
||||
snapshot.query().as_single_document().unwrap(),
|
||||
snapshot.query().source_type(),
|
||||
snapshot.query().file_path(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().formatter(),
|
||||
snapshot.encoding(),
|
||||
false,
|
||||
|
@ -71,6 +80,8 @@ pub(super) fn format_document(snapshot: &DocumentSnapshot) -> Result<super::Form
|
|||
format_text_document(
|
||||
text_document,
|
||||
snapshot.query().source_type(),
|
||||
snapshot.query().file_path(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().formatter(),
|
||||
snapshot.encoding(),
|
||||
snapshot.query().as_notebook().is_some(),
|
||||
|
@ -80,10 +91,24 @@ pub(super) fn format_document(snapshot: &DocumentSnapshot) -> Result<super::Form
|
|||
fn format_text_document(
|
||||
text_document: &TextDocument,
|
||||
source_type: PySourceType,
|
||||
file_path: &Path,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
formatter_settings: &FormatterSettings,
|
||||
encoding: PositionEncoding,
|
||||
is_notebook: bool,
|
||||
) -> Result<super::FormatResponse> {
|
||||
// If the document is excluded, return early.
|
||||
if let Some(exclusion) = match_any_exclusion(
|
||||
file_path,
|
||||
&file_resolver_settings.exclude,
|
||||
&file_resolver_settings.extend_exclude,
|
||||
None,
|
||||
Some(&formatter_settings.exclude),
|
||||
) {
|
||||
tracing::debug!("Ignored path via `{}`: {}", exclusion, file_path.display());
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let source = text_document.contents();
|
||||
let mut formatted = crate::format::format(text_document, source_type, formatter_settings)
|
||||
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
use std::path::Path;
|
||||
|
||||
use lsp_types::{self as types, request as req, Range};
|
||||
|
||||
use ruff_python_ast::PySourceType;
|
||||
use ruff_workspace::resolver::match_any_exclusion;
|
||||
use ruff_workspace::{FileResolverSettings, FormatterSettings};
|
||||
|
||||
use crate::edit::{RangeExt, ToRangeExt};
|
||||
use crate::server::api::LSPResult;
|
||||
use crate::server::{client::Notifier, Result};
|
||||
use crate::session::DocumentSnapshot;
|
||||
use lsp_types::{self as types, request as req};
|
||||
use crate::{PositionEncoding, TextDocument};
|
||||
|
||||
pub(crate) struct FormatRange;
|
||||
|
||||
|
@ -17,25 +25,63 @@ impl super::BackgroundDocumentRequestHandler for FormatRange {
|
|||
_notifier: Notifier,
|
||||
params: types::DocumentRangeFormattingParams,
|
||||
) -> Result<super::FormatResponse> {
|
||||
let document = snapshot
|
||||
.query()
|
||||
.as_single_document()
|
||||
.expect("hover should only be called on text documents or notebook cells");
|
||||
let text = document.contents();
|
||||
let index = document.index();
|
||||
let range = params.range.to_text_range(text, index, snapshot.encoding());
|
||||
let formatted_range = crate::format::format_range(
|
||||
document,
|
||||
snapshot.query().source_type(),
|
||||
snapshot.query().settings().formatter(),
|
||||
range,
|
||||
)
|
||||
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
|
||||
Ok(Some(vec![types::TextEdit {
|
||||
range: formatted_range
|
||||
.source_range()
|
||||
.to_range(text, index, snapshot.encoding()),
|
||||
new_text: formatted_range.into_code(),
|
||||
}]))
|
||||
format_document_range(&snapshot, params.range)
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the specified [`Range`] in the [`DocumentSnapshot`].
|
||||
fn format_document_range(
|
||||
snapshot: &DocumentSnapshot,
|
||||
range: Range,
|
||||
) -> Result<super::FormatResponse> {
|
||||
let text_document = snapshot
|
||||
.query()
|
||||
.as_single_document()
|
||||
.expect("format should only be called on text documents or notebook cells");
|
||||
format_text_document_range(
|
||||
text_document,
|
||||
range,
|
||||
snapshot.query().source_type(),
|
||||
snapshot.query().file_path(),
|
||||
snapshot.query().settings().file_resolver(),
|
||||
snapshot.query().settings().formatter(),
|
||||
snapshot.encoding(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Formats the specified [`Range`] in the [`TextDocument`].
|
||||
fn format_text_document_range(
|
||||
text_document: &TextDocument,
|
||||
range: Range,
|
||||
source_type: PySourceType,
|
||||
file_path: &Path,
|
||||
file_resolver_settings: &FileResolverSettings,
|
||||
formatter_settings: &FormatterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> Result<super::FormatResponse> {
|
||||
// If the document is excluded, return early.
|
||||
if let Some(exclusion) = match_any_exclusion(
|
||||
file_path,
|
||||
&file_resolver_settings.exclude,
|
||||
&file_resolver_settings.extend_exclude,
|
||||
None,
|
||||
Some(&formatter_settings.exclude),
|
||||
) {
|
||||
tracing::debug!("Ignored path via `{}`: {}", exclusion, file_path.display());
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let text = text_document.contents();
|
||||
let index = text_document.index();
|
||||
let range = range.to_text_range(text, index, encoding);
|
||||
let formatted_range =
|
||||
crate::format::format_range(text_document, source_type, formatter_settings, range)
|
||||
.with_failure_code(lsp_server::ErrorCode::InternalError)?;
|
||||
|
||||
Ok(Some(vec![types::TextEdit {
|
||||
range: formatted_range
|
||||
.source_range()
|
||||
.to_range(text, index, encoding),
|
||||
new_text: formatted_range.into_code(),
|
||||
}]))
|
||||
}
|
||||
|
|
|
@ -479,7 +479,7 @@ impl DocumentQuery {
|
|||
}
|
||||
|
||||
/// Get the underlying file path for the document selected by this query.
|
||||
pub(crate) fn file_path(&self) -> &PathBuf {
|
||||
pub(crate) fn file_path(&self) -> &Path {
|
||||
match self {
|
||||
Self::Text { file_path, .. } | Self::Notebook { file_path, .. } => file_path,
|
||||
}
|
||||
|
|
|
@ -73,10 +73,17 @@ impl RuffSettings {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the [`ruff_workspace::FileResolverSettings`] for this [`RuffSettings`].
|
||||
pub(crate) fn file_resolver(&self) -> &ruff_workspace::FileResolverSettings {
|
||||
&self.file_resolver
|
||||
}
|
||||
|
||||
/// Return the [`ruff_linter::settings::LinterSettings`] for this [`RuffSettings`].
|
||||
pub(crate) fn linter(&self) -> &ruff_linter::settings::LinterSettings {
|
||||
&self.linter
|
||||
}
|
||||
|
||||
/// Return the [`ruff_workspace::FormatterSettings`] for this [`RuffSettings`].
|
||||
pub(crate) fn formatter(&self) -> &ruff_workspace::FormatterSettings {
|
||||
&self.formatter
|
||||
}
|
||||
|
|
|
@ -626,6 +626,63 @@ pub fn match_candidate_exclusion(
|
|||
exclusion.is_match_candidate(file_path) || exclusion.is_match_candidate(file_basename)
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ExclusionKind {
|
||||
/// The exclusion came from the `exclude` setting.
|
||||
Exclude,
|
||||
/// The exclusion came from the `extend-exclude` setting.
|
||||
ExtendExclude,
|
||||
/// The exclusion came from the `lint.exclude` setting.
|
||||
LintExclude,
|
||||
/// The exclusion came from the `lint.extend-exclude` setting.
|
||||
FormatExclude,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ExclusionKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ExclusionKind::Exclude => write!(f, "exclude"),
|
||||
ExclusionKind::ExtendExclude => write!(f, "extend-exclude"),
|
||||
ExclusionKind::LintExclude => write!(f, "lint.exclude"),
|
||||
ExclusionKind::FormatExclude => write!(f, "lint.extend-exclude"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the [`ExclusionKind`] for a given [`Path`], if the path or any of its ancestors match
|
||||
/// any of the exclusion criteria.
|
||||
pub fn match_any_exclusion(
|
||||
path: &Path,
|
||||
exclude: &GlobSet,
|
||||
extend_exclude: &GlobSet,
|
||||
lint_exclude: Option<&GlobSet>,
|
||||
format_exclude: Option<&GlobSet>,
|
||||
) -> Option<ExclusionKind> {
|
||||
for path in path.ancestors() {
|
||||
if let Some(basename) = path.file_name() {
|
||||
let path = Candidate::new(path);
|
||||
let basename = Candidate::new(basename);
|
||||
if match_candidate_exclusion(&path, &basename, exclude) {
|
||||
return Some(ExclusionKind::Exclude);
|
||||
}
|
||||
if match_candidate_exclusion(&path, &basename, extend_exclude) {
|
||||
return Some(ExclusionKind::ExtendExclude);
|
||||
}
|
||||
if let Some(lint_exclude) = lint_exclude {
|
||||
if match_candidate_exclusion(&path, &basename, lint_exclude) {
|
||||
return Some(ExclusionKind::LintExclude);
|
||||
}
|
||||
}
|
||||
if let Some(format_exclude) = format_exclude {
|
||||
if match_candidate_exclusion(&path, &basename, format_exclude) {
|
||||
return Some(ExclusionKind::FormatExclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::{create_dir, File};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue