Skip to content

Conversation

@ematipico
Copy link
Member

@ematipico ematipico commented Dec 5, 2025

Summary

Closes #7343

Test created with AI, and uses AI to identify potential solutions.

Test Plan

Added a test and verified that it works as expected

Docs

@changeset-bot
Copy link

changeset-bot bot commented Dec 5, 2025

🦋 Changeset detected

Latest commit: dec5477

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

@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project labels Dec 5, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

Walkthrough

Adds a changelog entry for a patch release and a test that validates multi-level extends resolution using a dynamic filesystem. Changes configuration resolution to use a new is_relative_specifier helper from the resolver: relative specifiers are detected via that function and joined with the base path; non-relative entries continue to use ResolveOptions-based resolution. Exports is_relative_specifier from the resolver for cross-crate use.

Suggested labels

A-Resolver

Suggested reviewers

  • dyc3
  • chansuke

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main change: fixing CLI config resolution from parent paths, which directly addresses the linked issue.
Description check ✅ Passed The description provides relevant context, links the issue, mentions test creation, and discloses AI assistance appropriately.
Linked Issues check ✅ Passed The PR directly addresses issue #7343 by implementing relative path resolution for extended configurations in multi-level nested configs using is_relative_specifier.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the config extends issue: changelog entry, test case for multi-level extends, and resolver logic updates for relative paths.
✨ 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/relative-config-extends

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

🧹 Nitpick comments (1)
crates/biome_service/src/configuration.rs (1)

558-582: Using is_relative_specifier here tightens relative vs package specifier handling

This neatly routes ././/../ entries to a plain join on the config directory and leaves everything else to the resolver, which is exactly what you want for the multi-level parent-config case.

Tiny polish you might consider: make the verbose advice reflect the actual base path used (relative vs external) by caching the is_relative flag and a base_path_for_diagnostics and reusing that in the CantResolve/CantLoadExtendFile advice, e.g.:

-            for extend_entry in extends.iter() {
-                let extend_configuration_file_path = if is_relative_specifier(extend_entry.as_ref())
-                {
-                    relative_resolution_base_path.join(extend_entry.as_ref())
-                } else {
+            for extend_entry in extends.iter() {
+                let is_relative = is_relative_specifier(extend_entry.as_ref());
+                let base_path_for_diagnostics = if is_relative {
+                    relative_resolution_base_path
+                } else {
+                    external_resolution_base_path
+                };
+                let extend_configuration_file_path = if is_relative {
+                    relative_resolution_base_path.join(extend_entry.as_ref())
+                } else {
                     const RESOLVE_OPTIONS: ResolveOptions = ResolveOptions::new()
                         .with_assume_relative()
                         .with_condition_names(&["biome", "default"]);
@@
-                    .map_err(|error| {
+                    .map_err(|error| {
                         CantResolve::new(Utf8PathBuf::from(extend_entry), error)
                             .with_verbose_advice(markup! {
                                 "Biome tried to resolve the configuration file \""<Emphasis>{
                                     extend_entry
                                 }</Emphasis>"\" in \"extends\" using \""<Emphasis>{
-                                    external_resolution_base_path.to_string()
+                                    base_path_for_diagnostics.to_string()
                                 }</Emphasis>"\" as the base path."
                             })
                     })?
@@
-                    .map_err(|err| {
+                    .map_err(|err| {
                         CantLoadExtendFile::new(
                             extend_configuration_file_path.to_string(),
                             err.to_string(),
                         )
                         .with_verbose_advice(markup! {
                             "Biome tried to load the configuration file \""<Emphasis>{
                                 extend_configuration_file_path.to_string()
                             }</Emphasis>"\" in \"extends\" using \""<Emphasis>{
-                                external_resolution_base_path.to_string()
+                                base_path_for_diagnostics.to_string()
                             }</Emphasis>"\" as the base path."
                         })
                     })?;

Not essential for the fix, but it should make debugging failed extends a bit less head-scratching.

📜 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 9c12fcf and dec5477.

📒 Files selected for processing (1)
  • crates/biome_service/src/configuration.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use the dbg!() macro for debugging output during testing, and pass the --show-output flag to cargo to view debug output
Use cargo t or cargo test to run tests; for a single test, pass the test name after the test command
Use snapshot testing with the insta crate; run cargo insta accept, cargo insta reject, or cargo insta review to manage snapshot changes
Write doctests as doc comments with code blocks; the code inside code blocks will be run during the testing phase
Use just f (alias for just format) to format Rust and TOML files before committing

Files:

  • crates/biome_service/src/configuration.rs
🧠 Learnings (20)
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/scoped_resolver.rs : Implement full inference to resolve `TypeReference::Import` variants across the entire module graph

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : When using `ResolvedTypeData`, track the `ResolverId` to ensure subsequent resolver calls use the correct context

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Implement the `Merge` trait for rule options to define how options from extended configuration merge with user configuration (usually reset instead of extend)

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Always apply the correct `ResolverId` when retrieving raw type data from `ResolvedTypeData.as_raw_data()` to prevent panics during subsequent resolution calls

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeReference` variants (`Qualifier`, `Resolved`, `Import`, `Unknown`) to represent different phases of type resolution

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Wrap optional rule option fields in `Option<_>` to properly track set vs unset options during configuration merging

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:04:57.309Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:57.309Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Use helper types from the biome_diagnostics::v2 module (CodeFrameAdvice, CommandAdvice, DiffAdvice, LogAdvice) or implement the Advices trait yourself for custom advice handling

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:06:12.048Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_service/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:12.048Z
Learning: Applies to crates/biome_service/src/workspace*.rs : Implement the Workspace trait in the Biome Service to manage internal state of projects, including open documents, project layout instances, and module graph instances

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/language_kind.rs : Add a new language prefix to the `LANGUAGE_PREFIXES` constant in `language_kind.rs` file

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Expose a public `format_node` function that accepts formatting options and a root syntax node, returning a `FormatResult<Formatted<Context>>` with appropriate documentation

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/context.rs : Define `<Language>FormatContext` struct in a `context.rs` file containing `comments` and `source_map` fields, implementing `FormatContext` and `CstFormatContext` traits

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/src/lib.rs : Define a type alias `<Language>Formatter<'buf>` as `Formatter<'buf, <Language>FormatContext>` in the main formatter crate

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/language.rs : Implement `TestFormatLanguage` trait in `tests/language.rs` for the formatter's test language

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : A parser struct must implement the `Parser` trait and save the token source, parser context, and optional parser options

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `IntoFormat<Context>` trait in `lib.rs` with implementations for `SyntaxResult` and `Option` types as part of the formatter infrastructure

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:05:20.371Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.371Z
Learning: Implement the `AsFormat<Context>` trait in `lib.rs` with generic implementations for references, `SyntaxResult`, and `Option` types as provided in the formatter boilerplate code

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_service/src/configuration.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/src/**/*.rs : Rule options struct fields should use `#[serde(rename_all = "camelCase")]`, `#[serde(deny_unknown_fields)]`, and `#[serde(default)]` attributes for proper JSON serialization

Applied to files:

  • crates/biome_service/src/configuration.rs
🧬 Code graph analysis (1)
crates/biome_service/src/configuration.rs (1)
crates/biome_resolver/src/lib.rs (1)
  • is_relative_specifier (672-674)
⏰ 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: Documentation
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test Node.js API
🔇 Additional comments (1)
crates/biome_service/src/configuration.rs (1)

32-32: Importing is_relative_specifier keeps resolution logic cohesive

Good call delegating “is this relative?” to the shared resolver helper; it keeps config handling in step with the rest of the resolution stack.

@ematipico ematipico requested review from a team December 5, 2025 18:10
@ematipico ematipico merged commit d71924e into main Dec 7, 2025
13 checks passed
@ematipico ematipico deleted the fix/relative-config-extends branch December 7, 2025 06:15
@github-actions github-actions bot mentioned this pull request Dec 6, 2025
ematipico added a commit that referenced this pull request Dec 8, 2025
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
ematipico added a commit that referenced this pull request Dec 8, 2025
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This was referenced Dec 15, 2025
l0ngvh pushed a commit to l0ngvh/biome that referenced this pull request Dec 21, 2025
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
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.

🐛 extends is not able to resolve configuration file in monorepo when child config is two levels deep

2 participants