Skip to content

Commit f6590ec

Browse files
committed
fix(oxfmt): Handle relative path starts with dot
1 parent 7a953d9 commit f6590ec

6 files changed

+132
-33
lines changed

apps/oxfmt/src/format.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,15 @@ impl FormatRunner {
6161
}
6262
};
6363

64-
// Instead of `oxlint`'s `--ignore-pattern=PAT`, `oxfmt` supports `!` prefix in paths like Prettier
65-
let (exclude_patterns, target_paths): (Vec<_>, Vec<_>) =
66-
paths.into_iter().partition(|p| p.to_string_lossy().starts_with('!'));
67-
68-
// Default to cwd if no `target_paths` are provided
69-
// NOTE: Do not specify `.` as cwd here, it behaves differently
70-
let target_paths = if target_paths.is_empty() { vec![cwd.clone()] } else { target_paths };
71-
72-
// Resolve relative paths against the current working directory
73-
let target_paths: Vec<PathBuf> = target_paths
74-
.into_iter()
75-
.map(|path| if path.is_relative() { cwd.join(path) } else { path })
76-
.collect();
64+
// Normalize user input paths
65+
let (target_paths, exclude_patterns) = normalize_paths(&cwd, &paths);
7766

7867
// Build exclude patterns if any exist
7968
let override_builder = (!exclude_patterns.is_empty())
8069
.then(|| {
8170
let mut builder = OverrideBuilder::new(&cwd);
82-
for pattern in exclude_patterns {
83-
builder.add(&pattern.to_string_lossy()).ok()?;
71+
for pattern_str in exclude_patterns {
72+
builder.add(&pattern_str).ok()?;
8473
}
8574
builder.build().ok()
8675
})
@@ -213,6 +202,49 @@ fn load_config(cwd: &Path, config: Option<&PathBuf>) -> Result<FormatOptions, St
213202
Ok(FormatOptions::default())
214203
}
215204

205+
/// Normalize user input paths into `target_paths` and `exclude_patterns`.
206+
/// - `target_paths`: Absolute paths to format
207+
/// - `exclude_patterns`: Pattern strings to exclude (with `!` prefix)
208+
fn normalize_paths(cwd: &Path, input_paths: &[PathBuf]) -> (Vec<PathBuf>, Vec<String>) {
209+
let mut target_paths = vec![];
210+
let mut exclude_patterns = vec![];
211+
212+
for path in input_paths {
213+
let path_str = path.to_string_lossy();
214+
215+
// Instead of `oxlint`'s `--ignore-pattern=PAT`,
216+
// `oxfmt` supports `!` prefix in paths like Prettier.
217+
if path_str.starts_with('!') {
218+
exclude_patterns.push(path_str.to_string());
219+
continue;
220+
}
221+
222+
// Otherwise, treat as target path
223+
224+
if path.is_absolute() {
225+
target_paths.push(path.clone());
226+
continue;
227+
}
228+
229+
// NOTE: `.` and cwd behaves differently, need to normalize
230+
let path = if path_str == "." {
231+
cwd.to_path_buf()
232+
} else if let Some(stripped) = path_str.strip_prefix("./") {
233+
cwd.join(stripped)
234+
} else {
235+
cwd.join(path)
236+
};
237+
target_paths.push(path);
238+
}
239+
240+
// Default to cwd if no `target_paths` are provided
241+
if target_paths.is_empty() {
242+
target_paths.push(cwd.into());
243+
}
244+
245+
(target_paths, exclude_patterns)
246+
}
247+
216248
fn print_and_flush_stdout(stdout: &mut dyn Write, message: &str) {
217249
use std::io::{Error, ErrorKind};
218250
fn check_for_writer_error(error: Error) -> Result<(), Error> {

apps/oxfmt/src/walk.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ impl Walk {
6565
/// Will not canonicalize paths.
6666
/// # Panics
6767
pub fn new(paths: &[PathBuf], override_builder: Option<Override>) -> Self {
68-
assert!(!paths.is_empty(), "At least one path must be provided to Walk::new");
69-
7068
let mut inner = ignore::WalkBuilder::new(
7169
paths
7270
.iter()

apps/oxfmt/tests/mod.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ fn multiple_files() {
2020
.test_and_snapshot_multiple(&[
2121
// Explicit file list
2222
&["--check", "simple.js", "arrow.js"],
23-
// Directory
24-
&["--check", "."],
2523
// Default to current directory
2624
&["--check"],
25+
// Explicit cwd
26+
&["--check", "."],
27+
&["--check", "./"],
2728
]);
2829
}
2930

@@ -106,18 +107,22 @@ fn exclude_nested_paths() {
106107
#[test]
107108
fn exclude_nested_paths_with_dot() {
108109
// All these cases should not report parse error from `foo/bar/error.js`
109-
// TODO: Make the commented cases work as well.
110110
Tester::new()
111111
.with_cwd(PathBuf::from("tests/fixtures/exclude_nested"))
112112
.test_and_snapshot_multiple(&[
113-
// &["--check", ".", "!foo/bar/error.js"],
114-
// &["--check", ".", "!foo/bar"],
113+
&["--check", ".", "!foo/bar/error.js"],
114+
&["--check", ".", "!foo/bar"],
115115
&["--check", ".", "!foo"],
116116
&["--check", ".", "!**/error.js"],
117+
]);
118+
// Split to avoid too long file name error...
119+
Tester::new()
120+
.with_cwd(PathBuf::from("tests/fixtures/exclude_nested"))
121+
.test_and_snapshot_multiple(&[
117122
&["--check", "./foo", "!**/bar/error.js"],
118123
&["--check", "./foo", "!**/error.js"],
119124
&["--check", "./foo", "!**/bar/*"],
120-
// &["--check", "./foo", "!foo/bar/error.js"],
121-
// &["--check", "./foo", "!foo/bar"],
125+
&["--check", "./foo", "!foo/bar/error.js"],
126+
&["--check", "./foo", "!foo/bar"],
122127
]);
123128
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
source: apps/oxfmt/tests/tester.rs
3+
---
4+
##########
5+
arguments: --check . !foo/bar/error.js
6+
working directory: tests/fixtures/exclude_nested
7+
----------
8+
Checking formatting...
9+
10+
All matched files use the correct format.
11+
Finished in <variable>ms on 3 files using 1 threads.
12+
----------
13+
CLI result: FormatSucceeded
14+
----------
15+
16+
##########
17+
arguments: --check . !foo/bar
18+
working directory: tests/fixtures/exclude_nested
19+
----------
20+
Checking formatting...
21+
22+
All matched files use the correct format.
23+
Finished in <variable>ms on 2 files using 1 threads.
24+
----------
25+
CLI result: FormatSucceeded
26+
----------
27+
28+
##########
29+
arguments: --check . !foo
30+
working directory: tests/fixtures/exclude_nested
31+
----------
32+
Checking formatting...
33+
34+
All matched files use the correct format.
35+
Finished in <variable>ms on 1 files using 1 threads.
36+
----------
37+
CLI result: FormatSucceeded
38+
----------
39+
40+
##########
41+
arguments: --check . !**/error.js
42+
working directory: tests/fixtures/exclude_nested
43+
----------
44+
Checking formatting...
45+
46+
All matched files use the correct format.
47+
Finished in <variable>ms on 3 files using 1 threads.
48+
----------
49+
CLI result: FormatSucceeded
50+
----------
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,43 @@
22
source: apps/oxfmt/tests/tester.rs
33
---
44
##########
5-
arguments: --check . !foo
5+
arguments: --check ./foo !**/bar/error.js
66
working directory: tests/fixtures/exclude_nested
77
----------
88
Checking formatting...
99

1010
All matched files use the correct format.
11-
Finished in <variable>ms on 1 files using 1 threads.
11+
Finished in <variable>ms on 2 files using 1 threads.
1212
----------
1313
CLI result: FormatSucceeded
1414
----------
1515

1616
##########
17-
arguments: --check . !**/error.js
17+
arguments: --check ./foo !**/error.js
1818
working directory: tests/fixtures/exclude_nested
1919
----------
2020
Checking formatting...
2121

2222
All matched files use the correct format.
23-
Finished in <variable>ms on 3 files using 1 threads.
23+
Finished in <variable>ms on 2 files using 1 threads.
2424
----------
2525
CLI result: FormatSucceeded
2626
----------
2727

2828
##########
29-
arguments: --check ./foo !**/bar/error.js
29+
arguments: --check ./foo !**/bar/*
3030
working directory: tests/fixtures/exclude_nested
3131
----------
3232
Checking formatting...
3333

3434
All matched files use the correct format.
35-
Finished in <variable>ms on 2 files using 1 threads.
35+
Finished in <variable>ms on 1 files using 1 threads.
3636
----------
3737
CLI result: FormatSucceeded
3838
----------
3939

4040
##########
41-
arguments: --check ./foo !**/error.js
41+
arguments: --check ./foo !foo/bar/error.js
4242
working directory: tests/fixtures/exclude_nested
4343
----------
4444
Checking formatting...
@@ -50,7 +50,7 @@ CLI result: FormatSucceeded
5050
----------
5151

5252
##########
53-
arguments: --check ./foo !**/bar/*
53+
arguments: --check ./foo !foo/bar
5454
working directory: tests/fixtures/exclude_nested
5555
----------
5656
Checking formatting...
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ Finished in <variable>ms on 2 files using 1 threads.
1515
CLI result: FormatMismatch
1616
----------
1717

18+
##########
19+
arguments: --check
20+
working directory: tests/fixtures/multiple_files
21+
----------
22+
Checking formatting...
23+
arrow.js (<variable>ms)
24+
simple.js (<variable>ms)
25+
26+
Format issues found in above 2 files. Run without `--check` to fix.
27+
Finished in <variable>ms on 2 files using 1 threads.
28+
----------
29+
CLI result: FormatMismatch
30+
----------
31+
1832
##########
1933
arguments: --check .
2034
working directory: tests/fixtures/multiple_files
@@ -30,7 +44,7 @@ CLI result: FormatMismatch
3044
----------
3145

3246
##########
33-
arguments: --check
47+
arguments: --check ./
3448
working directory: tests/fixtures/multiple_files
3549
----------
3650
Checking formatting...

0 commit comments

Comments
 (0)