+
Skip to content

Conversation

arendjr
Copy link
Contributor

@arendjr arendjr commented Aug 29, 2025

Summary

Deprecated the option files.experimentalScannerIgnores in favour of force-ignore syntax in files.includes.

files.includes supports ignoring files by prefixing globs with an exclamation mark (!). With this change, it also supports force-ignoring globs by prefixing them with a double exclamation mark (!!).

The effect of force-ignoring is that the scanner will not index files matching
the glob, even in project mode and those files are imported by other files.

Example

Let's take the following configuration:

{
    "files": {
        "includes": [
            "**",
            "!**/generated",
            "!!**/dist",
            "fixtures/example/dist/*.js"
        ]
    },
    "linter": {
        "domains": {
            "project": "all"
        }
    }
}

This configuration achieves the following:

  • Because the project domain is enabled, all supported files in the project are indexed and processed by the linter, except:
  • Files inside a generated folder are not processed by the linter, but they will get indexed if a file outside of a generated folder imports them.
  • Files inside a dist folder are never indexed nor processed, not even if they are imported for any purpose, except:
  • When the dist folder is inside fixtures/example/, its .js files do get both indexed and processed.

In general, we now recommend using the force-ignore syntax for any folders that contain output files, such as build/ and dist/. For such folders, it is highly unlikely that indexing has any useful benefits. For folders containing generated files, you may wish to use the regular ignore syntax so that type information can still be extracted from the files.

Test Plan

Multiple tests added.

Docs

@arendjr arendjr requested review from a team August 29, 2025 17:23
Copy link

changeset-bot bot commented Aug 29, 2025

🦋 Changeset detected

Latest commit: 90a8387

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 15 packages
Name Type
@biomejs/biome Minor
@biomejs/plugin-api Major
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

coderabbitai bot commented Aug 29, 2025

Walkthrough

This PR deprecates files.experimentalScannerIgnores and implements force-ignore semantics via ! and !! prefixes in globs inside files.includes. Core glob logic gains a GlobKind (Normal, Negated, ForceNegated) with parsing, display and matching updates plus CandidatePath forced-negation checks. Configuration deserialization now emits deprecation/migration guidance for experimentalScannerIgnores. Service/settings layers remove scanner-ignore entries, add Includes::is_force_ignored, and switch project/server checks to use force-ignore. Tests and diagnostics were updated to validate force-ignore behaviour for files, folders and indexing.

Possibly related PRs

Suggested labels

A-Core, L-JSON, A-Tooling

Suggested reviewers

  • dyc3
  • ematipico

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project labels Aug 29, 2025
@dyc3
Copy link
Contributor

dyc3 commented Aug 29, 2025

This needs to be based on next since its a minor.

@arendjr arendjr force-pushed the force-ignore-syntax branch from 5062216 to e897e72 Compare August 29, 2025 17:30
@arendjr arendjr changed the base branch from main to next August 29, 2025 17:30
Copy link

codspeed-hq bot commented Aug 29, 2025

CodSpeed Performance Report

Merging #7359 will not alter performance

Comparing arendjr:force-ignore-syntax (90a8387) with next (87b2cf6)

Summary

✅ 133 untouched benchmarks

@siketyan
Copy link
Member

We could include a migration so users only have to run biome migrate

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (9)
crates/biome_cli/tests/cases/included_files.rs (1)

132-167: Make directory intent explicit in the glob.

Prefer !!test/** (or !!**/test/**) over !!test to unambiguously force-ignore the directory and all descendants across platforms.

Apply this diff:

-        r#"{ "files": { "includes": ["*.js", "!!test"] } }"#.as_bytes(),
+        r#"{ "files": { "includes": ["*.js", "!!test/**"] } }"#.as_bytes(),
.changeset/forced-files-forget.md (3)

9-9: Grammar/punctuation: clarify the sentence.

Add a missing comma and tweak phrasing for readability.

Apply this diff:

-The effect of force-ignoring is that the scanner will not index files matching the glob, even in project mode and those files are imported by other files.
+The effect of force-ignoring is that the scanner will not index files matching the glob, even in project mode, and even if those files are imported by other files.

33-41: Tighten prose and consistency.

  • Use “outside” instead of “outside of”.
  • End bullet sentences with a period for consistency.

Apply this diff:

- - Files inside a `generated` folder are not processed by the linter, but they will get indexed _if_ a file outside of a `generated` folder imports them.
+ - Files inside a `generated` folder are not processed by the linter, but they will get indexed _if_ a file outside a `generated` folder imports them.

And please add trailing periods to the other bullets in this list.


1-3: Confirm package list in the changeset.

This change spans multiple crates (glob, service, CLI, configuration, module_graph). Ensure all affected packages are listed in the front‑matter, or split into multiple changesets as appropriate.

Happy to generate a draft changeset enumerating crates touched by this PR if you want.

crates/biome_glob/src/lib.rs (5)

253-262: Document negated() behaviour for force-negated inputs.

Currently negated() maps ForceNegated -> Normal. Callers may expect a full toggle; make it explicit in the docs.

Apply this diff to the doc comment:

 /// Returns the negated version of this glob.
 ///
 /// ```
 /// let glob = "!*.js".parse::<biome_glob::Glob>().unwrap();
 /// assert!(!glob.negated().is_negated());
 ///
 /// let glob = "*.js".parse::<biome_glob::Glob>().unwrap();
 /// assert!(glob.negated().is_negated());
 /// ```
+/// Note: calling this on a force‑negated glob (`!!…`) clears negation and returns a normal glob.

302-306: Display renders the correct !/!! prefix. Add a test for !!.

Add a quick assertion in test_to_string to lock this in.

Add to test_to_string():

assert_eq!(Glob::from_str("!!**/*.rs").unwrap().to_string(), "!!**/*.rs");

318-343: Triple ! inputs.

"!!!*.js" becomes ForceNegated("!*.js"). That’s fine, but worth a test to avoid surprises.

Add a unit test:

assert!(Glob::from_str("!!!*.js").unwrap().is_force_negated());
assert_eq!(Glob::from_str("!!!*.js").unwrap().to_string(), "!!!*.js");

524-565: matches_forced_negation logic looks right. Add focused tests.

Add unit tests to cover:

  • Forced‑negated overridden by later include.
  • No match defaults to false.

Example tests:

#[test]
fn test_matches_forced_negation() {
    let globs = &[
        Glob::from_str("**").unwrap(),
        Glob::from_str("!!a*").unwrap(),
        Glob::from_str("a").unwrap(),
    ];
    assert!(CandidatePath::new(&"abc").matches_forced_negation(globs));
    assert!(!CandidatePath::new(&"a").matches_forced_negation(globs));
    assert!(!CandidatePath::new(&"b").matches_forced_negation(globs));
}

207-210: Update crate-level docs to mention !! force-negation.

Top-of-file docs still only describe !. Please add a short section for !! and fix the minor typo on Line 28 (“pat” → “path”).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5062216 and 5e2c872.

⛔ Files ignored due to path filters (6)
  • crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_files_inside_force_ignored_folders.snap is excluded by !**/*.snap and included by **
  • crates/biome_cli/tests/snapshots/main_cases_included_files/does_not_handle_included_files_if_overridden_by_forced_ignore.snap is excluded by !**/*.snap and included by **
  • crates/biome_configuration/tests/invalid/files_extraneous_field.json.snap is excluded by !**/*.snap and included by **
  • crates/biome_service/src/snapshots/module_diagnostic.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (10)
  • .changeset/forced-files-forget.md (1 hunks)
  • biome.json (1 hunks)
  • crates/biome_cli/tests/cases/included_files.rs (1 hunks)
  • crates/biome_configuration/src/lib.rs (0 hunks)
  • crates/biome_glob/src/lib.rs (8 hunks)
  • crates/biome_module_graph/src/js_module_info/diagnostics.rs (1 hunks)
  • crates/biome_service/src/projects.rs (3 hunks)
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs (1 hunks)
  • crates/biome_service/src/settings.rs (1 hunks)
  • crates/biome_service/src/workspace/server.rs (1 hunks)
💤 Files with no reviewable changes (1)
  • crates/biome_configuration/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/biome_module_graph/src/js_module_info/diagnostics.rs
  • crates/biome_service/src/projects.rs
  • biome.json
  • crates/biome_service/src/settings.rs
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_service/src/workspace/server.rs
  • crates/biome_cli/tests/cases/included_files.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
crates/biome_service/src/workspace/server.rs

📄 CodeRabbit inference engine (crates/biome_service/CONTRIBUTING.md)

Use WorkspaceServer (src/workspace/server.rs) to maintain workspace state in daemon and CLI daemonless modes

Files:

  • crates/biome_service/src/workspace/server.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_service/src/workspace/server.rs
  • crates/biome_cli/tests/cases/included_files.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_cli/tests/cases/included_files.rs
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: Create changesets with just new-changeset; store them in .changeset/ with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.

Files:

  • .changeset/forced-files-forget.md
🧠 Learnings (6)
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace.rs : Implement the Workspace trait in src/workspace.rs

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Place watcher tests for workspace methods in src/workspace/watcher.tests.rs

Applied to files:

  • crates/biome_service/src/workspace/server.rs
  • crates/biome_cli/tests/cases/included_files.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace/server.rs : Use WorkspaceServer (src/workspace/server.rs) to maintain workspace state in daemon and CLI daemonless modes

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-11T11:53:15.299Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:53:15.299Z
Learning: Applies to crates/biome_service/src/workspace_watcher.rs : Keep workspace state in sync with the filesystem using WorkspaceWatcher; only active in daemon mode

Applied to files:

  • crates/biome_service/src/workspace/server.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_cli/tests/cases/included_files.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_cli/tests/cases/included_files.rs
🧬 Code graph analysis (3)
crates/biome_cli/tests/cases/included_files.rs (3)
crates/biome_fs/src/fs/memory.rs (1)
  • default (37-49)
crates/biome_cli/tests/main.rs (1)
  • run_cli (332-347)
crates/biome_cli/tests/snap_test.rs (2)
  • assert_file_contents (438-449)
  • assert_cli_snapshot (407-409)
crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs (3)
crates/biome_glob/src/lib.rs (5)
  • from (179-181)
  • from (313-315)
  • new (423-425)
  • from_str (185-188)
  • from_str (319-344)
crates/biome_service/src/workspace.rs (5)
  • from (637-642)
  • from (646-648)
  • fs (1468-1468)
  • new (460-462)
  • new (672-674)
crates/biome_service/src/test_utils.rs (1)
  • setup_workspace_and_open_project (14-21)
crates/biome_glob/src/lib.rs (1)
crates/biome_service/src/settings.rs (1)
  • matches (999-1010)
🪛 LanguageTool
.changeset/forced-files-forget.md

[style] ~7-~7: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 1492 characters long)
Context: ...ng them with a double exclamation mark (!!). The effect of force-ignoring is tha...

(EN_EXCESSIVE_EXCLAMATION)


[uncategorized] ~9-~9: Possible missing comma found.
Context: ...iles matching the glob, even in project mode and those files are imported by other f...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~36-~36: This phrase is redundant. Consider using “outside”.
Context: ..., but they will get indexed if a file outside of a generated folder imports them. - Fi...

(OUTSIDE_OF)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: autofix
🔇 Additional comments (5)
crates/biome_cli/tests/cases/included_files.rs (1)

95-130: Good coverage for per-file forced ignore.

Test clearly proves that !!test.js wins over a broader include. Nicely done.

crates/biome_glob/src/lib.rs (2)

218-226: is_negated now treats !! as negated — good.

The behaviour matches the new semantics and keeps is_match* logic simple.


228-243: Clear separation with is_force_negated.

Nice API; callers can distinguish ! vs !! without parsing prefixes themselves.

crates/biome_service/src/workspace/server.rs (1)

545-547: Early exit on force-ignored paths is correct and keeps the scanner honest.

This neatly enforces “never index” before other ignore modes kick in.

Confirm Projects::is_force_ignored normalises paths the same way as Includes::matches (relative to working directory) to avoid false negatives at repo roots.

crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs (1)

297-345: Great regression test for “dependency still ignored when force-ignored”.

Also nice use of a later positive include to prove override precedence.

@Conaclos
Copy link
Member

Conaclos commented Aug 29, 2025

It could be nice to have a migration rule to convert files.experimentalScannerIgnores into files.includes. We could take some inspiration from the migration rule for files.{include,ignore}.

EDIT: I've realized that @siketyan already made this suggestion :)

@arendjr arendjr force-pushed the force-ignore-syntax branch from 01b5638 to 90a8387 Compare August 30, 2025 09:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (11)
.changeset/forced-files-forget.md (2)

35-38: Tighten sentence endings in bullets.

Guidelines ask every sentence to end with a period. Lines 35 and 37 end with a colon; consider converting those to full sentences.

- Because the [project domain](https://biomejs.dev/linter/domains/#project) is enabled, all supported files in the project are indexed _and_ processed by the linter, _except_:
+ Because the [project domain](https://biomejs.dev/linter/domains/#project) is enabled, all supported files in the project are indexed and processed by the linter, except for the cases below.
@@
- Files inside a `dist` folder are never indexed nor processed, not even if they are imported for any purpose, _except_:
+ Files inside a `dist` folder are never indexed nor processed, not even if they are imported for any purpose. The only exception is described below.

11-31: Add a Migration section with before/after config.

Helps users run through “what changed” quickly and aligns with comments asking for a migration. Keep headers at level 4 per guidelines.

 #### Example
+
+#### Migration
+
+Before (using `files.experimentalScannerIgnores`):
+
+```json
+{
+  "files": {
+    "experimentalScannerIgnores": [".cache", "dist"]
+  }
+}
+```
+
+After (using `files.includes` with force-ignore):
+
+```json
+{
+  "files": {
+    "includes": ["**", "!!**/dist"]
+  }
+}
+```
+
+Run `biome migrate` to update existing configs automatically.
crates/biome_configuration/src/lib.rs (2)

564-572: Link clarity for deprecation notice.

The docs anchor is correct; consider adding a brief “Use !! to force-ignore, ! to ignore” sentence in the diagnostic to reduce click-through.

-    /// **Deprecated:** Please use _force-ignore syntax_ in `files.includes`
-    /// instead: https://biomejs.dev/reference/configuration/#filesincludes
+    /// **Deprecated:** Use the _force-ignore_ syntax in `files.includes` instead
+    /// (https://biomejs.dev/reference/configuration/#filesincludes). Use `!!` to
+    /// force-ignore and `!` to ignore.

643-674: Edge-cases for suggestions.

If a user had entries with slashes or glob meta (e.g. tmp/cache or *.cache), the suggested "!!**/{entry}" may be misleading. Consider ignoring entries containing /, *, {, }, [, ], or ? or quoting them differently in the note.

-                            .map(|entry| format!("\"!!**/{entry}\""))
+                            .filter(|entry| !entry.chars().any(|c| matches!(c, '/' | '*' | '{' | '}' | '[' | ']' | '?')))
+                            .map(|entry| format!("\"!!**/{entry}\""))
crates/biome_glob/src/lib.rs (4)

228-243: Public API: expose force-negation clearly.

is_force_negated is helpful. Consider whether the method should live on NormalizedGlob as well for parity (tiny convenience).


253-261: Behaviour of negated() with force-negated inputs.

Calling negated() on a force-negated glob returns a normal glob (i.e. removes both negations). That’s reasonable, but please add a doc sentence to set expectations explicitly.

     /// Returns the negated version of this glob.
     ///
@@
     /// ```
     pub fn negated(self) -> Self {

Add:

+    /// Note: If this glob is force-negated (`!!`), calling `negated()` returns
+    /// a non-negated glob (it removes the forced negation).

317-344: Triple-bang inputs like !!!foo.

Parser treats !! as force-negation and the remaining ! as part of the pattern. This is likely fine; please add a small test asserting the intended behaviour so it doesn’t regress.

+    #[test]
+    fn test_triple_bang() {
+        let g = Glob::from_str("!!!foo").unwrap();
+        assert!(g.is_force_negated());
+        // Remaining '!' is literal; won't match "foo".
+        assert!(!g.is_match("foo"));
+        assert!(g.is_match("!foo"));
+    }

524-565: Semantics: can ! undo a prior !!?

matches_forced_negation returns the negation status of the last matching glob. That means a later !pattern will undo a prior !!pattern. The doc comment only mentions “undone by a later include”. If last-match-wins is the intended rule, update the doc. If “only includes undo force-negation” is intended, tweak the logic to skip non-forced negations when searching backwards and add tests for both cases.

Possible implementation if we want “only includes undo”:

-        for glob in globs.into_iter().rev() {
-            if glob.as_ref().is_raw_match_candidate(self) {
-                return glob.as_ref().is_force_negated();
-            }
-        }
+        let mut seen_force = false;
+        for glob in globs.into_iter().rev() {
+            let g = glob.as_ref();
+            if g.is_raw_match_candidate(self) {
+                if g.is_force_negated() {
+                    seen_force = true;
+                } else {
+                    // only a non-negated (include) clears forced status
+                    return !g.is_negated() && seen_force && false;
+                }
+            }
+        }
+        if seen_force { true } else { false }

…and add tests for ["*", "!!a*", "!a*"] to lock behaviour.

crates/biome_service/src/projects.rs (3)

128-155: Backward-compat check for deprecated scanner ignores.

Nice to keep a compatibility path. Please add a TODO with a version or milestone to remove this branch once the deprecation period ends.

-        // Deprecated: Check `experimentalScannerIgnores` too.
+        // Deprecated: Check `experimentalScannerIgnores` too.
+        // TODO: Remove after <target version> once migration has been available for a full cycle.

146-155: Nested vs root includes selection.

The “first nested project that prefixes the path” heuristic is fine; consider documenting that the closest (longest prefix) wins if multiple nested configs exist. Alternatively, pick the longest prefix explicitly.

-        let includes = project_data
-            .nested_settings
-            .iter()
-            .find(|(project_path, _)| path.starts_with(project_path))
+        let includes = project_data
+            .nested_settings
+            .iter()
+            .max_by_key(|(project_path, _)| if path.starts_with(project_path) { project_path.as_str().len() } else { 0 })
+            .filter(|(project_path, _)| path.starts_with(project_path))
             .map_or(
                 &project_data.root_settings.files.includes,
                 |(_, settings)| &settings.files.includes,
             );

198-236: Force-ignore vs inclusion in feature resolution.

get_file_features checks includes.is_included(path) but not Projects::is_force_ignored. If the server already gates indexing earlier via is_force_ignored, all good; otherwise, consider early-out here to treat force-ignored files as ignored for all features.

-        } else if !settings.files.includes.is_included(path)
+        } else if self.is_force_ignored(project_key, path)
+            || !settings.files.includes.is_included(path)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5e2c872 and 90a8387.

⛔ Files ignored due to path filters (4)
  • crates/biome_configuration/tests/invalid/experimental_scanner_ignores.json.snap is excluded by !**/*.snap and included by **
  • crates/biome_service/src/snapshots/module_diagnostic.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • .changeset/forced-files-forget.md (1 hunks)
  • crates/biome_configuration/src/lib.rs (3 hunks)
  • crates/biome_configuration/tests/invalid/experimental_scanner_ignores.json (1 hunks)
  • crates/biome_glob/src/lib.rs (8 hunks)
  • crates/biome_module_graph/src/js_module_info/diagnostics.rs (1 hunks)
  • crates/biome_service/src/projects.rs (1 hunks)
  • crates/biome_service/src/settings.rs (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • crates/biome_configuration/tests/invalid/experimental_scanner_ignores.json
  • crates/biome_module_graph/src/js_module_info/diagnostics.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_service/src/settings.rs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (use just f/just format).

Files:

  • crates/biome_service/src/projects.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/lib.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_service/src/projects.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/lib.rs
crates/biome_configuration/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Keep configuration sources under biome_configuration/src/

Files:

  • crates/biome_configuration/src/lib.rs
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: Create changesets with just new-changeset; store them in .changeset/ with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.

Files:

  • .changeset/forced-files-forget.md
🧬 Code graph analysis (2)
crates/biome_service/src/projects.rs (1)
crates/biome_service/src/settings.rs (1)
  • is_force_ignored (933-944)
crates/biome_configuration/src/lib.rs (1)
crates/biome_deserialize/src/lib.rs (2)
  • range (134-134)
  • visit_map (422-440)
🪛 LanguageTool
.changeset/forced-files-forget.md

[style] ~7-~7: Using many exclamation marks might seem excessive (in this case: 3 exclamation marks for a text that’s 1592 characters long)
Context: ...ng them with a double exclamation mark (!!). The effect of force-ignoring is tha...

(EN_EXCESSIVE_EXCLAMATION)

🔇 Additional comments (4)
.changeset/forced-files-forget.md (1)

1-3: Changeset frontmatter looks correct.

Package key and change type are in order.

crates/biome_configuration/src/lib.rs (2)

75-87: Confirm default ignore entries are intentional.

This list excludes common output dirs like dist/, build/, and target/. That’s fine if we want users to migrate those explicitly to !!**/<name>, but please double-check product intent so we don’t generate surprising suggestions.


574-641: Good custom deserialisation with targeted diagnostics.

Nice touch to filter defaults and emit actionable suggestions for migration.

crates/biome_glob/src/lib.rs (1)

207-213: is_negated covers both ! and !!.

API reads well and matches expectations.

Also applies to: 218-226

@humanchimp
Copy link

I am porting over from old "ignore" syntax from 120 days ago or so... i must say, I really find this new syntax quite difficult to wrap my head around. I didn't see the discussion, but I've always enjoyed "include"/"exclude" with globs where exclude rules override include rules. I find this syntax much harder to reason about. I have not been able to get it working the way I want

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Project Area: project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载