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.
246 lines (238 loc) ⢠9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = require("fs");
const path_1 = require("path");
const git_hooks_1 = require("./git-hooks");
const guardian_1 = require("./guardian");
const post_install_1 = require("./post-install");
const utils_1 = require("./utils");
function parseArgs(args) {
const result = {};
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === "--hook") {
result.isHook = true;
}
else if (arg === "--help" || arg === "-h") {
result.help = true;
}
else if (!result.command && !arg.startsWith("--")) {
result.command = arg;
}
}
return result;
}
function getVersion() {
try {
const packageJsonPath = (0, path_1.join)(__dirname, "..", "package.json");
if ((0, fs_1.existsSync)(packageJsonPath)) {
const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, "utf8"));
return packageJson.version || "1.0.0";
}
}
catch {
// Fallback if package.json can't be read
}
return "1.0.0";
}
function showHelp() {
const version = getVersion();
console.log(`
š Lockfile Guardian v${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.
USAGE:
npx lockfile-guardian [command]
COMMANDS:
install Setup lockfile monitoring (one-time setup)
uninstall Remove all hooks and cleanup
check Manually check for lock file changes
help Show this help message
EXAMPLES:
npx lockfile-guardian install # Setup lockfile monitoring
npx lockfile-guardian check # Check dependencies manually
npx lockfile-guardian uninstall # Remove all hooks
CONFIGURATION:
Add optional configuration to your package.json:
{
"lockfileGuardian": {
"autoInstall": true, // Automatically run install commands
"silent": false, // Suppress non-warning output
"checkNodeModules": true // Warn if node_modules isn't gitignored
}
}
SUPPORTED PACKAGE MANAGERS:
⢠pnpm - pnpm-lock.yaml ā pnpm install
⢠yarn - yarn.lock ā yarn install
⢠npm - package-lock.json ā npm install
For more information, visit: https://github.com/your-username/lockfile-guardian
`);
}
function showStatus() {
const cwd = process.cwd();
const version = getVersion();
console.log(`š Lockfile Guardian v${version}\n`);
// Check if we're in a git repository
if (!(0, utils_1.isGitRepository)(cwd)) {
console.log("ā Not a git repository");
return;
}
console.log("ā
Git repository detected");
// Check Husky compatibility
const isHusky = (0, utils_1.isHuskyProject)(cwd);
const hooksDir = (0, utils_1.getActiveHooksDir)(cwd);
if (isHusky) {
console.log("š¶ Husky detected - using .husky/ directory");
console.log(` Hooks directory: ${hooksDir}`);
}
else {
console.log("š§ Using standard git hooks");
console.log(` Hooks directory: ${hooksDir}`);
}
// Check for lockfile
const lockfileInfo = (0, utils_1.findLockfile)(cwd);
if (!lockfileInfo) {
console.log("ā No supported lockfile found");
console.log(` Supported: ${utils_1.PACKAGE_MANAGERS.map((pm) => pm.lockFile).join(", ")}`);
return;
}
console.log(`ā
Lockfile found: ${lockfileInfo.packageManager.lockFile} (${lockfileInfo.packageManager.name})`);
// Check if hooks are installed
const gitHooksInstalled = (0, git_hooks_1.areHooksInstalled)(cwd);
const postInstallHookInstalled = (0, post_install_1.isPostInstallHookInstalled)(cwd);
if (gitHooksInstalled) {
console.log("ā
Git hooks installed");
}
else {
console.log("ā Git hooks not installed");
}
if (postInstallHookInstalled) {
console.log("ā
Post-install hook installed");
}
else {
console.log("ā Post-install hook not installed");
}
if (!gitHooksInstalled || !postInstallHookInstalled) {
console.log(' Run "npx lockfile-guardian install" to set up');
}
// Show configuration
const config = (0, utils_1.loadConfig)(cwd);
console.log("\nConfiguration:");
console.log(` autoInstall: ${config.autoInstall || false}`);
console.log(` silent: ${config.silent || false}`);
console.log(` checkNodeModules: ${config.checkNodeModules !== false}`);
if (isHusky) {
console.log("\nš Husky Compatibility:");
console.log(" ā
Compatible with lint-staged, prettier, and other tools");
console.log(" ā
Lockfile Guardian runs after other hooks");
console.log(" ā
Preserves existing hook configurations");
}
console.log("\nš” Quick start: npx lockfile-guardian install");
}
async function handleInstall() {
const cwd = process.cwd();
if (!(0, utils_1.isGitRepository)(cwd)) {
(0, utils_1.logError)("Error: Not a git repository. Please run this command in a git repository.");
process.exit(1);
}
const lockfileInfo = (0, utils_1.findLockfile)(cwd);
if (!lockfileInfo) {
(0, utils_1.logError)("Error: No supported lockfile found.");
(0, utils_1.logError)(`Supported lockfiles: ${utils_1.PACKAGE_MANAGERS.map((pm) => pm.lockFile).join(", ")}`);
process.exit(1);
}
const isHusky = (0, utils_1.isHuskyProject)(cwd);
try {
// Install both git hooks and post-install hooks for optimal experience
(0, git_hooks_1.installGitHooks)(cwd);
(0, post_install_1.installPostInstallHook)(cwd);
if (isHusky) {
(0, utils_1.log)("š Lockfile Guardian installed successfully! (Husky compatible)");
(0, utils_1.log)("š¶ Git hooks installed to .husky/ directory");
(0, utils_1.log)("š Compatible with lint-staged, prettier, and other Husky tools");
}
else {
(0, utils_1.log)("š Lockfile Guardian installed successfully!");
(0, utils_1.log)("š§ Git hooks installed to .git/hooks/ directory");
}
(0, utils_1.log)("š Post-install hook added to package.json");
(0, utils_1.log)(`š Monitoring: ${lockfileInfo.packageManager.lockFile}`);
(0, utils_1.log)("š Git hooks will warn about lockfile changes when switching branches");
(0, utils_1.log)("š Post-install hook will update hash when you install packages");
// Initialize with current hash
await (0, guardian_1.checkLockfile)(false, cwd);
}
catch (error) {
(0, utils_1.logError)(`Error installing lockfile guardian: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
}
}
async function handleUninstall() {
const cwd = process.cwd();
try {
(0, git_hooks_1.uninstallGitHooks)(cwd);
(0, post_install_1.uninstallPostInstallHook)(cwd);
(0, guardian_1.clearStoredHash)(cwd);
(0, utils_1.log)("š Lockfile Guardian uninstalled successfully");
(0, utils_1.log)("š All git hooks, post-install hooks, and data have been removed");
}
catch (error) {
(0, utils_1.logError)(`Error uninstalling: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
}
}
async function handleCheck(isHook = false) {
const cwd = process.cwd();
try {
await (0, guardian_1.checkLockfile)(isHook, cwd);
}
catch (error) {
(0, utils_1.logError)(`Error checking lockfile: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
}
}
async function handlePostInstall() {
const cwd = process.cwd();
try {
(0, post_install_1.runPostInstallHook)(cwd);
}
catch (error) {
(0, utils_1.logError)(`Error running post-install hook: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
}
}
async function main() {
const args = parseArgs(process.argv.slice(2));
if (args.help) {
showHelp();
return;
}
switch (args.command) {
case "install":
await handleInstall();
break;
case "uninstall":
await handleUninstall();
break;
case "check":
await handleCheck(args.isHook);
break;
case "post-install":
await handlePostInstall();
break;
case "help":
showHelp();
break;
default:
showStatus();
break;
}
}
// Run the CLI
main().catch((error) => {
(0, utils_1.logError)(`Unexpected error: ${error instanceof Error ? error.message : "Unknown error"}`);
process.exit(1);
});
//# sourceMappingURL=cli.js.map