BangleApps/bin/exempt-lint.mjs

70 lines
2.3 KiB
JavaScript
Raw Permalink Normal View History

2024-03-04 20:34:17 +00:00
#!/usr/bin/env node
2024-03-05 11:47:04 +00:00
/**
2024-03-04 20:34:17 +00:00
* @file
* You can use this script to exempt an app file from a specific eslint rule.
2024-03-05 11:47:04 +00:00
*
2024-03-04 20:34:17 +00:00
* This should only be used to exempt existing apps when a new lint rule is added.
* You are not allowed to exempt your new app from existing lint rules.
2024-03-05 11:47:04 +00:00
*
2024-03-04 20:34:17 +00:00
* Run it like this:
* node bin/exempt-lint.mjs LINTRULE FILEPATH
2024-03-05 11:47:04 +00:00
*
2024-03-04 20:34:17 +00:00
* Example command:
* node bin/exempt-lint.mjs no-unused-vars ./apps/_example_app/app.js
*/
import fs from "node:fs/promises";
2024-03-07 09:20:47 +00:00
// Nodejs v18 compatibility (v18 is end-of-life in april 2025)
if(!("crypto" in globalThis)) globalThis.crypto = (await import("node:crypto")).webcrypto;
2024-03-04 20:34:17 +00:00
const lintRule = process.argv[2];
2024-03-05 11:47:04 +00:00
if (!lintRule) {
throw new Error(
"First argument needs to be a lint rule, something like 'no-unused-vars'",
);
2024-03-04 20:34:17 +00:00
}
const filePathInput = process.argv[3];
2024-03-05 11:47:04 +00:00
const filePathMatch = filePathInput?.match(
2024-05-04 21:21:43 +00:00
/^(?:.*?\/apps\/|apps\/|\/)?(?<path>.*\.[jt]s)$/iu,
2024-03-05 11:47:04 +00:00
);
2024-03-04 20:34:17 +00:00
const filePath = filePathMatch?.groups?.path;
2024-03-05 11:47:04 +00:00
if (!filePath) {
throw new Error(
"Second argument needs to be a file path that looks something like './apps/_example_app/app.js'",
);
2024-03-04 20:34:17 +00:00
}
const exemptionsFilePath = "../apps/lint_exemptions.js";
const exemptions = (await import(exemptionsFilePath)).default;
2024-03-05 11:47:04 +00:00
const fileContents = await fs.readFile(`apps/${filePath}`, "utf8");
2024-03-04 20:34:17 +00:00
const exemption = exemptions[filePath] || {};
exemption.hash = await hashContents(fileContents);
const rules = new Set(exemption.rules || []);
rules.add(lintRule);
exemption.rules = [...rules];
exemptions[filePath] = exemption;
const output = `module.exports = ${JSON.stringify(exemptions, undefined, 2)};\n`;
2024-03-05 11:47:04 +00:00
await fs.writeFile(`bin/${exemptionsFilePath}`, output);
2024-03-04 20:34:17 +00:00
console.log(`✔️ '${filePath}' is now exempt from the rule '${lintRule}'`);
/**
* https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string
*/
async function hashContents(message) {
2024-03-05 11:47:04 +00:00
const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); // hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
const hashHex = hashArray
.map((b) => b.toString(16).padStart(2, "0"))
.join(""); // convert bytes to hex string
return hashHex;
2024-03-04 20:34:17 +00:00
}