117 lines
3.7 KiB
TypeScript
117 lines
3.7 KiB
TypeScript
/**
|
|
* Automated Git Hooks PoC (Gen 2 - Production Tooling)
|
|
*
|
|
* This script proves that we can hook into Git's native events to automatically
|
|
* generate code intelligence graphs. It creates a temporary Git repository,
|
|
* writes a real bash script to `.git/hooks/pre-commit`, and triggers a commit.
|
|
*/
|
|
|
|
import {
|
|
join,
|
|
} from "https://deno.land/std@0.224.0/path/mod.ts";
|
|
|
|
async function runCommand(cmd: string[], cwd: string): Promise<string> {
|
|
const command = new Deno.Command(cmd[0], {
|
|
args: cmd.slice(1),
|
|
cwd,
|
|
stdout: "piped",
|
|
stderr: "piped",
|
|
});
|
|
const { code, stdout, stderr } = await command.output();
|
|
const decoder = new TextDecoder();
|
|
|
|
if (code !== 0) {
|
|
throw new Error(
|
|
`Command ${cmd.join(" ")} failed: ${decoder.decode(stderr)}`,
|
|
);
|
|
}
|
|
return decoder.decode(stdout);
|
|
}
|
|
|
|
async function runGitHooksPoc() {
|
|
console.log("Starting Automated Git Hooks PoC (Gen 2)\n");
|
|
|
|
// Setup temporary directory
|
|
const tempDir = await Deno.makeTempDir({
|
|
prefix: "agent-forum-githook-poc-",
|
|
});
|
|
console.log(`[Git] Created temporary workspace: ${tempDir}`);
|
|
|
|
try {
|
|
// Init git
|
|
await runCommand(["git", "init"], tempDir);
|
|
|
|
// Write a mock pre-commit hook that simulates generating a SCIP index
|
|
const hookPath = join(tempDir, ".git", "hooks", "pre-commit");
|
|
const hookScript = `#!/bin/bash
|
|
echo "[Hook] Pre-commit hook triggered by Git natively!"
|
|
echo "[Hook] Extracting modified files..."
|
|
git diff --cached --name-only
|
|
echo "[Hook] Generating 'scip.graph' (Simulated via touch)..."
|
|
touch scip.graph
|
|
echo "[Hook] Execution complete. Proceeding with commit."
|
|
`;
|
|
|
|
await Deno.writeTextFile(hookPath, hookScript);
|
|
|
|
// Make the hook executable (chmod +x)
|
|
const chmodCmd = new Deno.Command("chmod", { args: ["+x", hookPath] });
|
|
await chmodCmd.output();
|
|
console.log("[Git] pre-commit hook installed and made executable.");
|
|
|
|
// Create a dummy file to commit
|
|
const testFile = join(tempDir, "target.js");
|
|
await Deno.writeTextFile(testFile, "console.log('Hello World');");
|
|
|
|
console.log("[Git] Staging files...");
|
|
await runCommand(["git", "add", "target.js"], tempDir);
|
|
|
|
console.log("[Git] Committing files to trigger hook...\n");
|
|
|
|
console.log("[Git] Configuring local git user...");
|
|
await runCommand(["git", "config", "user.name", "Test User"], tempDir);
|
|
await runCommand(["git", "config", "user.email", "test@test.com"], tempDir);
|
|
|
|
// We run the commit command and pipe the output so we can see the hook execute
|
|
const commitCmd = new Deno.Command("git", {
|
|
args: ["commit", "-m", "Initial commit"],
|
|
cwd: tempDir,
|
|
stdout: "piped",
|
|
stderr: "piped",
|
|
});
|
|
|
|
const { code: _code, stdout, stderr } = await commitCmd.output();
|
|
const decoder = new TextDecoder();
|
|
|
|
const output = decoder.decode(stdout);
|
|
console.log(output);
|
|
|
|
if (output.includes("Pre-commit hook triggered by Git natively!")) {
|
|
console.log(
|
|
"✅ Git pre-commit hook successfully intercepted commit and executed.",
|
|
);
|
|
|
|
// Verify the hook actually created the simulated artifact
|
|
const stat = await Deno.stat(join(tempDir, "scip.graph"));
|
|
if (stat.isFile) {
|
|
console.log(
|
|
"✅ Artifact 'scip.graph' successfully generated by the hook.",
|
|
);
|
|
}
|
|
} else {
|
|
console.error("❌ Hook did not appear to trigger.");
|
|
console.error(decoder.decode(stderr));
|
|
throw new Error("Hook execution failed.");
|
|
}
|
|
} finally {
|
|
// Cleanup
|
|
console.log(`\n[Git] Cleaning up temporary workspace: ${tempDir}`);
|
|
await Deno.remove(tempDir, { recursive: true });
|
|
console.log("Gen 2 Git Hooks execution completed successfully.");
|
|
}
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
runGitHooksPoc().catch(console.error);
|
|
}
|