-
Notifications
You must be signed in to change notification settings - Fork 37
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
feat(rule-finder): Omit deprecated rules #270
feat(rule-finder): Omit deprecated rules #270
Conversation
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.
I'm hesitant to make this breaking change; I think an option might be better.
src/lib/rule-finder.js
Outdated
return normalized.prefix + '/' + rule; | ||
}) | ||
Object.keys(rules) | ||
.filter(rule => !_isDeprecated(rules[rule])) |
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.
I would expect this line to be indented one level farther
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.
Yes, good catch. I think I was following the pattern of something else in the file. I'll fix that up.
src/lib/rule-finder.js
Outdated
}) | ||
Object.keys(rules) | ||
.filter(rule => !_isDeprecated(rules[rule])) | ||
.map(rule => normalized.prefix + '/' + rule) |
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 should use a template literal
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.
Agreed; I just moved the existing code around a bit. I'll take care of it.
src/lib/rule-finder.js
Outdated
]; | ||
function _getCoreRules() { | ||
const rules = eslint.linter.getRules() | ||
return [...rules.keys()] |
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.
Nbd but this would be slightly more efficient as Array.from(rules.keys(), rule => !_isDeprecated(rules.get(rule))).filter(Boolean)
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.
Ah, cool! That's way better. I didn't know about Array.from. I tend to use Ramda for stuff like this. I'll fix that up.
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.
Wait, no, that doesn't work. We need the actual keys out, and this is mapping them to Booleans, returning a list of true
values.
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.
Ah, good point. Yours is fine then :-)
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.
I switched it to Array.from
instead - seems a bit clearer.
Regarding the "breaking-ness" of the change: IMO, this is more like the expected behavior and so should be the default. Also, we're already in breaking-change land due to #237, which this PR depends on. But if you really want this to be behind an option, I can do that. |
Regardless of which is the default, we'd need an option for it - I'd want to be able to include deprecated rules. |
Codecov Report
@@ Coverage Diff @@
## master #270 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 9 9
Lines 179 186 +7
=====================================
+ Hits 179 186 +7
Continue to review full report at Codecov.
|
Code comments addressed; I'll take a look at adding the option later today (hopefully). |
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, pending the option.
To restate: I'm content with the default being "filter out the deprecated rules", making this PR semver-major, as long as there's an option to explicitly restore the behavior where deprecated rules are included.
@ljharb I could use some input on the flag to use for including/excluding deprecated rules; I'm trying to keep #188 in mind as well. It feels like #188 should be another "option" (similar to If that's what we do there, then I'm not sure what to use for the flag for this rule. Maybe |
I think |
I've added the Let me know if you want me to remove the backwards-compatibility handling for the I see that the tests are failing on Travis; I'm not sure what's happening there. They're all passing locally. |
README.md
Outdated
@@ -42,15 +42,21 @@ The intended usage is as an npm script: | |||
} | |||
``` | |||
|
|||
Then run it with: `$ npm run -s eslint-find-option-rules` (the `-s` is to silence npm output). |
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.
probably best to use --silent
, rather than abbreviations - it's also more googleable.
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.
Fixed.
README.md
Outdated
|
||
By default, core rules will be included in the output of `-c|--current`, `-a|--all-available`, and `-u|--unused`. If you want to report on plugin rules only, use the `--no-core` flag. | ||
|
||
By default, deprecated rules will be omitted from the output of `-a|--all-available`, `-p|--plugin` and `-u|--unused`. If you want to report on deprecated rules as well, use the `--include deprecated` or `-i deprecated` flag. |
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.
not --include=deprecated
?
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.
yargs works both ways. I updated the test and the doc to use the =
, if only to have Travis try again and hopefully pass this time.
Thanks so much for the work on this! Looks great and I'm looking forward to us finally supporting this long awaited and discussed feature. Re: Failing tests on Travis Re: Versioning and breaking changes |
@ta2edchimp we should always go full semver :-) that doesn't, however, mean that we need two majors - they can be bunched up as one. |
"full semver"... didn't know how to put it otherwise 😜 |
@ta2edchimp I'm running 6.10.3 locally and having no problems with the tests. I just pushed up a new commit, so I'll see what happens. |
The builds are still failing on Travis. From the failures, it looks like it's not picking up the changes I made to the Perhaps I should try taking out the backwards-compatibility code to see what happens? Any other ideas? |
If you don't mind, please give that a try. Nevertheless, I'm curious to find out what happens there. |
OK, backwards-compatibility code removed. I also realized that I forgot to update the signature of the exported rule finder function; I was changing the constructor, but not the exported function. Maybe that will help on Travis? |
I'm not sure what was going on, but I reversed the sense of the I think this is finally ready to merge. If you want me to squash commits and rebase on master, I'm happy to do that. Or, you can just squash when you merge. |
PR description updated to make clear what the breaking changes are. |
Yes, please rebase on master. We can squash on merge. |
389e82e
to
d777afd
Compare
I just squashed and rebased both. Should be ready to go now. |
Is there anything else I need to do with this before it can be merged? I'd like to start working on #188 soon, and I'll need this merged in order to do that. 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.
Seems legit. Thanks!
Sorry, I found a few issues with the automatism for releasing and "lost my time". I will get back to this tomorrow at the earliest (releasing the previous, merging and releasing this). |
Hey @randycoulman, sorry for the long break. |
Filter out deprecated rules in `_getAllAvailableRules()` and `_getPluginRules()`. With this change, the lists of rules displayed with the `-a` and `-u` flags will not include deprecated rules. Breaking: The output is now different from what it was, as deprecated rules are now omitted by default. Breaking: The `getRuleFinder()` API has changed. Previously, it took an optional filename and an optional boolean, `noCore`. Now, it takes the optional filename and an options object: * `omitCore`: Exclude core rules from the output * `includeDeprecated`: Include deprecated rules in the output Both options default to `false` if they are not provided. Per a review request, I've added a flag to allow deprecated rules to be included. Adding `--include deprecated` or `-i deprecated` will include deprecated rules in the output; they're not included by default. To make the implementation of this flag cleaner, I refactored `getRuleFinder()` to take an options object instead of a boolean as the second argument. Adding a second boolean (`includeDeprecated`) made it a difficult interface to use. Note that `eslint.linter.getRules()` returns an ES6 Map, which cannot be directly filtered. Also, its `keys()` function returns an iterable, so we have to spread that into an array before we can filter it. That's why the code is written the way it is. To make this feature have a cleaner implementation, I also performed the following refactorings: * Don't pass plugin rules to `_getAllAvailableRules`. Plugin rules are now merged with core rules directly in `RuleFinder` instead. * Rename `_getAllAvailableRules` -> `_getCoreRules` to better reflect its purpose. I also: * Removed the `nc` option; it isn't documented and isn't being used. * Split some of the `find` tests into two `it` blocks. I found that calling `proxyquire` twice in the same test wasn't doing anything, so was potentially hiding failures. * Renamed some `rule-finder` tests to result in more consistent output.
d777afd
to
0dc7434
Compare
@ta2edchimp Done! |
@ta2edchimp CI is failing because of test coverage. The line it's reporting as uncovered is |
src/lib/rule-finder.js
Outdated
@@ -103,6 +108,6 @@ function RuleFinder(specifiedFile, noCore) { | |||
this.getUnusedRules = () => getSortedRules(unusedRules); | |||
} | |||
|
|||
module.exports = function (specifiedFile, noCore) { | |||
return new RuleFinder(specifiedFile, noCore); | |||
module.exports = function (specifiedFile, options = {}) { |
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.
If you leave out the default value (... (specifiedFile, options) {
) here, the tests will pass.
(It's left to RuleFinder
then, to assign a default value).
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.
CI is complaining, because the branch where RuleFinder
assigns the default value to its options
parameter never gets called (because the exported function already assigns an empty object as default value to option
).
It is understandable, that this fails ... this should not have been passing previously.
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.
Yeah, that's it, thanks. I can't tell you how many times I've forgotten that there's that other function sitting there.
The default is supplied by the exported function, so doesn't need to be repeated here.
Putting them on `RuleFinder` instead of the exported function so that they're closer to where they're used.
src/lib/rule-finder.js
Outdated
@@ -108,6 +108,6 @@ function RuleFinder(specifiedFile, options) { | |||
this.getUnusedRules = () => getSortedRules(unusedRules); | |||
} | |||
|
|||
module.exports = function (specifiedFile, options = {}) { | |||
module.exports = function (specifiedFile, options) { |
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.
Please continue specifying the default here also; it avoids contributing to the functions length.
For coverage, are you calling the function in tests without an options arg, so as to cover the defaulting?
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.
@ljharb This is well-covered in the tests; the problem is that specifying the default in both places means that the one on the RuleFinder
constructor isn't covered by tests because it's only ever called through this exported function.
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.
Exactly that.
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.
it should be specified in the exported place then; since that's what consumers see.
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.
I would have thought exactly the other way around, the reason being the exported function only "dispatching" its arguments through, to the original RuleFinder
. And exactly that is the place where errors would occur, when no option
parameter would be specified.
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.
@ta2edchimp Can you just revert my last commit, or do you need me to submit a new PR with this change?
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.
I cannot simply push to this repo after using the git scalpel locally. So I would have reverted this with another separate commit when bumping the version number.
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.
That's what git revert
does, isn't it? My understanding is that it makes a new commit that backs out the changes that were made in the commit being reverted.
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.
You're right. I have no idea what I was thinking about.
Feel free to open a new PR regarding this.
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.
Done. #276
@ta2edchimp please hold off before releasing; this should have been fixed prior to merging. |
I think we covered everything. If I'm still missing something, please add a comment to #277 |
Filter out deprecated rules in
_getAllAvailableRules()
and_getPluginRules()
. With this change, the lists of rules displayed with the-a
and-u
flags will not include deprecated rules.Breaking: The output is now different from what it was, as deprecated rules are now omitted by default.
Breaking: The
getRuleFinder()
API has changed. Previously, it took an optional filename and an optional boolean,noCore
. Now, it takes the optional filename and an options object:omitCore
: Exclude core rules from the outputincludeDeprecated
: Include deprecated rules in the outputBoth options default to
false
if they are not provided.Per a review request, I've added a flag to allow deprecated rules to be included. Adding
--include deprecated
or-i deprecated
will include deprecated rules in the output; they're not included by default.To make the implementation of this flag cleaner, I refactored
getRuleFinder()
to take an options object instead of a boolean as the second argument. Adding a second boolean (includeDeprecated
) made it a difficult interface to use.Note that
eslint.linter.getRules()
returns an ES6 Map, which cannot be directly filtered. Also, itskeys()
function returns an iterable, so we have to spread that into an array before we can filter it. That's why the code is written the way it is.To make this feature have a cleaner implementation, I also performed the following refactorings:
_getAllAvailableRules
. Plugin rules are now merged with core rules directly inRuleFinder
instead._getAllAvailableRules
->_getCoreRules
to better reflect its purpose.I also:
Removed the
nc
option; it isn't documented and isn't being used.Split some of the
find
tests into twoit
blocks. I found that callingproxyquire
twice in the same test wasn't doing anything, so was potentially hiding failures.Renamed some
rule-finder
tests to result in more consistent output.Fixes #172