57 lines
2.5 KiB
JavaScript
57 lines
2.5 KiB
JavaScript
// Ставит в .git/hooks/pre-commit диспетчер зонных хуков. Идемпотентен: свой (по маркеру)
|
||
// перезаписывает свежей версией, чужой не трогает. Зовётся из npm prepare — то есть
|
||
// каждый npm install/ci в frontend/ ставит защиту сам, отдельного шага у сессии нет.
|
||
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';
|
||
|
||
// Диспетчер зонно-нейтрален: каждая зона может положить свой фрагмент в
|
||
// <зона>/scripts/githooks/pre-commit, и он подхватится без правки этого файла.
|
||
const dispatcher = `#!/bin/sh
|
||
# ${MARKER} v1 — сгенерирован frontend/scripts/githooks/install.mjs; правки перетираются.
|
||
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: не git-репозиторий — установка хука пропущена');
|
||
process.exit(0);
|
||
}
|
||
|
||
let hooksPath = '';
|
||
try {
|
||
hooksPath = git('config core.hooksPath');
|
||
} catch {
|
||
// не задан — стандартное расположение, путь ниже
|
||
}
|
||
if (hooksPath !== '') {
|
||
console.log(`githooks: задан core.hooksPath=${hooksPath} — ставить туда не берусь.`);
|
||
console.log('Подключите frontend/scripts/githooks/pre-commit из своего pre-commit вручную.');
|
||
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} уже существует и написан не нами — не перетираю.`);
|
||
console.log('Подключите frontend/scripts/githooks/pre-commit из своего pre-commit вручную.');
|
||
process.exit(0);
|
||
}
|
||
mkdirSync(hooksDir, { recursive: true });
|
||
writeFileSync(target, dispatcher);
|
||
chmodSync(target, 0o755);
|
||
console.log(`githooks: pre-commit диспетчер установлен → ${target}`);
|