TL;DR: Same config file, different results depending on where you run oxlint from.
Overview
Given this file structure:
repo/
├── .oxlintrc.json
└── packages/
└── foo/
├── src/index.js
└── dist/bundle.js
and this config:
{
"ignorePatterns": ["packages/foo/dist"]
}
- 🆗 Running
oxlint . from repo/ as CWD
- ignores
packages/foo/dist as expected
- 🆖 Running
oxlint . from repo/packages/foo/
- finds the same
repo/.oxlintrc.json via ancestor search, but dist/bundle.js is now linted
The pattern is anchored at CWD (repo/packages/foo/), so it looks for repo/packages/foo/packages/foo/dist, which does not exist.
Why
The implementation roots the root config's ignorePatterns at CWD:
LintIgnoreMatcher::new(&base_ignore_patterns, &self.cwd, ...) in apps/oxlint/src/lint.rs. (The LSP roots them at the workspace root instead.)
This is inconsistent in several ways:
- The doc comment on
Oxlintrc::ignore_patterns already says "These are resolved from the configuration file path"
- Nested configs'
ignorePatterns are already rooted at each config file's directory
- Oxfmt roots
ignorePatterns at the config file's directory
- ESLint's
ignorePatterns is also resolved relative to the config file's directory
Rooting at the config file's directory would make all of these consistent.
Note
This is technically a breaking change: users who run oxlint from a subdirectory with path-anchored patterns (containing /) would see different results.
The impact should be small though, most users write bare file/directory names (dist, *.min.js) or **/-prefixed patterns (which match at any depth) and are unaffected by the root. For that reason, I think it could be justified as a bug fix.
As a follow-up, we can also port #24286 (reject .. in ignorePatterns at config load time), which only makes sense once patterns are rooted at the config directory.
TL;DR: Same config file, different results depending on where you run
oxlintfrom.Overview
Given this file structure:
and this config:
{ "ignorePatterns": ["packages/foo/dist"] }oxlint .fromrepo/as CWDpackages/foo/distas expectedoxlint .fromrepo/packages/foo/repo/.oxlintrc.jsonvia ancestor search, butdist/bundle.jsis now lintedThe pattern is anchored at CWD (
repo/packages/foo/), so it looks forrepo/packages/foo/packages/foo/dist, which does not exist.Why
The implementation roots the root config's
ignorePatternsat CWD:LintIgnoreMatcher::new(&base_ignore_patterns, &self.cwd, ...)inapps/oxlint/src/lint.rs. (The LSP roots them at the workspace root instead.)This is inconsistent in several ways:
Oxlintrc::ignore_patternsalready says "These are resolved from the configuration file path"ignorePatternsare already rooted at each config file's directoryignorePatternsat the config file's directoryignorePatternsis also resolved relative to the config file's directoryRooting at the config file's directory would make all of these consistent.
Note
This is technically a breaking change: users who run
oxlintfrom a subdirectory with path-anchored patterns (containing/) would see different results.The impact should be small though, most users write bare file/directory names (
dist,*.min.js) or**/-prefixed patterns (which match at any depth) and are unaffected by the root. For that reason, I think it could be justified as a bug fix.As a follow-up, we can also port #24286 (reject
..inignorePatternsat config load time), which only makes sense once patterns are rooted at the config directory.