#!/usr/bin/env node import { execFileSync } from "node:child_process"; import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs"; import { join } from "node:path"; const MARKER = "# sf-secret-scan"; function git(args) { return execFileSync("git", args, { encoding: "utf8", shell: process.platform === "win32", }).trim(); } const gitDir = git(["rev-parse", "--git-dir"]); const repoRoot = git(["rev-parse", "--show-toplevel"]); const hookDir = join(gitDir, "hooks"); const hookFile = join(hookDir, "pre-commit"); const hookCommand = `node "${join(repoRoot, "scripts", "secret-scan.mjs")}"`; mkdirSync(hookDir, { recursive: true }); if (existsSync(hookFile)) { const current = readFileSync(hookFile, "utf8"); if (current.includes(MARKER)) { process.stdout.write("secret-scan pre-commit hook already installed.\n"); process.exit(0); } const next = `${current.replace(/\s*$/, "\n")}${MARKER}\n${hookCommand}\n`; writeFileSync(hookFile, next, "utf8"); process.stdout.write("secret-scan appended to existing pre-commit hook.\n"); process.exit(0); } const hookBody = [ "#!/usr/bin/env sh", "# sf-secret-scan", "# Pre-commit hook: scan staged files for hardcoded secrets", hookCommand, "", ].join("\n"); writeFileSync(hookFile, hookBody, "utf8"); try { chmodSync(hookFile, 0o755); } catch { // Best effort on Windows filesystems that do not honor chmod. } process.stdout.write("secret-scan pre-commit hook installed.\n");