diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 7f57d9706..a15734589 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -19,6 +19,13 @@ You can set the options like this: "import/no-extraneous-dependencies": ["error", {"devDependencies": false, "optionalDependencies": false, "peerDependencies": false}] ``` +You can also use an array of globs instead of literal booleans: + +```js +"import/no-extraneous-dependencies": ["error", {"devDependencies": ['*.test.js', '*.spec.js']}] +``` + +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/package.json b/package.json index cd646efa4..c9da183ab 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 059307e04..65bdb27e5 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' @@ -71,8 +72,18 @@ function reportIfMissing(context, deps, depsOptions, node, name) { context.report(node, missingErrorMessage(packageName)) } +function testConfig(config, filename) { + // Simplest configuration first, either a boolean or nothing. + if (typeof config === 'boolean' || typeof config === 'undefined') { + return config + } + // Array of globs. + return config.some(c => minimatch(filename, c)) +} + module.exports = function (context) { const options = context.options[0] || {} + const filename = context.getFilename() const deps = getDependencies(context) if (!deps) { @@ -80,9 +91,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 +113,9 @@ module.exports.schema = [ { 'type': 'object', 'properties': { - 'devDependencies': { 'type': 'boolean' }, - 'optionalDependencies': { 'type': 'boolean' }, - 'peerDependencies': { 'type': 'boolean' }, + '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 f0b43b09b..4d739ee71 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: ['*.spec.js']}], + filename: 'foo.spec.js', + }), + test({ + code: 'import chai from "chai"', + options: [{devDependencies: ['*.test.js', '*.spec.js']}], + filename: 'foo.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.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', '*.spec.js']}], + 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}],