Spaces:
Configuration error
Configuration error
| import fs from "node:fs"; | |
| import path from "node:path"; | |
| import { spawnSync } from "node:child_process"; | |
| import { fileURLToPath } from "node:url"; | |
| const DEFAULT_HOOKS_PATH = "git-hooks"; | |
| const PRE_COMMIT_HOOK = "pre-commit"; | |
| function getRepoRoot() { | |
| const here = path.dirname(fileURLToPath(import.meta.url)); | |
| return path.resolve(here, ".."); | |
| } | |
| function runGitCommand(args, options = {}) { | |
| return spawnSync("git", args, { | |
| cwd: options.cwd, | |
| encoding: "utf-8", | |
| stdio: options.stdio ?? "pipe", | |
| }); | |
| } | |
| function ensureExecutable(targetPath) { | |
| if (process.platform === "win32") return; | |
| if (!fs.existsSync(targetPath)) return; | |
| try { | |
| const mode = fs.statSync(targetPath).mode & 0o777; | |
| if (mode & 0o100) return; | |
| fs.chmodSync(targetPath, 0o755); | |
| } catch (err) { | |
| console.warn(`[setup-git-hooks] chmod failed: ${err}`); | |
| } | |
| } | |
| function isGitAvailable({ repoRoot = getRepoRoot(), runGit = runGitCommand } = {}) { | |
| const result = runGit(["--version"], { cwd: repoRoot, stdio: "ignore" }); | |
| return result.status === 0; | |
| } | |
| function isGitRepo({ repoRoot = getRepoRoot(), runGit = runGitCommand } = {}) { | |
| const result = runGit(["rev-parse", "--is-inside-work-tree"], { | |
| cwd: repoRoot, | |
| stdio: "pipe", | |
| }); | |
| if (result.status !== 0) return false; | |
| return String(result.stdout ?? "").trim() === "true"; | |
| } | |
| function setHooksPath({ | |
| repoRoot = getRepoRoot(), | |
| hooksPath = DEFAULT_HOOKS_PATH, | |
| runGit = runGitCommand, | |
| } = {}) { | |
| const result = runGit(["config", "core.hooksPath", hooksPath], { | |
| cwd: repoRoot, | |
| stdio: "ignore", | |
| }); | |
| return result.status === 0; | |
| } | |
| function setupGitHooks({ | |
| repoRoot = getRepoRoot(), | |
| hooksPath = DEFAULT_HOOKS_PATH, | |
| runGit = runGitCommand, | |
| } = {}) { | |
| if (!isGitAvailable({ repoRoot, runGit })) { | |
| return { ok: false, reason: "git-missing" }; | |
| } | |
| if (!isGitRepo({ repoRoot, runGit })) { | |
| return { ok: false, reason: "not-repo" }; | |
| } | |
| if (!setHooksPath({ repoRoot, hooksPath, runGit })) { | |
| return { ok: false, reason: "config-failed" }; | |
| } | |
| ensureExecutable(path.join(repoRoot, hooksPath, PRE_COMMIT_HOOK)); | |
| return { ok: true }; | |
| } | |
| export { | |
| DEFAULT_HOOKS_PATH, | |
| PRE_COMMIT_HOOK, | |
| ensureExecutable, | |
| getRepoRoot, | |
| isGitAvailable, | |
| isGitRepo, | |
| runGitCommand, | |
| setHooksPath, | |
| setupGitHooks, | |
| }; | |
| if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { | |
| setupGitHooks(); | |
| } | |