Skip to content

Conversation

@ematipico
Copy link
Member

Summary

This issue came up here: haydenbleasel/ultracite#332

I realised that we don't do anything particular during the merging of files.includes, however, we do document that ** must start with **.

We do have noBiomeFirstException, however, this rule doesn't make sense if we end up extending a config that does use ** at the beginning. The problem is, when we do the merging, we don't move ** in the first place.

This PR adds a new GlobsList type that makes sure of it. It's a newtype that manually implements Merge and uses a specialised Ord implementation.

Test Plan

I initially implemented the code with AI, but I eventually scrapped most of it. The tests inside glob_list are generated from AI, the test is being implemented by me

Docs

Probably not needed

@changeset-bot
Copy link

changeset-bot bot commented Oct 31, 2025

🦋 Changeset detected

Latest commit: 1de08b4

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

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

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

@ematipico ematipico requested review from a team and Conaclos October 31, 2025 11:24
@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project labels Oct 31, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Oct 31, 2025

CodSpeed Performance Report

Merging #7930 will not alter performance

Comparing fix/custom-includes-merging (1de08b4) with main (7165d06)1

Summary

✅ 1 untouched
⏩ 139 skipped2

Footnotes

  1. No successful run was found on main (e27892b) during the generation of this report, so 7165d06 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 139 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 2025

Walkthrough

This PR introduces a new GlobList struct wrapping glob patterns with merge functionality. It replaces direct Vec<NormalizedGlob> usage throughout the configuration system, incorporating this new type into configuration structures, migrations, and service layers. Associated changes add Hash, PartialOrd, and Ord traits to NormalizedGlob to support ordering logic that prioritises ** patterns at the start and deduplicates entries during merge operations.

Possibly related PRs

  • biomejs/biome#7359 — Modifies glob handling implementation with new traits and behaviours for glob values
  • biomejs/biome#7275 — Updates file include/glob pattern representation in Includes and settings

Suggested labels

A-Core, A-Linter, A-Formatter

Suggested reviewers

  • arendjr

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.61% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "fix(core): properly merge files.includes" directly captures the core change in this PR. The changeset introduces a GlobList newtype with specialized Merge and Ord implementations to ensure "**" patterns are positioned first during config merging, exactly as the title describes. The title is specific, concise, and uses conventional commit format without noise, making it clear that this fixes the merging behaviour of files.includes.
Description Check ✅ Passed The description clearly relates to the changeset by explaining the problem (files.includes not being merged with "**" at the beginning as documented) and the solution (a new GlobsList newtype with custom Merge and Ord implementations). It references the triggering issue, mentions the test strategy, and notes AI assistance appropriately. The description directly aligns with the actual changes across multiple configuration files switching from Vec to GlobList.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/custom-includes-merging

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 2

🧹 Nitpick comments (2)
crates/biome_cli/tests/cases/config_extends.rs (1)

554-602: Test structure looks correct.

The test validates the glob merging behaviour where ** should remain at the start when extending configurations. However, consider adding a brief comment explaining the expected final includes pattern (e.g., ["**", "!**/dist", "!components"]) to make the test's intent immediately clear.

.changeset/tricky-worms-allow.md (1)

5-12: Clear explanation with minor grammar tweaks.

The changeset accurately describes the fix. Consider these optional grammar improvements:

  • Line 6: "As per requirements" → "As per requirement" (singular after "per")
  • Line 11: "The following example," → "In the following example,"
  • Line 12: Add comma after "example": "...example, the final files.includes list..."
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e27892b and 3ebe750.

⛔ Files ignored due to path filters (2)
  • crates/biome_cli/tests/snapshots/main_cases_config_extends/extends_config_by_moving_double_star_at_the_beginning_from_extend_config.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 **
📒 Files selected for processing (16)
  • .changeset/tricky-worms-allow.md (1 hunks)
  • crates/biome_cli/src/commands/init.rs (1 hunks)
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs (5 hunks)
  • crates/biome_cli/src/execute/migrate/prettier.rs (2 hunks)
  • crates/biome_cli/tests/cases/config_extends.rs (1 hunks)
  • crates/biome_configuration/src/analyzer/assist/mod.rs (2 hunks)
  • crates/biome_configuration/src/analyzer/linter/mod.rs (2 hunks)
  • crates/biome_configuration/src/formatter.rs (2 hunks)
  • crates/biome_configuration/src/glob_list.rs (1 hunks)
  • crates/biome_configuration/src/lib.rs (3 hunks)
  • crates/biome_configuration/src/overrides.rs (2 hunks)
  • crates/biome_glob/src/lib.rs (3 hunks)
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs (5 hunks)
  • crates/biome_service/src/settings.rs (5 hunks)
  • crates/biome_service/src/settings.tests.rs (1 hunks)
  • crates/biome_service/src/workspace.tests.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Format Rust and TOML files before committing (e.g., via just f)

Files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_service/src/settings.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/glob_list.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Document rules, assists, and their options with inline rustdoc in the Rust source

Files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_service/src/settings.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/glob_list.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

.changeset/*.md: In changeset files, only use #### or ##### headers
Changesets should describe user-facing changes; internal-only changes do not need changesets
Use past tense for what you did in the changeset description and present tense for current behavior
For bug fixes, start the changeset description with a link to the issue (e.g., Fixed #1234: ...)
When referencing a rule or assist in a changeset, include a link to the rule/assist page on the website
Include a code block in the changeset when applicable to illustrate the change
End every sentence in a changeset with a full stop (.)

Files:

  • .changeset/tricky-worms-allow.md
🧠 Learnings (53)
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Prefer Box<[Box<str>]> over Vec<String> for options string lists to reduce memory usage

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_service/src/settings.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/glob_list.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Add the provided AsFormat, IntoFormat, and iterator plumbing code to lib.rs

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/glob_list.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import and use the `FormatNode` trait for AST nodes

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Place per-rule options types in biome_rule_options crate under lib/, one file per rule

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Derive Serialize, Deserialize, and Deserializable for rule options; add #[serde(rename_all = "camelCase", deny_unknown_fields, default)]

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_glob/src/lib.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/glob_list.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : When schema feature is enabled, derive schemars::JsonSchema for options and related enums

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use `dbg_write!` to debug and inspect the emitted IR during formatting

Applied to files:

  • crates/biome_configuration/src/formatter.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Avoid deep indentation by using combinators (map, filter, and_then) rather than nested if-let/unwrap chains

Applied to files:

  • crates/biome_configuration/src/formatter.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code; if a mandatory token/node is missing, return `None` instead

Applied to files:

  • crates/biome_configuration/src/formatter.rs
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in ../biome_lsp/src/server.tests.rs

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/tests/quick_test.rs : Quick test lives in biome_js_analyze/tests/quick_test.rs; unignore #[ignore] and set rule filter and SOURCE for ad-hoc runs

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Use options/full_options/use_options code block modifiers as specified to demonstrate configuration in docs; keep modifier order consistent

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/commands/init.rs
  • crates/biome_service/src/workspace.tests.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/** : Create a tests directory containing a specs subfolder and the files spec_test.rs, spec_tests.rs, and language.rs

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_tests.rs : In tests/spec_tests.rs, generate tests with `tests_macros::gen_tests! {"tests/specs/html/**/*.html", crate::spec_test::run, ""}`

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_configuration/src/glob_list.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/tests/specs/**/{invalid*,valid*}.* : Name snapshot test files with invalid* and valid* prefixes to indicate reported vs non-reported cases

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/src/workspace/watcher.tests.rs : Place watcher tests related to workspace methods in src/workspace/watcher.tests.rs

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/tests/spec_test.rs : Implement a `run` function in tests/spec_test.rs that wires SpecSnapshot and includes!("language.rs") as shown

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : When banning globals (e.g., console), check semantic model to avoid flagging locally shadowed variables

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : In ### Invalid doc examples, each snippet must use the expect_diagnostic modifier and emit exactly one diagnostic

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/tests/specs/**/*.jsonc : .jsonc snapshot test files must contain an array of code strings and are interpreted as script (no ESM import/export)

Applied to files:

  • crates/biome_cli/tests/cases/config_extends.rs
📚 Learning: 2025-10-15T09:25:05.698Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/src/workspace.rs : Implement and expose the Workspace trait in src/workspace.rs

Applied to files:

  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-10-26T15:28:00.951Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-10-26T15:28:00.951Z
Learning: Applies to {Cargo.toml,crates/**/Cargo.toml} : Use workspace dependencies for internal crates (set `workspace = true` in Cargo.toml)

Applied to files:

  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : For cross-file analyses, use custom visitors/Queryable to emit matches during main traversal to avoid redundant passes

Applied to files:

  • crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/src/{type_info,local_inference,resolver,flattening}.rs : Avoid recursive type structures and cross-module Arcs; represent links between types using TypeReference and TypeData::Reference.

Applied to files:

  • crates/biome_configuration/src/overrides.rs
  • crates/biome_cli/src/commands/init.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/assist/**/*.rs : Assist (actions) must have severity: info

Applied to files:

  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Set associated type Options of the rule to the concrete options type from biome_rule_options when options exist; otherwise use ()

Applied to files:

  • crates/biome_configuration/src/overrides.rs
  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_configuration/src/analyzer/assist/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : In declare_lint_rule! macros, set version: "next"

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Default severity is information; override severity intentionally using biome_diagnostics::Severity when needed

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Rule documentation: first paragraph must be a single line summary

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Prefer conventional naming families when applicable: use<Framework>..., noConstant<Concept>, noDuplicate<Concept>, noEmpty<Concept>, noExcessive<Concept>, noRedundant<Concept>, noUnused<Concept>, noUseless<Concept>, noInvalid<Concept>, useValid<Concept>, noUnknown<Concept>, noMisleading<Concept>, noRestricted<Concept>, noUndeclared<Concept>, noUnsafe<Concept>, useConsistent<Concept>, useShorthand<Concept>

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/lint/nursery/**/*.rs : Place all new rules in the nursery group

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_service/src/settings.tests.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/correctness/**/*.rs : Rules in correctness group must have severity: error

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : If a rule is inspired by an external source, populate sources in declare_lint_rule! with RuleSource::{Eslint,...} and same()/inspired()

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
  • crates/biome_configuration/src/lib.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/performance/**/*.rs : Rules in performance group must have severity: warn

Applied to files:

  • crates/biome_configuration/src/analyzer/linter/mod.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/biome_*_{syntax,factory}/** : Create per-language crates biome_<lang>_syntax and biome_<lang>_factory under crates/

Applied to files:

  • crates/biome_cli/src/commands/init.rs
  • crates/biome_cli/src/execute/migrate/prettier.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-15T09:23:33.055Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/**/*.rs : Do not copy or clone data between module graph entries (including behind Arc). Each module must avoid holding duplicated data from another module to enable simple invalidation.

Applied to files:

  • crates/biome_service/src/workspace.tests.rs
📚 Learning: 2025-10-15T09:24:31.042Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Lexer must implement the biome_parser::Lexer trait

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Implement the `Format` trait for your node type and use `JsFormatter` with `write!`/`format_args!` to define formatting

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Implement FormatLanguage for HtmlFormatLanguage with associated types: SyntaxLanguage=HtmlLanguage, Context=HtmlFormatContext, FormatRule=FormatHtmlSyntaxNode

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/comments.rs : Define HtmlCommentStyle implementing CommentStyle in comments.rs

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Define the HtmlFormatter type alias: `type HtmlFormatter<'buf> = Formatter<'buf, HtmlFormatContext>;`

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Expose a documented public function `format_node(options: HtmlFormatOptions, root: &HtmlSyntaxNode) -> FormatResult<Formatted<HtmlFormatContext>>` delegating to `biome_formatter::format_node`

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:15.851Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/context.rs : Create HtmlFormatContext in context.rs with comments and source_map fields and implement FormatContext and CstFormatContext

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-15T09:22:46.002Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:46.002Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : For non-mandatory tokens, use the provided helper constructors (e.g., `token`, `space_token`, `dynamic_token`)

Applied to files:

  • crates/biome_cli/src/execute/migrate/prettier.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Use rule_category! macro to reference the diagnostic category created by declare_lint_rule!

Applied to files:

  • crates/biome_configuration/src/lib.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : When using semantic/control-flow services with Ast queries, ensure the rule runs in a phase where the services exist (e.g., use Semantic<> or custom visitor in proper phase)

Applied to files:

  • crates/biome_configuration/src/lib.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : When emitting multiple diagnostics/actions for one query, prefer Box<[_]> over Vec<_> for Signals to reduce memory

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : When returning a code action, pass category via ctx.action_category(ctx.category(), ctx.group()) and applicability via ctx.metadata().applicability()

Applied to files:

  • crates/biome_configuration/src/analyzer/assist/mod.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/style/**/*.rs : Rules in style group must have severity: info or warn (prefer info if unsure)

Applied to files:

  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/a11y/**/*.rs : Rules in a11y group must have severity: error

Applied to files:

  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Set the language field in declare_lint_rule! to the most appropriate dialect (js/jsx/ts/tsx)

Applied to files:

  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
📚 Learning: 2025-10-24T21:24:58.650Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/*_analyze/**/src/**/lint/**/*.rs : Every code block in docs must declare a language

Applied to files:

  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
🧬 Code graph analysis (13)
crates/biome_configuration/src/formatter.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_cli/tests/cases/config_extends.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 (1)
  • assert_cli_snapshot (407-409)
crates/biome_service/src/scanner/workspace_scanner_bridge.tests.rs (1)
crates/biome_glob/src/lib.rs (2)
  • from_str (188-191)
  • from_str (345-370)
crates/biome_configuration/src/overrides.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_glob/src/lib.rs (1)
  • is_match_candidate (296-298)
crates/biome_configuration/src/analyzer/linter/mod.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_service/src/settings.tests.rs (4)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (2)
  • OverrideGlobs (1012-1012)
  • NormalizedGlob (889-889)
crates/biome_configuration/src/glob_list.rs (1)
  • new (16-18)
crates/biome_glob/src/lib.rs (3)
  • new (449-451)
  • from_str (188-191)
  • from_str (345-370)
crates/biome_service/src/settings.rs (2)
  • new (933-938)
  • new (1017-1022)
crates/biome_service/src/workspace.tests.rs (3)
crates/biome_configuration/src/glob_list.rs (1)
  • new (16-18)
crates/biome_service/src/settings.rs (2)
  • new (933-938)
  • new (1017-1022)
crates/biome_glob/src/lib.rs (2)
  • from_str (188-191)
  • from_str (345-370)
crates/biome_service/src/settings.rs (2)
crates/biome_configuration/src/glob_list.rs (1)
  • new (16-18)
crates/biome_glob/src/lib.rs (1)
  • new (449-451)
crates/biome_cli/src/execute/migrate/prettier.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (2)
  • NormalizedGlob (889-889)
  • OverrideGlobs (1012-1012)
crates/biome_configuration/src/glob_list.rs (1)
  • new (16-18)
crates/biome_configuration/src/lib.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_configuration/src/glob_list.rs (1)
crates/biome_glob/src/lib.rs (4)
  • from (182-184)
  • from (339-341)
  • deref (177-179)
  • is_negated (245-247)
crates/biome_configuration/src/analyzer/assist/mod.rs (1)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_cli/src/execute/migrate/eslint_to_biome.rs (3)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
  • GlobList (378-378)
crates/biome_cli/src/execute/migrate/prettier.rs (1)
  • files (321-324)
crates/biome_configuration/src/glob_list.rs (1)
  • new (16-18)
🪛 LanguageTool
.changeset/tricky-worms-allow.md

[uncategorized] ~6-~6: Did you mean “requirement”? If following ‘per’, nouns are often singular.
Context: ...incorrect list of glob patterns. As per requirements, the list of files.includes must have...

(CONFUSION_OF_NNS_NN_UN)


[uncategorized] ~11-~11: Possible missing preposition found.
Context: ... will contain ** in the first place. The following example, the final `files.inc...

(AI_HYDRA_LEO_MISSING_IN)


[uncategorized] ~12-~12: Possible missing comma found.
Context: ...ing example, the final files.includes list will be `["", "!/dist", "!component...

(AI_HYDRA_LEO_MISSING_COMMA)

⏰ 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). (8)
  • GitHub Check: Test Node.js API
  • GitHub Check: autofix
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Check JS Files
🔇 Additional comments (12)
crates/biome_glob/src/lib.rs (2)

152-152: LGTM!

Adding Hash is appropriate for use in collections like HashMap and HashSet.


305-308: Useful addition.

The as_str() method provides clean access to the underlying pattern.

crates/biome_configuration/src/overrides.rs (1)

4-4: Clean migration to GlobList.

The changes correctly adopt the new GlobList wrapper throughout the overrides handling.

Also applies to: 82-82, 89-89

crates/biome_cli/src/commands/init.rs (1)

26-32: Straightforward GlobList adoption.

The .into() conversion cleanly wraps the glob vector in the new GlobList type.

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

233-239: Consistent test updates for GlobList.

All test cases correctly adopt the new .into() pattern for includes construction.

Also applies to: 276-282, 325-332, 371-377, 414-420

crates/biome_configuration/src/formatter.rs (1)

2-2: API updated to use GlobList.

The formatter configuration now consistently uses GlobList for includes, matching the pattern across other configuration types.

Also applies to: 90-90

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

701-703: Test updated for GlobList.

The override patterns now correctly box the GlobList-wrapped glob vectors.

Also applies to: 710-713

.changeset/tricky-worms-allow.md (1)

14-32: Helpful example.

The JSON examples clearly illustrate the merging behaviour and expected result.

crates/biome_service/src/settings.rs (4)

9-9: LGTM!

Clean addition of the import for the new GlobList type.


930-930: LGTM!

The type change from Vec<NormalizedGlob> to GlobList is clean. Since the field is private, this maintains encapsulation whilst enabling the new merge behaviour.


933-933: LGTM!

Constructor signature correctly updated to match the field type change.


970-970: LGTM!

The .as_slice() calls correctly adapt the new GlobList type to the existing matching functions. The pattern is consistent across all three usages.

Also applies to: 990-990, 1004-1004

Comment on lines +50 to +55
impl Merge for GlobList {
fn merge_with(&mut self, other: Self) {
self.extend(other.0);
self.sort();
}
}
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 31, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Please de-duplicate merged globs.

merge_with only extends and sorts, so duplicates hang around. The new tests expect len() to shrink after merging and real configs rely on deduped globs to prevent duplicated work. Add a dedup step after sorting (e.g. self.dedup(); or self.dedup_by(...)) so merges behave as intended. Happy to review that tweak once it lands.

     fn merge_with(&mut self, other: Self) {
         self.extend(other.0);
         self.sort();
+        self.dedup();
     }
🤖 Prompt for AI Agents
In crates/biome_configuration/src/glob_list.rs around lines 50 to 55, the
Merge::merge_with implementation currently extends and sorts the list but does
not remove duplicate globs; modify the method to deduplicate after sorting (for
example call self.dedup() or self.dedup_by(...) if a custom equality is needed)
so merged GlobList values do not retain duplicates and len() shrinks as
expected.

Copy link
Member Author

Choose a reason for hiding this comment

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

@coderabbitai can you make sure that dedup() is actually available for that type?

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the NormalizedGlob struct definition and its derives
rg -A 5 "pub struct NormalizedGlob" crates/biome_glob/src/lib.rs

Length of output: 199


🏁 Script executed:

#!/bin/bash
# Check NormalizedGlob with more context before the struct to see derives
rg -B 3 -A 2 "pub struct NormalizedGlob" crates/biome_glob/src/lib.rs

Length of output: 319


🏁 Script executed:

#!/bin/bash
# Check with more before context to find the derive line
rg -B 5 -A 3 "pub struct NormalizedGlob" crates/biome_glob/src/lib.rs

Length of output: 383


🏁 Script executed:

#!/bin/bash
# Check with even more before context
rg -B 10 -A 2 "pub struct NormalizedGlob" crates/biome_glob/src/lib.rs

Length of output: 537


@ematipico Yes, dedup() is available! I've verified that:

  1. NormalizedGlob derives PartialEq (line in crates/biome_glob/src/lib.rs shows #[derive(Debug, Clone, Eq, PartialEq, Hash)])
  2. GlobList implements DerefMut with Target = Vec<NormalizedGlob>
  3. Vec::dedup() is available for any T: PartialEq

So calling self.dedup() in the merge_with method will work correctly through deref coercion—Rust will automatically treat self as &mut Vec<NormalizedGlob> and call Vec::dedup(), which removes consecutive duplicate elements after sorting.


🧠 Learnings used
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Derive Serialize, Deserialize, and Deserializable for rule options; add #[serde(rename_all = "camelCase", deny_unknown_fields, default)]

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Prefer Box<[Box<str>]> over Vec<String> for options string lists to reduce memory usage

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : When schema feature is enabled, derive schemars::JsonSchema for options and related enums

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:24:31.042Z
Learning: Applies to crates/biome_parser/crates/biome_*_{syntax,factory}/** : Create per-language crates biome_<lang>_syntax and biome_<lang>_factory under crates/

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/**/*.rs : After generation, remove usages of `format_verbatim_node` and implement real formatting with biome_formatter utilities

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/../biome_lsp/src/server.tests.rs : Keep end-to-end LSP tests in ../biome_lsp/src/server.tests.rs

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:22:15.851Z
Learning: Applies to crates/biome_formatter/src/lib.rs : Add the provided AsFormat, IntoFormat, and iterator plumbing code to lib.rs

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-10-24T21:24:58.650Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Place per-rule options types in biome_rule_options crate under lib/, one file per rule

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:25:05.698Z
Learning: Applies to crates/biome_service/src/workspace.rs : Implement and expose the Workspace trait in src/workspace.rs

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-10-15T09:23:33.055Z
Learning: Applies to crates/biome_js_type_info/biome_module_graph/src/**/*.rs : Do not copy or clone data between module graph entries (including behind Arc). Each module must avoid holding duplicated data from another module to enable simple invalidation.

Comment on lines +204 to +221
impl PartialOrd for NormalizedGlob {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for NormalizedGlob {
fn cmp(&self, other: &Self) -> Ordering {
// SAFETY: "**" is a valid pattern
let self_is_double_star = self.0 == Glob::from_str("**").unwrap();
let other_is_double_star = other.0 == Glob::from_str("**").unwrap();

match (self_is_double_star, other_is_double_star) {
(true, false) => Ordering::Less, // ** comes first
(false, true) => Ordering::Greater, // ** comes first
_ => Ordering::Equal, // keep ordering as is
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that partial ordering semantics are sufficient for the use case.

The Ord implementation treats all non-** patterns as equal (Ordering::Equal), which violates the total ordering requirement. This works for the specific goal of sorting ** to the front, but standard sorting algorithms may behave unpredictably when multiple non-** patterns exist (their relative order becomes unstable).

If the only requirement is "move ** to the front and preserve insertion order otherwise", consider documenting this explicitly or using a dedicated sorting function instead of implementing Ord.

Run the following to check how GlobList sorting is used:


🏁 Script executed:

#!/bin/bash
# Search for uses of sort/ordering on NormalizedGlob or GlobList
rg -n "\.sort\(\)" --type=rust -C3
rg -n "NormalizedGlob.*Ord" --type=rust -C3
rg -n "GlobList.*sort" --type=rust -C3

Length of output: 4181


🏁 Script executed:

#!/bin/bash
# Examine GlobList type definition and sort implementation
rg -n "impl.*GlobList\|struct GlobList\|type GlobList" --type=rust -A5 -B2 crates/biome_configuration/src/glob_list.rs

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Look at GlobList structure and sort method
cat crates/biome_configuration/src/glob_list.rs

Length of output: 6223


🏁 Script executed:

#!/bin/bash
# Check if NormalizedGlob is used elsewhere and what sort actually does
rg -n "NormalizedGlob" --type=rust -C2

Length of output: 15744


Use sort_stable() to guarantee insertion-order preservation for non-** patterns.

The Ord implementation correctly treats all non-** patterns as equal (enabling ** to sort first), but GlobList::merge_with calls the unstable sort() method. This risks reordering non-** patterns arbitrarily, contradicting the tests that expect insertion order preservation (e.g., test_merge_with_mixed_globs_preserves_insertion_order). Replace self.sort() with self.sort_stable() at crates/biome_configuration/src/glob_list.rs:53 to guarantee stable ordering semantics.

🤖 Prompt for AI Agents
crates/biome_configuration/src/glob_list.rs around line 53: replace the call to
self.sort() with self.sort_stable() so non-"**" patterns preserve insertion
order as intended by the Ord impl in crates/biome_glob/src/lib.rs; update any
imports or trait bounds if needed to make sort_stable() available in this scope
and run tests to confirm insertion-order-preserving behavior (e.g.,
test_merge_with_mixed_globs_preserves_insertion_order).

Copy link
Member

@Conaclos Conaclos left a comment

Choose a reason for hiding this comment

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

I am not fond of this fix for two reasons:

  1. Sorting the globs breaks the intended semantic: If a user writes ["**", "!**", "**"], then the last "**" should take precedence over "!**". Sorting the globs results in a different semantic.
  2. This doesn't take account other globs like **/* (yes users should use ** because it is simpler, however some users - like ultracite - use this pattern) or src/** that a shared config could start with.

I wonder if it makes sense of merging files.includes.
Perhaps we want to keep them separated:

  • First check the file against the user files.includes
  • If the file matches, then check against the shared files.includes

EDIT: We could also reverse the check. In other words, a file has to match the two lists of globs.

EDIT 2: we certainly have the same issues for other inherited includes...

If I remember correctly we don't handle extends in shared config?


```json5
// biome.json, the user configuration
{
Copy link
Member

Choose a reason for hiding this comment

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

I think an extends property is missing here.

@Conaclos
Copy link
Member

Conaclos commented Oct 31, 2025

Let me think about that a bit more. I have several idea to sort out.

@ematipico
Copy link
Member Author

I am not fond of this fix for two reasons:

1. Sorting the globs breaks the intended semantic:  If  a user writes `["**", "!**", "**"]`, then the last `"**"` should take precedence over `"!**"`. Sorting the globs results in a different semantic.

If we need an argument, at least let's make one using a valid example that users might use. I doubt that this is a valid case in user-land, and if we need to take this into account, I wouldn't do it.

2. This doesn't take account other globs like `**/*` (yes users should use `**` because it is simpler, however some users - like ultracite - use this pattern) or `src/**` that a shared config could start with.

That's fair, we can definitely make the checks and order more granular, but I hope you see the problem

If I remember correctly we don't handle extends in shared config?

We don't by design, exactly, and we intend to keep it that way.

Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

Nice!

Consider deduping the list in the Merge impl, like the bot suggested.

@Conaclos
Copy link
Member

Conaclos commented Nov 2, 2025

includes is very flat by nature. It is not well suited for merging.
I see several approaches to "fix" the current issue:

  1. Overriding.
    If a user set <any>.includes, then the inherited <any>.includes is overrided (discarded).
  2. Complementing (what I previously proposed)
    Every file is matched against both the user's <any>.includes and the inherited <any>.includes.
  3. Recommend users to not start <any>.includes with ** when extending a shared configuration with an extended includes.
    noBiomeFirstException should make an exception here.
    This has thje advantage of working with today's semantic. Also this doesn't requre any change from shared config authors.
  4. Removing ** and **/* from the start of includes when merging it with a shared includes.
    This has the advantage of working today and to avoid too much dispruptions.

(1) or (2) seems the best approaches to me on the long term.
It is technically a breaking change.

As a quick fix I could opt for (3).

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.

4 participants