106 lines
3.0 KiB
TypeScript
Executable File
106 lines
3.0 KiB
TypeScript
Executable File
#!/usr/bin/env runts -- --allow-all
|
|
|
|
import {
|
|
execCommandAndStdout,
|
|
formatHumanTime,
|
|
log,
|
|
ProcessBar,
|
|
readFileToString,
|
|
stringifyPretty,
|
|
term,
|
|
uint8ArrayToHexString,
|
|
writeStringToFile,
|
|
} from "https://script.hatter.ink/@35/deno-commons-mod.ts";
|
|
import {
|
|
getGitLocalRev,
|
|
getGitRemoteRev,
|
|
} from "https://script.hatter.ink/@0/deno-git-mod.ts";
|
|
import { parseArgs } from "jsr:@std/cli/parse-args";
|
|
|
|
const MILLIS_OF_HOUR = 60 * 60 * 1000;
|
|
|
|
async function sha256OfString(input: string): Promise<string> {
|
|
const data = new TextEncoder().encode(input);
|
|
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
return uint8ArrayToHexString(new Uint8Array(hashBuffer));
|
|
}
|
|
|
|
async function getPwd(): Promise<string> {
|
|
return await execCommandAndStdout("pwd");
|
|
}
|
|
|
|
interface GitCheckCache {
|
|
path: string;
|
|
lastCheckTime: number;
|
|
}
|
|
|
|
async function main() {
|
|
const flags = parseArgs(Deno.args, {
|
|
boolean: [
|
|
"help",
|
|
],
|
|
string: [
|
|
"interval",
|
|
],
|
|
alias: {
|
|
i: "interval",
|
|
},
|
|
});
|
|
|
|
if (flags.help) {
|
|
console.log(`Usage:
|
|
git-check.ts --help
|
|
git-check.ts [--interval NUMBER-OF-HOURS]`);
|
|
return;
|
|
}
|
|
const intervalHours = parseInt(flags.interval ?? "2", 10);
|
|
|
|
const pwd = await getPwd();
|
|
const pwdHash = await sha256OfString(pwd);
|
|
const gitCheckCacheFile = `~/.cache/git-check-${
|
|
pwdHash.substring(0, 20)
|
|
}.json`;
|
|
log.debug(`Check git cache file: ${gitCheckCacheFile}`);
|
|
const gitCheckCacheContent = await readFileToString(gitCheckCacheFile);
|
|
const gitCheckCache = gitCheckCacheContent
|
|
? JSON.parse(gitCheckCacheContent) as GitCheckCache
|
|
: null;
|
|
if (gitCheckCache) {
|
|
const timeBefore = Date.now() - gitCheckCache.lastCheckTime;
|
|
if (timeBefore < MILLIS_OF_HOUR * intervalHours) {
|
|
const lastCheckTime = new Date(gitCheckCache.lastCheckTime);
|
|
const timeBeforeHuman = formatHumanTime(timeBefore);
|
|
log.info(term.auto(
|
|
`Last check at [under]${lastCheckTime.toLocaleString()}[/], in [under]${timeBeforeHuman}[/], [green]skip check git remote rev[/]`,
|
|
));
|
|
return;
|
|
}
|
|
}
|
|
|
|
const localRev = await getGitLocalRev();
|
|
const remoteRev = await new ProcessBar("Checking remote rev").call(
|
|
getGitRemoteRev,
|
|
);
|
|
if (localRev === remoteRev) {
|
|
log.success(`Check rev successfully, rev: ${localRev}`);
|
|
const gitCheckCache: GitCheckCache = {
|
|
path: pwd,
|
|
lastCheckTime: Date.now(),
|
|
};
|
|
await writeStringToFile(
|
|
gitCheckCacheFile,
|
|
stringifyPretty(gitCheckCache),
|
|
);
|
|
} else {
|
|
log.error(
|
|
`Check rev failed, local rev: ${localRev} vs remote rev: ${remoteRev}`,
|
|
);
|
|
Deno.exit(1);
|
|
}
|
|
}
|
|
|
|
await main();
|
|
|
|
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260208T235727+08:00.MEUCIQDm/E1d7mGqJ4nbguao
|
|
// +eFwlDMp/x7ZOWn95z2BSnIrfwIgJg0lHcBV8C2fQ5B/4Suvq7f9/f+M2CHrNn9CSzve4wA=
|