Skip to content

Commit 3dfea16

Browse files
ematipicocoderabbitai[bot]dyc3
authored
feat(core): hidden files and config dirs (#8663)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Carson McManus <dyc3@users.noreply.github.com>
1 parent 46f33a7 commit 3dfea16

24 files changed

Lines changed: 886 additions & 81 deletions

.changeset/blue-buttons-own.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@biomejs/biome": minor
3+
---
4+
5+
Added support for Cursor files. When Biome sees a Cursor JSON file, it will parse it with comments enabled and trailing commas enabled:
6+
- `$PROJECT/.cursor/`
7+
- `%APPDATA%\Cursor\User\` on Windows
8+
- `~/Library/Application Support/Cursor/User/` on macOS
9+
- `~/.config/Cursor/User/` on Linux

.changeset/fast-months-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed [#901](https://github.com/biomejs/biome-vscode/issues/901). Biome now allows trailing commas in inside Zed `settings.json` and VSCode `settings.json`.

.changeset/rotten-squids-ring.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"@biomejs/biome": minor
3+
---
4+
5+
Added the ability to load the configuration from new known paths. Biome now attempts to load the configuration files
6+
from the following locations:
7+
- `$XDG_CONFIG_HOME` or `$HOME/.config/biome` on Linux
8+
- `/Users/$USER/Library/Application Support/biome` on macOS
9+
- `C:\Users\$USER\AppData\Roaming\biome\config` on Windows
10+
11+
The priority how Biome will attempt to load the configuration files is the following:
12+
1. project folder (working directory)
13+
2. parent folders
14+
3. config home
15+
1. `$XDG_CONFIG_HOME` or `$HOME/.config/biome` on Linux
16+
2. `/Users/$USER/Library/Application Support/biome` on macOS
17+
3. `C:\Users\$USER\AppData\Roaming\biome\config` on Windows

.changeset/tangy-dingos-design.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@biomejs/biome": minor
3+
---
4+
5+
Added the ability to load the hidden files `.biome.json` and `.biome.jsonc`. This is the order how Biome will attempt the configuration file is:
6+
1. `biome.json`
7+
2. `biome.jsonc`
8+
3. `.biome.json`
9+
4. `.biome.jsonc`

Cargo.lock

Lines changed: 2 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ cfg-if = "1.0.4"
112112
countme = "3.0.1"
113113
crossbeam = "0.8.4"
114114
dashmap = "6.1.0"
115-
dirs = "6.0.0"
115+
directories = "6.0.0"
116116
either = "1.15.0"
117117
enumflags2 = "0.7.12"
118118
getrandom = "0.2.15"

crates/biome_cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ biome_css_formatter = { workspace = true }
8484
biome_js_formatter = { workspace = true }
8585
biome_json_formatter = { workspace = true }
8686
biome_json_parser = { workspace = true }
87+
directories = { workspace = true }
8788
insta = { workspace = true }
8889
regex = { workspace = true }
8990
tokio = { workspace = true, features = ["io-util"] }

crates/biome_cli/src/commands/rage.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ impl Display for RageConfiguration<'_> {
217217
directory_path,
218218
file_path,
219219
extended_configurations,
220+
loaded_location: _,
220221
} = loaded_configuration;
221222
let vcs_enabled = configuration.is_vcs_enabled();
222223
let mut settings = Settings::default();

crates/biome_cli/src/runner/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ use biome_console::{Console, ConsoleExt, markup};
150150
use biome_diagnostics::PrintDiagnostic;
151151
use biome_fs::{BiomePath, FileSystem};
152152
use biome_resolver::FsWithResolverProxy;
153-
use biome_service::configuration::{LoadedConfiguration, ProjectScanComputer, load_configuration};
153+
use biome_service::configuration::{
154+
LoadedConfiguration, LoadedLocation, ProjectScanComputer, load_configuration,
155+
};
156+
use biome_service::diagnostics::ConfigurationOutsideProject;
154157
use biome_service::projects::ProjectKey;
155158
use biome_service::settings::ModuleGraphResolutionKind;
156159
use biome_service::workspace::{
@@ -358,6 +361,7 @@ pub(crate) trait CommandRunner {
358361
diagnostics: _,
359362
directory_path,
360363
file_path,
364+
mut loaded_location,
361365
} = loaded_configuration;
362366

363367
// Merge the FS configuration with the CLI arguments
@@ -381,8 +385,14 @@ pub(crate) trait CommandRunner {
381385
let project_dir = if root_configuration_dir.starts_with(&working_dir) {
382386
&working_dir
383387
} else {
388+
loaded_location = LoadedLocation::InProject;
384389
&root_configuration_dir
385390
};
391+
if !loaded_location.is_in_project() {
392+
console.log(markup! {
393+
{PrintDiagnostic::simple(&ConfigurationOutsideProject)}
394+
})
395+
}
386396

387397
let paths = self.get_files_to_process(fs, &configuration)?;
388398
let paths = self.validated_paths_for_execution(paths, &working_dir, execution.as_ref())?;
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
use crate::run_cli;
2+
use crate::snap_test::{SnapshotPayload, assert_cli_snapshot};
3+
use biome_console::BufferConsole;
4+
use biome_fs::{FileSystem, MemoryFileSystem};
5+
use bpaf::Args;
6+
use camino::Utf8Path;
7+
8+
#[test]
9+
fn can_read_hidden_biome_json_file() {
10+
let fs = MemoryFileSystem::default();
11+
let mut console = BufferConsole::default();
12+
13+
let file_path = Utf8Path::new("src/index.js");
14+
fs.insert(file_path.into(), "a['b'] = 42;".as_bytes());
15+
16+
let config_path = Utf8Path::new(".biome.json");
17+
fs.insert(
18+
config_path.into(),
19+
r#"{
20+
"javascript": {
21+
"formatter": {
22+
"quoteStyle": "single"
23+
}
24+
}
25+
}"#
26+
.as_bytes(),
27+
);
28+
29+
let (fs, result) = run_cli(fs, &mut console, Args::from(["check"].as_slice()));
30+
31+
assert!(result.is_err(), "run_cli returned {result:?}");
32+
33+
assert_cli_snapshot(SnapshotPayload::new(
34+
module_path!(),
35+
"can_read_hidden_biome_json_file",
36+
fs,
37+
console,
38+
result,
39+
));
40+
}
41+
42+
#[test]
43+
fn can_read_hidden_biome_jsonc_file() {
44+
let fs = MemoryFileSystem::default();
45+
let mut console = BufferConsole::default();
46+
47+
let file_path = Utf8Path::new("src/index.js");
48+
fs.insert(file_path.into(), "a['b'] = 42;".as_bytes());
49+
50+
let config_path = Utf8Path::new(".biome.jsonc");
51+
fs.insert(
52+
config_path.into(),
53+
r#"{
54+
"javascript": {
55+
"formatter": {
56+
// comment
57+
"quoteStyle": "single"
58+
}
59+
}
60+
}"#
61+
.as_bytes(),
62+
);
63+
64+
let (fs, result) = run_cli(fs, &mut console, Args::from(["check"].as_slice()));
65+
66+
assert!(result.is_err(), "run_cli returned {result:?}");
67+
68+
assert_cli_snapshot(SnapshotPayload::new(
69+
module_path!(),
70+
"can_read_hidden_biome_jsonc_file",
71+
fs,
72+
console,
73+
result,
74+
));
75+
}
76+
77+
#[test]
78+
fn can_read_configuration_from_user_home() {
79+
let fs = MemoryFileSystem::default();
80+
let mut console = BufferConsole::default();
81+
82+
let file_path = Utf8Path::new("src/index.js");
83+
fs.insert(file_path.into(), "a['b'] = 42;".as_bytes());
84+
85+
let config_dir = fs.user_config_dir().expect("config dir to exist");
86+
let config_file = config_dir.join("biome.json");
87+
fs.insert(
88+
config_file,
89+
r#"{
90+
"javascript": {
91+
"formatter": {
92+
"quoteStyle": "single"
93+
}
94+
}
95+
}"#
96+
.as_bytes(),
97+
);
98+
99+
let (fs, result) = run_cli(fs, &mut console, Args::from(["check"].as_slice()));
100+
101+
assert!(result.is_err(), "run_cli returned {result:?}");
102+
103+
assert_cli_snapshot(SnapshotPayload::new(
104+
module_path!(),
105+
"can_read_configuration_from_user_home",
106+
fs,
107+
console,
108+
result,
109+
));
110+
}
111+
112+
#[test]
113+
fn uses_project_config_before_user_config() {
114+
let fs = MemoryFileSystem::default();
115+
let mut console = BufferConsole::default();
116+
117+
let file_path = Utf8Path::new("src/index.js");
118+
fs.insert(file_path.into(), "a['b'] = 42;".as_bytes());
119+
120+
let config_path = Utf8Path::new(".biome.json");
121+
fs.insert(
122+
config_path.into(),
123+
r#"{
124+
"javascript": {
125+
"formatter": {
126+
"quoteStyle": "single"
127+
}
128+
}
129+
}"#
130+
.as_bytes(),
131+
);
132+
133+
let config_dir = fs.user_config_dir().expect("config dir to exist");
134+
let config_file = config_dir.join("biome.json");
135+
fs.insert(
136+
config_file,
137+
r#"{
138+
"javascript": {
139+
"formatter": {
140+
"enabled": false
141+
}
142+
}
143+
}"#
144+
.as_bytes(),
145+
);
146+
147+
let (fs, result) = run_cli(fs, &mut console, Args::from(["check"].as_slice()));
148+
149+
assert!(result.is_err(), "run_cli returned {result:?}");
150+
151+
assert_cli_snapshot(SnapshotPayload::new(
152+
module_path!(),
153+
"uses_project_config_before_user_config",
154+
fs,
155+
console,
156+
result,
157+
));
158+
}

0 commit comments

Comments
 (0)