-
Notifications
You must be signed in to change notification settings - Fork 5
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
Support extends
#4
Conversation
@@ -31,3 +34,12 @@ function getConfig() { | |||
} | |||
} | |||
|
|||
function getRules(set) { | |||
var configFileName = set ? ('eslint-config-' + set) : 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.
I wonder if we could find how ESLint resolves these extends
because you can actually have files extend others like so. So we can either recreate the behavior or see if we can use ESLint's implementation somehow.
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.
Oh yes, that's a good point. Didn't think of such a case at all ...
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 investigated this a bit and came to the conclusion that we could use eslint itself to resolve all this for us.
That is, we could require('./node_modules/eslint/lib/config.js')
, instantiate the exposed Config
object and simply use its getConfig
method, it will return an object with a property rules
— from there on, it would be the same procedure that is already implemented.
But ...
- We'd have to make eslint a (peer) dependency, which (in my opinion) would be just fine, as the whole purpose of this module is to work with it.
- We'd have to require a part of eslint's internals that are not part of their public api, when used as a lib (as in
require('eslint')
).
Only drawback I can think of would be breaking when they change their internal architecture, concerning this certain part.
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.
We'd have to make eslint a (peer) dependency, which (in my opinion) would be just fine, as the whole purpose of this module is to work with it.
Been meaning to do this anyway. 👍
We'd have to require a part of eslint's internals that are not part of their public api, when used as a lib (as in require('eslint')).
Maybe someone from the ESLint team could give us some insight on a better way to do this or at least give us an idea of how likely it is that this would lead to issues in the future. Cc @nzakas, @gyandeeps, @mysticatea, @ilyavolodin (top 4 code contributors on the project)
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.
Sorry, I'm not sure I'm following exactly what you are trying to do, but I think you are looking for this: http://eslint.org/docs/developer-guide/nodejs-api#getconfigforfile This will automatically calculate all of the config values for you (including extends
), and it's available as public API. I would suggest not using internals directly as they do often 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.
How could we not see this ...
getConfigForFile()
of the exposed CLIEngine
object basically only wraps the functionality of the private api's Config.getConfig()
m(
(I misinterpreted its documentation as only detecting the applicable rules/config of a particular [JavaScript] file based on its location within the filesystem.)
So, sth like
var path = require('path')
var eslint = require('eslint')
var rulesCombined = new eslint.CLIEngine().getConfigForFile(path.resolve('../path/to/config.file'))
(with ../path/to/config.file
being the package.json or .eslintrc*) indeed seems to just do what we want.
I'll alter my code correspondingly later today or no later than tomorrow.
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.
Hmm... the downside of getConfigForFile()
is, when checking an eslint config outside of the own project's path it will inevitably break, because the path to lookup for extended configs will be reset to the own project's.
This would be no problem as long as eslint-find-new-rules
is installed locally on a project's package and only used on configs that are contained within that project.
Installing eslint-find-new-rules
globally and would not work, as referenced configs couldn't be found.
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.
Installing eslint-find-new-rules globally and would not work, as referenced configs couldn't be found.
I'm not a fan of installing tools like this globally anyway, so that's fine.
What I'm worried about though is that doing this will utilize the ~/.eslintrc
file which could contain extra rules (unless I'm mistaken). Also, in projects like mine where there are multiple files representing eslint config, I worry that having an .eslintrc
file in there would be a problem... Am I misunderstanding it?
I was thinking a way to get around this would be to copy the config to a temporary directory on the filesystem and doing the check there... Thoughts?
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.
Installing eslint-find-new-rules globally and would not work, as referenced configs couldn't be found.
I'm not a fan of installing tools like this globally anyway, so that's fine.
Ok, thought similar about this. I just wanted to be sure, we make the same assumptions here.
I thought of achieving the following:
- Determine a particular eslint config als base
- That is, when running
eslint-find-new-rules
without any argument: taking the currently applicable eslint config (from an.eslintrc
file — or.js
,.json
,yml
— or its corresponding property within the project'spackage.json
). - When running
eslint-find-new-rules
with an argument: using that as particular eslint config file (even the corresponding property within a package.json, when specified as argument).
- That is, when running
- Collect all rules contained within the determined eslint config, as well as those from configs referenced to via
extends
. - Do not take any rules into account that may be applicable by considering the current location on the filesystem.
According to your example project:
- When testing against
index.js
: collect only the rules within. - When testing against
.eslintrc
: collect all the rules within, extending the rules ofreact.js
, extending the rules ofindex.js
.
When we use the eslint api's method and there would be the sideeffect of accidentally taking environmental configs into account, that would also be the case when copying the file to test anywhere else on the filesystem (but within / somewhere below the same project root), because the api's method would look up all the way up to the project root ... at least this is as I currently understand its working behaviour. Or am I missing something?
My time's running out currently, and I have another appointment soon, but I'll have a closer look and run some more tests later tonight and tomorrow.
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 just wanted to be sure, we make the same assumptions here.
We should probably document this limitation though, because other people make other assumptions :-)
Yeah, I think you've described the desired behavior. We'll probably run into some issues with those side-effects. But let's see how far we can get :-)
On the testing side of things, I think we need to implement some tests for |
To catch up with the discussion from #1: When adding another test to test('provokes a memory leak warning', t => {
const rules = [1, 2]
t.same(rules, [1, 2, 3])
}) the following warning will be yielded:
Edit |
Re lowering the standards temporarily: personally I'd rather hold this back for some time to see if we can get around the mentioned issue with the test and maybe also implement a more comprehensive resolution of the |
Sounds good to me! |
From @jamestalmage in gitter:
👍 |
I think from here, we have three options:
That is, of course, only until there's a definite decision from the eslint team re considering exposing it's extends resolution, and then either use it or – if the proposal gets declined – „reproduce“ their way of resolving the extending rule configs. Personally, I tend towards the 2nd option; it would at least make one comfortable with their way of doing it. |
@sarbbottam, I think you're referencing the wrong issue number in your commit message :-) |
Sorry about it, I fixed it. |
Collect configured rules using the eslint api methods, taking extending configs and plugins into account.
da46003
to
18b8aae
Compare
33fc9f3
to
c1205f9
Compare
Current coverage is
|
@kentcdodds @sarbbottam anyone of you got an idea how we could test the support of plugins? |
Oh, and before merging, we'd have to make "dependencies": {
"eslint": "^2.4.0"
} to assure eslint What do you think? |
I just realized, this pr will alter the behavior mentioned in the README, concerning defaulting to @kentcdodds should I change this back to inspect the referenced |
First, this is great! I think your suggestion on ESLint is good. But could we do
Which do you think is more intuitive. I built this originally for |
So, I'll make it
Regarding whether to use a package.json's |
There is a little documentation about that, but I agree :-) |
} else { | ||
return require(path.join(process.cwd(), specifiedFile)) | ||
return path.join(process.cwd(), specifiedFile) | ||
} | ||
} else { | ||
// this is not being called with an arg. Use the package.json `main` |
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.
Should this comment be updated?
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.
Well, I'm currently about to rewrite that part anyway (to restore the desired behavior described in the comment).
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.
Cool, that's what I thought. Thanks!
This looks awesome. I think there are just a few docs changes that we should add (like that we support |
Regarding |
Restore the module's original behavior of interpreting the current package's main script as source of an eslint config, rather than taking the local package.json's eslintConfig property into account.
@kentcdodds mind having a final look (esp. regarding changes in README, as I'm not a native speaker) and eventually merging or comment on anything you'd yet like to get included? |
"html_url": "https://twitter.com/ta2edchimp", | ||
"contributions": [ | ||
"code", "test" | ||
] |
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 might want to add "docs" too.
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.
👍
Other than the notes I've provided, this looks good. |
Looks good to me, and I think @sarbbottam approves as well. Let's do this! |
This Pull Request extends the interpretation of a given eslint configuration to take its
extends
field into account and also include the rules inherited thereby.At the moment, it lacks the following:
.all-contributorsrc
update