From 1cce8bd49ab6b5948381d10537796a7f30bd1bb8 Mon Sep 17 00:00:00 2001 From: Masafumi Koba <473530+ybiquitous@users.noreply.github.com> Date: Sun, 22 Jan 2023 15:26:52 +0900 Subject: [PATCH] Fix `overrides.files` in config to allow basename glob patterns (#6547) This change fixes the `overrides.files` property in config to allow basename glob patterns like `*.css` or `*.html`. For example, let's consider `stylelint-config-standard-vue`: ```js { overrides: [ { files: ["*.vue", "**/*.vue"], extends: [/* ... */], }, ] } ``` People should expect the `*.vue` pattern matches any `.vue` files in any directories. See See also the `basename` option `micromatch`: --- .changeset/slow-dots-hug.md | 5 +++++ lib/__tests__/overrides.test.js | 21 ++++++++++++++----- lib/augmentConfig.js | 36 +++++++++++++++++---------------- lib/isPathIgnored.js | 7 ++----- 4 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 .changeset/slow-dots-hug.md diff --git a/.changeset/slow-dots-hug.md b/.changeset/slow-dots-hug.md new file mode 100644 index 0000000000..8f90688bfd --- /dev/null +++ b/.changeset/slow-dots-hug.md @@ -0,0 +1,5 @@ +--- +"stylelint": patch +--- + +Fixed: `overrides.files` in config to allow basename glob patterns diff --git a/lib/__tests__/overrides.test.js b/lib/__tests__/overrides.test.js index d787a44bb7..f99895da89 100644 --- a/lib/__tests__/overrides.test.js +++ b/lib/__tests__/overrides.test.js @@ -7,8 +7,12 @@ const fixturesPath = path.join(__dirname, 'fixtures', 'config-overrides'); describe('single input file. all overrides are matching', () => { it('simple override', async () => { + const inputFiles = [ + path.join(fixturesPath, 'style.css'), + path.join(fixturesPath, 'testPrintConfig', 'style.css'), + ]; const linted = await standalone({ - files: [path.join(fixturesPath, 'style.css')], + files: inputFiles, config: { rules: { 'block-no-empty': true, @@ -25,10 +29,17 @@ describe('single input file. all overrides are matching', () => { configBasedir: fixturesPath, }); - expect(linted.results).toHaveLength(1); - expect(linted.results[0].warnings).toHaveLength(2); - expect(linted.results[0].warnings[0].rule).toBe('block-no-empty'); - expect(linted.results[0].warnings[1].rule).toBe('color-named'); + expect(linted.results).toHaveLength(2); + expect(linted.results[0].source).toBe(inputFiles[0]); + expect(linted.results[0].warnings.map((w) => w.rule)).toEqual([ + 'block-no-empty', + 'color-named', + ]); + expect(linted.results[1].source).toBe(inputFiles[1]); + expect(linted.results[1].warnings.map((w) => w.rule)).toEqual([ + 'block-no-empty', + 'color-named', + ]); }); it('override with plugins', async () => { diff --git a/lib/augmentConfig.js b/lib/augmentConfig.js index aa9208f551..3393d97cc9 100644 --- a/lib/augmentConfig.js +++ b/lib/augmentConfig.js @@ -19,6 +19,18 @@ const path = require('path'); /** @typedef {import('stylelint').CodeProcessor} StylelintCodeProcessor */ /** @typedef {import('stylelint').ResultProcessor} StylelintResultProcessor */ +/** + * @param {string} glob + * @param {string} basedir + * @returns {string} + */ +function absolutizeGlob(glob, basedir) { + const result = path.isAbsolute(glob.replace(/^!/, '')) ? glob : globjoin(basedir, glob); + + // Glob patterns for micromatch should be in POSIX-style + return normalizePath(result); +} + /** * - Merges config and stylelint options * - Makes all paths absolute @@ -142,11 +154,7 @@ async function augmentConfigFull(stylelint, filePath, cosmiconfigResult) { */ function absolutizePaths(config, configDir, cwd) { if (config.ignoreFiles) { - config.ignoreFiles = [config.ignoreFiles].flat().map((glob) => { - if (path.isAbsolute(glob.replace(/^!/, ''))) return glob; - - return globjoin(configDir, glob); - }); + config.ignoreFiles = [config.ignoreFiles].flat().map((glob) => absolutizeGlob(glob, configDir)); } if (config.plugins) { @@ -453,19 +461,13 @@ function applyOverrides(fullConfig, rootConfigDir, filePath) { ); } - const filesGlobs = [files] - .flat() - .map((glob) => { - if (path.isAbsolute(glob.replace(/^!/, ''))) { - return glob; - } - - return globjoin(rootConfigDir, glob); - }) - // Glob patterns for micromatch should be in POSIX-style - .map((s) => normalizePath(s)); + const absoluteGlobs = [files].flat().map((glob) => absolutizeGlob(glob, rootConfigDir)); - if (micromatch.isMatch(filePath, filesGlobs, { dot: true })) { + if ( + micromatch.isMatch(filePath, absoluteGlobs, { dot: true }) || + // E.g. `*.css` matches any CSS files in any directories. + micromatch.isMatch(filePath, files, { dot: true, basename: true }) + ) { config = mergeConfigs(config, configOverrides); } } diff --git a/lib/isPathIgnored.js b/lib/isPathIgnored.js index 5b22c61322..93b0331815 100644 --- a/lib/isPathIgnored.js +++ b/lib/isPathIgnored.js @@ -1,7 +1,6 @@ 'use strict'; const micromatch = require('micromatch'); -const normalizePath = require('normalize-path'); const path = require('path'); const filterFilePaths = require('./utils/filterFilePaths'); @@ -30,12 +29,10 @@ module.exports = async function isPathIgnored(stylelint, filePath) { return true; } - // Glob patterns for micromatch should be in POSIX-style - const ignoreFiles = [result.config.ignoreFiles || []].flat().map((s) => normalizePath(s)); - + const ignoreFiles = result.config.ignoreFiles || []; const absoluteFilePath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath); - if (micromatch([absoluteFilePath], ignoreFiles).length) { + if (micromatch([absoluteFilePath], ignoreFiles).length > 0) { return true; }