Files
2026-07-13 12:25:07 +08:00

71 lines
3.7 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 "zx/globals";
function lint_git(sha) {
if (!sha || typeof sha !== "string") {
throw new Error(`invalid sha: ${sha}`);
}
const result = $.sync`git log -1 ${sha} | grep -F "Signed-off-by: "`;
if (result.exitCode !== 0) {
console.error(
"`git log -1 " +
sha +
"` is missing a Signed-off-by: and DCO check will surely fail.",
);
console.error("To sign off, run:\ngit commit --amend --edit --sign");
process.exit(1);
}
}
async function readPrePushInput() {
// Git supplies information about the push to the hook on stdin.
// https://git-scm.com/docs/githooks#_pre_push
const chunks = [];
if (process.stdin.isTTY) {
// Makes developing the pre-push script more convenient. In particular
// when you run `pnpm run prepush` from a shell terminal you don't have
// to send EOF on stdin.
return [];
}
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
const input = Buffer.concat(chunks).toString();
const lines = input.split("\n").filter((l) => l.length > 0);
return lines.map((line) => {
const parts = line.trim().split(" ");
return {
local_ref: parts[0],
local_object_name: parts[1],
remote_ref: parts[2],
remote_object_name: parts[3],
};
});
}
if (import.meta.main) {
// Does not actually run all pre-push hook checks (it does not run the repo
// lint script). These are lints which run only in pre-push. The
// `prepush` script defined in package.json is responsible for running the
// repo lint script.
const pushes = await readPrePushInput();
for (const push of pushes) {
const { local_object_name } = push;
lint_git(local_object_name);
}
}