What minimal example or steps are needed to reproduce the bug?
Create two CSS files and lint them via the Node API:
other.css:
src/test.css:
import stylelint from 'stylelint';
// Lint with the file that doesn't match any override listed first.
const result = await stylelint.lint({
files: ['other.css', 'src/test.css'],
});
console.log(result.ruleMetadata);
// => {}, but should contain color-hex-length and block-no-empty metadata
What minimal configuration is needed to reproduce the bug?
{
"rules": {},
"overrides": [
{
"files": ["src/**/*.css"],
"rules": {
"color-hex-length": "long",
"block-no-empty": true
}
}
]
}
How did you run Stylelint?
Via the Node API using stylelint.lint() with an explicit file list as shown above. The bug also reproduces with globs when the non-matching file sorts first alphabetically, e.g.:
const result = await stylelint.lint({ files: ['**/*.css'] });
Which Stylelint-related dependencies are you using?
{
"stylelint": "^17.4.0"
}
What did you expect to happen?
result.ruleMetadata should contain metadata for all rules that ran during the lint, regardless of file order. Linting ["other.css", "src/test.css"] should produce the same ruleMetadata as ["src/test.css", "other.css"].
What actually happened?
ruleMetadata is {} when the first file in the list has no rules applied to it. The metadata from subsequent files is discarded.
| File order |
ruleMetadata |
["other.css"] |
{} - correct |
["src/test.css"] |
{color-hex-length: ..., block-no-empty: ...} - correct |
["src/test.css", "other.css"] |
{color-hex-length: ..., block-no-empty: ...} - correct |
["other.css", "src/test.css"] |
{} - bug |
["**/*.css"] |
{} - bug, other.css sorts first |
Do you have a proposal to fix the bug?
In lib/prepareReturnValue.mjs, getRuleMetadata destructures only the first element of lintResults:
/**
* @param {LintResult[]} lintResults
*/
function getRuleMetadata(lintResults) {
const [lintResult] = lintResults;
if (lintResult === undefined) return {};
if (lintResult._postcssResult === undefined) return {};
return lintResult._postcssResult.stylelint.ruleMetadata;
}
It should probably merge metadata across all results instead:
/**
* @param {LintResult[]} lintResults
*/
function getRuleMetadata(lintResults) {
const merged = {};
for (const lintResult of lintResults) {
if (lintResult?._postcssResult === undefined) continue;
Object.assign(merged, lintResult._postcssResult.stylelint.ruleMetadata);
}
return merged;
}
What minimal example or steps are needed to reproduce the bug?
Create two CSS files and lint them via the Node API:
other.css:src/test.css:What minimal configuration is needed to reproduce the bug?
{ "rules": {}, "overrides": [ { "files": ["src/**/*.css"], "rules": { "color-hex-length": "long", "block-no-empty": true } } ] }How did you run Stylelint?
Via the Node API using
stylelint.lint()with an explicit file list as shown above. The bug also reproduces with globs when the non-matching file sorts first alphabetically, e.g.:Which Stylelint-related dependencies are you using?
{ "stylelint": "^17.4.0" }What did you expect to happen?
result.ruleMetadatashould contain metadata for all rules that ran during the lint, regardless of file order. Linting["other.css", "src/test.css"]should produce the sameruleMetadataas["src/test.css", "other.css"].What actually happened?
ruleMetadatais{}when the first file in the list has no rules applied to it. The metadata from subsequent files is discarded.ruleMetadata["other.css"]{}- correct["src/test.css"]{color-hex-length: ..., block-no-empty: ...}- correct["src/test.css", "other.css"]{color-hex-length: ..., block-no-empty: ...}- correct["other.css", "src/test.css"]{}- bug["**/*.css"]{}- bug, other.css sorts firstDo you have a proposal to fix the bug?
In
lib/prepareReturnValue.mjs,getRuleMetadatadestructures only the first element oflintResults:It should probably merge metadata across all results instead: