From b3c9ea7161bd94b77f3ca25b9a51d9d9c402741b Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 2 Jun 2019 15:05:17 +0200 Subject: [PATCH] Allow ESLint rules to override extensions and glob patterns --- eslint-plugin-helper.js | 33 ++++-- test/eslint-plugin-helper.js | 104 +++++++++++++++++- .../eslint-plugin-helper/ava.config.js | 4 +- .../for-overriding/ava.config.js | 8 ++ .../for-overriding/package.json | 1 + 5 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 test/fixture/eslint-plugin-helper/for-overriding/ava.config.js create mode 100644 test/fixture/eslint-plugin-helper/for-overriding/package.json diff --git a/eslint-plugin-helper.js b/eslint-plugin-helper.js index 3766ed2f3..513cdd383 100644 --- a/eslint-plugin-helper.js +++ b/eslint-plugin-helper.js @@ -4,15 +4,34 @@ const normalizeExtensions = require('./lib/extensions'); const {hasExtension, normalizeGlobs, classify} = require('./lib/globs'); const loadConfig = require('./lib/load-config'); -const cache = new Map(); +const configCache = new Map(); +const helperCache = new Map(); -function load(projectDir) { - if (cache.has(projectDir)) { - return cache.get(projectDir); +function load(projectDir, overrides) { + const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`; + if (helperCache.has(cacheKey)) { + return helperCache.get(cacheKey); + } + + let conf; + let babelConfig; + if (configCache.has(projectDir)) { + ({conf, babelConfig} = configCache.get(projectDir)); + } else { + conf = loadConfig(projectDir); + babelConfig = babelPipeline.validate(conf.babel); + configCache.set(projectDir, {conf, babelConfig}); + } + + if (overrides) { + conf = {...conf, ...overrides}; + if (overrides.extensions) { + // Ignore extensions from the Babel config. Assume all extensions are + // provided in the override. + babelConfig = null; + } } - const conf = loadConfig(projectDir); - const babelConfig = babelPipeline.validate(conf.babel); const extensions = normalizeExtensions(conf.extensions || [], babelConfig); const globs = {cwd: projectDir, ...normalizeGlobs(conf.files, conf.helpers, conf.sources, extensions.all)}; @@ -30,7 +49,7 @@ function load(projectDir) { return classify(`${importPath}.${globs.extensions[0]}`, globs); } }); - cache.set(projectDir, helper); + helperCache.set(cacheKey, helper); return helper; } diff --git a/test/eslint-plugin-helper.js b/test/eslint-plugin-helper.js index 343e403e7..6e7778c5c 100644 --- a/test/eslint-plugin-helper.js +++ b/test/eslint-plugin-helper.js @@ -5,11 +5,16 @@ const {test} = require('tap'); const {load} = require('../eslint-plugin-helper'); const projectDir = path.join(__dirname, 'fixture/eslint-plugin-helper'); +const overrideDir = path.join(__dirname, 'fixture/eslint-plugin-helper/for-overriding'); test('caches loaded configuration', t => { const expected = load(projectDir); - const actual = load(projectDir); - t.is(expected, actual); + t.is(expected, load(projectDir)); + + const withOverride = load(projectDir, {}); + t.not(expected, withOverride); + t.is(withOverride, load(projectDir, {})); + t.end(); }); @@ -43,6 +48,41 @@ test('classifies files according to the configuration', t => { t.end(); }); +test('classifies files according to configuration override', t => { + const helper = load(overrideDir, { + extensions: ['foo'], + files: ['tests/**/*'], + helpers: ['helpers/*'], + sources: ['source.*'] + }); + t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/test.foo')), { + isHelper: false, + isSource: false, + isTest: true + }); + t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/_helper.foo')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyFile(path.join(overrideDir, 'helpers/helper.foo')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyFile(path.join(overrideDir, 'source.foo')), { + isHelper: false, + isSource: true, + isTest: false + }); + t.deepEqual(helper.classifyFile(path.join(overrideDir, 'tests/test.js')), { + isHelper: false, + isSource: false, + isTest: false + }); + t.end(); +}); + test('classifies imports with extension according to the configuration', t => { const helper = load(projectDir); t.deepEqual(helper.classifyImport(path.join(projectDir, 'tests/test.foo')), { @@ -68,6 +108,36 @@ test('classifies imports with extension according to the configuration', t => { t.end(); }); +test('classifies imports with extension according to the override', t => { + const helper = load(overrideDir, { + extensions: ['foo'], + files: ['tests/**/*'], + helpers: ['helpers/*'], + sources: ['source.*'] + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/test.foo')), { + isHelper: false, + isSource: false, + isTest: true + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/_helper.foo')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'helpers/helper.foo')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'source.foo')), { + isHelper: false, + isSource: true, + isTest: false + }); + t.end(); +}); + test('classifies imports without extension according to the configuration', t => { const helper = load(projectDir); t.deepEqual(helper.classifyImport(path.join(projectDir, 'tests/test')), { @@ -92,3 +162,33 @@ test('classifies imports without extension according to the configuration', t => }); t.end(); }); + +test('classifies imports without extension according to the override', t => { + const helper = load(overrideDir, { + extensions: ['foo'], + files: ['tests/**/*'], + helpers: ['helpers/*'], + sources: ['source.*'] + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/test')), { + isHelper: false, + isSource: false, + isTest: true + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'tests/_helper')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'helpers/helper')), { + isHelper: true, + isSource: false, + isTest: false + }); + t.deepEqual(helper.classifyImport(path.join(overrideDir, 'source')), { + isHelper: false, + isSource: true, + isTest: false + }); + t.end(); +}); diff --git a/test/fixture/eslint-plugin-helper/ava.config.js b/test/fixture/eslint-plugin-helper/ava.config.js index a60653214..51bc34384 100644 --- a/test/fixture/eslint-plugin-helper/ava.config.js +++ b/test/fixture/eslint-plugin-helper/ava.config.js @@ -1,6 +1,6 @@ export default { babel: false, + extensions: ['foo'], files: ['tests/**/*'], - helpers: ['helpers/*'], - extensions: ['foo'] + helpers: ['helpers/*'] }; diff --git a/test/fixture/eslint-plugin-helper/for-overriding/ava.config.js b/test/fixture/eslint-plugin-helper/for-overriding/ava.config.js new file mode 100644 index 000000000..d1eebb4b4 --- /dev/null +++ b/test/fixture/eslint-plugin-helper/for-overriding/ava.config.js @@ -0,0 +1,8 @@ +export default { + babel: { + extensions: ['bar'] + }, + files: ['build/tests/**/*'], + helpers: ['build/helpers/*'], + sources: ['src/**/*'] +}; diff --git a/test/fixture/eslint-plugin-helper/for-overriding/package.json b/test/fixture/eslint-plugin-helper/for-overriding/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/fixture/eslint-plugin-helper/for-overriding/package.json @@ -0,0 +1 @@ +{}