From b752c6ff5d4c4a9041ba144bf80de9df0e14e05a Mon Sep 17 00:00:00 2001 From: Nathan Houle Date: Sun, 17 Nov 2019 13:06:05 -0800 Subject: [PATCH] feat: make abusing eslint-disable more difficult This changeset adds `eslint-plugin-eslint-comments` and a [set of rules](https://github.com/mysticatea/eslint-plugin-eslint-comments/blob/d2d21f2496232248370da851d7dbd634e2a37d87/lib/configs/recommended.js) intended to help prevent abuse of `eslint-disable` comments and to provide feedback when `eslint-disable`s can be removed. Closes #204. --- package.json | 2 ++ src/config/recommended.js | 45 ++++++++++++++++++++++++++++++++++----- yarn.lock | 13 ++++++++++- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 50c3159e..6a82c797 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "eslint-config-prettier": "^6.5.0", "eslint-config-problems": "^3.0.1", "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-eslint-comments": "^3.1.2", "eslint-plugin-flowtype": "^3.13.0", "eslint-plugin-goodeggs": "file:.", "eslint-plugin-import": "^2.18.2", @@ -57,6 +58,7 @@ "eslint-config-prettier": "^6.5.0", "eslint-config-problems": "^3.0.1", "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-eslint-comments": "^3.1.2", "eslint-plugin-flowtype": "^3.13.0", "eslint-plugin-import": "^2.18.2", "eslint-plugin-jest": "^23.0.3", diff --git a/src/config/recommended.js b/src/config/recommended.js index 1dede216..ca2d75d9 100644 --- a/src/config/recommended.js +++ b/src/config/recommended.js @@ -5,6 +5,8 @@ export default { plugins: [ // https://github.com/babel/eslint-plugin-babel 'babel', + // https://github.com/mysticatea/eslint-plugin-eslint-comments + 'eslint-comments', // https://github.com/benmosher/eslint-plugin-import 'import', // https://github.com/wix/eslint-plugin-lodash @@ -19,6 +21,7 @@ export default { 'eslint:recommended', // https://github.com/RyanZim/eslint-config-problems 'problems', + 'plugin:eslint-comments/recommended', 'plugin:import/recommended', 'plugin:lodash/recommended', 'prettier', @@ -29,6 +32,9 @@ export default { es6: true, }, rules: { + /* + * Built-in rules + */ eqeqeq: ['error', 'always', {null: 'ignore'}], 'global-require': 'error', 'guard-for-in': 'error', @@ -63,7 +69,37 @@ export default { 'operator-assignment': ['error', 'always'], 'spaced-comment': ['error', 'always'], - // eslint-plugin-import + /* + * eslint-plugin-eslint-comments + */ + // Allow `eslint-disable`s at the top of a file, but prevent users from forgetting to close an + // `eslint-disable` in the middle of a file. We should consider whether or not we actually want + // to allow whole-file `eslint-disable`s, but in practice we do it frequently for somtimes- + // legitimate reasons. + 'eslint-comments/disable-enable-pair': ['error', {allowWholeFile: true}], + // Restrict the use of eslint directives in files. ESLint rules should be specified in the + // ESLint configuration as much as possible; this prevents, for example, users from changing + // rules for a specific file (e.g. `/* eslint no-undef: warn */`), but allows users to disable + // rules for a region of a file. + 'eslint-comments/no-use': [ + 'error', + { + allow: [ + 'eslint-disable', + 'eslint-disable-line', + 'eslint-disable-next-line', + 'eslint-enable', + // Eventually, we should force users to specify all globals in their project's ESLint + // configuration file(s). + 'global', + 'globals', + ], + }, + ], + + /* + * eslint-plugin-import + */ 'import/first': 'error', 'import/newline-after-import': 'error', 'import/no-absolute-path': 'error', @@ -82,7 +118,9 @@ export default { }, ], - // eslint-plugin-lodash + /* + * eslint-plugin-lodash + */ 'lodash/chaining': ['error', 'always', 2], 'lodash/import-scope': ['error', 'full'], 'lodash/matches-prop-shorthand': ['error', 'never'], @@ -98,9 +136,6 @@ export default { 'lodash/prefer-thru': 'off', 'lodash/preferred-alias': 'error', 'lodash/prop-shorthand': ['error', 'never'], - - // eslint-plugin-unicorn - 'unicorn/no-abusive-eslint-disable': 'error', }, overrides: [ // Configuration files (e.g. webpack.config.js) that are *not* transpiled through Babel. diff --git a/yarn.lock b/yarn.lock index 8c40e4ea..622e023a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1785,6 +1785,13 @@ eslint-plugin-babel@^5.3.0: dependencies: eslint-rule-composer "^0.3.0" +eslint-plugin-eslint-comments@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz#4ef6c488dbe06aa1627fea107b3e5d059fc8a395" + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + eslint-plugin-flowtype@^3.13.0: version "3.13.0" resolved "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c" @@ -1792,7 +1799,7 @@ eslint-plugin-flowtype@^3.13.0: lodash "^4.17.15" "eslint-plugin-goodeggs@file:./.": - version "8.0.0-beta.7" + version "8.0.0-beta.9" dependencies: "@goodeggs/prettier-config" "^1.0.0" @@ -2403,6 +2410,10 @@ ignore@^4.0.6: version "4.0.6" resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" +ignore@^5.0.5: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + import-fresh@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390"