From 9e0a308ea62bbba6810a46e60676170bb9a51719 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Thu, 21 Mar 2024 09:01:36 +0000 Subject: [PATCH 1/4] fix(project): correctly ignore folders --- crates/biome_cli/src/execute/mod.rs | 19 +++++++++++++++---- crates/biome_cli/src/execute/traverse.rs | 2 +- crates/biome_service/src/workspace.rs | 2 +- crates/biome_service/src/workspace/server.rs | 14 +++++++++++--- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/crates/biome_cli/src/execute/mod.rs b/crates/biome_cli/src/execute/mod.rs index 16cccdeb67a0..166eb02f7556 100644 --- a/crates/biome_cli/src/execute/mod.rs +++ b/crates/biome_cli/src/execute/mod.rs @@ -10,7 +10,7 @@ use crate::execute::traverse::traverse; use crate::{CliDiagnostic, CliSession}; use biome_diagnostics::{category, Category}; use biome_fs::BiomePath; -use biome_service::workspace::{FeatureName, FixFileMode}; +use biome_service::workspace::{FeatureName, FeaturesBuilder, FixFileMode}; use std::ffi::OsString; use std::fmt::{Display, Formatter}; use std::path::{Path, PathBuf}; @@ -28,10 +28,21 @@ pub(crate) struct Execution { } impl Execution { - pub(crate) fn as_feature_name(&self) -> FeatureName { + pub(crate) fn to_features(&self) -> Vec { match self.traversal_mode { - TraversalMode::Format { .. } => FeatureName::Format, - _ => FeatureName::Lint, + TraversalMode::Format { .. } => FeaturesBuilder::new() + .with_formatter() + .build(), + TraversalMode::Lint { ..} => FeaturesBuilder::new() + .with_linter() + .build(), + TraversalMode::Check { .. } | TraversalMode::CI { .. } => FeaturesBuilder::new() + .with_organize_imports() + .with_formatter() + .with_linter() + .build(), + TraversalMode::Migrate { .. } => vec![] + } } } diff --git a/crates/biome_cli/src/execute/traverse.rs b/crates/biome_cli/src/execute/traverse.rs index 002207d08641..a58b3791e076 100644 --- a/crates/biome_cli/src/execute/traverse.rs +++ b/crates/biome_cli/src/execute/traverse.rs @@ -702,7 +702,7 @@ impl<'ctx, 'app> TraversalContext for TraversalOptions<'ctx, 'app> { .workspace .is_path_ignored(IsPathIgnoredParams { biome_path: biome_path.clone(), - feature: self.execution.as_feature_name(), + features: self.execution.to_features(), }) .unwrap_or_else(|err| { self.push_diagnostic(err.into()); diff --git a/crates/biome_service/src/workspace.rs b/crates/biome_service/src/workspace.rs index 7a30c7fde66e..d862d566e984 100644 --- a/crates/biome_service/src/workspace.rs +++ b/crates/biome_service/src/workspace.rs @@ -659,7 +659,7 @@ impl RageEntry { #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct IsPathIgnoredParams { pub biome_path: BiomePath, - pub feature: FeatureName, + pub features: Vec, } pub trait Workspace: Send + Sync + RefUnwindSafe { diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index 3a5d4f5347e9..690c26e90ce5 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -243,14 +243,22 @@ impl WorkspaceServer { /// Check whether a file is ignored in the top-level config `files.ignore`/`files.include` /// or in the feature `ignore`/`include` - fn is_ignored(&self, path: &Path, feature: FeatureName) -> bool { + fn is_ignored(&self, path: &Path, features: Vec) -> bool { let file_name = path.file_name().and_then(|s| s.to_str()); + let ignored_by_features = { + let mut ignored = false; + for feature in features { + // a path is ignored if it's ignored by all features + ignored &= self.is_ignored_by_feature_config(path, feature) + } + ignored + }; // Never ignore Biome's config file regardless `include`/`ignore` (file_name != Some(ConfigName::biome_json()) || file_name != Some(ConfigName::biome_jsonc())) && // Apply top-level `include`/`ignore` (self.is_ignored_by_top_level_config(path) || // Apply feature-level `include`/`ignore` - self.is_ignored_by_feature_config(path, feature)) + ignored_by_features) } /// Check whether a file is ignored in the top-level config `files.ignore`/`files.include` @@ -363,7 +371,7 @@ impl Workspace for WorkspaceServer { } } fn is_path_ignored(&self, params: IsPathIgnoredParams) -> Result { - Ok(self.is_ignored(params.biome_path.as_path(), params.feature)) + Ok(self.is_ignored(params.biome_path.as_path(), params.features)) } /// Update the global settings for this workspace /// From 21f01af52a79a4cd0c3d1060baedcc66c4ad651a Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Thu, 21 Mar 2024 09:18:13 +0000 Subject: [PATCH 2/4] fix(project): correctly ignore folders --- CHANGELOG.md | 4 ++ crates/biome_cli/src/execute/mod.rs | 11 +--- crates/biome_cli/src/execute/process_file.rs | 6 +- .../src/execute/process_file/check.rs | 1 + crates/biome_cli/src/execute/traverse.rs | 8 +-- crates/biome_cli/tests/commands/check.rs | 49 +++++++++++++++ crates/biome_cli/tests/commands/format.rs | 56 +++++++++++++++++ ..._formatter_when_linter_ignores_folder.snap | 61 +++++++++++++++++++ ..._file_ignored_by_linter_inside_folder.snap | 34 +++++++++++ crates/biome_service/src/workspace.rs | 1 + crates/biome_service/src/workspace/server.rs | 4 +- .../src/content/docs/internals/changelog.md | 4 ++ 12 files changed, 218 insertions(+), 21 deletions(-) create mode 100644 crates/biome_cli/tests/snapshots/main_commands_check/should_show_diagnostics_for_formatter_when_linter_ignores_folder.snap create mode 100644 crates/biome_cli/tests/snapshots/main_commands_format/should_fix_file_ignored_by_linter_inside_folder.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 8391c236c584..e4888f9f07c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ### CLI +#### Bug fixes + +- Fixes [#2131](https://github.com/biomejs/biome/issues/2131), where folders were incorrectly ignored when running the command `check`. Now folders are correctly ignored based on their command. Contributed by @ematipico + ### Configuration #### Bug fixes diff --git a/crates/biome_cli/src/execute/mod.rs b/crates/biome_cli/src/execute/mod.rs index 166eb02f7556..dc799b787337 100644 --- a/crates/biome_cli/src/execute/mod.rs +++ b/crates/biome_cli/src/execute/mod.rs @@ -30,19 +30,14 @@ pub(crate) struct Execution { impl Execution { pub(crate) fn to_features(&self) -> Vec { match self.traversal_mode { - TraversalMode::Format { .. } => FeaturesBuilder::new() - .with_formatter() - .build(), - TraversalMode::Lint { ..} => FeaturesBuilder::new() - .with_linter() - .build(), + TraversalMode::Format { .. } => FeaturesBuilder::new().with_formatter().build(), + TraversalMode::Lint { .. } => FeaturesBuilder::new().with_linter().build(), TraversalMode::Check { .. } | TraversalMode::CI { .. } => FeaturesBuilder::new() .with_organize_imports() .with_formatter() .with_linter() .build(), - TraversalMode::Migrate { .. } => vec![] - + TraversalMode::Migrate { .. } => vec![], } } } diff --git a/crates/biome_cli/src/execute/process_file.rs b/crates/biome_cli/src/execute/process_file.rs index 3ca932c126fc..db5b9a5a2133 100644 --- a/crates/biome_cli/src/execute/process_file.rs +++ b/crates/biome_cli/src/execute/process_file.rs @@ -132,11 +132,7 @@ pub(crate) fn process_file(ctx: &TraversalOptions, path: &Path) -> FileResult { .workspace .file_features(SupportsFeatureParams { path: biome_path, - feature: FeaturesBuilder::new() - .with_formatter() - .with_linter() - .with_organize_imports() - .build(), + feature: ctx.execution.to_features(), }) .with_file_path_and_code_and_tags( path.display().to_string(), diff --git a/crates/biome_cli/src/execute/process_file/check.rs b/crates/biome_cli/src/execute/process_file/check.rs index 02567da8bff7..703e47bb78fe 100644 --- a/crates/biome_cli/src/execute/process_file/check.rs +++ b/crates/biome_cli/src/execute/process_file/check.rs @@ -16,6 +16,7 @@ pub(crate) fn check_file<'ctx>( let mut changed = false; tracing::info_span!("Process check", path =? workspace_file.path.display()).in_scope( move || { + dbg!(&path); if file_features.supports_lint() { let lint_result = lint_with_guard(ctx, &mut workspace_file); match lint_result { diff --git a/crates/biome_cli/src/execute/traverse.rs b/crates/biome_cli/src/execute/traverse.rs index a58b3791e076..40ddbc3d5692 100644 --- a/crates/biome_cli/src/execute/traverse.rs +++ b/crates/biome_cli/src/execute/traverse.rs @@ -13,7 +13,7 @@ use biome_diagnostics::PrintGitHubDiagnostic; use biome_diagnostics::{category, DiagnosticExt, Error, PrintDiagnostic, Resource, Severity}; use biome_fs::{BiomePath, FileSystem, PathInterner}; use biome_fs::{TraversalContext, TraversalScope}; -use biome_service::workspace::{FeaturesBuilder, IsPathIgnoredParams}; +use biome_service::workspace::IsPathIgnoredParams; use biome_service::{extension_error, workspace::SupportsFeatureParams, Workspace, WorkspaceError}; use crossbeam::channel::{unbounded, Receiver, Sender}; use rustc_hash::FxHashSet; @@ -713,11 +713,7 @@ impl<'ctx, 'app> TraversalContext for TraversalOptions<'ctx, 'app> { let file_features = self.workspace.file_features(SupportsFeatureParams { path: biome_path.clone(), - feature: FeaturesBuilder::new() - .with_linter() - .with_formatter() - .with_organize_imports() - .build(), + feature: self.execution.to_features(), }); let file_features = match file_features { diff --git a/crates/biome_cli/tests/commands/check.rs b/crates/biome_cli/tests/commands/check.rs index 9c0a2cd0911c..2b844f021ab9 100644 --- a/crates/biome_cli/tests/commands/check.rs +++ b/crates/biome_cli/tests/commands/check.rs @@ -2797,3 +2797,52 @@ fn use_literal_keys_should_emit_correct_ast_issue_266() { result, )); } + +#[test] +fn should_show_diagnostics_for_formatter_when_linter_ignores_folder() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let file_path = Path::new("build/file.js"); + fs.insert( + file_path.into(), + r#" + value['optimizelyService'] = optimizelyService; + "#, + ); + + let biome_json = Path::new("biome.json"); + fs.insert( + biome_json.into(), + r#"{ + "$schema": "https://biomejs.dev/schemas/1.6.1/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "ignore": ["build/**"], + "enabled": true, + "rules": { + "recommended": true + } + } +} + "#, + ); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from([("check"), file_path.as_os_str().to_str().unwrap()].as_slice()), + ); + + assert!(result.is_err(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "should_show_diagnostics_for_formatter_when_linter_ignores_folder", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/commands/format.rs b/crates/biome_cli/tests/commands/format.rs index 62a7720ce412..cb316b786dd5 100644 --- a/crates/biome_cli/tests/commands/format.rs +++ b/crates/biome_cli/tests/commands/format.rs @@ -3461,3 +3461,59 @@ fn format_empty_svelte_ts_files_write() { result, )); } + +#[test] +fn should_fix_file_ignored_by_linter_inside_folder() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let file_path = Path::new("build/file.js"); + fs.insert( + file_path.into(), + r#" + value['optimizelyService'] = optimizelyService; + "#, + ); + + let biome_json = Path::new("biome.json"); + fs.insert( + biome_json.into(), + r#"{ + "$schema": "https://biomejs.dev/schemas/1.6.1/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "ignore": ["**/build"], + "enabled": true, + "rules": { + "recommended": true + } + } +} + "#, + ); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("format"), + "--write", + file_path.as_os_str().to_str().unwrap(), + ] + .as_slice(), + ), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "should_fix_file_ignored_by_linter_inside_folder", + fs, + console, + result, + )); +} diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/should_show_diagnostics_for_formatter_when_linter_ignores_folder.snap b/crates/biome_cli/tests/snapshots/main_commands_check/should_show_diagnostics_for_formatter_when_linter_ignores_folder.snap new file mode 100644 index 000000000000..943f4150015a --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_commands_check/should_show_diagnostics_for_formatter_when_linter_ignores_folder.snap @@ -0,0 +1,61 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: content +--- +## `biome.json` + +```json +{ + "$schema": "https://biomejs.dev/schemas/1.6.1/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "ignore": ["build/**"], + "enabled": true, + "rules": { + "recommended": true + } + } +} +``` + +## `build/file.js` + +```js + + value['optimizelyService'] = optimizelyService; + +``` + +# Termination Message + +```block +check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Some errors were emitted while running checks. + + + +``` + +# Emitted Messages + +```block +build/file.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + i Formatter would have printed the following content: + + 1 │ - + 2 │ - → value['optimizelyService']·=·optimizelyService; + 3 │ - → → + 1 │ + value["optimizelyService"]·=·optimizelyService; + 2 │ + + + +``` + +```block +Checked 1 file in