From ce320733b6f5c60b439b98c7c5be1bdeef6c09ca Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Fri, 19 Dec 2025 17:41:34 +0800 Subject: [PATCH 01/10] fix(cli): allow --stdin-file-path outside files.includes --- .changeset/warm-houses-switch.md | 6 +++ crates/biome_cli/src/execute/process_file.rs | 1 + crates/biome_cli/src/execute/std_in.rs | 4 ++ crates/biome_cli/src/execute/traverse.rs | 1 + crates/biome_cli/tests/commands/format.rs | 47 ++++++++++++++++++- crates/biome_cli/tests/configs.rs | 13 +++++ ...formats_virtual_path_outside_includes.snap | 31 ++++++++++++ crates/biome_formatter_test/src/spec.rs | 1 + crates/biome_lsp/src/handlers/analysis.rs | 2 + crates/biome_lsp/src/handlers/formatting.rs | 3 ++ crates/biome_lsp/src/session.rs | 1 + crates/biome_service/src/projects.rs | 23 ++++++++- crates/biome_service/src/workspace.rs | 7 +++ crates/biome_service/src/workspace/server.rs | 1 + 14 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 .changeset/warm-houses-switch.md create mode 100644 crates/biome_cli/tests/snapshots/main_commands_format/format_stdin_formats_virtual_path_outside_includes.snap diff --git a/.changeset/warm-houses-switch.md b/.changeset/warm-houses-switch.md new file mode 100644 index 000000000000..bb838b916459 --- /dev/null +++ b/.changeset/warm-houses-switch.md @@ -0,0 +1,6 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#6783](https://github.com/biomejs/biome/issues/6783): stdin formatting using `--stdin-file-path` is no longer blocked by `files.includes` when the provided path doesn't exist on disk. + diff --git a/crates/biome_cli/src/execute/process_file.rs b/crates/biome_cli/src/execute/process_file.rs index 978d3c64657f..6620f9242607 100644 --- a/crates/biome_cli/src/execute/process_file.rs +++ b/crates/biome_cli/src/execute/process_file.rs @@ -136,6 +136,7 @@ pub(crate) fn process_file(ctx: &TraversalOptions, biome_path: &BiomePath) -> Fi project_key: ctx.project_key, path: biome_path.clone(), features: ctx.execution.to_feature(), + ignore_includes: false, }) .with_file_path_and_code_and_tags( biome_path.to_string(), diff --git a/crates/biome_cli/src/execute/std_in.rs b/crates/biome_cli/src/execute/std_in.rs index 6972f7750eee..2b4db6bd059b 100644 --- a/crates/biome_cli/src/execute/std_in.rs +++ b/crates/biome_cli/src/execute/std_in.rs @@ -38,6 +38,8 @@ pub(crate) fn run<'a>( return Ok(()); } + let ignore_includes = !workspace.fs().path_exists(biome_path.as_path()); + if mode.is_format() { let FileFeaturesResult { features_supported: file_features, @@ -45,6 +47,7 @@ pub(crate) fn run<'a>( project_key, path: biome_path.clone(), features: FeaturesBuilder::new().with_formatter().build(), + ignore_includes, })?; if file_features.is_ignored() { @@ -126,6 +129,7 @@ pub(crate) fn run<'a>( .with_assist() .with_formatter() .build(), + ignore_includes, })?; if file_features.is_ignored() { diff --git a/crates/biome_cli/src/execute/traverse.rs b/crates/biome_cli/src/execute/traverse.rs index 26968c1821c8..3654d1a4a2a1 100644 --- a/crates/biome_cli/src/execute/traverse.rs +++ b/crates/biome_cli/src/execute/traverse.rs @@ -576,6 +576,7 @@ impl TraversalContext for TraversalOptions<'_, '_> { project_key: self.project_key, path: biome_path.clone(), features: self.execution.to_feature(), + ignore_includes: false, }); let can_read = DocumentFileSource::can_read(biome_path); diff --git a/crates/biome_cli/tests/commands/format.rs b/crates/biome_cli/tests/commands/format.rs index 2ea9e8ba8291..5e0be5964f0d 100644 --- a/crates/biome_cli/tests/commands/format.rs +++ b/crates/biome_cli/tests/commands/format.rs @@ -1,6 +1,6 @@ use crate::configs::{ - CONFIG_DISABLED_FORMATTER, CONFIG_FILE_SIZE_LIMIT, CONFIG_FORMAT, CONFIG_FORMAT_JSONC, - CONFIG_ISSUE_3175_1, CONFIG_ISSUE_3175_2, + CONFIG_DISABLED_FORMATTER, CONFIG_FILE_SIZE_LIMIT, CONFIG_FILES_INCLUDES_EXCLUDES_STDIN_PATH, + CONFIG_FORMAT, CONFIG_FORMAT_JSONC, CONFIG_ISSUE_3175_1, CONFIG_ISSUE_3175_2, }; use crate::snap_test::{SnapshotPayload, assert_file_contents, markup_to_string}; use crate::{ @@ -1210,6 +1210,49 @@ fn format_stdin_successfully() { )); } +#[test] +fn format_stdin_formats_virtual_path_outside_includes() { + let fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let config_path = Utf8Path::new("biome.json"); + fs.insert( + config_path.into(), + CONFIG_FILES_INCLUDES_EXCLUDES_STDIN_PATH.as_bytes(), + ); + + console + .in_buffer + .push("function f() {return{}}".to_string()); + + let (fs, result) = run_cli( + fs, + &mut console, + Args::from(["format", "--stdin-file-path", "a.tsx"].as_slice()), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + let message = console + .out_buffer + .first() + .expect("Console should have written a message"); + + let content = markup_to_string(markup! { + {message.content} + }); + + assert_eq!(content, "function f() {\n\treturn {};\n}\n"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "format_stdin_formats_virtual_path_outside_includes", + fs, + console, + result, + )); +} + #[test] fn format_stdin_with_errors() { let fs = MemoryFileSystem::default(); diff --git a/crates/biome_cli/tests/configs.rs b/crates/biome_cli/tests/configs.rs index efa48efb444c..f2adfb6cf596 100644 --- a/crates/biome_cli/tests/configs.rs +++ b/crates/biome_cli/tests/configs.rs @@ -33,6 +33,19 @@ pub const CONFIG_DISABLED_FORMATTER_JSONC: &str = r#"{ } "#; +pub const CONFIG_FILES_INCLUDES_EXCLUDES_STDIN_PATH: &str = r#"{ + "files": { + "includes": [ + "apps/**/*.{ts,tsx}", + "packages/**/*.{ts,tsx}" + ] + }, + "formatter": { + "enabled": true + } +} +"#; + pub const CONFIG_ALL_FIELDS: &str = r#"{ "formatter": { "enabled": true, diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/format_stdin_formats_virtual_path_outside_includes.snap b/crates/biome_cli/tests/snapshots/main_commands_format/format_stdin_formats_virtual_path_outside_includes.snap new file mode 100644 index 000000000000..885ee33e9423 --- /dev/null +++ b/crates/biome_cli/tests/snapshots/main_commands_format/format_stdin_formats_virtual_path_outside_includes.snap @@ -0,0 +1,31 @@ +--- +source: crates/biome_cli/tests/snap_test.rs +expression: redactor(content) +--- +## `biome.json` + +```json +{ + "files": { + "includes": ["apps/**/*.{ts,tsx}", "packages/**/*.{ts,tsx}"] + }, + "formatter": { + "enabled": true + } +} +``` + +# Input messages + +```block +function f() {return{}} +``` + +# Emitted Messages + +```block +function f() { + return {}; +} + +``` diff --git a/crates/biome_formatter_test/src/spec.rs b/crates/biome_formatter_test/src/spec.rs index 18035fa9f55c..aacc16500e92 100644 --- a/crates/biome_formatter_test/src/spec.rs +++ b/crates/biome_formatter_test/src/spec.rs @@ -70,6 +70,7 @@ impl<'a> SpecTestFile<'a> { project_key, path: input_file.clone(), features: FeaturesBuilder::new().with_formatter().build(), + ignore_includes: false, }) .unwrap(); diff --git a/crates/biome_lsp/src/handlers/analysis.rs b/crates/biome_lsp/src/handlers/analysis.rs index 1292c7be6b13..b3d7c3881684 100644 --- a/crates/biome_lsp/src/handlers/analysis.rs +++ b/crates/biome_lsp/src/handlers/analysis.rs @@ -78,6 +78,7 @@ pub(crate) fn code_actions( project_key: doc.project_key, path: path.clone(), features, + ignore_includes: false, })?; if !file_features.supports_lint() && !file_features.supports_assist() { @@ -315,6 +316,7 @@ fn fix_all( .with_linter() .with_assist() .build(), + ignore_includes: false, })?; let should_format = file_features.supports_format(); diff --git a/crates/biome_lsp/src/handlers/formatting.rs b/crates/biome_lsp/src/handlers/formatting.rs index 42eb49f42105..93744052e3fd 100644 --- a/crates/biome_lsp/src/handlers/formatting.rs +++ b/crates/biome_lsp/src/handlers/formatting.rs @@ -38,6 +38,7 @@ pub(crate) fn format( project_key: doc.project_key, path: path.clone(), features, + ignore_includes: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); @@ -107,6 +108,7 @@ pub(crate) fn format_range( project_key: doc.project_key, path: path.clone(), features, + ignore_includes: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); @@ -199,6 +201,7 @@ pub(crate) fn format_on_type( project_key: doc.project_key, path: path.clone(), features, + ignore_includes: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); diff --git a/crates/biome_lsp/src/session.rs b/crates/biome_lsp/src/session.rs index 7381c11cdf77..b699331b0c62 100644 --- a/crates/biome_lsp/src/session.rs +++ b/crates/biome_lsp/src/session.rs @@ -422,6 +422,7 @@ impl Session { project_key: doc.project_key, features: FeaturesBuilder::new().with_linter().with_assist().build(), path: biome_path.clone(), + ignore_includes: false, })?; if !file_features.supports_lint() && !file_features.supports_assist() { diff --git a/crates/biome_service/src/projects.rs b/crates/biome_service/src/projects.rs index 050583ce5dcd..ffb4b13dc443 100644 --- a/crates/biome_service/src/projects.rs +++ b/crates/biome_service/src/projects.rs @@ -207,6 +207,7 @@ impl Projects { features: FeatureName, language: DocumentFileSource, capabilities: &Capabilities, + ignore_includes: bool, ) -> Result { let data = self.0.pin(); let project_data = data @@ -231,7 +232,27 @@ impl Projects { .is_some_and(|dir_path| dir_path == project_data.path) { // Never ignore Biome's top-level config file - } else if self.is_ignored(fs, project_key, path, features, IgnoreKind::Ancestors) { + } else if { + let is_ignored_by_top_level_config = if ignore_includes { + project_data + .root_settings + .vcs_settings + .is_ignored(path, Some(project_data.path.as_path())) + } else { + is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors) + }; + + // If there are specific features enabled, but all of them ignore the + // path, then we treat the path as ignored too. + let is_ignored_by_features = !features.is_empty() + && features.iter().all(|feature| { + project_data + .root_settings + .is_path_ignored_for_feature(path, feature) + }); + + is_ignored_by_top_level_config || is_ignored_by_features + } { file_features.set_ignored_for_all_features(); } else { for feature in features.iter() { diff --git a/crates/biome_service/src/workspace.rs b/crates/biome_service/src/workspace.rs index 1d81d2152e1c..4ef740dfb2de 100644 --- a/crates/biome_service/src/workspace.rs +++ b/crates/biome_service/src/workspace.rs @@ -109,6 +109,10 @@ pub enum ServiceNotification { WatcherStopped, } +fn is_false(value: &bool) -> bool { + !*value +} + #[derive(Debug, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "camelCase")] @@ -116,6 +120,9 @@ pub struct SupportsFeatureParams { pub project_key: ProjectKey, pub path: BiomePath, pub features: FeatureName, + + #[serde(default, skip_serializing_if = "is_false")] + pub ignore_includes: bool, } #[derive(Debug, serde::Serialize, serde::Deserialize, Default)] diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index c621305ebce5..f2173c92ed22 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -1238,6 +1238,7 @@ impl Workspace for WorkspaceServer { params.features, language, &capabilities, + params.ignore_includes, ) } From ddb7b6e60675bf150cc960a284f4de41618f8288 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 19 Dec 2025 09:48:19 +0000 Subject: [PATCH 02/10] [autofix.ci] apply automated fixes --- packages/@biomejs/backend-jsonrpc/src/workspace.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 1836a69b1abb..8856b91fc26b 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -2,6 +2,7 @@ import type { Transport } from "./transport"; export interface SupportsFeatureParams { features: FeatureName; + ignoreIncludes?: boolean; path: BiomePath; projectKey: ProjectKey; } From 6a7823f8a3c76af95efb7b0e388f52a3eff19da9 Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Fri, 19 Dec 2025 20:44:30 +0800 Subject: [PATCH 03/10] docs(cli): clarify stdin-file-path and files.includes --- crates/biome_cli/src/commands/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 156cd0ed33c0..274c749bcbf1 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -181,6 +181,10 @@ pub enum BiomeCommand { /// Also, if you have overrides configured and/or nested configurations, /// the path may determine the settings being applied. /// + /// If the path doesn't exist on disk (virtual path), `files.includes` + /// won't block stdin processing. If the path exists, `files.includes` + /// applies as usual. + /// /// Example: /// ```shell /// echo 'let a;' | biome check --stdin-file-path=file.js --write @@ -287,6 +291,10 @@ pub enum BiomeCommand { /// /// The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to lint the code. /// + /// If the path doesn't exist on disk (virtual path), `files.includes` + /// won't block stdin processing. If the path exists, `files.includes` + /// applies as usual. + /// /// Example: /// ```shell /// echo 'let a;' | biome lint --stdin-file-path=file.js --write @@ -345,6 +353,10 @@ pub enum BiomeCommand { /// /// The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to format the code. /// + /// If the path doesn't exist on disk (virtual path), `files.includes` + /// won't block stdin processing. If the path exists, `files.includes` + /// applies as usual. + /// /// Example: /// ```shell /// echo 'let a;' | biome format --stdin-file-path=file.js --write From 86583103e8ddcbae7339a64dc771e7b3e1bfc2d6 Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Fri, 19 Dec 2025 21:10:14 +0800 Subject: [PATCH 04/10] docs(cli): clarify stdin-file-path ignore behavior --- crates/biome_cli/src/commands/mod.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 274c749bcbf1..311b9df62f3e 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -181,9 +181,10 @@ pub enum BiomeCommand { /// Also, if you have overrides configured and/or nested configurations, /// the path may determine the settings being applied. /// - /// If the path doesn't exist on disk (virtual path), `files.includes` - /// won't block stdin processing. If the path exists, `files.includes` - /// applies as usual. + /// The provided path may also affect whether the input is treated as + /// ignored. If the path doesn't exist on disk (virtual path), Biome + /// won't require it to be part of the project file set, but ignore rules + /// may still apply (e.g. VCS ignore files). /// /// Example: /// ```shell @@ -291,9 +292,10 @@ pub enum BiomeCommand { /// /// The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to lint the code. /// - /// If the path doesn't exist on disk (virtual path), `files.includes` - /// won't block stdin processing. If the path exists, `files.includes` - /// applies as usual. + /// The provided path may also affect whether the input is treated as + /// ignored. If the path doesn't exist on disk (virtual path), Biome + /// won't require it to be part of the project file set, but ignore rules + /// may still apply (e.g. VCS ignore files). /// /// Example: /// ```shell @@ -353,9 +355,10 @@ pub enum BiomeCommand { /// /// The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to format the code. /// - /// If the path doesn't exist on disk (virtual path), `files.includes` - /// won't block stdin processing. If the path exists, `files.includes` - /// applies as usual. + /// The provided path may also affect whether the input is treated as + /// ignored. If the path doesn't exist on disk (virtual path), Biome + /// won't require it to be part of the project file set, but ignore rules + /// may still apply (e.g. VCS ignore files). /// /// Example: /// ```shell From b346779668b9b45a32d97e26288657e6114377ee Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Fri, 19 Dec 2025 21:24:16 +0800 Subject: [PATCH 05/10] fix: satisfy clippy and update help snapshots --- .../main_commands_check/check_help.snap | 4 + .../main_commands_format/format_help.snap | 4 + .../main_commands_lint/lint_help.snap | 4 + crates/biome_service/src/projects.rs | 82 +++++++++++-------- crates/biome_service/src/workspace/server.rs | 18 ++-- 5 files changed, 70 insertions(+), 42 deletions(-) diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap index bb0130f2958e..9f17d0ccce17 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap @@ -262,6 +262,10 @@ Available options: code. Also, if you have overrides configured and/or nested configurations, the path may determine the settings being applied. + The provided path may also affect whether the input is treated as + ignored. If the path doesn't exist on disk (virtual path), Biome won't + require it to be part of the project file set, but ignore rules may + still apply (e.g. VCS ignore files). Example: ```shell echo 'let a;' | biome check --stdin-file-path=file.js --write ``` --staged When set to true, only the files that have been staged (the ones diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap b/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap index e6f62bf0aae9..6710e805d5dc 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap @@ -174,6 +174,10 @@ Available options: The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to format the code. + The provided path may also affect whether the input is treated as + ignored. If the path doesn't exist on disk (virtual path), Biome won't + require it to be part of the project file set, but ignore rules may + still apply (e.g. VCS ignore files). Example: ```shell echo 'let a;' | biome format --stdin-file-path=file.js --write ``` --write Writes formatted files to a file system. diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap index 0aab14924bf8..40dca46b2697 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap @@ -106,6 +106,10 @@ Available options: print the output to `stdout`. The file doesn't need to exist on disk, what matters is the extension of the file. Based on the extension, Biome knows how to lint the code. + The provided path may also affect whether the input is treated as + ignored. If the path doesn't exist on disk (virtual path), Biome won't + require it to be part of the project file set, but ignore rules may + still apply (e.g. VCS ignore files). Example: ```shell echo 'let a;' | biome lint --stdin-file-path=file.js --write ``` --staged When set to true, only the files that have been staged (the ones diff --git a/crates/biome_service/src/projects.rs b/crates/biome_service/src/projects.rs index ffb4b13dc443..b45285ad6313 100644 --- a/crates/biome_service/src/projects.rs +++ b/crates/biome_service/src/projects.rs @@ -15,6 +15,16 @@ use std::num::NonZeroUsize; use std::sync::atomic::{AtomicUsize, Ordering}; use tracing::{debug, instrument}; +pub struct GetFileFeaturesParams<'a> { + pub fs: &'a dyn FileSystem, + pub project_key: ProjectKey, + pub path: &'a Utf8Path, + pub features: FeatureName, + pub language: DocumentFileSource, + pub capabilities: &'a Capabilities, + pub ignore_includes: bool, +} + /// The information tracked for each project. #[derive(Debug, Default)] struct ProjectData { @@ -201,13 +211,15 @@ impl Projects { #[inline(always)] pub fn get_file_features( &self, - fs: &dyn FileSystem, - project_key: ProjectKey, - path: &Utf8Path, - features: FeatureName, - language: DocumentFileSource, - capabilities: &Capabilities, - ignore_includes: bool, + GetFileFeaturesParams { + fs, + project_key, + path, + features, + language, + capabilities, + ignore_includes, + }: GetFileFeaturesParams<'_>, ) -> Result { let data = self.0.pin(); let project_data = data @@ -232,36 +244,40 @@ impl Projects { .is_some_and(|dir_path| dir_path == project_data.path) { // Never ignore Biome's top-level config file - } else if { - let is_ignored_by_top_level_config = if ignore_includes { - project_data - .root_settings - .vcs_settings - .is_ignored(path, Some(project_data.path.as_path())) - } else { - is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors) + } else { + let is_ignored = { + let is_ignored_by_top_level_config = if ignore_includes { + project_data + .root_settings + .vcs_settings + .is_ignored(path, Some(project_data.path.as_path())) + } else { + is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors) + }; + + // If there are specific features enabled, but all of them ignore the + // path, then we treat the path as ignored too. + let is_ignored_by_features = !features.is_empty() + && features.iter().all(|feature| { + project_data + .root_settings + .is_path_ignored_for_feature(path, feature) + }); + + is_ignored_by_top_level_config || is_ignored_by_features }; - // If there are specific features enabled, but all of them ignore the - // path, then we treat the path as ignored too. - let is_ignored_by_features = !features.is_empty() - && features.iter().all(|feature| { - project_data + if is_ignored { + file_features.set_ignored_for_all_features(); + } else { + for feature in features.iter() { + if project_data .root_settings .is_path_ignored_for_feature(path, feature) - }); - - is_ignored_by_top_level_config || is_ignored_by_features - } { - file_features.set_ignored_for_all_features(); - } else { - for feature in features.iter() { - if project_data - .root_settings - .is_path_ignored_for_feature(path, feature) - || settings.is_path_ignored_for_feature(path, feature) - { - file_features.set_ignored(feature); + || settings.is_path_ignored_for_feature(path, feature) + { + file_features.set_ignored(feature); + } } } } diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index f2173c92ed22..cf0e75c85b64 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -10,7 +10,7 @@ use crate::file_handlers::{ Capabilities, CodeActionsParams, DiagnosticsAndActionsParams, DocumentFileSource, Features, FixAllParams, FormatEmbedNode, LintParams, LintResults, ParseResult, UpdateSnippetsNodes, }; -use crate::projects::Projects; +use crate::projects::{GetFileFeaturesParams, Projects}; use crate::scanner::{ IndexRequestKind, IndexTrigger, ScanOptions, Scanner, ScannerWatcherBridge, WatcherInstruction, WorkspaceScannerBridge, @@ -1231,15 +1231,15 @@ impl Workspace for WorkspaceServer { ); let capabilities = self.features.get_capabilities(language); - self.projects.get_file_features( - self.fs.as_ref(), - params.project_key, - ¶ms.path, - params.features, + self.projects.get_file_features(GetFileFeaturesParams { + fs: self.fs.as_ref(), + project_key: params.project_key, + path: ¶ms.path, + features: params.features, language, - &capabilities, - params.ignore_includes, - ) + capabilities: &capabilities, + ignore_includes: params.ignore_includes, + }) } fn is_path_ignored(&self, params: PathIsIgnoredParams) -> Result { From bc1ac0a456288d9a0952a72ea6c3095da9840aea Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Tue, 23 Dec 2025 21:36:39 +0800 Subject: [PATCH 06/10] refactor: rename ignore_includes to skip_ignore_check Address reviewer feedback: use a more generic name since the check involves both files.includes and VCS-ignore files, not just includes. Also updated changeset wording per maintainer suggestion. --- .changeset/warm-houses-switch.md | 2 +- crates/biome_cli/src/execute/process_file.rs | 2 +- crates/biome_cli/src/execute/std_in.rs | 6 +++--- crates/biome_cli/src/execute/traverse.rs | 2 +- crates/biome_formatter_test/src/spec.rs | 2 +- crates/biome_lsp/src/handlers/analysis.rs | 4 ++-- crates/biome_lsp/src/handlers/formatting.rs | 6 +++--- crates/biome_lsp/src/session.rs | 2 +- crates/biome_service/src/projects.rs | 6 +++--- crates/biome_service/src/workspace.rs | 2 +- crates/biome_service/src/workspace/server.rs | 2 +- packages/@biomejs/backend-jsonrpc/src/workspace.ts | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.changeset/warm-houses-switch.md b/.changeset/warm-houses-switch.md index bb838b916459..f7f4f1e00419 100644 --- a/.changeset/warm-houses-switch.md +++ b/.changeset/warm-houses-switch.md @@ -2,5 +2,5 @@ "@biomejs/biome": patch --- -Fixed [#6783](https://github.com/biomejs/biome/issues/6783): stdin formatting using `--stdin-file-path` is no longer blocked by `files.includes` when the provided path doesn't exist on disk. +Fixed [#6783](https://github.com/biomejs/biome/issues/6783): now, when a path is provided via `--stdin-file-path`, Biome checks whether the file exists within the current project. If the path doesn't exist, ignore checks - `files.includes` and VCS-ignore files - are skipped, and the file is handled. diff --git a/crates/biome_cli/src/execute/process_file.rs b/crates/biome_cli/src/execute/process_file.rs index 6620f9242607..d227e2096763 100644 --- a/crates/biome_cli/src/execute/process_file.rs +++ b/crates/biome_cli/src/execute/process_file.rs @@ -136,7 +136,7 @@ pub(crate) fn process_file(ctx: &TraversalOptions, biome_path: &BiomePath) -> Fi project_key: ctx.project_key, path: biome_path.clone(), features: ctx.execution.to_feature(), - ignore_includes: false, + skip_ignore_check: false, }) .with_file_path_and_code_and_tags( biome_path.to_string(), diff --git a/crates/biome_cli/src/execute/std_in.rs b/crates/biome_cli/src/execute/std_in.rs index 2b4db6bd059b..fb24c7cb6297 100644 --- a/crates/biome_cli/src/execute/std_in.rs +++ b/crates/biome_cli/src/execute/std_in.rs @@ -38,7 +38,7 @@ pub(crate) fn run<'a>( return Ok(()); } - let ignore_includes = !workspace.fs().path_exists(biome_path.as_path()); + let skip_ignore_check = !workspace.fs().path_exists(biome_path.as_path()); if mode.is_format() { let FileFeaturesResult { @@ -47,7 +47,7 @@ pub(crate) fn run<'a>( project_key, path: biome_path.clone(), features: FeaturesBuilder::new().with_formatter().build(), - ignore_includes, + skip_ignore_check, })?; if file_features.is_ignored() { @@ -129,7 +129,7 @@ pub(crate) fn run<'a>( .with_assist() .with_formatter() .build(), - ignore_includes, + skip_ignore_check, })?; if file_features.is_ignored() { diff --git a/crates/biome_cli/src/execute/traverse.rs b/crates/biome_cli/src/execute/traverse.rs index 3654d1a4a2a1..b05d0982e7cd 100644 --- a/crates/biome_cli/src/execute/traverse.rs +++ b/crates/biome_cli/src/execute/traverse.rs @@ -576,7 +576,7 @@ impl TraversalContext for TraversalOptions<'_, '_> { project_key: self.project_key, path: biome_path.clone(), features: self.execution.to_feature(), - ignore_includes: false, + skip_ignore_check: false, }); let can_read = DocumentFileSource::can_read(biome_path); diff --git a/crates/biome_formatter_test/src/spec.rs b/crates/biome_formatter_test/src/spec.rs index aacc16500e92..23acfd5e6762 100644 --- a/crates/biome_formatter_test/src/spec.rs +++ b/crates/biome_formatter_test/src/spec.rs @@ -70,7 +70,7 @@ impl<'a> SpecTestFile<'a> { project_key, path: input_file.clone(), features: FeaturesBuilder::new().with_formatter().build(), - ignore_includes: false, + skip_ignore_check: false, }) .unwrap(); diff --git a/crates/biome_lsp/src/handlers/analysis.rs b/crates/biome_lsp/src/handlers/analysis.rs index b3d7c3881684..aaa447014c11 100644 --- a/crates/biome_lsp/src/handlers/analysis.rs +++ b/crates/biome_lsp/src/handlers/analysis.rs @@ -78,7 +78,7 @@ pub(crate) fn code_actions( project_key: doc.project_key, path: path.clone(), features, - ignore_includes: false, + skip_ignore_check: false, })?; if !file_features.supports_lint() && !file_features.supports_assist() { @@ -316,7 +316,7 @@ fn fix_all( .with_linter() .with_assist() .build(), - ignore_includes: false, + skip_ignore_check: false, })?; let should_format = file_features.supports_format(); diff --git a/crates/biome_lsp/src/handlers/formatting.rs b/crates/biome_lsp/src/handlers/formatting.rs index 93744052e3fd..1911124b99ca 100644 --- a/crates/biome_lsp/src/handlers/formatting.rs +++ b/crates/biome_lsp/src/handlers/formatting.rs @@ -38,7 +38,7 @@ pub(crate) fn format( project_key: doc.project_key, path: path.clone(), features, - ignore_includes: false, + skip_ignore_check: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); @@ -108,7 +108,7 @@ pub(crate) fn format_range( project_key: doc.project_key, path: path.clone(), features, - ignore_includes: false, + skip_ignore_check: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); @@ -201,7 +201,7 @@ pub(crate) fn format_on_type( project_key: doc.project_key, path: path.clone(), features, - ignore_includes: false, + skip_ignore_check: false, })?; if !file_features.supports_format() { return notify_user(file_features, path); diff --git a/crates/biome_lsp/src/session.rs b/crates/biome_lsp/src/session.rs index b699331b0c62..efa1e7dddc1f 100644 --- a/crates/biome_lsp/src/session.rs +++ b/crates/biome_lsp/src/session.rs @@ -422,7 +422,7 @@ impl Session { project_key: doc.project_key, features: FeaturesBuilder::new().with_linter().with_assist().build(), path: biome_path.clone(), - ignore_includes: false, + skip_ignore_check: false, })?; if !file_features.supports_lint() && !file_features.supports_assist() { diff --git a/crates/biome_service/src/projects.rs b/crates/biome_service/src/projects.rs index b45285ad6313..691c124118e3 100644 --- a/crates/biome_service/src/projects.rs +++ b/crates/biome_service/src/projects.rs @@ -22,7 +22,7 @@ pub struct GetFileFeaturesParams<'a> { pub features: FeatureName, pub language: DocumentFileSource, pub capabilities: &'a Capabilities, - pub ignore_includes: bool, + pub skip_ignore_check: bool, } /// The information tracked for each project. @@ -218,7 +218,7 @@ impl Projects { features, language, capabilities, - ignore_includes, + skip_ignore_check, }: GetFileFeaturesParams<'_>, ) -> Result { let data = self.0.pin(); @@ -246,7 +246,7 @@ impl Projects { // Never ignore Biome's top-level config file } else { let is_ignored = { - let is_ignored_by_top_level_config = if ignore_includes { + let is_ignored_by_top_level_config = if skip_ignore_check { project_data .root_settings .vcs_settings diff --git a/crates/biome_service/src/workspace.rs b/crates/biome_service/src/workspace.rs index 4ef740dfb2de..e0c412b850ba 100644 --- a/crates/biome_service/src/workspace.rs +++ b/crates/biome_service/src/workspace.rs @@ -122,7 +122,7 @@ pub struct SupportsFeatureParams { pub features: FeatureName, #[serde(default, skip_serializing_if = "is_false")] - pub ignore_includes: bool, + pub skip_ignore_check: bool, } #[derive(Debug, serde::Serialize, serde::Deserialize, Default)] diff --git a/crates/biome_service/src/workspace/server.rs b/crates/biome_service/src/workspace/server.rs index cf0e75c85b64..41fcd6975562 100644 --- a/crates/biome_service/src/workspace/server.rs +++ b/crates/biome_service/src/workspace/server.rs @@ -1238,7 +1238,7 @@ impl Workspace for WorkspaceServer { features: params.features, language, capabilities: &capabilities, - ignore_includes: params.ignore_includes, + skip_ignore_check: params.skip_ignore_check, }) } diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index 8856b91fc26b..c6c267bfd3c7 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -2,9 +2,9 @@ import type { Transport } from "./transport"; export interface SupportsFeatureParams { features: FeatureName; - ignoreIncludes?: boolean; path: BiomePath; projectKey: ProjectKey; + skipIgnoreCheck?: boolean; } export type FeatureName = FeatureKind[]; export type BiomePath = string; From 18eeba2e219342dfa19bbd93a12cf1847d51049a Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Tue, 23 Dec 2025 22:00:56 +0800 Subject: [PATCH 07/10] docs(changeset): fix wording to match actual behavior The files.includes check is skipped for non-existent stdin paths, but VCS ignore rules still apply (as documented in CLI help). --- .changeset/warm-houses-switch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/warm-houses-switch.md b/.changeset/warm-houses-switch.md index f7f4f1e00419..2ac0f21a2e6a 100644 --- a/.changeset/warm-houses-switch.md +++ b/.changeset/warm-houses-switch.md @@ -2,5 +2,5 @@ "@biomejs/biome": patch --- -Fixed [#6783](https://github.com/biomejs/biome/issues/6783): now, when a path is provided via `--stdin-file-path`, Biome checks whether the file exists within the current project. If the path doesn't exist, ignore checks - `files.includes` and VCS-ignore files - are skipped, and the file is handled. +Fixed [#6783](https://github.com/biomejs/biome/issues/6783): now, when a path is provided via `--stdin-file-path`, Biome checks whether the file exists on disk. If the path doesn't exist, the `files.includes` check is skipped, but VCS ignore rules still apply. From 9fea9083a751ba4e80a691a69e03b410f5911e3b Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Tue, 23 Dec 2025 22:17:37 +0800 Subject: [PATCH 08/10] test: update noUndeclaredEnvVars snapshot Add nursery group info message to diagnostics. --- .../nursery/noUndeclaredEnvVars/invalid.js.snap | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/biome_js_analyze/tests/specs/nursery/noUndeclaredEnvVars/invalid.js.snap b/crates/biome_js_analyze/tests/specs/nursery/noUndeclaredEnvVars/invalid.js.snap index 2d48ffbe1976..aead8919bdfc 100644 --- a/crates/biome_js_analyze/tests/specs/nursery/noUndeclaredEnvVars/invalid.js.snap +++ b/crates/biome_js_analyze/tests/specs/nursery/noUndeclaredEnvVars/invalid.js.snap @@ -90,6 +90,8 @@ invalid.js:9:23 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 10 │ 11 │ // Bracket notation with string literals should also be checked + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` @@ -104,6 +106,8 @@ invalid.js:12:20 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 13 │ const bracketMeta = import.meta.env["BRACKET_META_VAR"]; 14 │ + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` @@ -119,6 +123,8 @@ invalid.js:13:21 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 14 │ 15 │ // Bun.env should also be checked + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` @@ -133,6 +139,8 @@ invalid.js:16:16 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 17 │ const bunBracketVar = Bun.env["BUN_BRACKET_VAR"]; 18 │ + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` @@ -148,6 +156,8 @@ invalid.js:17:23 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 18 │ 19 │ // Deno.env.get should also be checked + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` @@ -162,6 +172,8 @@ invalid.js:20:17 lint/nursery/noUndeclaredEnvVars ━━━━━━━━━━ 21 │ const denoVar2 = Deno.env.get("ANOTHER_DENO_VAR"); 22 │ + i This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information. + ``` From 87e6fcf44c9f0daffca21f808747bac6e02c9c4e Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Wed, 24 Dec 2025 14:25:35 +0800 Subject: [PATCH 09/10] fix: skip both files.includes and VCS ignore for virtual stdin paths --- .changeset/warm-houses-switch.md | 3 +- crates/biome_cli/src/commands/mod.rs | 12 ++--- .../main_commands_check/check_help.snap | 4 +- .../main_commands_format/format_help.snap | 4 +- .../main_commands_lint/lint_help.snap | 4 +- crates/biome_service/src/projects.rs | 52 +++++++++---------- 6 files changed, 37 insertions(+), 42 deletions(-) diff --git a/.changeset/warm-houses-switch.md b/.changeset/warm-houses-switch.md index 2ac0f21a2e6a..fcfcb7888fd7 100644 --- a/.changeset/warm-houses-switch.md +++ b/.changeset/warm-houses-switch.md @@ -2,5 +2,4 @@ "@biomejs/biome": patch --- -Fixed [#6783](https://github.com/biomejs/biome/issues/6783): now, when a path is provided via `--stdin-file-path`, Biome checks whether the file exists on disk. If the path doesn't exist, the `files.includes` check is skipped, but VCS ignore rules still apply. - +Fixed [#6783](https://github.com/biomejs/biome/issues/6783): now, when a path is provided via `--stdin-file-path`, Biome checks whether the file exists on disk. If the path doesn't exist (virtual path), ignore checks (`files.includes` and VCS ignore rules) are skipped. diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 311b9df62f3e..9f7ade90069a 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -183,8 +183,8 @@ pub enum BiomeCommand { /// /// The provided path may also affect whether the input is treated as /// ignored. If the path doesn't exist on disk (virtual path), Biome - /// won't require it to be part of the project file set, but ignore rules - /// may still apply (e.g. VCS ignore files). + /// won't require it to be part of the project file set, and ignore + /// checks (`files.includes` and VCS ignore rules) are skipped. /// /// Example: /// ```shell @@ -294,8 +294,8 @@ pub enum BiomeCommand { /// /// The provided path may also affect whether the input is treated as /// ignored. If the path doesn't exist on disk (virtual path), Biome - /// won't require it to be part of the project file set, but ignore rules - /// may still apply (e.g. VCS ignore files). + /// won't require it to be part of the project file set, and ignore + /// checks (`files.includes` and VCS ignore rules) are skipped. /// /// Example: /// ```shell @@ -357,8 +357,8 @@ pub enum BiomeCommand { /// /// The provided path may also affect whether the input is treated as /// ignored. If the path doesn't exist on disk (virtual path), Biome - /// won't require it to be part of the project file set, but ignore rules - /// may still apply (e.g. VCS ignore files). + /// won't require it to be part of the project file set, and ignore + /// checks (`files.includes` and VCS ignore rules) are skipped. /// /// Example: /// ```shell diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap index 9f17d0ccce17..53e1dc18a570 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap @@ -264,8 +264,8 @@ Available options: the path may determine the settings being applied. The provided path may also affect whether the input is treated as ignored. If the path doesn't exist on disk (virtual path), Biome won't - require it to be part of the project file set, but ignore rules may - still apply (e.g. VCS ignore files). + require it to be part of the project file set, and ignore checks + (`files.includes` and VCS ignore rules) are skipped. Example: ```shell echo 'let a;' | biome check --stdin-file-path=file.js --write ``` --staged When set to true, only the files that have been staged (the ones diff --git a/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap b/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap index 6710e805d5dc..6e83c90bc878 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap @@ -176,8 +176,8 @@ Available options: code. The provided path may also affect whether the input is treated as ignored. If the path doesn't exist on disk (virtual path), Biome won't - require it to be part of the project file set, but ignore rules may - still apply (e.g. VCS ignore files). + require it to be part of the project file set, and ignore checks + (`files.includes` and VCS ignore rules) are skipped. Example: ```shell echo 'let a;' | biome format --stdin-file-path=file.js --write ``` --write Writes formatted files to a file system. diff --git a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap index 40dca46b2697..08db0ee4846d 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_lint/lint_help.snap @@ -108,8 +108,8 @@ Available options: of the file. Based on the extension, Biome knows how to lint the code. The provided path may also affect whether the input is treated as ignored. If the path doesn't exist on disk (virtual path), Biome won't - require it to be part of the project file set, but ignore rules may - still apply (e.g. VCS ignore files). + require it to be part of the project file set, and ignore checks + (`files.includes` and VCS ignore rules) are skipped. Example: ```shell echo 'let a;' | biome lint --stdin-file-path=file.js --write ``` --staged When set to true, only the files that have been staged (the ones diff --git a/crates/biome_service/src/projects.rs b/crates/biome_service/src/projects.rs index 691c124118e3..6f818dcf8245 100644 --- a/crates/biome_service/src/projects.rs +++ b/crates/biome_service/src/projects.rs @@ -245,38 +245,34 @@ impl Projects { { // Never ignore Biome's top-level config file } else { - let is_ignored = { - let is_ignored_by_top_level_config = if skip_ignore_check { - project_data - .root_settings - .vcs_settings - .is_ignored(path, Some(project_data.path.as_path())) - } else { - is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors) + if !skip_ignore_check { + let is_ignored = { + let is_ignored_by_top_level_config = + is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors); + + // If there are specific features enabled, but all of them ignore the + // path, then we treat the path as ignored too. + let is_ignored_by_features = !features.is_empty() + && features.iter().all(|feature| { + project_data + .root_settings + .is_path_ignored_for_feature(path, feature) + }); + + is_ignored_by_top_level_config || is_ignored_by_features }; - // If there are specific features enabled, but all of them ignore the - // path, then we treat the path as ignored too. - let is_ignored_by_features = !features.is_empty() - && features.iter().all(|feature| { - project_data + if is_ignored { + file_features.set_ignored_for_all_features(); + } else { + for feature in features.iter() { + if project_data .root_settings .is_path_ignored_for_feature(path, feature) - }); - - is_ignored_by_top_level_config || is_ignored_by_features - }; - - if is_ignored { - file_features.set_ignored_for_all_features(); - } else { - for feature in features.iter() { - if project_data - .root_settings - .is_path_ignored_for_feature(path, feature) - || settings.is_path_ignored_for_feature(path, feature) - { - file_features.set_ignored(feature); + || settings.is_path_ignored_for_feature(path, feature) + { + file_features.set_ignored(feature); + } } } } From 785732c4e19e5fe53393a87924c7e3390fca33c7 Mon Sep 17 00:00:00 2001 From: Tu Shaokun <2801884530@qq.com> Date: Wed, 24 Dec 2025 14:30:26 +0800 Subject: [PATCH 10/10] fix: satisfy clippy (collapse else-if) --- crates/biome_service/src/projects.rs | 52 +++++++++++++--------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/crates/biome_service/src/projects.rs b/crates/biome_service/src/projects.rs index 6f818dcf8245..a7df2d66d6d9 100644 --- a/crates/biome_service/src/projects.rs +++ b/crates/biome_service/src/projects.rs @@ -244,35 +244,33 @@ impl Projects { .is_some_and(|dir_path| dir_path == project_data.path) { // Never ignore Biome's top-level config file - } else { - if !skip_ignore_check { - let is_ignored = { - let is_ignored_by_top_level_config = - is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors); - - // If there are specific features enabled, but all of them ignore the - // path, then we treat the path as ignored too. - let is_ignored_by_features = !features.is_empty() - && features.iter().all(|feature| { - project_data - .root_settings - .is_path_ignored_for_feature(path, feature) - }); - - is_ignored_by_top_level_config || is_ignored_by_features - }; - - if is_ignored { - file_features.set_ignored_for_all_features(); - } else { - for feature in features.iter() { - if project_data + } else if !skip_ignore_check { + let is_ignored = { + let is_ignored_by_top_level_config = + is_ignored_by_top_level_config(fs, project_data, path, IgnoreKind::Ancestors); + + // If there are specific features enabled, but all of them ignore the + // path, then we treat the path as ignored too. + let is_ignored_by_features = !features.is_empty() + && features.iter().all(|feature| { + project_data .root_settings .is_path_ignored_for_feature(path, feature) - || settings.is_path_ignored_for_feature(path, feature) - { - file_features.set_ignored(feature); - } + }); + + is_ignored_by_top_level_config || is_ignored_by_features + }; + + if is_ignored { + file_features.set_ignored_for_all_features(); + } else { + for feature in features.iter() { + if project_data + .root_settings + .is_path_ignored_for_feature(path, feature) + || settings.is_path_ignored_for_feature(path, feature) + { + file_features.set_ignored(feature); } } }