UNPKG

lockfile-guardian

Version:

Never forget to install dependencies again! Automatically detect when your lock files change after git operations and warn you (or auto-install) when your dependencies are out of sync.

128 lines 5.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.installGitHooks = installGitHooks; exports.uninstallGitHooks = uninstallGitHooks; exports.areHooksInstalled = areHooksInstalled; const fs_1 = require("fs"); const path_1 = require("path"); const utils_1 = require("./utils"); const HOOK_SHEBANG = "#!/bin/sh"; const HOOK_COMMAND = "npx lockfile-guardian check --hook"; const GIT_HOOKS = [ { name: "post-checkout", path: "post-checkout" }, { name: "post-merge", path: "post-merge" }, { name: "post-rewrite", path: "post-rewrite" }, ]; function createHookContent(existingContent, isHusky = false) { const hookLine = HOOK_COMMAND; // If there's existing content, preserve it and add our hook if (existingContent && existingContent.trim()) { const lines = existingContent.split("\n"); // Check if our hook is already present if (lines.some((line) => line.includes(HOOK_COMMAND))) { return existingContent; } // For Husky hooks, we want to add our command at the end to run after other hooks // For traditional hooks, we add after the shebang if (isHusky) { // Husky hooks don't need shebang handling, just append return existingContent + "\n\n# Lockfile Guardian\n" + hookLine; } else { // Traditional git hooks - add after shebang const shebangIndex = lines.findIndex((line) => line.startsWith("#!")); if (shebangIndex >= 0) { lines.splice(shebangIndex + 1, 0, "", `# Lockfile Guardian`, hookLine); } else { lines.unshift(HOOK_SHEBANG, "", "# Lockfile Guardian", hookLine); } return lines.join("\n"); } } // Create new hook content if (isHusky) { // Husky hooks are simpler - just the command with a comment return ["# Lockfile Guardian", hookLine, ""].join("\n"); } else { // Traditional hooks need shebang return [HOOK_SHEBANG, "", "# Lockfile Guardian", hookLine, ""].join("\n"); } } function removeHookContent(content, isHusky = false) { const lines = content.split("\n"); const filteredLines = lines.filter((line) => !line.includes(HOOK_COMMAND) && !line.includes("# Lockfile Guardian")); const remainingContent = filteredLines.join("\n").trim(); if (isHusky) { // For Husky hooks, if no content remains, remove the file if (remainingContent === "") { return null; } return filteredLines.join("\n"); } else { // For traditional hooks, if only shebang remains, remove the file entirely if (remainingContent === HOOK_SHEBANG || remainingContent === "") { return null; } return filteredLines.join("\n"); } } function installGitHooks(cwd = process.cwd()) { if (!(0, utils_1.isGitRepository)(cwd)) { throw new Error("Not a git repository. Please run this command in a git repository."); } const isHusky = (0, utils_1.isHuskyProject)(cwd); const hooksDir = (0, utils_1.getActiveHooksDir)(cwd); // Create hooks directory if it doesn't exist if (!(0, fs_1.existsSync)(hooksDir)) { (0, fs_1.mkdirSync)(hooksDir, { recursive: true }); } for (const hook of GIT_HOOKS) { const hookPath = (0, path_1.join)(hooksDir, hook.path); let existingContent = ""; if ((0, fs_1.existsSync)(hookPath)) { existingContent = (0, fs_1.readFileSync)(hookPath, "utf8"); } const newContent = createHookContent(existingContent, isHusky); (0, fs_1.writeFileSync)(hookPath, newContent, "utf8"); // Make executable (important for both traditional and Husky hooks) (0, fs_1.chmodSync)(hookPath, 0o755); } } function uninstallGitHooks(cwd = process.cwd()) { if (!(0, utils_1.isGitRepository)(cwd)) { return; // Silently skip if not a git repository } const isHusky = (0, utils_1.isHuskyProject)(cwd); const hooksDir = (0, utils_1.getActiveHooksDir)(cwd); for (const hook of GIT_HOOKS) { const hookPath = (0, path_1.join)(hooksDir, hook.path); if ((0, fs_1.existsSync)(hookPath)) { const content = (0, fs_1.readFileSync)(hookPath, "utf8"); const newContent = removeHookContent(content, isHusky); if (newContent === null) { (0, fs_1.unlinkSync)(hookPath); } else { (0, fs_1.writeFileSync)(hookPath, newContent, "utf8"); } } } } function areHooksInstalled(cwd = process.cwd()) { if (!(0, utils_1.isGitRepository)(cwd)) { return false; } const hooksDir = (0, utils_1.getActiveHooksDir)(cwd); return GIT_HOOKS.every((hook) => { const hookPath = (0, path_1.join)(hooksDir, hook.path); if (!(0, fs_1.existsSync)(hookPath)) { return false; } const content = (0, fs_1.readFileSync)(hookPath, "utf8"); return content.includes(HOOK_COMMAND); }); } //# sourceMappingURL=git-hooks.js.map