From d9b97308534cd0f57a069da64d42c03ed7b1a707 Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Sat, 27 Aug 2016 15:12:45 -0400 Subject: [PATCH 1/7] Allow regular expressions for rule no-extraneous-dependencies. --- src/rules/no-extraneous-dependencies.js | 21 ++++++++++---- tests/src/rules/no-extraneous-dependencies.js | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index 059307e043..00ef6e5735 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -71,8 +71,17 @@ function reportIfMissing(context, deps, depsOptions, node, name) { context.report(node, missingErrorMessage(packageName)) } +function testConfig(config, filename) { + if (typeof config === 'boolean' || typeof config === 'undefined') { + return config + } + const pattern = new RegExp(config) // `config` is either a string or RegExp + return pattern.test(filename) +} + module.exports = function (context) { const options = context.options[0] || {} + const filename = context.getFilename() const deps = getDependencies(context) if (!deps) { @@ -80,9 +89,9 @@ module.exports = function (context) { } const depsOptions = { - allowDevDeps: options.devDependencies !== false, - allowOptDeps: options.optionalDependencies !== false, - allowPeerDeps: options.peerDependencies !== false, + allowDevDeps: testConfig(options.devDependencies, filename) !== false, + allowOptDeps: testConfig(options.optionalDependencies, filename) !== false, + allowPeerDeps: testConfig(options.peerDependencies, filename) !== false, } // todo: use module visitor from module-utils core @@ -102,9 +111,9 @@ module.exports.schema = [ { 'type': 'object', 'properties': { - 'devDependencies': { 'type': 'boolean' }, - 'optionalDependencies': { 'type': 'boolean' }, - 'peerDependencies': { 'type': 'boolean' }, + 'devDependencies': { 'type': ['boolean', 'string', 'object'] }, + 'optionalDependencies': { 'type': ['boolean', 'string', 'object'] }, + 'peerDependencies': { 'type': ['boolean', 'string', 'object'] }, }, 'additionalProperties': false, }, diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index f0b43b09be..d874b649e2 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -35,6 +35,16 @@ ruleTester.run('no-extraneous-dependencies', rule, { code: 'import "importType"', settings: { 'import/resolver': { node: { paths: [ path.join(__dirname, '../../files') ] } } }, }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: /test|spec/}], + filename: 'glob.test.js', + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: 'test|spec'}], + filename: 'glob.spec.js', + }), ], invalid: [ test({ @@ -89,6 +99,24 @@ ruleTester.run('no-extraneous-dependencies', rule, { message: '\'glob\' should be listed in the project\'s dependencies, not devDependencies.', }], }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: /test|spec/}], + filename: 'foo.tes.js', + errors: [{ + ruleId: 'no-extraneous-dependencies', + message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', + }], + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: 'test|spec'}], + filename: 'foo.tes.js', + errors: [{ + ruleId: 'no-extraneous-dependencies', + message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', + }], + }), test({ code: 'var eslint = require("lodash.isarray")', options: [{optionalDependencies: false}], From c739798b547689769a26c57ecfa21781d2ab4389 Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Sat, 27 Aug 2016 19:58:47 -0400 Subject: [PATCH 2/7] Add RegExp documentation for no-extraneous-dependencies. --- docs/rules/no-extraneous-dependencies.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 7f57d97068..b73bf0797f 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -19,6 +19,19 @@ You can set the options like this: "import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}] ``` +You can also use regular expressions instead of literal booleans: + +```js +"import/no-extraneous-dependencies": ["error", {"devDependencies": "test|spec"}] +``` + +If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can use a RegExp literal instead of a string: + +```js +"import/no-extraneous-dependencies": ["error", {"devDependencies": /test|spec/}] +``` + +When using a regular expression the result of running [`test`] against the name of the file being linted is used as the boolean value. For example, the above configurations will allow the import of `devDependencies` in files whose names include `test` or `spec`. ## Rule Details @@ -86,3 +99,5 @@ import react from 'react'; ## When Not To Use It If you do not have a `package.json` file in your project. + +[`test`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test "RegExp.prototype.test" From 1be47202268cfc786e89fd0161ab01ab51e693ba Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Sun, 28 Aug 2016 18:10:42 -0400 Subject: [PATCH 3/7] Update doc due to review. --- docs/rules/no-extraneous-dependencies.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index b73bf0797f..1b7f94bacb 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -31,7 +31,7 @@ If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can u "import/no-extraneous-dependencies": ["error", {"devDependencies": /test|spec/}] ``` -When using a regular expression the result of running [`test`] against the name of the file being linted is used as the boolean value. For example, the above configurations will allow the import of `devDependencies` in files whose names include `test` or `spec`. +When using a regular expression, the setting will be activated if the name of the file being linted matches the given regular expression. For example, the above configurations will allow the import of `devDependencies` in files whose names include `test` or `spec`. ## Rule Details @@ -99,5 +99,3 @@ import react from 'react'; ## When Not To Use It If you do not have a `package.json` file in your project. - -[`test`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test "RegExp.prototype.test" From 8ff322d5865226af79052be15580582c23a2113a Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Sun, 28 Aug 2016 19:25:24 -0400 Subject: [PATCH 4/7] Extend no-extraneous-dependencies to support globs and arrays. --- docs/rules/no-extraneous-dependencies.md | 18 ++++++-- package.json | 1 + src/rules/no-extraneous-dependencies.js | 25 ++++++++--- tests/src/rules/no-extraneous-dependencies.js | 41 +++++++++++++++++-- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 1b7f94bacb..a51ef7324c 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -19,10 +19,16 @@ You can set the options like this: "import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}] ``` -You can also use regular expressions instead of literal booleans: +You can also use globs instead of literal booleans: ```js -"import/no-extraneous-dependencies": ["error", {"devDependencies": "test|spec"}] +"import/no-extraneous-dependencies": ["error", {"devDependencies": "*.test.js"}] +``` + +You can also use regular expressions instead of literal booleans or globs (note: the string must begin and end with `/`): + +```js +"import/no-extraneous-dependencies": ["error", {"devDependencies": "/test|spec/"}] ``` If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can use a RegExp literal instead of a string: @@ -31,7 +37,13 @@ If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can u "import/no-extraneous-dependencies": ["error", {"devDependencies": /test|spec/}] ``` -When using a regular expression, the setting will be activated if the name of the file being linted matches the given regular expression. For example, the above configurations will allow the import of `devDependencies` in files whose names include `test` or `spec`. +When using a glob or regular expression, the setting will be activated if the name of the file being linted matches the given glob or regular expression. In addition, you can use an array to specify multiple globs or regular expressions: + +```js +"import/no-extraneous-dependencies": ["error", {"devDependencies": [/test/, '/spec/', '*.test.js', '*.spec.js']}] +``` + +When using an array of globs or regular expressions, the setting will be activated if the name of the file being linted matches a single glob or regular expression in the array. ## Rule Details diff --git a/package.json b/package.json index cd646efa4e..c9da183abf 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "lodash.endswith": "^4.0.1", "lodash.find": "^4.3.0", "lodash.findindex": "^4.3.0", + "minimatch": "^3.0.3", "object-assign": "^4.0.1", "pkg-dir": "^1.0.0", "pkg-up": "^1.0.0" diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index 00ef6e5735..daa08fa0a5 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -1,5 +1,6 @@ import fs from 'fs' import pkgUp from 'pkg-up' +import minimatch from 'minimatch' import importType from '../core/importType' import isStaticRequire from '../core/staticRequire' @@ -72,11 +73,25 @@ function reportIfMissing(context, deps, depsOptions, node, name) { } function testConfig(config, filename) { + // Simplest configuration first if (typeof config === 'boolean' || typeof config === 'undefined') { return config } - const pattern = new RegExp(config) // `config` is either a string or RegExp - return pattern.test(filename) + // Account for the possibility of an array for multiple configuration + return [].concat(config).some(c => { + if (typeof c === 'object') { + // `c` is a literal RegExp + return c.test(filename) + } + // By this point `c` must be a string. + if (/^\/.+\/$/.test(c)) { + // `c` is a string representation of a RegExp. + const pattern = new RegExp(c.substring(1, c.length - 1)) + return pattern.test(filename) + } + // `c` must be a string representing a glob + return minimatch(filename, c) + }) } module.exports = function (context) { @@ -111,9 +126,9 @@ module.exports.schema = [ { 'type': 'object', 'properties': { - 'devDependencies': { 'type': ['boolean', 'string', 'object'] }, - 'optionalDependencies': { 'type': ['boolean', 'string', 'object'] }, - 'peerDependencies': { 'type': ['boolean', 'string', 'object'] }, + 'devDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, + 'optionalDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, + 'peerDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, }, 'additionalProperties': false, }, diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index d874b649e2..7d370539dc 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -38,12 +38,27 @@ ruleTester.run('no-extraneous-dependencies', rule, { test({ code: 'import chai from "chai"', options: [{devDependencies: /test|spec/}], - filename: 'glob.test.js', + filename: 'foo.test.js', }), test({ code: 'import chai from "chai"', - options: [{devDependencies: 'test|spec'}], - filename: 'glob.spec.js', + options: [{devDependencies: '/test|spec/'}], + filename: 'foo.spec.js', + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: '*.spec.js'}], + filename: 'foo.spec.js', + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: ['*.test.js', '*.spec.js']}], + filename: 'foo.spec.js', + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: [/\.test\.js$/, /\.spec\.js$/]}], + filename: 'foo.spec.js', }), ], invalid: [ @@ -110,7 +125,25 @@ ruleTester.run('no-extraneous-dependencies', rule, { }), test({ code: 'import chai from "chai"', - options: [{devDependencies: 'test|spec'}], + options: [{devDependencies: '/test|spec/'}], + filename: 'foo.tes.js', + errors: [{ + ruleId: 'no-extraneous-dependencies', + message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', + }], + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: '*.test.js'}], + filename: 'foo.tes.js', + errors: [{ + ruleId: 'no-extraneous-dependencies', + message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', + }], + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: ['*.test.js', /test\.js$/, '/test/']}], filename: 'foo.tes.js', errors: [{ ruleId: 'no-extraneous-dependencies', From 8d16c0895e2580ce6c12b34066a13fca0fdee636 Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Mon, 29 Aug 2016 19:45:20 -0400 Subject: [PATCH 5/7] Remove regular expression support from no-extraneous-dependencies. --- docs/rules/no-extraneous-dependencies.md | 18 ++-------- src/rules/no-extraneous-dependencies.js | 21 +++-------- tests/src/rules/no-extraneous-dependencies.js | 35 +------------------ 3 files changed, 8 insertions(+), 66 deletions(-) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index a51ef7324c..2a5fca86e4 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -25,25 +25,13 @@ You can also use globs instead of literal booleans: "import/no-extraneous-dependencies": ["error", {"devDependencies": "*.test.js"}] ``` -You can also use regular expressions instead of literal booleans or globs (note: the string must begin and end with `/`): +When using a glob, the setting will be activated if the name of the file being linted matches the given glob. In addition, you can use an array to specify multiple globs: ```js -"import/no-extraneous-dependencies": ["error", {"devDependencies": "/test|spec/"}] +"import/no-extraneous-dependencies": ["error", {"devDependencies": ['*.test.js', '*.spec.js']}] ``` -If you are using JavaScript configuration (e.g., `.eslintrc.js`), then you can use a RegExp literal instead of a string: - -```js -"import/no-extraneous-dependencies": ["error", {"devDependencies": /test|spec/}] -``` - -When using a glob or regular expression, the setting will be activated if the name of the file being linted matches the given glob or regular expression. In addition, you can use an array to specify multiple globs or regular expressions: - -```js -"import/no-extraneous-dependencies": ["error", {"devDependencies": [/test/, '/spec/', '*.test.js', '*.spec.js']}] -``` - -When using an array of globs or regular expressions, the setting will be activated if the name of the file being linted matches a single glob or regular expression in the array. +When using an array of globs, the setting will be activated if the name of the file being linted matches a single glob in the array. ## Rule Details diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index daa08fa0a5..e128c10609 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -78,20 +78,7 @@ function testConfig(config, filename) { return config } // Account for the possibility of an array for multiple configuration - return [].concat(config).some(c => { - if (typeof c === 'object') { - // `c` is a literal RegExp - return c.test(filename) - } - // By this point `c` must be a string. - if (/^\/.+\/$/.test(c)) { - // `c` is a string representation of a RegExp. - const pattern = new RegExp(c.substring(1, c.length - 1)) - return pattern.test(filename) - } - // `c` must be a string representing a glob - return minimatch(filename, c) - }) + return [].concat(config).some(c => minimatch(filename, c)) } module.exports = function (context) { @@ -126,9 +113,9 @@ module.exports.schema = [ { 'type': 'object', 'properties': { - 'devDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, - 'optionalDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, - 'peerDependencies': { 'type': ['boolean', 'string', 'object', 'array'] }, + 'devDependencies': { 'type': ['boolean', 'string', 'array'] }, + 'optionalDependencies': { 'type': ['boolean', 'string', 'array'] }, + 'peerDependencies': { 'type': ['boolean', 'string', 'array'] }, }, 'additionalProperties': false, }, diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index 7d370539dc..a66a0325e1 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -35,16 +35,6 @@ ruleTester.run('no-extraneous-dependencies', rule, { code: 'import "importType"', settings: { 'import/resolver': { node: { paths: [ path.join(__dirname, '../../files') ] } } }, }), - test({ - code: 'import chai from "chai"', - options: [{devDependencies: /test|spec/}], - filename: 'foo.test.js', - }), - test({ - code: 'import chai from "chai"', - options: [{devDependencies: '/test|spec/'}], - filename: 'foo.spec.js', - }), test({ code: 'import chai from "chai"', options: [{devDependencies: '*.spec.js'}], @@ -55,11 +45,6 @@ ruleTester.run('no-extraneous-dependencies', rule, { options: [{devDependencies: ['*.test.js', '*.spec.js']}], filename: 'foo.spec.js', }), - test({ - code: 'import chai from "chai"', - options: [{devDependencies: [/\.test\.js$/, /\.spec\.js$/]}], - filename: 'foo.spec.js', - }), ], invalid: [ test({ @@ -114,24 +99,6 @@ ruleTester.run('no-extraneous-dependencies', rule, { message: '\'glob\' should be listed in the project\'s dependencies, not devDependencies.', }], }), - test({ - code: 'import chai from "chai"', - options: [{devDependencies: /test|spec/}], - filename: 'foo.tes.js', - errors: [{ - ruleId: 'no-extraneous-dependencies', - message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', - }], - }), - test({ - code: 'import chai from "chai"', - options: [{devDependencies: '/test|spec/'}], - filename: 'foo.tes.js', - errors: [{ - ruleId: 'no-extraneous-dependencies', - message: '\'chai\' should be listed in the project\'s dependencies, not devDependencies.', - }], - }), test({ code: 'import chai from "chai"', options: [{devDependencies: '*.test.js'}], @@ -143,7 +110,7 @@ ruleTester.run('no-extraneous-dependencies', rule, { }), test({ code: 'import chai from "chai"', - options: [{devDependencies: ['*.test.js', /test\.js$/, '/test/']}], + options: [{devDependencies: ['*.test.js', '*.spec.js']}], filename: 'foo.tes.js', errors: [{ ruleId: 'no-extraneous-dependencies', From 505aea8fce2a9cc4219fdbd300beeca3173634cb Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Tue, 30 Aug 2016 12:25:48 -0400 Subject: [PATCH 6/7] Only support arrays of globs. --- docs/rules/no-extraneous-dependencies.md | 8 +------- src/rules/no-extraneous-dependencies.js | 8 ++++---- tests/src/rules/no-extraneous-dependencies.js | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 2a5fca86e4..a157345895 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -19,13 +19,7 @@ You can set the options like this: "import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}] ``` -You can also use globs instead of literal booleans: - -```js -"import/no-extraneous-dependencies": ["error", {"devDependencies": "*.test.js"}] -``` - -When using a glob, the setting will be activated if the name of the file being linted matches the given glob. In addition, you can use an array to specify multiple globs: +You can also use an array of globs instead of literal booleans: ```js "import/no-extraneous-dependencies": ["error", {"devDependencies": ['*.test.js', '*.spec.js']}] diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index e128c10609..0b1f3b4fda 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -78,7 +78,7 @@ function testConfig(config, filename) { return config } // Account for the possibility of an array for multiple configuration - return [].concat(config).some(c => minimatch(filename, c)) + return config.some(c => minimatch(filename, c)) } module.exports = function (context) { @@ -113,9 +113,9 @@ module.exports.schema = [ { 'type': 'object', 'properties': { - 'devDependencies': { 'type': ['boolean', 'string', 'array'] }, - 'optionalDependencies': { 'type': ['boolean', 'string', 'array'] }, - 'peerDependencies': { 'type': ['boolean', 'string', 'array'] }, + 'devDependencies': { 'type': ['boolean', 'array'] }, + 'optionalDependencies': { 'type': ['boolean', 'array'] }, + 'peerDependencies': { 'type': ['boolean', 'array'] }, }, 'additionalProperties': false, }, diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index a66a0325e1..4d739ee714 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -37,7 +37,7 @@ ruleTester.run('no-extraneous-dependencies', rule, { }), test({ code: 'import chai from "chai"', - options: [{devDependencies: '*.spec.js'}], + options: [{devDependencies: ['*.spec.js']}], filename: 'foo.spec.js', }), test({ @@ -101,7 +101,7 @@ ruleTester.run('no-extraneous-dependencies', rule, { }), test({ code: 'import chai from "chai"', - options: [{devDependencies: '*.test.js'}], + options: [{devDependencies: ['*.test.js']}], filename: 'foo.tes.js', errors: [{ ruleId: 'no-extraneous-dependencies', From 2b9b500ca9253c53cb727f46cd3201e34dc1d10b Mon Sep 17 00:00:00 2001 From: Kenneth Powers Date: Tue, 30 Aug 2016 12:47:43 -0400 Subject: [PATCH 7/7] Update comments for no-extraneous-dependencies configuration. --- src/rules/no-extraneous-dependencies.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index 0b1f3b4fda..65bdb27e56 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -73,11 +73,11 @@ function reportIfMissing(context, deps, depsOptions, node, name) { } function testConfig(config, filename) { - // Simplest configuration first + // Simplest configuration first, either a boolean or nothing. if (typeof config === 'boolean' || typeof config === 'undefined') { return config } - // Account for the possibility of an array for multiple configuration + // Array of globs. return config.some(c => minimatch(filename, c)) }