-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update: Cache files that failed linting (fixes #9948) #10571
Conversation
The related issue was accepted in today's TSC meeting. @eslint/eslint-team Could this get a review? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This generally looks good, I left a few questions.
lib/util/lint-result-cache.js
Outdated
* read the file from the filesystem to set the value again. | ||
*/ | ||
if (resultToSerialize.source) { | ||
resultToSerialize.source = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this interact with the --fix
flag?
- If the user uses the
--fix
flag on the initial linting run, I think the results object will have anoutput
property rather than asource
property. Should that be omitted from the cache as well? - If the user uses the
--fix-dry-run
flag (orfix: true
withCLIEngine
), the errors returned byLinter
will correspond to errors that would apply to the fixed text, even though the fixed text isn't written to the filesystem. If the next invocation does not use--fix-dry-run
, then it seems like the cached results would be incorrect because they would apply to the fixed text rather than the original text. Do we need to invalidate the cache in that scenario? (This might already be a problem without this change.)
lib/util/lint-result-cache.js
Outdated
* In `getCachedLintResults`, if source is explicitly null, we will | ||
* read the file from the filesystem to set the value again. | ||
*/ | ||
if (resultToSerialize.source) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this cause problems if the source is an empty string? That will cause this if
check to fail even though the source
property is present. It might be better to use an explicit hasOwnProperty
check instead.
@not-an-aardvark Thanks for reviewing! I've fixed the issue about empty source. Regarding interaction with autofix: It looks like writing of fixes occurs after caching the lint results in the current implementation. (CLIEngine caches during executeOnFiles, whereas lib/cli.js calls CLIEngine.outputFixes after executeOnFiles returns). So it could be safe to let fixes be written after caching, because the file mtime would change and so the cache would be invalidated. That said, I'm not super comfortable caching lint results when fixes are written, in case the flow changes. I'm also not 100% sure yet what happens when fixes are generated but not output. I'll do some testing (in any case I'll need to make some sort of change, either to add cases for results with |
I've just pushed a commit that simply doesn't cache results with an output property. Maybe we can find a way to cache them safely, but I think releasing this without caching fixed files would still be a win for at least some of our users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
So we hit a case where this assumption fails, when a rule depends on a 3rd file - nodejs/node#24202. Any fix we can apply to our rule: https://github.com/nodejs/node/blob/master/tools/eslint-rules/documented-errors.js |
@refack To clarify, is the issue that you made modifications to a custom rule and ESLint is returning previously-cached results from before the modification? (That sounds plausible, I just want to make sure I'm understanding correctly.) |
@refack @not-an-aardvark Could we discuss this in a new issue? Thanks! |
Ack: #11060 |
What is the purpose of this pull request? (put an "X" next to item)
[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain: Updates
--cache
to store messages for files that failed linting, as well as those which succeeded in linting.Fixes #9948.
What changes did you make? (Give an overview)
Building on #10562, this changes the cache logic to cache files that failed linting as well as files that passed linting. The rationale is that, as long as the file contents or ESLint config (including ESLint version) haven't changed, we can assume the lint results will be the same even in the failure case.
Is there anything you'd like reviewers to focus on?
Is there sufficient test coverage?