diff --git a/apps/oxfmt/src/core/utils.rs b/apps/oxfmt/src/core/utils.rs index bcff2dd0dea80..44329b536efac 100644 --- a/apps/oxfmt/src/core/utils.rs +++ b/apps/oxfmt/src/core/utils.rs @@ -59,12 +59,24 @@ pub fn print_and_flush(writer: &mut dyn Write, message: &str) { writer.flush().unwrap(); } -/// Normalize a relative path by stripping `./` prefix and joining with `cwd`. -/// This ensures consistent path format and avoids issues with relative paths. +/// Normalize a relative path by: +/// - stripping `./` prefix, +/// - joining with `cwd`, +/// - and canonicalizing to resolve `..` components +/// +/// This ensures consistent absolute path format, +/// which is required for gitignore-based pattern matching +/// (e.g., `ignorePatterns` resolution). pub fn normalize_relative_path(cwd: &Path, path: &Path) -> PathBuf { if path.is_absolute() { return path.to_path_buf(); } - if let Ok(stripped) = path.strip_prefix("./") { cwd.join(stripped) } else { cwd.join(path) } + let joined = if let Ok(stripped) = path.strip_prefix("./") { + cwd.join(stripped) + } else { + cwd.join(path) + }; + + fs::canonicalize(&joined).unwrap_or(joined) } diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/__snapshots__/config_ignore_patterns.test.ts.snap b/apps/oxfmt/test/cli/config_ignore_patterns/__snapshots__/config_ignore_patterns.test.ts.snap index a71e3402d656b..6535f0eafc493 100644 --- a/apps/oxfmt/test/cli/config_ignore_patterns/__snapshots__/config_ignore_patterns.test.ts.snap +++ b/apps/oxfmt/test/cli/config_ignore_patterns/__snapshots__/config_ignore_patterns.test.ts.snap @@ -1,5 +1,22 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`config_ignore_patterns > explicit --config with parent-relative path resolves ignorePatterns correctly 1`] = ` +"-------------------- +arguments: --check --config ../.oxfmtrc.json . +working directory: config_ignore_patterns/fixtures/nested_cwd/sub +exit code: 1 +--- STDOUT --------- +Checking formatting... + +src/test.js (ms) + +Format issues found in above 1 files. Run without \`--check\` to fix. +Finished in ms on 1 files using 1 threads. +--- STDERR --------- + +--------------------" +`; + exports[`config_ignore_patterns > nested cwd - ignorePatterns resolved relative to .oxfmtrc.json location 1`] = ` "-------------------- arguments: --check . diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/config_ignore_patterns.test.ts b/apps/oxfmt/test/cli/config_ignore_patterns/config_ignore_patterns.test.ts index 32a46b3a30c62..44041db64aa0a 100644 --- a/apps/oxfmt/test/cli/config_ignore_patterns/config_ignore_patterns.test.ts +++ b/apps/oxfmt/test/cli/config_ignore_patterns/config_ignore_patterns.test.ts @@ -34,4 +34,20 @@ describe("config_ignore_patterns", () => { const snapshot = await runAndSnapshot(nestedCwd, [["--check", "."]]); expect(snapshot).toMatchSnapshot(); }); + + // Same structure as above, but explicitly specifying `--config ../.oxfmtrc.json` + // instead of relying on automatic upward config search. + // + // When `--config` contains `..`, `normalize_relative_path` joins + // cwd + `../.oxfmtrc.json` without resolving `..`, leaving the path as + // `.../sub/../.oxfmtrc.json`. This causes `GitignoreBuilder`'s root + // to be `.../sub/..` which doesn't match file paths via `strip_prefix`, + // making `ignorePatterns` ineffective. + it("explicit --config with parent-relative path resolves ignorePatterns correctly", async () => { + const nestedCwd = join(import.meta.dirname, "fixtures", "nested_cwd", "sub"); + const snapshot = await runAndSnapshot(nestedCwd, [ + ["--check", "--config", "../.oxfmtrc.json", "."], + ]); + expect(snapshot).toMatchSnapshot(); + }); }); diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/error.html b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/error.html new file mode 100644 index 0000000000000..83fe83255b0eb --- /dev/null +++ b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/error.html @@ -0,0 +1 @@ + diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/ignored.js b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/ignored.js deleted file mode 100644 index 6dd369d986dfb..0000000000000 --- a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/generated/ignored.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file should be ignored -const x=1 diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/error.html b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/error.html new file mode 100644 index 0000000000000..83fe83255b0eb --- /dev/null +++ b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/error.html @@ -0,0 +1 @@ + diff --git a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/ignored.js b/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/ignored.js deleted file mode 100644 index 6dd369d986dfb..0000000000000 --- a/apps/oxfmt/test/cli/config_ignore_patterns/fixtures/nested_cwd/sub/generated/ignored.js +++ /dev/null @@ -1,2 +0,0 @@ -// This file should be ignored -const x=1