-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Set ESLint rules as errors while preventing hooks/CI from failing #6945
Conversation
If we are adding the whole project to Calypso, why not just make it a dependency? I know we chatted about having the code as part as Calypso, but in this case it should live in |
bin/run-lint
Outdated
const argsBranchName = [ 'rev-parse', '--abbrev-ref', 'HEAD' ]; | ||
const branchName = child_process.spawnSync( 'git', argsBranchName ).stdout.toString().trim(); | ||
|
||
if ( branchName === 'master' ) { |
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.
Is there a chance we can move this logic out of the run-lint
script and somehow into the eslines
code? I would like to keep running eslint
simple, so that people can easily do it outside of Calypso. If we always need those format
arguments, it will be much harder to integrate with editors.
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.
Thanks for the suggestion! At the moment, what I have done is to create a new formatter at eslint-formatters-calypso
: it is only a wrapper for deciding which formatter to return depending on the git branch. I would need to check how different editors call eslint
, but I guess passing a formatter like in eslint -f eslines .
should be possible. However it may be, moving the logic inside eslint-formatters-calypso
is a good idea.
As an aside: eslines
has been rebranded to a more meaningful name: eslint-formatters-calypso
, as its responsibilities have grown and changed. eslines
is now the name of the smart and wrapper formatter inside that package.
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.
Why does it need to be a formatter? Can’t it be an eslint
plugin, so that we can include it in the configuration?
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.
TL;DR:
- It can't be a plugin, but we need something more than a formatter (at least, the ability to control
exit codes
). This is something we can easily do by pipingeslint . | eslines
. - Take advantage of this work from the editors seems easy, as they usually execute
npm run lint
for linting or allow to configure a command manually - I need to research more on this, though.
# More context about formatters VS plugins
An ESLint plugin bundles a set of rules, environment variables and processors. An ESLint formatter is something you pass as an argument to the CLI and there is no way to make it play together with the config file (see code - currentOptions.format
is the command line option --format
). The ESLint team has already had some discussions around this: move formatters into plugins or have the ability to pass options to formatters.
# More than a formatter
There are situations where people needs to configure the formatter (for example, to configure the colors or the file paths for a specific environment) or it needs to do more than an ESLint formatter is capable of.
To work around this, sometimes, people encapsulates the call to ESLint in its own script (eslint-nibble, eslint-pretty).
Other approaches that I have seen in practice while using ESLint directly are:
The recommended way is:
eslint -f json . | formatter --your-options
This is something we can benefit from as it would allow us to control the exit code
(actually, we can already do this, as before it was migrated to formatter this is the approach I was taking).
The common way to pass info to the formatter is by using environment variables or a config file (we use also the config file).
There is some other hacky way that depends on the fact that ESLint uses optionator for parsing options from the command line. This is used by eslint-friendly-formatter. The way this works is:
-
ESLint uses optionator to parse command line arguments.
-
Optionator provides an API to do
optionator.parse(process.argv)
(see ESLint code) that returns an object like{opt1: 2, opt2:3, _: ['positional-param-1', 'positional-param-2']}
with keys being the options and any other positional parameter added in the_
array. -
ESLint uses the contents in the
_
array as the input files (but discards any file that does not exist). -
Optionator happen to follow the bash convention of using
--
as a marker for end of options so any value that follows the marker is considered a positional parameter. example of the hack:command --opt1 2 --opt2 3 -- file-to-process-1 file-to-process-2 --opt3
for this command,
optionator.parse(process.argv)
would return{opt1: 2, opt2:3, _: ['file-to-process-1', 'file-to-process-2', '--opt3']}
. -
eslint-friendly-formatter takes advantage of this hack (ESLint would not process --opt3 as that file does not exists) to retrieve the command line options after the
--
marker and use them for its own configuration.
Something I didn't understand very well from the previous discussion around this—do we ever run CircleCI on |
@seear yup, on every commit to master. Right now failures only get reported to project owners via email. |
@seear @blowery CircleCI build runs on every merge (which may include more than one commit, depending on how the topic branch is merged into master - squashed or not). See for example these two random builds: one commit and a merge with several commits. |
* | ||
* ex: @@ -65,3 +65,3 @@ module.exports = { | ||
* | ||
* 65 is the starting point, 3 the number of lines affected, |
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.
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.
Ignore above comment, just spotted the -U0
passed to the diff command in git-diff
😄
@nb In response to #6945 (comment). Well, you already know I think it makes sense to distribute this as an independent repo/package. In importing this into Calypso repo, I asked myself a few questions:
|
@nb this is ready for a second round. The git hooks If this approach generates consensus, I would like to merge this PR into master after resolving any issues that may appear within this second round. Then, I would address anything left (for example: editors integration with ESLint, etc) within other PRs. |
863296a
to
f9d4a6c
Compare
@nb this branch has been rebased. I have also updated the |
Reverted the commits introduced for test-case this PR in CircleCI. This is ready to be merged into master. |
"test-differ": "./node_modules/.bin/tape tests/test-differ.js | ./node_modules/.bin/faucet", | ||
"test-parsing-errors": "./node_modules/.bin/tape tests/test-parsing-errors.js | ./node_modules/.bin/faucet" | ||
}, | ||
"dependencies": { |
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.
Do we need to run npm install
in this directory in order for the command-line tool to work?
Current state: editor integration is a blocker. We need the editors to run a custom command for linting so we can pipe So, either we provide a custom |
8d94e72
to
25b0c00
Compare
The linting task will report: - only parsing errors, when running on master branch - for other branches, any ESLint error in * lines modified within that branch * any linted files for the rule no-unused-vars pre-commit githook and CircleCI were modified to fail if linter reports any error
8098f1e
to
a522b04
Compare
I was about merging this, but on rebasing and shrinkwrapping again, I found that some tests were not passing and the cause was unrelated to this PR. I prefer separate concerns and solve these issues in a separate PR before this is merged. Proposal to fix it in #12356 After that is merged, this needs a rebase. |
a522b04
to
990ad45
Compare
The gist of this PR is: eslint -f json | eslines With these changes in place, the linting task will report: * only parsing errors, when running on master branch. * for other branches, any ESLint error in * lines modified within that branch * any linted files for the rule no-unused-vars
990ad45
to
e499569
Compare
They were removed in #6945 inadvertently.
@@ -1,7 +1,5 @@ | |||
#!/bin/sh | |||
|
|||
PATH="$PATH:/usr/local/bin" |
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.
@nosolosw For those of us using GUI git apps like Tower.app, removing PATH causes commit to stop working as the app no longer has PATH info to run the commands in .git/hooks/pre-commit
. Can you revert this line?
More info: https://www.git-tower.com/help/mac/faq-and-tips/faq#faq-hook-scripts
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.
Sure @raoulwegat , can you test #12548 works and green-lit it?
We are migrating old code to the new standards (see janitorial efforts at #8562). In the meantime, the new code is failing to adhere to our current code-style because there are rules set as warnings yet.
Until now, they could not be set to errors because doing so will break the git hooks and our CI tools. This PR aims to address that problem by only reporting errors in lines modified, instead of the whole code base. With this approach, we can enforce that all new code is always written following the up-to-date conventions, which will help the migration effort to be completed sooner.
The gist of this PR is just piping commands for several contexts:
Caveats
Editor integration has proven harder than expected, and, at this point, it's not a goal to aim for it. This means that in editors all rules will be reported as errors.
For editors that allow calling custom commands for linting, there may be a way out and a solution may be found. I'm happy to help with this. Yet, as it needs to be considered in a case-by-case basis and it is time-consuming I'd rather do it after this PR is merged/aborted.
How to test locally
git clone [email protected]:Automattic/wp-calypso.git
git checkout -b add/eslint-formatters-calypso-testcase origin/add/eslint-formatters-calypso-testcase
npm install
make githooks
Test that it works:
client/components/web-preview/index.jsx
and remove the spaces after and before the parens at line 167. Do not introduce any other change.client/components/web-preview/index.jsx
warning
)Test that it doesn't prevent you from commiting (if the errors are in lines not modified):
client/components/web-preview/index.jsx
and remove all debug statements and the debug importing. Do not introduce any other change.client/components/web-preview/index.jsx