58 lines
2.2 KiB
JavaScript
58 lines
2.2 KiB
JavaScript
// Puts the dispatcher of the zone hooks into .git/hooks/pre-commit. Idempotent: its own one (by the
|
|
// marker) it overwrites with a fresh version, somebody else's it does not touch. Called from
|
|
// npm prepare — that is, every npm install/ci in frontend/ puts the protection in place itself, and
|
|
// a session has no separate step for it.
|
|
import { execSync } from 'node:child_process';
|
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
|
|
const MARKER = 'textmachine zone-hook dispatcher';
|
|
|
|
// The dispatcher is zone-neutral: every zone may put its own fragment into
|
|
// <zone>/scripts/githooks/pre-commit, and it is picked up with no edit to this file.
|
|
const dispatcher = `#!/bin/sh
|
|
# ${MARKER} v1 — generated by frontend/scripts/githooks/install.mjs; edits are overwritten.
|
|
status=0
|
|
for hook in */scripts/githooks/pre-commit; do
|
|
[ -x "$hook" ] || continue
|
|
"$hook" || status=1
|
|
done
|
|
exit $status
|
|
`;
|
|
|
|
/** @param {string} args */
|
|
function git(args) {
|
|
return execSync(`git ${args}`, { encoding: 'utf8' }).trim();
|
|
}
|
|
|
|
let gitDir;
|
|
try {
|
|
gitDir = git('rev-parse --git-common-dir');
|
|
} catch {
|
|
console.log('githooks: not a git repository — installing the hook was skipped');
|
|
process.exit(0);
|
|
}
|
|
|
|
let hooksPath = '';
|
|
try {
|
|
hooksPath = git('config core.hooksPath');
|
|
} catch {
|
|
// not set — the standard location, the path is below
|
|
}
|
|
if (hooksPath !== '') {
|
|
console.log(`githooks: core.hooksPath=${hooksPath} is set — I will not install into it.`);
|
|
console.log('Wire frontend/scripts/githooks/pre-commit into your own pre-commit by hand.');
|
|
process.exit(0);
|
|
}
|
|
|
|
const hooksDir = resolve(process.cwd(), gitDir, 'hooks');
|
|
const target = resolve(hooksDir, 'pre-commit');
|
|
if (existsSync(target) && !readFileSync(target, 'utf8').includes(MARKER)) {
|
|
console.log(`githooks: ${target} already exists and was written not by us — not overwriting.`);
|
|
console.log('Wire frontend/scripts/githooks/pre-commit into your own pre-commit by hand.');
|
|
process.exit(0);
|
|
}
|
|
mkdirSync(hooksDir, { recursive: true });
|
|
writeFileSync(target, dispatcher);
|
|
chmodSync(target, 0o755);
|
|
console.log(`githooks: the pre-commit dispatcher is installed → ${target}`);
|