diff --git a/web/scripts/lint-colors.mjs b/web/scripts/lint-colors.mjs index 9f0ffc2..e6ed7e5 100644 --- a/web/scripts/lint-colors.mjs +++ b/web/scripts/lint-colors.mjs @@ -1,25 +1,28 @@ -// Fails when a hex colour literal appears in web/src outside the design -// tokens: every colour must come from a custom property in tokens.css. +// Fails when a hex colour literal appears in any CSS or TypeScript file under +// web/ outside the design tokens: every colour must come from a custom +// property in tokens.css. Dependencies, build output and hidden directories +// (tool caches) are not source and are skipped. import { readFileSync, readdirSync } from 'node:fs' import { extname, join, relative } from 'node:path' import { fileURLToPath } from 'node:url' const webRoot = fileURLToPath(new URL('..', import.meta.url)) -const srcDir = join(webRoot, 'src') const allowed = new Set(['src/styles/tokens.css']) +const skippedDirs = new Set([join(webRoot, 'node_modules'), join(webRoot, 'dist')]) const extensions = new Set(['.css', '.ts', '.tsx']) const hexColour = /#(?:[0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{3,4})\b/g function* sourceFiles(dir) { for (const entry of readdirSync(dir, { withFileTypes: true })) { const path = join(dir, entry.name) - if (entry.isDirectory()) yield* sourceFiles(path) - else if (extensions.has(extname(entry.name))) yield path + if (entry.isDirectory()) { + if (!skippedDirs.has(path) && !entry.name.startsWith('.')) yield* sourceFiles(path) + } else if (extensions.has(extname(entry.name))) yield path } } const violations = [] -for (const path of sourceFiles(srcDir)) { +for (const path of sourceFiles(webRoot)) { const name = relative(webRoot, path).split('\\').join('/') if (allowed.has(name)) continue readFileSync(path, 'utf8')