Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/salty-laws-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#7343](https://github.com/biomejs/biome/issues/7343), where Biome failed to resolve extended configurations from parent directories using relative paths.
66 changes: 65 additions & 1 deletion crates/biome_cli/tests/cases/config_extends.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::run_cli;
use crate::run_cli_with_dyn_fs;
use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
use biome_console::BufferConsole;
use biome_formatter::LineWidth;
use biome_fs::MemoryFileSystem;
use biome_fs::{MemoryFileSystem, TemporaryFs};
use bpaf::Args;
use camino::Utf8Path;

Expand Down Expand Up @@ -756,3 +757,66 @@ fn extends_config_rule_fine_grained_options_merge2() {
result,
));
}

// See: https://github.com/biomejs/biome/issues/7343
#[test]
fn extends_config_two_levels_deep() {
let mut console = BufferConsole::default();
let mut fs = TemporaryFs::new("extends_config_two_levels_deep");

// Root config at the project root
fs.create_file(
"biome.jsonc",
r#"{
"formatter": {
"lineWidth": 120
},
"linter": {
"enabled": true,
"rules": {
"suspicious": {
"noDebugger": "error"
}
}
}
}"#,
);

// Child config two levels deep: sub-project/sub-sub-project/biome.jsonc
// It extends the root config using a relative path ../../biome.jsonc
fs.create_file(
"sub-project/sub-sub-project/biome.jsonc",
r#"{
"extends": ["../../biome.jsonc"],
"root": false
}"#,
);

// Test file in the same directory as child config
fs.create_file(
"sub-project/sub-sub-project/test.js",
r#"debugger; console.log("string"); "#,
);

let result = run_cli_with_dyn_fs(
Box::new(fs.create_os()),
&mut console,
Args::from(
[
"check",
&format!("{}/sub-project/sub-sub-project/test.js", fs.cli_path()),
]
.as_slice(),
),
);

assert!(result.is_err(), "run_cli returned {result:?}");

assert_cli_snapshot(SnapshotPayload::new(
module_path!(),
"extends_config_two_levels_deep",
fs.create_mem(),
console,
result,
));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
source: crates/biome_cli/tests/snap_test.rs
expression: redactor(content)
---
## `biome.jsonc`

```json
{
"formatter": {
"lineWidth": 120
},
"linter": {
"enabled": true,
"rules": {
"suspicious": {
"noDebugger": "error"
}
}
}
}
```

## `sub-project/sub-sub-project/biome.jsonc`

```json
{
"extends": ["../../biome.jsonc"],
"root": false
}
```

## `sub-project/sub-sub-project/test.js`

```js
debugger; console.log("string");
```

# Termination Message

```block
check ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Some errors were emitted while running checks.
```

# Emitted Messages

```block
sub-project/sub-sub-project/test.js:1:1 lint/suspicious/noDebugger FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━
× This is an unexpected use of the debugger statement.
> 1 │ debugger; console.log("string");·
│ ^^^^^^^^^
i Unsafe fix: Remove debugger statement
1 │ debugger;·console.log("string");·
│ ----------
```

```block
sub-project/sub-sub-project/test.js format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Formatter would have printed the following content:
1 │ - debugger;·console.log("string");·
1 │ + debugger;
2 │ + console.log("string");
3 │ +
```

```block
Checked 1 file in <TIME>. No fixes applied.
Found 2 errors.
```
8 changes: 3 additions & 5 deletions crates/biome_service/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ use biome_json_analyze::METADATA as json_lint_metadata;
use biome_json_formatter::context::JsonFormatOptions;
use biome_json_parser::{JsonParserOptions, parse_json};
use biome_json_syntax::JsonLanguage;
use biome_resolver::{FsWithResolverProxy, ResolveOptions, resolve};
use biome_resolver::{FsWithResolverProxy, ResolveOptions, is_relative_specifier, resolve};
use biome_rowan::Language;
use camino::{Utf8Path, Utf8PathBuf};
use rustc_hash::FxHashSet;
use std::fmt::Debug;
use std::io::ErrorKind;
use std::iter::FusedIterator;
use std::ops::Deref;
use std::path::Path;
use std::str::FromStr;
use tracing::instrument;

Expand Down Expand Up @@ -556,9 +555,8 @@ impl ConfigurationExt for Configuration {
let mut deserialized_configurations = vec![];
if let Some(extends) = extends.as_list() {
for extend_entry in extends.iter() {
let extend_entry_as_path = Path::new(extend_entry.as_ref());

let extend_configuration_file_path = if extend_entry_as_path.starts_with(".") {
let extend_configuration_file_path = if is_relative_specifier(extend_entry.as_ref())
{
relative_resolution_base_path.join(extend_entry.as_ref())
} else {
const RESOLVE_OPTIONS: ResolveOptions = ResolveOptions::new()
Expand Down