Bloody dependabot. We're not compatible with ESLint 9 yet, darnit, and yet dependabot keeps pushing upgrades on us.
103 lines
3.4 KiB
JavaScript
103 lines
3.4 KiB
JavaScript
import { execFileSync } from "child_process";
|
|
import { ESLint } from "eslint";
|
|
import path from "path";
|
|
import process from "process";
|
|
|
|
// Code assumes this script is in the './web/scripts' folder.
|
|
const projectRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
encoding: "utf8",
|
|
}).replace("\n", "");
|
|
process.chdir(path.join(projectRoot, "./web"));
|
|
|
|
const eslintConfig = {
|
|
overrideConfig: {
|
|
env: {
|
|
browser: true,
|
|
es2021: true,
|
|
},
|
|
extends: [
|
|
"eslint:recommended",
|
|
"plugin:@typescript-eslint/recommended",
|
|
"plugin:lit/recommended",
|
|
"plugin:custom-elements/recommended",
|
|
"plugin:storybook/recommended",
|
|
"plugin:sonarjs/recommended",
|
|
],
|
|
parser: "@typescript-eslint/parser",
|
|
parserOptions: {
|
|
ecmaVersion: 12,
|
|
sourceType: "module",
|
|
},
|
|
plugins: ["@typescript-eslint", "lit", "custom-elements", "sonarjs"],
|
|
ignorePatterns: ["!./.storybook/**/*.ts"],
|
|
rules: {
|
|
"indent": "off",
|
|
"linebreak-style": ["error", "unix"],
|
|
"quotes": ["error", "double", { avoidEscape: true }],
|
|
"semi": ["error", "always"],
|
|
"@typescript-eslint/ban-ts-comment": "off",
|
|
"sonarjs/cognitive-complexity": ["warn", 9],
|
|
"sonarjs/no-duplicate-string": "off",
|
|
"sonarjs/no-nested-template-literals": "off",
|
|
},
|
|
},
|
|
};
|
|
|
|
function findChangedFiles() {
|
|
const porcelainV1 = /^(..)\s+(.*$)/;
|
|
const gitStatus = execFileSync("git", ["status", "--porcelain", "."], { encoding: "utf8" });
|
|
|
|
const statuses = gitStatus.split("\n").reduce((acc, line) => {
|
|
const match = porcelainV1.exec(line.replace("\n"));
|
|
if (!match) {
|
|
return acc;
|
|
}
|
|
const [status, path] = Array.from(match).slice(1, 3);
|
|
return [...acc, [status, path.split("\x00")[0]]];
|
|
}, []);
|
|
|
|
const isModified = /^(M|\?|\s)(M|\?|\s)/;
|
|
const modified = (s) => isModified.test(s);
|
|
|
|
const isCheckable = /\.(ts|js|mjs)$/;
|
|
const checkable = (s) => isCheckable.test(s);
|
|
|
|
const ignored = /\/\.storybook\//;
|
|
const notIgnored = (s) => !ignored.test(s);
|
|
|
|
return statuses.reduce(
|
|
(acc, [status, filename]) =>
|
|
modified(status) && checkable(filename) && notIgnored(filename)
|
|
? [...acc, path.join(projectRoot, filename)]
|
|
: acc,
|
|
[],
|
|
);
|
|
}
|
|
|
|
if (process.argv.length > 2 && (process.argv[2] === "-h" || process.argv[2] === "--help")) {
|
|
// eslint-disable-next-line no-console
|
|
console.log(`Run eslint with extra-hard checks
|
|
|
|
options:
|
|
-c, --changed: (default) check only the files that have changed
|
|
-n, --nightmare: check all the files in the repository
|
|
-h, --help: This help message
|
|
`);
|
|
process.exit(0);
|
|
}
|
|
|
|
const updated =
|
|
process.argv.length > 2 && (process.argv[2] === "-n" || process.argv[2] === "--nightmare")
|
|
? ["./src/", "./build.mjs", "./scripts/*.mjs"]
|
|
: findChangedFiles();
|
|
|
|
const eslint = new ESLint(eslintConfig);
|
|
const results = await eslint.lintFiles(updated);
|
|
const formatter = await eslint.loadFormatter("stylish");
|
|
const resultText = formatter.format(results);
|
|
const errors = results.reduce((acc, result) => acc + result.errorCount, 0);
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.log(resultText);
|
|
process.exit(errors > 1 ? 1 : 0);
|