Files
discourse/stylelint-rules/no-renamed-variables.mjs
T
David Taylor 439efc7419 DEV: Introduce system for renaming CSS variables (#42733)
From time-to-time, variables may need to be renamed in core. To avoid
breaking existing themes and plugins, this commit introduces a system to
automatically rewrite old variable names to new ones. A list of renames
is maintained in `stylesheets/variable-renames.json`, and is applied
when CSS is compiled. This list also powers a stylelint rule which will
automatically rewrite old names to new names in source code.

Transformations apply to all core/theme/plugin code. For now, the
stylelint rule/autofix applies to core only, but this will be extracted
to `@discourse/lint-configs` in the near future.

When a transformation is applied, it adds a trailing `/* automatically
renamed --old to --new */` comment so that the behavior is
understandable from the browser developer tools.
2026-09-01 11:34:46 +01:00

61 lines
1.6 KiB
JavaScript

import { readFileSync } from "node:fs";
import valueParser from "postcss-value-parser";
import stylelint from "stylelint";
const renames = JSON.parse(
readFileSync(
new URL("../app/assets/stylesheets/variable-renames.json", import.meta.url)
)
);
const ruleName = "discourse/no-renamed-variables";
const messages = stylelint.utils.ruleMessages(ruleName, {
renamed: (oldName, newName) => `"${oldName}" was renamed to "${newName}"`,
});
const ruleFunction = (primaryOption) => {
return (root, result) => {
if (!primaryOption) {
return;
}
root.walkDecls((decl) => {
const newProp = renames[decl.prop];
if (newProp) {
stylelint.utils.report({
message: messages.renamed(decl.prop, newProp),
node: decl,
result,
ruleName,
word: decl.prop,
fix: () => (decl.prop = newProp),
});
}
const parsed = valueParser(decl.value);
parsed.walk((node) => {
const newName = node.type === "word" && renames[node.value];
if (newName) {
stylelint.utils.report({
message: messages.renamed(node.value, newName),
node: decl,
result,
ruleName,
word: node.value,
fix: () => {
node.value = newName;
decl.value = parsed.toString();
},
});
}
});
});
};
};
ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;
ruleFunction.meta = { fixable: true };
export default stylelint.createPlugin(ruleName, ruleFunction);