vibe-codex
Version:
CLI tool to install development rules and git hooks with interactive configuration
175 lines (145 loc) • 4.87 kB
JavaScript
/**
* Downloads and installs actual hook scripts from the repository
*/
const fs = require("fs-extra");
const path = require("path");
const fetch = require("node-fetch");
const chalk = require("chalk");
const logger = require("../utils/logger");
const HOOKS_BASE_URL =
"https://raw.githubusercontent.com/tyabonil/vibe-codex/main/hooks";
const HOOK_SCRIPTS = {
"enhanced-pre-commit.sh": "Comprehensive pre-commit validation",
"commit-msg-validator.sh": "Commit message format validation",
"issue-progress-tracker.sh": "GitHub issue progress tracking",
"pr-health-check.sh": "Pull request health checks",
"security-pre-commit.sh": "Security and secrets scanning",
"test-coverage-validator.sh": "Test coverage validation",
"branch-name-validator.sh": "Branch naming convention checks",
"post-merge-cleanup.sh": "Post-merge branch cleanup",
};
/**
* Download and install hook scripts
* @param {Object} config - Configuration object
* @param {Object} options - Installation options
* @returns {Promise<Array>} List of installed hooks
*/
async function downloadHookScripts(config, options = {}) {
const hooksDir = "hooks";
await fs.ensureDir(hooksDir);
const installedHooks = [];
const selectedHooks = selectHooksForConfig(config);
for (const hookFile of selectedHooks) {
try {
console.log(chalk.blue(` 📥 Downloading ${hookFile}...`));
const url = `${HOOKS_BASE_URL}/${hookFile}`;
await downloadFile(url, path.join(hooksDir, hookFile));
// Make the hook executable
await fs.chmod(path.join(hooksDir, hookFile), "755");
installedHooks.push(hookFile);
console.log(chalk.green(` ✓ Installed ${hookFile}`));
} catch (error) {
logger.warn(` ⚠ Failed to download ${hookFile}: ${error.message}`);
}
}
// Create install-hooks.sh script
await createInstallScript(hooksDir);
return installedHooks;
}
/**
* Select which hooks to download based on configuration
* @param {Object} config - Configuration object
* @returns {Array<string>} List of hook files to download
*/
function selectHooksForConfig(config) {
const hooks = new Set();
// Always include core hooks
hooks.add("enhanced-pre-commit.sh");
hooks.add("commit-msg-validator.sh");
hooks.add("security-pre-commit.sh");
// Add module-specific hooks
if (config.modules?.github?.enabled) {
hooks.add("issue-progress-tracker.sh");
hooks.add("pr-health-check.sh");
}
if (config.modules?.testing?.enabled) {
hooks.add("test-coverage-validator.sh");
}
// Add workflow hooks
hooks.add("branch-name-validator.sh");
hooks.add("post-merge-cleanup.sh");
return Array.from(hooks);
}
/**
* Download a file from URL
* @param {string} url - URL to download from
* @param {string} destination - Local file path
* @returns {Promise<void>}
*/
async function downloadFile(url, destination) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to download: ${response.statusText}`);
}
const content = await response.text();
await fs.writeFile(destination, content, "utf-8");
}
/**
* Create install-hooks.sh script
* @param {string} hooksDir - Hooks directory path
* @returns {Promise<void>}
*/
async function createInstallScript(hooksDir) {
const installScript = `#!/bin/bash
# vibe-codex hooks installer
# Generated by vibe-codex
set -e
echo "🔧 Installing vibe-codex git hooks..."
# Ensure .git/hooks directory exists
mkdir -p .git/hooks
# Install pre-commit hook
if [ -f "hooks/enhanced-pre-commit.sh" ]; then
cp hooks/enhanced-pre-commit.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
echo "✓ Installed pre-commit hook"
fi
# Install commit-msg hook
if [ -f "hooks/commit-msg-validator.sh" ]; then
cp hooks/commit-msg-validator.sh .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg
echo "✓ Installed commit-msg hook"
fi
# Install post-commit hook
if [ -f "hooks/issue-progress-tracker.sh" ]; then
cat > .git/hooks/post-commit << 'EOF'
#!/bin/bash
# Run issue progress tracker
if [ -f "./hooks/issue-progress-tracker.sh" ]; then
./hooks/issue-progress-tracker.sh auto commit
fi
EOF
chmod +x .git/hooks/post-commit
echo "✓ Installed post-commit hook"
fi
# Install post-merge hook
if [ -f "hooks/post-merge-cleanup.sh" ]; then
cp hooks/post-merge-cleanup.sh .git/hooks/post-merge
chmod +x .git/hooks/post-merge
echo "✓ Installed post-merge hook"
fi
echo "✅ Git hooks installation complete!"
echo ""
echo "To manually run hooks:"
echo " ./hooks/enhanced-pre-commit.sh"
echo " ./hooks/pr-health-check.sh"
echo ""
`;
const scriptPath = path.join(hooksDir, "..", "install-hooks.sh");
await fs.writeFile(scriptPath, installScript, "utf-8");
await fs.chmod(scriptPath, "755");
}
module.exports = {
downloadHookScripts,
selectHooksForConfig,
HOOK_SCRIPTS,
};