Files
perspective-dev--perspective/tools/scripts/lint_headers.mjs
T
2026-07-13 12:25:07 +08:00

120 lines
6.6 KiB
JavaScript

// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
import { glob } from "glob-gitignore";
import { promises as fs } from "fs";
import * as fs_sync from "fs";
const IGNORE_PATHS = fs_sync
.readFileSync(".gitignore")
.toString()
.split("\n")
.map((x) => x.trim())
.filter((x) => x.length > 0 && !x.startsWith("#"))
.concat(["llvm/*", "cmake/*", "pnpm-lock.yaml", "pnpm-workspace.yaml"]);
const FIX_PATHS = [
["**/*.rs", ["//", "/*", " *", " */"]],
["**/*.js", ["//", "/*", " *", " */"]],
["**/*.mjs", ["//", "/*", " *", " */"]],
// ["**/*.css", ["//", "/*", " *", " */"]],
["**/*.scss", ["//", "/*", " *", " */"]],
["**/*.toml", ["# ", "#"]],
["**/*.yaml", ["# ", "#"]],
["**/*.py", ["# ", "#"]],
["**/*.ts", ["//", "/*", " *", " */"]],
["**/*.tsx", ["//", "/*", " *", " */"]],
["**/*.cpp", ["//", "/*", " *", " */"]],
["**/*.h", ["//", "/*", " *", " */"]],
[".github/**/*.yaml", ["# ", "#"]],
];
function header_text(c, ...args) {
return (
`
${c} ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
${c} ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
${c} ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
${c} ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
${c} ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
${c} ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
${c} ┃ Copyright (c) 2017, the Perspective Authors. ┃
${c} ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
${c} ┃ This file is part of the Perspective library, distributed under the terms ┃
${c} ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
${c} ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
`.trim() + args.join("")
);
}
async function check(is_write, pattern, comment) {
const matches = await glob(pattern, {
ignore: IGNORE_PATHS,
});
let exit_code = 0;
for (const match of matches) {
if (fs_sync.lstatSync(match).isDirectory()) {
continue;
}
const data = await fs.readFile(match);
let contents = data.toString();
let default_comment = comment;
if (Array.isArray(comment)) {
default_comment = comment[0];
} else {
comment = [comment];
}
const expected_header = header_text(default_comment);
let seen_whitespace = false;
// Nightly builds modify the version of metadata scripts in place to
// tag the nightly, so lint will fail if we don't make an exception
// for these files.
const is_nightly =
process.argv.indexOf("--nightly") > -1 &&
(match.indexOf("Cargo.toml") > -1 ||
match.indexOf("pyproject.toml") > -1);
if (!contents.startsWith(expected_header) && !is_nightly) {
console.error(`Missing header in file ${match}`);
while (
contents.length > 0 &&
((!seen_whitespace &&
comment.some((x) => contents.startsWith(x))) ||
(seen_whitespace = contents.startsWith("\n")))
) {
contents = contents.substring(contents.indexOf("\n") + 1);
}
if (is_write) {
await fs.writeFile(match, `${expected_header}\n\n${contents}`);
} else {
exit_code = 1;
}
}
}
return exit_code;
}
export default async function run(is_write) {
let exit_code = 0;
for (const [patt, comment] of FIX_PATHS) {
const result = await check(is_write, patt, comment);
exit_code = exit_code || result;
}
return exit_code;
}