From 9826f5c29c22a5d6519eaa06cfbf53f0b73a9521 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Wed, 18 Oct 2017 20:51:20 -0400 Subject: [PATCH 01/18] Remove unused docs images --- docs/images/fork.png | Bin 20951 -> 0 bytes docs/images/pr-button.png | Bin 41991 -> 0 bytes docs/images/pr.png | Bin 74354 -> 0 bytes docs/images/rule-link.png | Bin 16276 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/images/fork.png delete mode 100644 docs/images/pr-button.png delete mode 100644 docs/images/pr.png delete mode 100644 docs/images/rule-link.png diff --git a/docs/images/fork.png b/docs/images/fork.png deleted file mode 100644 index 9aeffc8625e57b79595f18a63755c9c80ffd93b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20951 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 diff --git a/docs/images/pr-button.png b/docs/images/pr-button.png deleted file mode 100644 index 9dfc9466900fe1be4c3610eab54edefbf15e887b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41991 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 diff --git a/docs/images/pr.png b/docs/images/pr.png deleted file mode 100644 index a398facd476deed5b17c0ac2b79433e5cecd19f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74354 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 diff --git a/docs/images/rule-link.png b/docs/images/rule-link.png deleted file mode 100644 index 58b5840680e03022b40b7cc03b5d2f8f481b606a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16276 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 Date: Wed, 18 Oct 2017 20:53:04 -0400 Subject: [PATCH 02/18] Remove mention of blog post MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s out-of-date, and not actually even running right now. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 658c4a60..1d284bd6 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,7 @@ eslint --init ``` Alternatively you can create the `.eslintrc` file by yourself. It is a good -idea to have a look at the [Get Started With ESLint](http://devnull.guru/get-started-with-eslint/) -blog post by [IanVS](https://github.com/IanVS) and [the ESLint documentation](http://eslint.org/docs/user-guide/configuring), +idea to have a look at the [the ESLint documentation](http://eslint.org/docs/user-guide/configuring), including the [list of rules](http://eslint.org/docs/rules/). ## A Note About Settings From 81aea6896af892e0efa8631e9ac24927e8a8f0f2 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Wed, 18 Oct 2017 21:45:51 -0400 Subject: [PATCH 03/18] Rearrange and order settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By default, Atom will sort settings alphabetically, which can result in a really strange, non-logical order. This commit attempts to put more important or commonly used settings up top, while also grouping similar settings together. So, the scopes are together with the lint html setting, the use global and global paths are together, the fixing options are grouped, etc. I’m sure this isn’t perfect, but it’s a start. --- package.json | 113 +++++++++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index d1bbe902..b498f734 100644 --- a/package.json +++ b/package.json @@ -9,45 +9,54 @@ "atom": ">=1.13.0 <2.0.0" }, "configSchema": { + "scopes": { + "title": "List of scopes to run ESLint on, run `Editor: Log Cursor Scope` to determine the scopes for a file.", + "type": "array", + "default": [ + "source.js", + "source.jsx", + "source.js.jsx", + "source.babel", + "source.js-semantic" + ], + "items": { + "type": "string" + }, + "order": 1 + }, "lintHtmlFiles": { "title": "Lint HTML Files", "description": "You should also add `eslint-plugin-html` to your .eslintrc plugins", "type": "boolean", - "default": false + "default": false, + "order": 2 }, "useGlobalEslint": { "title": "Use global ESLint installation", "description": "Make sure you have it in your $PATH", "type": "boolean", - "default": false + "default": false, + "order": 3 }, - "showRuleIdInMessage": { - "title": "Show Rule ID in Messages", - "type": "boolean", - "default": true + "globalNodePath": { + "title": "Global Node Installation Path", + "description": "Write the value of `npm get prefix` here", + "type": "string", + "default": "", + "order": 4 }, "disableWhenNoEslintConfig": { "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", "type": "boolean", - "default": true + "default": true, + "order": 5 }, "eslintrcPath": { "title": ".eslintrc Path", "description": "It will only be used when there's no config file in project", "type": "string", - "default": "" - }, - "globalNodePath": { - "title": "Global Node Installation Path", - "description": "Write the value of `npm get prefix` here", - "type": "string", - "default": "" - }, - "advancedLocalNodeModules": { - "title": "Path to the local node_modules folder", - "description": "Optionally specify the path to the local node_modules folder", - "type": "string", - "default": "" + "default": "", + "order": 6 }, "eslintRulesDirs": { "title": "ESLint Rules Directories", @@ -56,47 +65,34 @@ "default": [], "items": { "type": "string" - } + }, + "order": 7 }, "disableEslintIgnore": { "title": "Don't use .eslintignore files", "type": "boolean", - "default": false + "default": false, + "order": 8 }, "disableFSCache": { "title": "Disable FileSystem Cache", "description": "Paths of node_modules, .eslintignore and others are cached", "type": "boolean", - "default": false + "default": false, + "order": 9 + }, + "showRuleIdInMessage": { + "title": "Show Rule ID in Messages", + "type": "boolean", + "default": true, + "order": 10 }, "fixOnSave": { "title": "Fix errors on save", "description": "Have eslint attempt to fix some errors automatically when saving the file.", "type": "boolean", - "default": false - }, - "scopes": { - "title": "List of scopes to run ESLint on, run `Editor: Log Cursor Scope` to determine the scopes for a file.", - "type": "array", - "default": [ - "source.js", - "source.jsx", - "source.js.jsx", - "source.babel", - "source.js-semantic" - ], - "items": { - "type": "string" - } - }, - "rulesToSilenceWhileTyping": { - "title": "Silence specific rules while typing", - "description": "Useful when Atom fixes errors on save like `no-trailing-spaces` or `eol-last`.", - "type": "array", - "default": [], - "items": { - "type": "string" - } + "default": false, + "order": 11 }, "rulesToDisableWhileFixing": { "title": "Disable specific rules from fixes", @@ -105,13 +101,32 @@ "default": [], "items": { "type": "string" - } + }, + "order": 12 }, "ignoreFixableRulesWhileTyping": { "title": "Ignore fixable rules while typing", "description": "Have the linter ignore all fixable rules during linting when editing a document. The list is automatically updated on each lint job, and requires at least one run to be populated. Only supported when using ESLint v4+.", "type": "boolean", - "default": false + "default": false, + "order": 13 + }, + "rulesToSilenceWhileTyping": { + "title": "Silence specific rules while typing", + "description": "Useful when Atom fixes errors on save like `no-trailing-spaces` or `eol-last`.", + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "order": 14 + }, + "advancedLocalNodeModules": { + "title": "Path to the local node_modules folder", + "description": "Optionally specify the path to the local node_modules folder", + "type": "string", + "default": "", + "order": 15 } }, "scripts": { From 6130412fd24e75aa1aa744f67df1c80e0073dc8f Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 29 Oct 2017 23:19:24 -0400 Subject: [PATCH 04/18] Group disabling options together This creates an options group for settings that disable linting in one way or another. Because moving options into groups will require a lot of migrations, this also creates a new file/function to handle those migrations, thus keeping them out of `main.js`. There may be a more elegant way to manage the migrations, but this gets us started. --- package.json | 69 +++++++++++++++++++---------------- spec/linter-eslint-spec.js | 16 ++++---- src/main.js | 24 ++++-------- src/migrate-config-options.js | 65 +++++++++++++++++++++++++++++++++ src/worker.js | 2 +- 5 files changed, 119 insertions(+), 57 deletions(-) create mode 100644 src/migrate-config-options.js diff --git a/package.json b/package.json index b498f734..6cb6f61a 100644 --- a/package.json +++ b/package.json @@ -45,12 +45,6 @@ "default": "", "order": 4 }, - "disableWhenNoEslintConfig": { - "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", - "type": "boolean", - "default": true, - "order": 5 - }, "eslintrcPath": { "title": ".eslintrc Path", "description": "It will only be used when there's no config file in project", @@ -94,32 +88,43 @@ "default": false, "order": 11 }, - "rulesToDisableWhileFixing": { - "title": "Disable specific rules from fixes", - "description": "Prevent rules from being auto-fixed by ESLint. Applies to fixes made during saves as well as when running the `Linter Eslint: Fix File` command.", - "type": "array", - "default": [], - "items": { - "type": "string" - }, - "order": 12 - }, - "ignoreFixableRulesWhileTyping": { - "title": "Ignore fixable rules while typing", - "description": "Have the linter ignore all fixable rules during linting when editing a document. The list is automatically updated on each lint job, and requires at least one run to be populated. Only supported when using ESLint v4+.", - "type": "boolean", - "default": false, - "order": 13 - }, - "rulesToSilenceWhileTyping": { - "title": "Silence specific rules while typing", - "description": "Useful when Atom fixes errors on save like `no-trailing-spaces` or `eol-last`.", - "type": "array", - "default": [], - "items": { - "type": "string" - }, - "order": 14 + "disabling": { + "type": "object", + "properties": { + "disableWhenNoEslintConfig": { + "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", + "type": "boolean", + "default": true, + "order": 1 + }, + "ignoreFixableRulesWhileTyping": { + "title": "Ignore fixable rules while typing", + "description": "Have the linter ignore all fixable rules during linting when editing a document. The list is automatically updated on each lint job, and requires at least one run to be populated. Only supported when using ESLint v4+.", + "type": "boolean", + "default": false, + "order": 2 + }, + "rulesToDisableWhileFixing": { + "title": "Disable specific rules from fixes", + "description": "Prevent rules from being auto-fixed by ESLint. Applies to fixes made during saves as well as when running the `Linter Eslint: Fix File` command.", + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "order": 3 + }, + "rulesToSilenceWhileTyping": { + "title": "Silence specific rules while typing", + "description": "Useful when Atom fixes errors on save like `no-trailing-spaces` or `eol-last`.", + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "order": 4 + } + } }, "advancedLocalNodeModules": { "title": "Path to the local node_modules folder", diff --git a/spec/linter-eslint-spec.js b/spec/linter-eslint-spec.js index 9a1ecf5d..2e2ffc9f 100644 --- a/spec/linter-eslint-spec.js +++ b/spec/linter-eslint-spec.js @@ -298,7 +298,7 @@ describe('The eslint provider for Linter', () => { }) it('should not fix linting errors for rules that are disabled with rulesToDisableWhileFixing', async () => { - atom.config.set('linter-eslint.rulesToDisableWhileFixing', ['semi']) + atom.config.set('linter-eslint.disabling.rulesToDisableWhileFixing', ['semi']) await firstLint(editor) await makeFixes(editor) @@ -382,8 +382,8 @@ describe('The eslint provider for Linter', () => { } it('does nothing on saved files', async () => { - atom.config.set('linter-eslint.rulesToSilenceWhileTyping', ['no-trailing-spaces']) - atom.config.set('linter-eslint.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.disabling.rulesToSilenceWhileTyping', ['no-trailing-spaces']) + atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) expectedPath = paths.modifiedIgnoreSpace const editor = await atom.workspace.open(expectedPath) // Run once to populate the fixable rules list @@ -409,7 +409,7 @@ describe('The eslint provider for Linter', () => { checkNew(messages) // Enable the option under test - atom.config.set('linter-eslint.rulesToSilenceWhileTyping', ['no-trailing-spaces']) + atom.config.set('linter-eslint.disabling.rulesToSilenceWhileTyping', ['no-trailing-spaces']) // Check the lint results const newMessages = await lint(editor) @@ -433,7 +433,7 @@ describe('The eslint provider for Linter', () => { // Enable the option under test // NOTE: Depends on no-trailing-spaces being marked as fixable by ESLint - atom.config.set('linter-eslint.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) // Check the lint results const newMessages = await lint(editor) @@ -459,7 +459,7 @@ describe('The eslint provider for Linter', () => { // Enable the option under test // NOTE: Depends on mport/newline-after-import rule being marked as fixable - atom.config.set('linter-eslint.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) // Check the lint results const newMessages = await lint(editor) @@ -516,7 +516,7 @@ describe('The eslint provider for Linter', () => { let tempFixtureDir beforeEach(async () => { - atom.config.set('linter-eslint.disableWhenNoEslintConfig', false) + atom.config.set('linter-eslint.disabling.disableWhenNoEslintConfig', false) tempFilePath = await copyFileToTempDir(paths.badInline) editor = await atom.workspace.open(tempFilePath) @@ -549,7 +549,7 @@ describe('The eslint provider for Linter', () => { let tempFixtureDir beforeEach(async () => { - atom.config.set('linter-eslint.disableWhenNoEslintConfig', true) + atom.config.set('linter-eslint.disabling.disableWhenNoEslintConfig', true) const tempFilePath = await copyFileToTempDir(paths.badInline) editor = await atom.workspace.open(tempFilePath) diff --git a/src/main.js b/src/main.js index b3ebd46d..df9ac557 100644 --- a/src/main.js +++ b/src/main.js @@ -14,6 +14,7 @@ let path let helpers let workerHelpers let isConfigAtHomeRoot +let migrateConfigOptions const loadDeps = () => { if (!path) { @@ -85,19 +86,10 @@ module.exports = { activate() { this.subscriptions = new CompositeDisposable() - /** - * FIXME: Deprecated eslintRulesDir{String} option in favor of - * eslintRulesDirs{Array}. Remove in the next major release, - * in v8.5.0, or after 2018-04. - */ - const oldRulesdir = atom.config.get('linter-eslint.eslintRulesDir') - if (oldRulesdir) { - const rulesDirs = atom.config.get('linter-eslint.eslintRulesDirs') - if (rulesDirs.length === 0) { - atom.config.set('linter-eslint.eslintRulesDirs', [oldRulesdir]) - } - atom.config.unset('linter-eslint.eslintRulesDir') + if (!migrateConfigOptions) { + migrateConfigOptions = require('./migrate-config-options') } + migrateConfigOptions() const embeddedScope = 'source.js.embedded.html' this.subscriptions.add(atom.config.observe( @@ -157,22 +149,22 @@ module.exports = { )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.disableWhenNoEslintConfig', + 'linter-eslint.disabling.disableWhenNoEslintConfig', (value) => { disableWhenNoEslintConfig = value } )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.rulesToSilenceWhileTyping', + 'linter-eslint.disabling.rulesToSilenceWhileTyping', (ids) => { ignoredRulesWhenModified = ids } )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.rulesToDisableWhileFixing', + 'linter-eslint.disabling.rulesToDisableWhileFixing', (ids) => { ignoredRulesWhenFixing = idsToIgnoredRules(ids) } )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.ignoreFixableRulesWhileTyping', + 'linter-eslint.disabling.ignoreFixableRulesWhileTyping', (value) => { ignoreFixableRulesWhileTyping = value } )) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js new file mode 100644 index 00000000..744af483 --- /dev/null +++ b/src/migrate-config-options.js @@ -0,0 +1,65 @@ +'use babel' + +function migrateConfigOptions() { + /** + * FIXME: Deprecated eslintRulesDir{String} option in favor of + * eslintRulesDirs{Array}. Remove in the next major release, + * in v8.5.0, or after 2018-04. + */ + const oldRulesdir = atom.config.get('linter-eslint.eslintRulesDir') + if (oldRulesdir) { + const rulesDirs = atom.config.get('linter-eslint.eslintRulesDirs') + if (rulesDirs.length === 0) { + atom.config.set('linter-eslint.eslintRulesDirs', [oldRulesdir]) + } + atom.config.unset('linter-eslint.eslintRulesDir') + } + + /** + * Move disableWhenNoEslintConfig into `disabling` section. + * Added November, 2017 + */ + const oldDisableWhenNoEslintConfig = atom.config.get('linter-eslint.disableWhenNoEslintConfig') + if (oldDisableWhenNoEslintConfig !== undefined) { + atom.config.set('linter-eslint.disabling.disableWhenNoEslintConfig', oldDisableWhenNoEslintConfig) + atom.config.unset('linter-eslint.disableWhenNoEslintConfig') + } + + /** + * Move ignoreFixableRulesWhileTyping into `disabling` section. + * Added November, 2017 + */ + const oldIgnoreFixableRulesWhileTyping = atom.config.get('linter-eslint.ignoreFixableRulesWhileTyping') + if (oldIgnoreFixableRulesWhileTyping !== undefined) { + atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', oldIgnoreFixableRulesWhileTyping) + atom.config.unset('linter-eslint.ignoreFixableRulesWhileTyping') + } + + /** + * Move rulesToDisableWhileFixing into `disabling` section. + * Added November, 2017 + */ + const oldRulesToDisableWhileFixing = atom.config.get('linter-eslint.rulesToDisableWhileFixing') + if (oldRulesToDisableWhileFixing !== undefined) { + const newRulesToDisableWhileFixing = atom.config.get('linter-eslint.disabling.rulesToDisableWhileFixing') + if (newRulesToDisableWhileFixing.length === 0) { + atom.config.set('linter-eslint.disabling.rulesToDisableWhileFixing', oldRulesToDisableWhileFixing) + } + atom.config.unset('linter-eslint.rulesToDisableWhileFixing') + } + + /** + * Move rulesToSilenceWhileTyping into `disabling` section. + * Added November, 2017 + */ + const oldRulesToSilenceWhileTyping = atom.config.get('linter-eslint.rulesToSilenceWhileTyping') + if (oldRulesToSilenceWhileTyping !== undefined) { + const newRulesToSilenceWhileTyping = atom.config.get('linter-eslint.disabling.rulesToSilenceWhileTyping') + if (newRulesToSilenceWhileTyping.length === 0) { + atom.config.set('linter-eslint.disabling.rulesToSilenceWhileTyping', oldRulesToSilenceWhileTyping) + } + atom.config.unset('linter-eslint.rulesToSilenceWhileTyping') + } +} + +module.exports = migrateConfigOptions diff --git a/src/worker.js b/src/worker.js index 845ee7c7..016d71e8 100644 --- a/src/worker.js +++ b/src/worker.js @@ -52,7 +52,7 @@ module.exports = async () => { const eslint = Helpers.getESLintInstance(fileDir, config, projectPath) const configPath = Helpers.getConfigPath(fileDir) const noProjectConfig = (configPath === null || isConfigAtHomeRoot(configPath)) - if (noProjectConfig && config.disableWhenNoEslintConfig) { + if (noProjectConfig && config.disabling.disableWhenNoEslintConfig) { emit(emitKey, { messages: [] }) return } From 11ceb0d78233407898e7174efeaf232f068e18d1 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 29 Oct 2017 23:32:16 -0400 Subject: [PATCH 05/18] Streamline config setting migrations For standard migrations, all we really need to do is check if the old setting is defined, then move it to the new setting, then unset the old setting. We can just make a simple loop for this, keeping the old and new setting strings as data, apart from the logic that moves them. --- src/migrate-config-options.js | 75 +++++++++++++++-------------------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index 744af483..cb937155 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -1,5 +1,29 @@ 'use babel' +// These are cases where the old setting should be directly moved to the new setting. +const directMoveMigrations = [ + { + /* Added November, 2017 */ + old: 'linter-eslint.disableWhenNoEslintConfig', + new: 'linter-eslint.disabling.disableWhenNoEslintConfig', + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.ignoreFixableRulesWhileTyping', + new: 'linter-eslint.disabling.ignoreFixableRulesWhileTyping' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.rulesToDisableWhileFixing', + new: 'linter-eslint.disabling.rulesToDisableWhileFixing' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.rulesToSilenceWhileTyping', + new: 'linter-eslint.disabling.rulesToSilenceWhileTyping' + } +] + function migrateConfigOptions() { /** * FIXME: Deprecated eslintRulesDir{String} option in favor of @@ -15,51 +39,14 @@ function migrateConfigOptions() { atom.config.unset('linter-eslint.eslintRulesDir') } - /** - * Move disableWhenNoEslintConfig into `disabling` section. - * Added November, 2017 - */ - const oldDisableWhenNoEslintConfig = atom.config.get('linter-eslint.disableWhenNoEslintConfig') - if (oldDisableWhenNoEslintConfig !== undefined) { - atom.config.set('linter-eslint.disabling.disableWhenNoEslintConfig', oldDisableWhenNoEslintConfig) - atom.config.unset('linter-eslint.disableWhenNoEslintConfig') - } - - /** - * Move ignoreFixableRulesWhileTyping into `disabling` section. - * Added November, 2017 - */ - const oldIgnoreFixableRulesWhileTyping = atom.config.get('linter-eslint.ignoreFixableRulesWhileTyping') - if (oldIgnoreFixableRulesWhileTyping !== undefined) { - atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', oldIgnoreFixableRulesWhileTyping) - atom.config.unset('linter-eslint.ignoreFixableRulesWhileTyping') - } - - /** - * Move rulesToDisableWhileFixing into `disabling` section. - * Added November, 2017 - */ - const oldRulesToDisableWhileFixing = atom.config.get('linter-eslint.rulesToDisableWhileFixing') - if (oldRulesToDisableWhileFixing !== undefined) { - const newRulesToDisableWhileFixing = atom.config.get('linter-eslint.disabling.rulesToDisableWhileFixing') - if (newRulesToDisableWhileFixing.length === 0) { - atom.config.set('linter-eslint.disabling.rulesToDisableWhileFixing', oldRulesToDisableWhileFixing) + // Copy old settings over to the new ones, then unset the old setting keys + directMoveMigrations.forEach((migration) => { + const oldSetting = atom.config.get(migration.old) + if (oldSetting !== undefined) { + atom.config.set(migration.new, oldSetting) + atom.config.unset(migration.old) } - atom.config.unset('linter-eslint.rulesToDisableWhileFixing') - } - - /** - * Move rulesToSilenceWhileTyping into `disabling` section. - * Added November, 2017 - */ - const oldRulesToSilenceWhileTyping = atom.config.get('linter-eslint.rulesToSilenceWhileTyping') - if (oldRulesToSilenceWhileTyping !== undefined) { - const newRulesToSilenceWhileTyping = atom.config.get('linter-eslint.disabling.rulesToSilenceWhileTyping') - if (newRulesToSilenceWhileTyping.length === 0) { - atom.config.set('linter-eslint.disabling.rulesToSilenceWhileTyping', oldRulesToSilenceWhileTyping) - } - atom.config.unset('linter-eslint.rulesToSilenceWhileTyping') - } + }) } module.exports = migrateConfigOptions From 7e8b0f5b6cbb9d3366a8c5ed27a42ee4b1078a5d Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Mon, 30 Oct 2017 00:14:19 -0400 Subject: [PATCH 06/18] =?UTF-8?q?Group=20=E2=80=9Cadvanced=E2=80=9D=20sett?= =?UTF-8?q?ings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are settings that are not commonly needed, so we may as well try to avoid confusing new users by indicating that they are “advanced” --- package.json | 71 +++++++++++++++++++---------------- spec/linter-eslint-spec.js | 18 ++++----- spec/worker-helpers-spec.js | 61 ++++++++++++++++++++---------- src/main.js | 2 +- src/migrate-config-options.js | 27 ++++++++++++- src/worker-helpers.js | 18 ++++----- src/worker.js | 2 +- 7 files changed, 126 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 6cb6f61a..0595532a 100644 --- a/package.json +++ b/package.json @@ -45,13 +45,6 @@ "default": "", "order": 4 }, - "eslintrcPath": { - "title": ".eslintrc Path", - "description": "It will only be used when there's no config file in project", - "type": "string", - "default": "", - "order": 6 - }, "eslintRulesDirs": { "title": "ESLint Rules Directories", "description": "Specify a comma separated list of directories for ESLint to load rules from.", @@ -62,25 +55,6 @@ }, "order": 7 }, - "disableEslintIgnore": { - "title": "Don't use .eslintignore files", - "type": "boolean", - "default": false, - "order": 8 - }, - "disableFSCache": { - "title": "Disable FileSystem Cache", - "description": "Paths of node_modules, .eslintignore and others are cached", - "type": "boolean", - "default": false, - "order": 9 - }, - "showRuleIdInMessage": { - "title": "Show Rule ID in Messages", - "type": "boolean", - "default": true, - "order": 10 - }, "fixOnSave": { "title": "Fix errors on save", "description": "Have eslint attempt to fix some errors automatically when saving the file.", @@ -90,6 +64,7 @@ }, "disabling": { "type": "object", + "order": 4, "properties": { "disableWhenNoEslintConfig": { "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", @@ -126,12 +101,44 @@ } } }, - "advancedLocalNodeModules": { - "title": "Path to the local node_modules folder", - "description": "Optionally specify the path to the local node_modules folder", - "type": "string", - "default": "", - "order": 15 + "advanced": { + "type": "object", + "order": 5, + "properties": { + "disableEslintIgnore": { + "title": "Don't use .eslintignore files", + "type": "boolean", + "default": false, + "order": 1 + }, + "disableFSCache": { + "title": "Disable FileSystem Cache", + "description": "Paths of node_modules, .eslintignore and others are cached", + "type": "boolean", + "default": false, + "order": 2 + }, + "showRuleIdInMessage": { + "title": "Show Rule ID in Messages", + "type": "boolean", + "default": true, + "order": 3 + }, + "eslintrcPath": { + "title": ".eslintrc Path", + "description": "It will only be used when there's no config file in project", + "type": "string", + "default": "", + "order": 4 + }, + "advancedLocalNodeModules": { + "title": "Path to the local node_modules folder", + "description": "Optionally specify the path to the local node_modules folder", + "type": "string", + "default": "", + "order": 5 + } + } } }, "scripts": { diff --git a/spec/linter-eslint-spec.js b/spec/linter-eslint-spec.js index 2e2ffc9f..46540469 100644 --- a/spec/linter-eslint-spec.js +++ b/spec/linter-eslint-spec.js @@ -113,8 +113,8 @@ describe('The eslint provider for Linter', () => { const { lint } = linterProvider beforeEach(async () => { - atom.config.set('linter-eslint.disableFSCache', false) - atom.config.set('linter-eslint.disableEslintIgnore', true) + atom.config.set('linter-eslint.advanced.disableFSCache', false) + atom.config.set('linter-eslint.advanced.disableEslintIgnore', true) // Activate the JavaScript language so Atom knows what the files are await atom.packages.activatePackage('language-javascript') @@ -206,7 +206,7 @@ describe('The eslint provider for Linter', () => { describe('when a file is specified in an .eslintignore file', () => { beforeEach(() => { - atom.config.set('linter-eslint.disableEslintIgnore', false) + atom.config.set('linter-eslint.advanced.disableEslintIgnore', false) }) it('will not give warnings when linting the file', async () => { @@ -233,7 +233,7 @@ describe('The eslint provider for Linter', () => { const tempDir = path.dirname(tempPath) const editor = await atom.workspace.open(tempPath) - atom.config.set('linter-eslint.disableEslintIgnore', false) + atom.config.set('linter-eslint.advanced.disableEslintIgnore', false) await copyFileToDir(path.join(paths.eslintignoreDir, '.eslintrc.yaml'), tempDir) const messages = await lint(editor) @@ -244,7 +244,7 @@ describe('The eslint provider for Linter', () => { describe('when a file is specified in an eslintIgnore key in package.json', () => { it('will still lint the file if an .eslintignore file is present', async () => { - atom.config.set('linter-eslint.disableEslintIgnore', false) + atom.config.set('linter-eslint.advanced.disableEslintIgnore', false) const editor = await atom.workspace.open(path.join(paths.eslintIgnoreKeyDir, 'ignored.js')) const messages = await lint(editor) @@ -256,7 +256,7 @@ describe('The eslint provider for Linter', () => { const tempDir = path.dirname(tempPath) const editor = await atom.workspace.open(tempPath) - atom.config.set('linter-eslint.disableEslintIgnore', false) + atom.config.set('linter-eslint.advanced.disableEslintIgnore', false) await copyFileToDir(path.join(paths.eslintIgnoreKeyDir, 'package.json'), tempDir) const messages = await lint(editor) @@ -571,7 +571,7 @@ describe('The eslint provider for Linter', () => { it('works when the cache fails', async () => { // Ensure the cache is enabled, since we will be taking advantage of // a failing in it's operation - atom.config.set('linter-eslint.disableFSCache', false) + atom.config.set('linter-eslint.advanced.disableFSCache', false) const fooPath = path.join(paths.badCache, 'temp', 'foo.js') const newConfigPath = path.join(paths.badCache, 'temp', '.eslintrc.js') const editor = await atom.workspace.open(fooPath) @@ -658,7 +658,7 @@ describe('The eslint provider for Linter', () => { const expectedUrl = 'https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md' it('shows the rule ID when enabled', async () => { - atom.config.set('linter-eslint.showRuleIdInMessage', true) + atom.config.set('linter-eslint.advanced.showRuleIdInMessage', true) const editor = await atom.workspace.open(paths.badImport) const messages = await lint(editor) const expected = "Unable to resolve path to module '../nonexistent'. (import/no-unresolved)" @@ -673,7 +673,7 @@ describe('The eslint provider for Linter', () => { }) it("doesn't show the rule ID when disabled", async () => { - atom.config.set('linter-eslint.showRuleIdInMessage', false) + atom.config.set('linter-eslint.advanced.showRuleIdInMessage', false) const editor = await atom.workspace.open(paths.badImport) const messages = await lint(editor) const expected = "Unable to resolve path to module '../nonexistent'." diff --git a/spec/worker-helpers-spec.js b/spec/worker-helpers-spec.js index fb40d493..9c50a43d 100644 --- a/spec/worker-helpers-spec.js +++ b/spec/worker-helpers-spec.js @@ -12,11 +12,19 @@ const globalNodePath = process.platform === 'win32' ? Path.join(getFixturesPath('global-eslint'), 'lib') : getFixturesPath('global-eslint') +function createConfig(overrides = {}) { + return { + ...overrides, + disabling: { ...overrides.disabling }, + advanced: { ...overrides.advanced }, + } +} + describe('Worker Helpers', () => { describe('findESLintDirectory', () => { it('returns an object with path and type keys', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const foundEslint = Helpers.findESLintDirectory(modulesDir, {}) + const foundEslint = Helpers.findESLintDirectory(modulesDir, createConfig()) expect(typeof foundEslint === 'object').toBe(true) expect(foundEslint.path).toBeDefined() expect(foundEslint.type).toBeDefined() @@ -24,7 +32,8 @@ describe('Worker Helpers', () => { it('finds a local eslint when useGlobalEslint is false', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const foundEslint = Helpers.findESLintDirectory(modulesDir, { useGlobalEslint: false }) + const config = createConfig({ useGlobalEslint: false }) + const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = Path.join(getFixturesPath('local-eslint'), 'node_modules', 'eslint') expect(foundEslint.path).toEqual(expectedEslintPath) expect(foundEslint.type).toEqual('local project') @@ -32,7 +41,7 @@ describe('Worker Helpers', () => { it('does not find a local eslint when useGlobalEslint is true', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const config = { useGlobalEslint: true, globalNodePath } + const config = createConfig({ useGlobalEslint: true, globalNodePath }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = Path.join(getFixturesPath('local-eslint'), 'node_modules', 'eslint') expect(foundEslint.path).not.toEqual(expectedEslintPath) @@ -41,7 +50,7 @@ describe('Worker Helpers', () => { it('finds a global eslint when useGlobalEslint is true and a valid globalNodePath is provided', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const config = { useGlobalEslint: true, globalNodePath } + const config = createConfig({ useGlobalEslint: true, globalNodePath }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = process.platform === 'win32' ? Path.join(globalNodePath, 'node_modules', 'eslint') @@ -52,7 +61,7 @@ describe('Worker Helpers', () => { it('falls back to the packaged eslint when no local eslint is found', () => { const modulesDir = 'not/a/real/path' - const config = { useGlobalEslint: false } + const config = createConfig({ useGlobalEslint: false }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedBundledPath = Path.join(__dirname, '..', 'node_modules', 'eslint') expect(foundEslint.path).toEqual(expectedBundledPath) @@ -65,56 +74,62 @@ describe('Worker Helpers', () => { it('tries to find an indirect local eslint using an absolute path', () => { const path = Path.join(getFixturesPath('indirect-local-eslint'), pathPart) - const eslint = Helpers.getESLintInstance('', { + const config = createConfig({ useGlobalEslint: false, - advancedLocalNodeModules: path + advanced: { advancedLocalNodeModules: path } }) + const eslint = Helpers.getESLintInstance('', config) expect(eslint).toBe('located') }) it('tries to find an indirect local eslint using a relative path', () => { const path = Path.join(getFixturesPath('indirect-local-eslint'), pathPart) const [projectPath, relativePath] = atom.project.relativizePath(path) - - const eslint = Helpers.getESLintInstance('', { + const config = createConfig({ useGlobalEslint: false, - advancedLocalNodeModules: relativePath - }, projectPath) + advanced: { advancedLocalNodeModules: relativePath } + }) + const eslint = Helpers.getESLintInstance('', config, projectPath) expect(eslint).toBe('located') }) it('tries to find a local eslint', () => { - const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), {}) + const config = createConfig() + const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) expect(eslint).toBe('located') }) it('cries if local eslint is not found', () => { expect(() => { - Helpers.getESLintInstance(getFixturesPath('files', {})) + const config = createConfig() + Helpers.getESLintInstance(getFixturesPath('files', config)) }).toThrow() }) it('tries to find a global eslint if config is specified', () => { - const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), { + const config = createConfig({ useGlobalEslint: true, globalNodePath }) + const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) expect(eslint).toBe('located') }) it('cries if global eslint is not found', () => { expect(() => { - Helpers.getESLintInstance(getFixturesPath('local-eslint'), { + const config = createConfig({ useGlobalEslint: true, globalNodePath: getFixturesPath('files') }) + Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) }).toThrow() }) it('tries to find a local eslint with nested node_modules', () => { const fileDir = Path.join(getFixturesPath('local-eslint'), 'lib', 'foo.js') - const eslint = Helpers.getESLintInstance(fileDir, {}) + const config = createConfig() + const eslint = Helpers.getESLintInstance(fileDir, config) expect(eslint).toBe('located') }) }) @@ -167,7 +182,8 @@ describe('Worker Helpers', () => { it('return path relative of ignore file if found', () => { const fixtureDir = getFixturesPath('eslintignore') const fixtureFile = Path.join(fixtureDir, 'ignored.js') - const relativePath = Helpers.getRelativePath(fixtureDir, fixtureFile, {}) + const config = createConfig() + const relativePath = Helpers.getRelativePath(fixtureDir, fixtureFile, config) const expectedPath = Path.relative(Path.join(__dirname, '..'), fixtureFile) expect(relativePath).toBe(expectedPath) }) @@ -175,8 +191,11 @@ describe('Worker Helpers', () => { it('does not return path relative to ignore file if config overrides it', () => { const fixtureDir = getFixturesPath('eslintignore') const fixtureFile = Path.join(fixtureDir, 'ignored.js') + const config = createConfig({ + advanced: { disableEslintIgnore: true } + }) const relativePath = - Helpers.getRelativePath(fixtureDir, fixtureFile, { disableEslintIgnore: true }) + Helpers.getRelativePath(fixtureDir, fixtureFile, config) expect(relativePath).toBe('ignored.js') }) @@ -187,8 +206,9 @@ describe('Worker Helpers', () => { const tempDir = Path.dirname(tempFixturePath) const filepath = Path.join(tempDir, 'good.js') const tempDirParent = Path.dirname(tempDir) + const config = createConfig() - const relativePath = Helpers.getRelativePath(tempDir, filepath, {}, tempDirParent) + const relativePath = Helpers.getRelativePath(tempDir, filepath, config, tempDirParent) // Since the project is the parent of the temp dir, the relative path should be // the dir containing the file, plus the file. (e.g. asgln3/good.js) const expectedPath = Path.join(Path.basename(tempDir), 'good.js') @@ -203,8 +223,9 @@ describe('Worker Helpers', () => { const tempFixturePath = await copyFileToTempDir(fixtureFile) const tempDir = Path.dirname(tempFixturePath) const filepath = Path.join(tempDir, 'good.js') + const config = createConfig() - const relativePath = Helpers.getRelativePath(tempDir, filepath, {}, null) + const relativePath = Helpers.getRelativePath(tempDir, filepath, config, null) expect(relativePath).toBe('good.js') // Remove the temporary directory diff --git a/src/main.js b/src/main.js index df9ac557..899e508c 100644 --- a/src/main.js +++ b/src/main.js @@ -144,7 +144,7 @@ module.exports = { })) this.subscriptions.add(atom.config.observe( - 'linter-eslint.showRuleIdInMessage', + 'linter-eslint.advanced.showRuleIdInMessage', (value) => { showRule = value } )) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index cb937155..d2a81aed 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -21,7 +21,32 @@ const directMoveMigrations = [ /* Added November, 2017 */ old: 'linter-eslint.rulesToSilenceWhileTyping', new: 'linter-eslint.disabling.rulesToSilenceWhileTyping' - } + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.disableEslintIgnore', + new: 'linter-eslint.advanced.disableEslintIgnore' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.disableFSCache', + new: 'linter-eslint.advanced.disableFSCache' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.showRuleIdInMessage', + new: 'linter-eslint.advanced.showRuleIdInMessage' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.eslintrcPath', + new: 'linter-eslint.advanced.eslintrcPath' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.advancedLocalNodeModules', + new: 'linter-eslint.advanced.advancedLocalNodeModules' + }, ] function migrateConfigOptions() { diff --git a/src/worker-helpers.js b/src/worker-helpers.js index bdcfd47e..8c75af7e 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -61,15 +61,15 @@ export function findESLintDirectory(modulesDir, config, projectPath) { // NPM on platforms other than Windows eslintDir = Path.join(prefixPath, 'lib', 'node_modules', 'eslint') } - } else if (!config.advancedLocalNodeModules) { + } else if (!config.advanced.advancedLocalNodeModules) { locationType = 'local project' eslintDir = Path.join(modulesDir || '', 'eslint') - } else if (Path.isAbsolute(cleanPath(config.advancedLocalNodeModules))) { + } else if (Path.isAbsolute(cleanPath(config.advanced.advancedLocalNodeModules))) { locationType = 'advanced specified' - eslintDir = Path.join(cleanPath(config.advancedLocalNodeModules), 'eslint') + eslintDir = Path.join(cleanPath(config.advanced.advancedLocalNodeModules), 'eslint') } else { locationType = 'advanced specified' - eslintDir = Path.join(projectPath || '', cleanPath(config.advancedLocalNodeModules), 'eslint') + eslintDir = Path.join(projectPath || '', cleanPath(config.advanced.advancedLocalNodeModules), 'eslint') } if (isDirectory(eslintDir)) { return { @@ -137,7 +137,7 @@ export function getConfigPath(fileDir) { } export function getRelativePath(fileDir, filePath, config, projectPath) { - const ignoreFile = config.disableEslintIgnore ? null : findCached(fileDir, '.eslintignore') + const ignoreFile = config.advanced.disableEslintIgnore ? null : findCached(fileDir, '.eslintignore') // If we can find an .eslintignore file, we can set cwd there // (because they are expected to be at the project root) @@ -159,11 +159,11 @@ export function getRelativePath(fileDir, filePath, config, projectPath) { export function getCLIEngineOptions(type, config, rules, filePath, fileDir, givenConfigPath) { const cliEngineConfig = { rules, - ignore: !config.disableEslintIgnore, + ignore: !config.advanced.disableEslintIgnore, fix: type === 'fix' } - const ignoreFile = config.disableEslintIgnore ? null : findCached(fileDir, '.eslintignore') + const ignoreFile = config.advanced.disableEslintIgnore ? null : findCached(fileDir, '.eslintignore') if (ignoreFile) { cliEngineConfig.ignorePath = ignoreFile } @@ -176,9 +176,9 @@ export function getCLIEngineOptions(type, config, rules, filePath, fileDir, give return rulesDir }).filter(path => path) - if (givenConfigPath === null && config.eslintrcPath) { + if (givenConfigPath === null && config.advanced.eslintrcPath) { // If we didn't find a configuration use the fallback from the settings - cliEngineConfig.configFile = cleanPath(config.eslintrcPath) + cliEngineConfig.configFile = cleanPath(config.advanced.eslintrcPath) } return cliEngineConfig diff --git a/src/worker.js b/src/worker.js index 016d71e8..2e0af61e 100644 --- a/src/worker.js +++ b/src/worker.js @@ -44,7 +44,7 @@ module.exports = async () => { contents, type, config, filePath, projectPath, rules, emitKey } = jobConfig try { - if (config.disableFSCache) { + if (config.advanced.disableFSCache) { FindCache.clear() } From 27631af60886dd5e00597651c43e3854d5647185 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Mon, 30 Oct 2017 00:29:53 -0400 Subject: [PATCH 07/18] Group global eslint options together --- package.json | 35 +++++++++++++++++++++-------------- spec/worker-helpers-spec.js | 20 ++++++++++---------- src/migrate-config-options.js | 10 ++++++++++ src/worker-helpers.js | 8 ++++---- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 0595532a..80800e2f 100644 --- a/package.json +++ b/package.json @@ -31,20 +31,6 @@ "default": false, "order": 2 }, - "useGlobalEslint": { - "title": "Use global ESLint installation", - "description": "Make sure you have it in your $PATH", - "type": "boolean", - "default": false, - "order": 3 - }, - "globalNodePath": { - "title": "Global Node Installation Path", - "description": "Write the value of `npm get prefix` here", - "type": "string", - "default": "", - "order": 4 - }, "eslintRulesDirs": { "title": "ESLint Rules Directories", "description": "Specify a comma separated list of directories for ESLint to load rules from.", @@ -62,6 +48,27 @@ "default": false, "order": 11 }, + "global": { + "type": "object", + "order": 3, + "title": "Global ESLint", + "properties": { + "useGlobalEslint": { + "title": "Use global ESLint installation", + "description": "Make sure you have it in your $PATH", + "type": "boolean", + "default": false, + "order": 1 + }, + "globalNodePath": { + "title": "Global Node Installation Path", + "description": "Write the value of `npm get prefix` here", + "type": "string", + "default": "", + "order": 2 + } + } + }, "disabling": { "type": "object", "order": 4, diff --git a/spec/worker-helpers-spec.js b/spec/worker-helpers-spec.js index 9c50a43d..85cd61b0 100644 --- a/spec/worker-helpers-spec.js +++ b/spec/worker-helpers-spec.js @@ -15,6 +15,7 @@ const globalNodePath = process.platform === 'win32' ? function createConfig(overrides = {}) { return { ...overrides, + global: { ...overrides.global }, disabling: { ...overrides.disabling }, advanced: { ...overrides.advanced }, } @@ -32,7 +33,7 @@ describe('Worker Helpers', () => { it('finds a local eslint when useGlobalEslint is false', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const config = createConfig({ useGlobalEslint: false }) + const config = createConfig({ global: { useGlobalEslint: false } }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = Path.join(getFixturesPath('local-eslint'), 'node_modules', 'eslint') expect(foundEslint.path).toEqual(expectedEslintPath) @@ -41,7 +42,7 @@ describe('Worker Helpers', () => { it('does not find a local eslint when useGlobalEslint is true', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const config = createConfig({ useGlobalEslint: true, globalNodePath }) + const config = createConfig({ global: { useGlobalEslint: true, globalNodePath } }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = Path.join(getFixturesPath('local-eslint'), 'node_modules', 'eslint') expect(foundEslint.path).not.toEqual(expectedEslintPath) @@ -50,7 +51,7 @@ describe('Worker Helpers', () => { it('finds a global eslint when useGlobalEslint is true and a valid globalNodePath is provided', () => { const modulesDir = Path.join(getFixturesPath('local-eslint'), 'node_modules') - const config = createConfig({ useGlobalEslint: true, globalNodePath }) + const config = createConfig({ global: { useGlobalEslint: true, globalNodePath } }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedEslintPath = process.platform === 'win32' ? Path.join(globalNodePath, 'node_modules', 'eslint') @@ -61,7 +62,7 @@ describe('Worker Helpers', () => { it('falls back to the packaged eslint when no local eslint is found', () => { const modulesDir = 'not/a/real/path' - const config = createConfig({ useGlobalEslint: false }) + const config = createConfig({ global: { useGlobalEslint: false } }) const foundEslint = Helpers.findESLintDirectory(modulesDir, config) const expectedBundledPath = Path.join(__dirname, '..', 'node_modules', 'eslint') expect(foundEslint.path).toEqual(expectedBundledPath) @@ -75,7 +76,7 @@ describe('Worker Helpers', () => { it('tries to find an indirect local eslint using an absolute path', () => { const path = Path.join(getFixturesPath('indirect-local-eslint'), pathPart) const config = createConfig({ - useGlobalEslint: false, + global: { useGlobalEslint: false }, advanced: { advancedLocalNodeModules: path } }) const eslint = Helpers.getESLintInstance('', config) @@ -86,7 +87,7 @@ describe('Worker Helpers', () => { const path = Path.join(getFixturesPath('indirect-local-eslint'), pathPart) const [projectPath, relativePath] = atom.project.relativizePath(path) const config = createConfig({ - useGlobalEslint: false, + global: { useGlobalEslint: false }, advanced: { advancedLocalNodeModules: relativePath } }) const eslint = Helpers.getESLintInstance('', config, projectPath) @@ -109,9 +110,9 @@ describe('Worker Helpers', () => { it('tries to find a global eslint if config is specified', () => { const config = createConfig({ - useGlobalEslint: true, - globalNodePath + global: { useGlobalEslint: true, globalNodePath } }) + console.log({ config }) const eslint = Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) expect(eslint).toBe('located') }) @@ -119,8 +120,7 @@ describe('Worker Helpers', () => { it('cries if global eslint is not found', () => { expect(() => { const config = createConfig({ - useGlobalEslint: true, - globalNodePath: getFixturesPath('files') + global: { useGlobalEslint: true, globalNodePath: getFixturesPath('files') } }) Helpers.getESLintInstance(getFixturesPath('local-eslint'), config) }).toThrow() diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index d2a81aed..49736fe0 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -47,6 +47,16 @@ const directMoveMigrations = [ old: 'linter-eslint.advancedLocalNodeModules', new: 'linter-eslint.advanced.advancedLocalNodeModules' }, + { + /* Added November, 2017 */ + old: 'linter-eslint.useGlobalEslint', + new: 'linter-eslint.global.useGlobalEslint' + }, + { + /* Added November, 2017 */ + old: 'linter-eslint.globalNodePath', + new: 'linter-eslint.global.globalNodePath' + }, ] function migrateConfigOptions() { diff --git a/src/worker-helpers.js b/src/worker-helpers.js index 8c75af7e..a21c83cf 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -51,9 +51,9 @@ function isDirectory(dirPath) { export function findESLintDirectory(modulesDir, config, projectPath) { let eslintDir = null let locationType = null - if (config.useGlobalEslint) { + if (config.global.useGlobalEslint) { locationType = 'global' - const configGlobal = cleanPath(config.globalNodePath) + const configGlobal = cleanPath(config.global.globalNodePath) const prefixPath = configGlobal || getNodePrefixPath() // NPM on Windows and Yarn on all platforms eslintDir = Path.join(prefixPath, 'node_modules', 'eslint') @@ -76,7 +76,7 @@ export function findESLintDirectory(modulesDir, config, projectPath) { path: eslintDir, type: locationType, } - } else if (config.useGlobalEslint) { + } else if (config.global.useGlobalEslint) { throw new Error('ESLint not found, please ensure the global Node path is set correctly.') } return { @@ -91,7 +91,7 @@ export function getESLintFromDirectory(modulesDir, config, projectPath) { // eslint-disable-next-line import/no-dynamic-require return require(ESLintDirectory) } catch (e) { - if (config.useGlobalEslint && e.code === 'MODULE_NOT_FOUND') { + if (config.global.useGlobalEslint && e.code === 'MODULE_NOT_FOUND') { throw new Error('ESLint not found, try restarting Atom to clear caches.') } // eslint-disable-next-line import/no-dynamic-require From 3f12099ff0b5a28a72c18c420c9f5d8e98311af2 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Mon, 30 Oct 2017 00:31:43 -0400 Subject: [PATCH 08/18] Rearrange remaining options --- package.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 80800e2f..ce42d07a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,20 @@ "atom": ">=1.13.0 <2.0.0" }, "configSchema": { + "fixOnSave": { + "title": "Fix errors on save", + "description": "Have eslint attempt to fix some errors automatically when saving the file.", + "type": "boolean", + "default": false, + "order": 1 + }, + "lintHtmlFiles": { + "title": "Lint HTML Files", + "description": "You should also add `eslint-plugin-html` to your .eslintrc plugins", + "type": "boolean", + "default": false, + "order": 2 + }, "scopes": { "title": "List of scopes to run ESLint on, run `Editor: Log Cursor Scope` to determine the scopes for a file.", "type": "array", @@ -22,14 +36,7 @@ "items": { "type": "string" }, - "order": 1 - }, - "lintHtmlFiles": { - "title": "Lint HTML Files", - "description": "You should also add `eslint-plugin-html` to your .eslintrc plugins", - "type": "boolean", - "default": false, - "order": 2 + "order": 3 }, "eslintRulesDirs": { "title": "ESLint Rules Directories", @@ -39,18 +46,11 @@ "items": { "type": "string" }, - "order": 7 - }, - "fixOnSave": { - "title": "Fix errors on save", - "description": "Have eslint attempt to fix some errors automatically when saving the file.", - "type": "boolean", - "default": false, - "order": 11 + "order": 4 }, "global": { "type": "object", - "order": 3, + "order": 5, "title": "Global ESLint", "properties": { "useGlobalEslint": { @@ -71,7 +71,7 @@ }, "disabling": { "type": "object", - "order": 4, + "order": 6, "properties": { "disableWhenNoEslintConfig": { "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", @@ -110,7 +110,7 @@ }, "advanced": { "type": "object", - "order": 5, + "order": 7, "properties": { "disableEslintIgnore": { "title": "Don't use .eslintignore files", From 2088026d280e53d0460311288af274fa187b2643 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 21:58:53 -0500 Subject: [PATCH 09/18] Wording tweaks --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d284bd6..39963185 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ eslint --init ``` Alternatively you can create the `.eslintrc` file by yourself. It is a good -idea to have a look at the [the ESLint documentation](http://eslint.org/docs/user-guide/configuring), +idea to have a look at the [ESLint documentation](http://eslint.org/docs/user-guide/configuring), including the [list of rules](http://eslint.org/docs/rules/). ## A Note About Settings diff --git a/package.json b/package.json index ce42d07a..3213bb43 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ }, "disableFSCache": { "title": "Disable FileSystem Cache", - "description": "Paths of node_modules, .eslintignore and others are cached", + "description": "Paths of node_modules, .eslintignore and others are normally cached", "type": "boolean", "default": false, "order": 2 From da1ac1a69a4ef3815c04c8fa00e7ff9d060c8a15 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 22:00:29 -0500 Subject: [PATCH 10/18] Move `eslintrcPath` setting to `global` section --- package.json | 14 +++++++------- src/migrate-config-options.js | 2 +- src/worker-helpers.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 3213bb43..239f0c9b 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,13 @@ "default": false, "order": 1 }, + "eslintrcPath": { + "title": ".eslintrc Path", + "description": "It will only be used when there's no config file in project", + "type": "string", + "default": "", + "order": 4 + }, "globalNodePath": { "title": "Global Node Installation Path", "description": "Write the value of `npm get prefix` here", @@ -131,13 +138,6 @@ "default": true, "order": 3 }, - "eslintrcPath": { - "title": ".eslintrc Path", - "description": "It will only be used when there's no config file in project", - "type": "string", - "default": "", - "order": 4 - }, "advancedLocalNodeModules": { "title": "Path to the local node_modules folder", "description": "Optionally specify the path to the local node_modules folder", diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index 49736fe0..36a3ac8d 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -40,7 +40,7 @@ const directMoveMigrations = [ { /* Added November, 2017 */ old: 'linter-eslint.eslintrcPath', - new: 'linter-eslint.advanced.eslintrcPath' + new: 'linter-eslint.global.eslintrcPath' }, { /* Added November, 2017 */ diff --git a/src/worker-helpers.js b/src/worker-helpers.js index a21c83cf..8c2d8c73 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -176,9 +176,9 @@ export function getCLIEngineOptions(type, config, rules, filePath, fileDir, give return rulesDir }).filter(path => path) - if (givenConfigPath === null && config.advanced.eslintrcPath) { + if (givenConfigPath === null && config.global.eslintrcPath) { // If we didn't find a configuration use the fallback from the settings - cliEngineConfig.configFile = cleanPath(config.advanced.eslintrcPath) + cliEngineConfig.configFile = cleanPath(config.global.eslintrcPath) } return cliEngineConfig From 03a79795a4baddcfbf79f5fa16a73e6bbe76e7cf Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 22:05:32 -0500 Subject: [PATCH 11/18] Move eslintRulesDirs to advanced section And also collapse advanced section. --- package.json | 21 +++++++++++---------- src/migrate-config-options.js | 5 +++++ src/worker-helpers.js | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 239f0c9b..48d68f33 100644 --- a/package.json +++ b/package.json @@ -38,16 +38,6 @@ }, "order": 3 }, - "eslintRulesDirs": { - "title": "ESLint Rules Directories", - "description": "Specify a comma separated list of directories for ESLint to load rules from.", - "type": "array", - "default": [], - "items": { - "type": "string" - }, - "order": 4 - }, "global": { "type": "object", "order": 5, @@ -117,6 +107,7 @@ }, "advanced": { "type": "object", + "collapsed": true, "order": 7, "properties": { "disableEslintIgnore": { @@ -138,6 +129,16 @@ "default": true, "order": 3 }, + "eslintRulesDirs": { + "title": "ESLint Rules Directories", + "description": "Specify a comma separated list of directories for ESLint to load rules from.", + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "order": 4 + }, "advancedLocalNodeModules": { "title": "Path to the local node_modules folder", "description": "Optionally specify the path to the local node_modules folder", diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index 36a3ac8d..e042605d 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -47,6 +47,11 @@ const directMoveMigrations = [ old: 'linter-eslint.advancedLocalNodeModules', new: 'linter-eslint.advanced.advancedLocalNodeModules' }, + { + /* Added November, 2017 */ + old: 'linter-eslint.eslintRulesDirs', + new: 'linter-eslint.advanced.eslintRulesDirs' + }, { /* Added November, 2017 */ old: 'linter-eslint.useGlobalEslint', diff --git a/src/worker-helpers.js b/src/worker-helpers.js index 8c2d8c73..5b275567 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -168,7 +168,7 @@ export function getCLIEngineOptions(type, config, rules, filePath, fileDir, give cliEngineConfig.ignorePath = ignoreFile } - cliEngineConfig.rulePaths = config.eslintRulesDirs.map((path) => { + cliEngineConfig.rulePaths = config.advanced.eslintRulesDirs.map((path) => { const rulesDir = cleanPath(path) if (!Path.isAbsolute(rulesDir)) { return findCached(fileDir, rulesDir) From 73ea71bcf7804a47c236dea980b7994b4b0522f7 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 22:41:20 -0500 Subject: [PATCH 12/18] Create an `autofix` section --- package.json | 80 +++++++++++++++++++---------------- spec/linter-eslint-spec.js | 8 ++-- src/main.js | 6 +-- src/migrate-config-options.js | 9 +++- 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 48d68f33..8631efba 100644 --- a/package.json +++ b/package.json @@ -9,20 +9,6 @@ "atom": ">=1.13.0 <2.0.0" }, "configSchema": { - "fixOnSave": { - "title": "Fix errors on save", - "description": "Have eslint attempt to fix some errors automatically when saving the file.", - "type": "boolean", - "default": false, - "order": 1 - }, - "lintHtmlFiles": { - "title": "Lint HTML Files", - "description": "You should also add `eslint-plugin-html` to your .eslintrc plugins", - "type": "boolean", - "default": false, - "order": 2 - }, "scopes": { "title": "List of scopes to run ESLint on, run `Editor: Log Cursor Scope` to determine the scopes for a file.", "type": "array", @@ -36,11 +22,49 @@ "items": { "type": "string" }, - "order": 3 + "order": 1 + }, + "lintHtmlFiles": { + "title": "Lint HTML Files", + "description": "You should also add `eslint-plugin-html` to your .eslintrc plugins", + "type": "boolean", + "default": false, + "order": 2 + }, + "autofix": { + "type": "object", + "order": 3, + "title": "Automatic Fixes", + "properties": { + "fixOnSave": { + "title": "Fix errors on save", + "description": "Have eslint attempt to fix some errors automatically when saving the file.", + "type": "boolean", + "default": false, + "order": 1 + }, + "ignoreFixableRulesWhileTyping": { + "title": "Ignore fixable rules while typing", + "description": "Have the linter ignore all fixable rules during linting when editing a document. The list is automatically updated on each lint job, and requires at least one run to be populated. Only supported when using ESLint v4+.", + "type": "boolean", + "default": false, + "order": 2 + }, + "rulesToDisableWhileFixing": { + "title": "Disable specific rules from fixes", + "description": "Prevent rules from being auto-fixed by ESLint. Applies to fixes made during saves as well as when running the `Linter Eslint: Fix File` command.", + "type": "array", + "default": [], + "items": { + "type": "string" + }, + "order": 3 + } + } }, "global": { "type": "object", - "order": 5, + "order": 4, "title": "Global ESLint", "properties": { "useGlobalEslint": { @@ -68,7 +92,7 @@ }, "disabling": { "type": "object", - "order": 6, + "order": 5, "properties": { "disableWhenNoEslintConfig": { "title": "Disable when no ESLint config is found (in package.json or .eslintrc)", @@ -76,23 +100,6 @@ "default": true, "order": 1 }, - "ignoreFixableRulesWhileTyping": { - "title": "Ignore fixable rules while typing", - "description": "Have the linter ignore all fixable rules during linting when editing a document. The list is automatically updated on each lint job, and requires at least one run to be populated. Only supported when using ESLint v4+.", - "type": "boolean", - "default": false, - "order": 2 - }, - "rulesToDisableWhileFixing": { - "title": "Disable specific rules from fixes", - "description": "Prevent rules from being auto-fixed by ESLint. Applies to fixes made during saves as well as when running the `Linter Eslint: Fix File` command.", - "type": "array", - "default": [], - "items": { - "type": "string" - }, - "order": 3 - }, "rulesToSilenceWhileTyping": { "title": "Silence specific rules while typing", "description": "Useful when Atom fixes errors on save like `no-trailing-spaces` or `eol-last`.", @@ -101,14 +108,15 @@ "items": { "type": "string" }, - "order": 4 + "order": 2 } } }, "advanced": { "type": "object", "collapsed": true, - "order": 7, + "title": "Uncommon", + "order": 6, "properties": { "disableEslintIgnore": { "title": "Don't use .eslintignore files", diff --git a/spec/linter-eslint-spec.js b/spec/linter-eslint-spec.js index 46540469..cecd3ae2 100644 --- a/spec/linter-eslint-spec.js +++ b/spec/linter-eslint-spec.js @@ -298,7 +298,7 @@ describe('The eslint provider for Linter', () => { }) it('should not fix linting errors for rules that are disabled with rulesToDisableWhileFixing', async () => { - atom.config.set('linter-eslint.disabling.rulesToDisableWhileFixing', ['semi']) + atom.config.set('linter-eslint.autofix.rulesToDisableWhileFixing', ['semi']) await firstLint(editor) await makeFixes(editor) @@ -383,7 +383,7 @@ describe('The eslint provider for Linter', () => { it('does nothing on saved files', async () => { atom.config.set('linter-eslint.disabling.rulesToSilenceWhileTyping', ['no-trailing-spaces']) - atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.autofix.ignoreFixableRulesWhileTyping', true) expectedPath = paths.modifiedIgnoreSpace const editor = await atom.workspace.open(expectedPath) // Run once to populate the fixable rules list @@ -433,7 +433,7 @@ describe('The eslint provider for Linter', () => { // Enable the option under test // NOTE: Depends on no-trailing-spaces being marked as fixable by ESLint - atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.autofix.ignoreFixableRulesWhileTyping', true) // Check the lint results const newMessages = await lint(editor) @@ -459,7 +459,7 @@ describe('The eslint provider for Linter', () => { // Enable the option under test // NOTE: Depends on mport/newline-after-import rule being marked as fixable - atom.config.set('linter-eslint.disabling.ignoreFixableRulesWhileTyping', true) + atom.config.set('linter-eslint.autofix.ignoreFixableRulesWhileTyping', true) // Check the lint results const newMessages = await lint(editor) diff --git a/src/main.js b/src/main.js index 899e508c..faf9e79d 100644 --- a/src/main.js +++ b/src/main.js @@ -121,7 +121,7 @@ module.exports = { this.subscriptions.add(atom.workspace.observeTextEditors((editor) => { editor.onDidSave(async () => { if (hasValidScope(editor, scopes) - && atom.config.get('linter-eslint.fixOnSave') + && atom.config.get('linter-eslint.autofix.fixOnSave') ) { await this.fixJob(true) } @@ -159,12 +159,12 @@ module.exports = { )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.disabling.rulesToDisableWhileFixing', + 'linter-eslint.autofix.rulesToDisableWhileFixing', (ids) => { ignoredRulesWhenFixing = idsToIgnoredRules(ids) } )) this.subscriptions.add(atom.config.observe( - 'linter-eslint.disabling.ignoreFixableRulesWhileTyping', + 'linter-eslint.autofix.ignoreFixableRulesWhileTyping', (value) => { ignoreFixableRulesWhileTyping = value } )) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index e042605d..96730ebd 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -7,15 +7,20 @@ const directMoveMigrations = [ old: 'linter-eslint.disableWhenNoEslintConfig', new: 'linter-eslint.disabling.disableWhenNoEslintConfig', }, + { + /* Added November, 2017 */ + old: 'linter-eslint.fixOnSave', + new: 'linter-eslint.autofix.fixOnSave' + }, { /* Added November, 2017 */ old: 'linter-eslint.ignoreFixableRulesWhileTyping', - new: 'linter-eslint.disabling.ignoreFixableRulesWhileTyping' + new: 'linter-eslint.autofix.ignoreFixableRulesWhileTyping' }, { /* Added November, 2017 */ old: 'linter-eslint.rulesToDisableWhileFixing', - new: 'linter-eslint.disabling.rulesToDisableWhileFixing' + new: 'linter-eslint.autofix.rulesToDisableWhileFixing' }, { /* Added November, 2017 */ From 398ecb9ec86d3778b029474b5e30c3bf3b0ccbee Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 22:49:05 -0500 Subject: [PATCH 13/18] Do a single `atom.config.get` --- src/migrate-config-options.js | 112 ++++++++++++++-------------------- 1 file changed, 45 insertions(+), 67 deletions(-) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index 96730ebd..b15dafa1 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -2,83 +2,61 @@ // These are cases where the old setting should be directly moved to the new setting. const directMoveMigrations = [ + /* Added January, 2018 */ { - /* Added November, 2017 */ - old: 'linter-eslint.disableWhenNoEslintConfig', - new: 'linter-eslint.disabling.disableWhenNoEslintConfig', - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.fixOnSave', - new: 'linter-eslint.autofix.fixOnSave' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.ignoreFixableRulesWhileTyping', - new: 'linter-eslint.autofix.ignoreFixableRulesWhileTyping' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.rulesToDisableWhileFixing', - new: 'linter-eslint.autofix.rulesToDisableWhileFixing' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.rulesToSilenceWhileTyping', - new: 'linter-eslint.disabling.rulesToSilenceWhileTyping' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.disableEslintIgnore', - new: 'linter-eslint.advanced.disableEslintIgnore' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.disableFSCache', - new: 'linter-eslint.advanced.disableFSCache' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.showRuleIdInMessage', - new: 'linter-eslint.advanced.showRuleIdInMessage' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.eslintrcPath', - new: 'linter-eslint.global.eslintrcPath' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.advancedLocalNodeModules', - new: 'linter-eslint.advanced.advancedLocalNodeModules' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.eslintRulesDirs', - new: 'linter-eslint.advanced.eslintRulesDirs' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.useGlobalEslint', - new: 'linter-eslint.global.useGlobalEslint' - }, - { - /* Added November, 2017 */ - old: 'linter-eslint.globalNodePath', - new: 'linter-eslint.global.globalNodePath' + old: 'disableWhenNoEslintConfig', + new: 'disabling.disableWhenNoEslintConfig', + }, { + old: 'fixOnSave', + new: 'autofix.fixOnSave' + }, { + old: 'ignoreFixableRulesWhileTyping', + new: 'autofix.ignoreFixableRulesWhileTyping' + }, { + old: 'rulesToDisableWhileFixing', + new: 'autofix.rulesToDisableWhileFixing' + }, { + old: 'rulesToSilenceWhileTyping', + new: 'disabling.rulesToSilenceWhileTyping' + }, { + old: 'disableEslintIgnore', + new: 'advanced.disableEslintIgnore' + }, { + old: 'disableFSCache', + new: 'advanced.disableFSCache' + }, { + old: 'showRuleIdInMessage', + new: 'advanced.showRuleIdInMessage' + }, { + old: 'eslintrcPath', + new: 'global.eslintrcPath' + }, { + old: 'advancedLocalNodeModules', + new: 'advanced.advancedLocalNodeModules' + }, { + old: 'eslintRulesDirs', + new: 'advanced.eslintRulesDirs' + }, { + old: 'useGlobalEslint', + new: 'global.useGlobalEslint' + }, { + old: 'globalNodePath', + new: 'global.globalNodePath' }, ] function migrateConfigOptions() { + const linterEslintConfig = atom.config.get('linter-eslint') + /** * FIXME: Deprecated eslintRulesDir{String} option in favor of * eslintRulesDirs{Array}. Remove in the next major release, * in v8.5.0, or after 2018-04. */ - const oldRulesdir = atom.config.get('linter-eslint.eslintRulesDir') + const oldRulesdir = linterEslintConfig.eslintRulesDir if (oldRulesdir) { - const rulesDirs = atom.config.get('linter-eslint.eslintRulesDirs') - if (rulesDirs.length === 0) { + const newRulesDirs = linterEslintConfig.eslintRulesDirs + if (newRulesDirs.length === 0) { atom.config.set('linter-eslint.eslintRulesDirs', [oldRulesdir]) } atom.config.unset('linter-eslint.eslintRulesDir') @@ -86,7 +64,7 @@ function migrateConfigOptions() { // Copy old settings over to the new ones, then unset the old setting keys directMoveMigrations.forEach((migration) => { - const oldSetting = atom.config.get(migration.old) + const oldSetting = linterEslintConfig[migration.old] if (oldSetting !== undefined) { atom.config.set(migration.new, oldSetting) atom.config.unset(migration.old) From fdb5de9cb058cb3eb4c6b57425c4238caaf5a148 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 23:06:03 -0500 Subject: [PATCH 14/18] Refine migration approach slightly --- src/migrate-config-options.js | 153 ++++++++++++++++++++-------------- 1 file changed, 91 insertions(+), 62 deletions(-) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index b15dafa1..e09a6d80 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -1,73 +1,102 @@ 'use babel' -// These are cases where the old setting should be directly moved to the new setting. -const directMoveMigrations = [ - /* Added January, 2018 */ +/* + * These migrations can take one of two forms, a direct move or a general function. + * + * Direct move: + * These objects have an array of `moves`, which + * are objects containing an `old` setting name and a `new` setting name. + * Any existing config found in the `old` name will be moved over to (and overwrite) + * the `new` key. + * + * Functions: + * These have a `migrate` function, which takes the + * current linter-eslint atom config as an argument, and can act on it however + * it needs to. + */ +const migrations = [ { - old: 'disableWhenNoEslintConfig', - new: 'disabling.disableWhenNoEslintConfig', - }, { - old: 'fixOnSave', - new: 'autofix.fixOnSave' - }, { - old: 'ignoreFixableRulesWhileTyping', - new: 'autofix.ignoreFixableRulesWhileTyping' - }, { - old: 'rulesToDisableWhileFixing', - new: 'autofix.rulesToDisableWhileFixing' - }, { - old: 'rulesToSilenceWhileTyping', - new: 'disabling.rulesToSilenceWhileTyping' - }, { - old: 'disableEslintIgnore', - new: 'advanced.disableEslintIgnore' - }, { - old: 'disableFSCache', - new: 'advanced.disableFSCache' - }, { - old: 'showRuleIdInMessage', - new: 'advanced.showRuleIdInMessage' - }, { - old: 'eslintrcPath', - new: 'global.eslintrcPath' - }, { - old: 'advancedLocalNodeModules', - new: 'advanced.advancedLocalNodeModules' - }, { - old: 'eslintRulesDirs', - new: 'advanced.eslintRulesDirs' - }, { - old: 'useGlobalEslint', - new: 'global.useGlobalEslint' - }, { - old: 'globalNodePath', - new: 'global.globalNodePath' + added: 'January, 2018', + description: 'Organized config settings into sections', + moves: [ + { + old: 'disableWhenNoEslintConfig', + new: 'disabling.disableWhenNoEslintConfig', + }, { + old: 'fixOnSave', + new: 'autofix.fixOnSave' + }, { + old: 'ignoreFixableRulesWhileTyping', + new: 'autofix.ignoreFixableRulesWhileTyping' + }, { + old: 'rulesToDisableWhileFixing', + new: 'autofix.rulesToDisableWhileFixing' + }, { + old: 'rulesToSilenceWhileTyping', + new: 'disabling.rulesToSilenceWhileTyping' + }, { + old: 'disableEslintIgnore', + new: 'advanced.disableEslintIgnore' + }, { + old: 'disableFSCache', + new: 'advanced.disableFSCache' + }, { + old: 'showRuleIdInMessage', + new: 'advanced.showRuleIdInMessage' + }, { + old: 'eslintrcPath', + new: 'global.eslintrcPath' + }, { + old: 'advancedLocalNodeModules', + new: 'advanced.advancedLocalNodeModules' + }, { + old: 'eslintRulesDirs', + new: 'advanced.eslintRulesDirs' + }, { + old: 'useGlobalEslint', + new: 'global.useGlobalEslint' + }, { + old: 'globalNodePath', + new: 'global.globalNodePath' + } + ] }, + { + added: 'September, 2017', + description: 'Deprecated eslintRulesDir{String} option in favor of eslintRulesDirs{Array}', + migrate(config) { + const oldRulesdir = config.eslintRulesDir + if (oldRulesdir) { + const newRulesDirs = config.eslintRulesDirs + if (newRulesDirs.length === 0) { + atom.config.set('linter-eslint.eslintRulesDirs', [oldRulesdir]) + } + atom.config.unset('linter-eslint.eslintRulesDir') + } + } + } ] +/* + * This function can be called when linter-eslint first activates in order to + * ensure that the user's settings are up-to-date with the current version of + * linter-eslint. Ideally, we would call this only when upgrading to a new + * version. + */ function migrateConfigOptions() { const linterEslintConfig = atom.config.get('linter-eslint') - - /** - * FIXME: Deprecated eslintRulesDir{String} option in favor of - * eslintRulesDirs{Array}. Remove in the next major release, - * in v8.5.0, or after 2018-04. - */ - const oldRulesdir = linterEslintConfig.eslintRulesDir - if (oldRulesdir) { - const newRulesDirs = linterEslintConfig.eslintRulesDirs - if (newRulesDirs.length === 0) { - atom.config.set('linter-eslint.eslintRulesDirs', [oldRulesdir]) - } - atom.config.unset('linter-eslint.eslintRulesDir') - } - - // Copy old settings over to the new ones, then unset the old setting keys - directMoveMigrations.forEach((migration) => { - const oldSetting = linterEslintConfig[migration.old] - if (oldSetting !== undefined) { - atom.config.set(migration.new, oldSetting) - atom.config.unset(migration.old) + migrations.forEach((migration) => { + if (migration.moves && Array.isArray(migration.moves)) { + // Copy old settings over to the new ones, then unset the old setting keys + migration.moves.forEach((move) => { + const oldSetting = linterEslintConfig[move.old] + if (oldSetting !== undefined) { + atom.config.set(move.new, oldSetting) + atom.config.unset(move.old) + } + }) + } else if (typeof migration.migrate === 'function') { + migration.migrate(linterEslintConfig) } }) } From 554ca6521ff0ad9b834123196ebbe3a4bfda2bae Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sat, 27 Jan 2018 23:24:28 -0500 Subject: [PATCH 15/18] Avoid object rest spread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (we don’t have babel configured for it) --- spec/worker-helpers-spec.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/spec/worker-helpers-spec.js b/spec/worker-helpers-spec.js index 85cd61b0..d1869a81 100644 --- a/spec/worker-helpers-spec.js +++ b/spec/worker-helpers-spec.js @@ -13,12 +13,14 @@ const globalNodePath = process.platform === 'win32' ? getFixturesPath('global-eslint') function createConfig(overrides = {}) { - return { - ...overrides, - global: { ...overrides.global }, - disabling: { ...overrides.disabling }, - advanced: { ...overrides.advanced }, - } + return Object.assign( + {}, + overrides, + { global: Object.assign({}, overrides.global) }, + { autofix: Object.assign({}, overrides.autofix) }, + { disabling: Object.assign({}, overrides.disabling) }, + { advanced: Object.assign({}, overrides.advanced) }, + ) } describe('Worker Helpers', () => { From 49b695c0536f5a5393db301f072a898930555baf Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 11 Feb 2018 21:31:32 -0500 Subject: [PATCH 16/18] Rename advancedLocalNodeModules to localNodeModules Since it has a prefix of `advanced` now anyways. --- package.json | 2 +- spec/worker-helpers-spec.js | 4 ++-- src/migrate-config-options.js | 2 +- src/worker-helpers.js | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 8631efba..9020a540 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ }, "order": 4 }, - "advancedLocalNodeModules": { + "localNodeModules": { "title": "Path to the local node_modules folder", "description": "Optionally specify the path to the local node_modules folder", "type": "string", diff --git a/spec/worker-helpers-spec.js b/spec/worker-helpers-spec.js index d1869a81..84943d3a 100644 --- a/spec/worker-helpers-spec.js +++ b/spec/worker-helpers-spec.js @@ -79,7 +79,7 @@ describe('Worker Helpers', () => { const path = Path.join(getFixturesPath('indirect-local-eslint'), pathPart) const config = createConfig({ global: { useGlobalEslint: false }, - advanced: { advancedLocalNodeModules: path } + advanced: { localNodeModules: path } }) const eslint = Helpers.getESLintInstance('', config) expect(eslint).toBe('located') @@ -90,7 +90,7 @@ describe('Worker Helpers', () => { const [projectPath, relativePath] = atom.project.relativizePath(path) const config = createConfig({ global: { useGlobalEslint: false }, - advanced: { advancedLocalNodeModules: relativePath } + advanced: { localNodeModules: relativePath } }) const eslint = Helpers.getESLintInstance('', config, projectPath) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index e09a6d80..5a9f8178 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -48,7 +48,7 @@ const migrations = [ new: 'global.eslintrcPath' }, { old: 'advancedLocalNodeModules', - new: 'advanced.advancedLocalNodeModules' + new: 'advanced.localNodeModules' }, { old: 'eslintRulesDirs', new: 'advanced.eslintRulesDirs' diff --git a/src/worker-helpers.js b/src/worker-helpers.js index 5b275567..ba6492f2 100644 --- a/src/worker-helpers.js +++ b/src/worker-helpers.js @@ -61,15 +61,15 @@ export function findESLintDirectory(modulesDir, config, projectPath) { // NPM on platforms other than Windows eslintDir = Path.join(prefixPath, 'lib', 'node_modules', 'eslint') } - } else if (!config.advanced.advancedLocalNodeModules) { + } else if (!config.advanced.localNodeModules) { locationType = 'local project' eslintDir = Path.join(modulesDir || '', 'eslint') - } else if (Path.isAbsolute(cleanPath(config.advanced.advancedLocalNodeModules))) { + } else if (Path.isAbsolute(cleanPath(config.advanced.localNodeModules))) { locationType = 'advanced specified' - eslintDir = Path.join(cleanPath(config.advanced.advancedLocalNodeModules), 'eslint') + eslintDir = Path.join(cleanPath(config.advanced.localNodeModules), 'eslint') } else { locationType = 'advanced specified' - eslintDir = Path.join(projectPath || '', cleanPath(config.advanced.advancedLocalNodeModules), 'eslint') + eslintDir = Path.join(projectPath || '', cleanPath(config.advanced.localNodeModules), 'eslint') } if (isDirectory(eslintDir)) { return { From 4aa80d7dd13acd32a55150d7b744cc11f52229b2 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 11 Feb 2018 21:31:57 -0500 Subject: [PATCH 17/18] =?UTF-8?q?Make=20=E2=80=9Ccalled=E2=80=9D=20method?= =?UTF-8?q?=20of=20spy=20return=20a=20boolean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I believe this is what was intended originally. --- spec/make-spy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/make-spy.js b/spec/make-spy.js index d195cfc0..fd2fb41a 100644 --- a/spec/make-spy.js +++ b/spec/make-spy.js @@ -17,6 +17,6 @@ export default (returnValue) => { return { call, calledWith, - called: () => calledWith.length + called: () => Boolean(calledWith.length) } } From ccb881ee9fbddaebdc1fbe8e9e1604cbf96855b2 Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Sun, 11 Feb 2018 21:32:22 -0500 Subject: [PATCH 18/18] Fix migrate-config-options and add specs --- spec/migrate-config-options-spec.js | 37 +++++++++++++++++++++++++++++ src/migrate-config-options.js | 36 +++++++++++++++------------- 2 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 spec/migrate-config-options-spec.js diff --git a/spec/migrate-config-options-spec.js b/spec/migrate-config-options-spec.js new file mode 100644 index 00000000..12fed26f --- /dev/null +++ b/spec/migrate-config-options-spec.js @@ -0,0 +1,37 @@ +'use babel' + +import migrateConfigOptions from '../src/migrate-config-options' +import makeSpy from './make-spy' + +describe('migrateConfigOptions()', () => { + it('calls the migrate functions of objects in a proided migrations array', () => { + const migrateSpy = makeSpy() + const migrations = [{ migrate: migrateSpy.call }] + migrateConfigOptions(migrations) + expect(migrateSpy.called()).toEqual(true) + }) + + it('provides the linter-eslint config to migrate functions', () => { + atom.config.set('linter-eslint.oldSetting', true) + const migrateSpy = makeSpy() + const migrations = [{ migrate: migrateSpy.call }] + migrateConfigOptions(migrations) + expect(migrateSpy.calledWith[0][0]).toEqual(atom.config.get('linter-eslint')) + }) + + it('moves configs using `moves` array in a provided migrations array', () => { + atom.config.set('linter-eslint.oldSetting', true) + const migrations = [{ + moves: [{ + old: 'oldSetting', + new: 'newSetting', + }], + }] + migrateConfigOptions(migrations) + const oldSetting = atom.config.get('linter-eslint.oldSetting') + const newSetting = atom.config.get('linter-eslint.newSetting') + console.log({ oldSetting, newSetting }) + expect(oldSetting).toEqual(undefined) + expect(newSetting).toEqual(true) + }) +}) diff --git a/src/migrate-config-options.js b/src/migrate-config-options.js index 5a9f8178..b2591ad0 100644 --- a/src/migrate-config-options.js +++ b/src/migrate-config-options.js @@ -14,7 +14,7 @@ * current linter-eslint atom config as an argument, and can act on it however * it needs to. */ -const migrations = [ +const activeMigrations = [ { added: 'January, 2018', description: 'Organized config settings into sections', @@ -83,22 +83,24 @@ const migrations = [ * linter-eslint. Ideally, we would call this only when upgrading to a new * version. */ -function migrateConfigOptions() { - const linterEslintConfig = atom.config.get('linter-eslint') - migrations.forEach((migration) => { - if (migration.moves && Array.isArray(migration.moves)) { - // Copy old settings over to the new ones, then unset the old setting keys - migration.moves.forEach((move) => { - const oldSetting = linterEslintConfig[move.old] - if (oldSetting !== undefined) { - atom.config.set(move.new, oldSetting) - atom.config.unset(move.old) - } - }) - } else if (typeof migration.migrate === 'function') { - migration.migrate(linterEslintConfig) - } - }) +function migrateConfigOptions(migrations = activeMigrations) { + if (migrations.length) { + const linterEslintConfig = atom.config.get('linter-eslint') + migrations.forEach((migration) => { + if (migration.moves && Array.isArray(migration.moves)) { + // Copy old settings over to the new ones, then unset the old setting keys + migration.moves.forEach((move) => { + const oldSetting = linterEslintConfig[move.old] + if (oldSetting !== undefined) { + atom.config.set(`linter-eslint.${move.new}`, oldSetting) + atom.config.unset(`linter-eslint.${move.old}`) + } + }) + } else if (typeof migration.migrate === 'function') { + migration.migrate(linterEslintConfig) + } + }) + } } module.exports = migrateConfigOptions