Adding ignore-path flag referencing a file in node_modules not respecting ignore config
kentcdodds opened this issue · comments
Tell us about your environment
- ESLint Version: 4.6.1 (latest)
- Node Version: 8.4.0 (latest)
- npm Version: 5.4.0 (latest)
What parser (default, Babel-ESLint, etc.) are you using? N/A
Please show your full configuration: N/A
Configuration
{}
What did you do? Please include the actual source code causing the issue.
eslint --ignore-path node_modules/kcd-scripts/dist/config/eslintignore .
What did you expect to happen?
I expected the eslintignore to be applied
What actually happened? Please include the actual, raw output from ESLint.
It is not. I get an error indicating that eslint is processing files in node_modules
.
Here's the contents of node_modules/kcd-scripts/dist/config/eslintignore
:
node_modules
coverage
dist
build
out
.next
I think that the docs indicate that the patterns here will be relative to the .eslintignore
file, so I changed the eslintignore file to various patterns (including ../../../node_modules/
, **/node_modules/**
). None of those combinations seemed to work. I think there may be a bug here, but I'm uncertain... Happy to dig in more if someone can tell me I'm not missing something obvious.
To reproduce: https://github.com/kentcdodds/eslint-config-issue
Install deps and run npm run broken
and npm run working
.
Thanks!
Thanks for reporting, I can reproduce this.
How can I help fix this?
From investigating just now, I think the issue was introduced in e395919, where we switched to resolving ignore patterns from the location of the .eslintignore
file rather than the CWD.
I think the problem is that in addition to resolving ignore patterns that appear in the .eslintignore
file from the ignore file's location, we're also resolving the default ignore patterns (such as /node_modules/*
) from the location of the ignore file, rather than the CWD. So when you use eslint --ignore-path node_modules/kcd-scripts/dist/config/eslintignore
, it's effectively ignoring files in node_modules/kcd-scripts/dist/config/node_modules
rather than ./node_modules
, which causes the rest of the files in ./node_modules
to get linted.
The cause of the issue seems to be here. this.baseDir
is currently always set to the location of the ignore file (or the CWD if no ignore file is being used), so we're using the same relative path for both the default ignore patterns and the custom ignore patterns. I think the issue will be fixed if we use different relative paths for each check there (a path relative to the CWD for default patterns, and a path relative to the ignore file location for custom patterns).
edit: I think this would also need to be changed in a similar way, too.
Thanks for that insight! So, if I understand you correctly, the fix would be changing this:
Lines 229 to 251 in c8bf687
to:
contains(filepath, category) {
let result = false;
const absolutePath = path.resolve(this.options.cwd, filepath);
- const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
+ const baseDir = category === "default" ? this.options.cwd : this.baseDir;
+ const relativePath = pathUtil.getRelativePath(absolutePath, baseDir);
if ((typeof category === "undefined") || (category === "default")) {
result = result || (this.ig.default.filter([relativePath]).length === 0);
}
if ((typeof category === "undefined") || (category === "custom")) {
result = result || (this.ig.custom.filter([relativePath]).length === 0);
}
return result;
}
Also, what's a good place to write tests for this changed behavior? in tests/lib/ignored-paths.js
?
I think that's almost right, although I think that would have the issue where category
can also be null
, in which case both the default
and custom
filters should be applied, so the if
statements in that function aren't mutually exclusive.
Something like this should work:
contains(filepath, category) {
let result = false;
const absolutePath = path.resolve(this.options.cwd, filepath);
- const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
if ((typeof category === "undefined") || (category === "default")) {
+ const relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd);
result = result || (this.ig.default.filter([relativePath]).length === 0);
}
if ((typeof category === "undefined") || (category === "custom")) {
+ const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
result = result || (this.ig.custom.filter([relativePath]).length === 0);
}
return result;
}
Also, after I commented before I noticed another place that might also need to be changed in a similar way (to resolve default patterns from the cwd
rather than this.baseDir
).
Also, what's a good place to write tests for this changed behavior? in
tests/lib/ignored-paths.js
?
Yes, I think that's the right place to put them.
I'd love for this to be fixed, but my pull request hit a wall and I don't have any more time for it.
Working on this.
Thank you! 👏
Still getting this error with latest eslint 5.6.1. I am on windows. Any ideas?
@cemremengu May you please create a new issue? It's possible that a different set of circumstances can lead to the same behavior, but it's hard to tell without more information.