diff --git a/lib/stylelint-todo.js b/lib/stylelint-todo.js new file mode 100644 index 0000000000..1340538578 --- /dev/null +++ b/lib/stylelint-todo.js @@ -0,0 +1,38 @@ +const semver = require('semver') +const stylelint = require('stylelint') + +const ruleName = 'primer-css/TODO' +const pattern = /\bTODO@([^:]+):\s+(.+)$/ + +const messages = stylelint.utils.ruleMessages(ruleName, { + rejected: message => message +}) + +module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => { + const {currentVersion} = options + if (!currentVersion) { + // eslint-disable-next-line no-console + console.warn(`No "currentVersion" supplied to ${ruleName}; bailing`) + return () => null + } + + let match + return (root, result) => { + root.walkComments(node => { + if ((match = node.text.match(pattern))) { + // eslint-disable-next-line no-unused-vars + const [substr, todoVersion, message] = match + if (semver.lte(todoVersion, currentVersion)) { + stylelint.utils.report({ + message: messages.rejected( + `Unresolved TODO comment: "${message}" (expected to be resolved in "${todoVersion}")` + ), + node, + result, + ruleName + }) + } + } + }) + } +}) diff --git a/stylelint.config.js b/stylelint.config.js index 2ee89ebdfe..0b48eb1e78 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -1,7 +1,11 @@ +const currentVersion = process.env.PRIMER_VERSION || require('./package.json').version + module.exports = { extends: ['stylelint-config-primer'], + plugins: ['./lib/stylelint-todo'], syntax: 'scss', rules: { - 'primer/no-override': false + 'primer/no-override': false, + 'primer-css/TODO': [true, {currentVersion, severity: 'error'}] } }