fix(ignore-filter): tolerate ./-prefixed and empty relative paths in isIgnored#453
fix(ignore-filter): tolerate ./-prefixed and empty relative paths in isIgnored#453tirth8205 wants to merge 1 commit into
Conversation
…isIgnored
IgnoreFilter.isIgnored delegated straight to ignore@7's ig.ignores(),
which throws on an empty string ("path must not be empty") and on a
leading './' ("path should be a path.relative()'d string"). Both arise
from ordinary inputs (path.relative(root, root) === "" and ./-prefixed
glob results), crashing the scan instead of returning a boolean.
Fix: normalize first — treat falsy/empty as not-ignored and strip a
leading './' before delegating to ig.ignores().
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thejesh23
left a comment
There was a problem hiding this comment.
A few concerns before this lands.
1. The normalization doesn't cover the other shapes path.relative actually produces. ig.ignores() from ignore@7 also throws on "../foo" (path escapes root) and on Windows backslash paths like ".\\src\\a.ts" / "src\\a.ts" — path.relative(projectRoot, target) produces both. The PR fixes one stripping rule but the body claims the contract violation is fixed; on Windows or with out-of-root callers it still throws. Either reject these explicitly with false, convert separators / leading ../, or document the input constraint.
2. The regex is one-shot and order-sensitive. "./".replace(/^\.\//, "") yields "" (correctly caught by the second guard), but "././foo" becomes "./foo" — still in the ignore@7 reject set — and ".//foo" becomes "/foo", also rejected. Use a loop / a stronger normalization (path.posix.normalize after slash-conversion) so the function is closed over its own output.
3. Test gap on the negation. The new tests confirm ./dist/index.js is ignored and ./src/index.ts is not, but there's no test that the previously-throwing inputs from the PR body actually return rather than throw (expect(() => ...).not.toThrow()), and no coverage for "./" alone (the trim-to-empty path), which is the one branch a future refactor is most likely to drop.
Nit: the JSDoc on IgnoreFilter.isIgnored still says "given relative path" with no mention of the now-tolerated ./ prefix or empty-as-root semantics — worth one line so callers know what's contractually accepted.
Problem
path must not be empty; isIgnored("./src/a.ts") throwspath should be a path.relative()'d string, but got "./src/a.ts". The documented contract (boolean return) is silently violated for…Fix
Testing
Adds unit test(s) that fail before the change and pass after. The full core test suite,
eslint, andtsc --noEmitall pass locally on this branch.Found via a static correctness audit of the ignore filter.
🤖 Generated with Claude Code