Enhances code extraction and project indexing
Adds support for Dart and Liquid languages with tree-sitter parsing. Improves accuracy of code symbol extraction for existing languages. Indexes project files to enhance code navigation features. Migrates build system to facilitate code contributions. Removes git hook functionality. Integrates Sentry for error tracking and reporting. Enhances project initialization and configuration loading.
This commit is contained in:
@@ -1,284 +0,0 @@
|
||||
/**
|
||||
* Git Hooks Management
|
||||
*
|
||||
* Installs and manages git hooks for automatic incremental indexing.
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
/**
|
||||
* Name of the post-commit hook file
|
||||
*/
|
||||
const POST_COMMIT_HOOK = 'post-commit';
|
||||
|
||||
/**
|
||||
* Marker comment to identify CodeGraph-managed hooks
|
||||
*/
|
||||
const CODEGRAPH_MARKER = '# CodeGraph auto-sync hook';
|
||||
|
||||
/**
|
||||
* The post-commit hook script content
|
||||
*
|
||||
* This script:
|
||||
* 1. Checks if codegraph CLI is available
|
||||
* 2. Falls back to npx if not
|
||||
* 3. Runs sync in the background to avoid blocking commits
|
||||
*/
|
||||
const POST_COMMIT_SCRIPT = `#!/bin/sh
|
||||
${CODEGRAPH_MARKER}
|
||||
# This hook was installed by CodeGraph to enable automatic incremental indexing.
|
||||
# It runs after each commit to keep the code graph in sync.
|
||||
# To remove this hook, run: codegraph hooks --remove
|
||||
# Or delete this file manually.
|
||||
|
||||
# Run sync in background to avoid blocking the commit
|
||||
(
|
||||
# Check if we're in a CodeGraph project
|
||||
if [ ! -d ".codegraph" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Try to run codegraph sync
|
||||
if command -v codegraph >/dev/null 2>&1; then
|
||||
codegraph sync --quiet 2>/dev/null &
|
||||
elif command -v npx >/dev/null 2>&1; then
|
||||
npx codegraph sync --quiet 2>/dev/null &
|
||||
fi
|
||||
) &
|
||||
|
||||
exit 0
|
||||
`;
|
||||
|
||||
/**
|
||||
* Result of hook installation
|
||||
*/
|
||||
export interface HookInstallResult {
|
||||
success: boolean;
|
||||
hookPath: string;
|
||||
message: string;
|
||||
previousHookBackedUp?: boolean;
|
||||
backupPath?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of hook removal
|
||||
*/
|
||||
export interface HookRemoveResult {
|
||||
success: boolean;
|
||||
message: string;
|
||||
restoredFromBackup?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Git hooks manager
|
||||
*/
|
||||
export class GitHooksManager {
|
||||
private gitDir: string;
|
||||
private hooksDir: string;
|
||||
|
||||
constructor(projectRoot: string) {
|
||||
this.gitDir = path.join(projectRoot, '.git');
|
||||
this.hooksDir = path.join(this.gitDir, 'hooks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the project is a git repository
|
||||
*/
|
||||
isGitRepository(): boolean {
|
||||
return fs.existsSync(this.gitDir) && fs.statSync(this.gitDir).isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the post-commit hook is installed by CodeGraph
|
||||
*/
|
||||
isHookInstalled(): boolean {
|
||||
const hookPath = path.join(this.hooksDir, POST_COMMIT_HOOK);
|
||||
|
||||
if (!fs.existsSync(hookPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const content = fs.readFileSync(hookPath, 'utf-8');
|
||||
return content.includes(CODEGRAPH_MARKER);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the post-commit hook
|
||||
*
|
||||
* If a hook already exists:
|
||||
* - If it's a CodeGraph hook, update it
|
||||
* - If it's a user hook, back it up and install ours
|
||||
*/
|
||||
installHook(): HookInstallResult {
|
||||
const hookPath = path.join(this.hooksDir, POST_COMMIT_HOOK);
|
||||
|
||||
// Check if this is a git repository
|
||||
if (!this.isGitRepository()) {
|
||||
return {
|
||||
success: false,
|
||||
hookPath,
|
||||
message: 'Not a git repository. Initialize git first with: git init',
|
||||
};
|
||||
}
|
||||
|
||||
// Ensure hooks directory exists
|
||||
if (!fs.existsSync(this.hooksDir)) {
|
||||
try {
|
||||
fs.mkdirSync(this.hooksDir, { recursive: true });
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
hookPath,
|
||||
message: `Failed to create hooks directory: ${error}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Check for existing hook
|
||||
let previousHookBackedUp = false;
|
||||
let backupPath: string | undefined;
|
||||
|
||||
if (fs.existsSync(hookPath)) {
|
||||
try {
|
||||
const existingContent = fs.readFileSync(hookPath, 'utf-8');
|
||||
|
||||
// If it's already our hook, just update it
|
||||
if (existingContent.includes(CODEGRAPH_MARKER)) {
|
||||
fs.writeFileSync(hookPath, POST_COMMIT_SCRIPT, { mode: 0o755 });
|
||||
return {
|
||||
success: true,
|
||||
hookPath,
|
||||
message: 'Post-commit hook updated.',
|
||||
};
|
||||
}
|
||||
|
||||
// It's a user hook - back it up
|
||||
backupPath = `${hookPath}.codegraph-backup`;
|
||||
fs.copyFileSync(hookPath, backupPath);
|
||||
previousHookBackedUp = true;
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
hookPath,
|
||||
message: `Failed to backup existing hook: ${error}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Write the hook
|
||||
try {
|
||||
fs.writeFileSync(hookPath, POST_COMMIT_SCRIPT, { mode: 0o755 });
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
hookPath,
|
||||
message: `Failed to write hook: ${error}`,
|
||||
};
|
||||
}
|
||||
|
||||
const message = previousHookBackedUp
|
||||
? `Post-commit hook installed. Previous hook backed up to: ${backupPath}`
|
||||
: 'Post-commit hook installed.';
|
||||
|
||||
return {
|
||||
success: true,
|
||||
hookPath,
|
||||
message,
|
||||
previousHookBackedUp,
|
||||
backupPath,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the CodeGraph post-commit hook
|
||||
*
|
||||
* If a backup exists, restore it.
|
||||
*/
|
||||
removeHook(): HookRemoveResult {
|
||||
const hookPath = path.join(this.hooksDir, POST_COMMIT_HOOK);
|
||||
const backupPath = `${hookPath}.codegraph-backup`;
|
||||
|
||||
// Check if hook exists
|
||||
if (!fs.existsSync(hookPath)) {
|
||||
return {
|
||||
success: true,
|
||||
message: 'No post-commit hook found.',
|
||||
};
|
||||
}
|
||||
|
||||
// Check if it's our hook
|
||||
try {
|
||||
const content = fs.readFileSync(hookPath, 'utf-8');
|
||||
if (!content.includes(CODEGRAPH_MARKER)) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Post-commit hook was not installed by CodeGraph. Not removing.',
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: `Failed to read hook: ${error}`,
|
||||
};
|
||||
}
|
||||
|
||||
// Remove the hook
|
||||
try {
|
||||
fs.unlinkSync(hookPath);
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: `Failed to remove hook: ${error}`,
|
||||
};
|
||||
}
|
||||
|
||||
// Restore backup if it exists
|
||||
if (fs.existsSync(backupPath)) {
|
||||
try {
|
||||
fs.renameSync(backupPath, hookPath);
|
||||
return {
|
||||
success: true,
|
||||
message: 'Post-commit hook removed. Previous hook restored from backup.',
|
||||
restoredFromBackup: true,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: true,
|
||||
message: `Post-commit hook removed. Warning: failed to restore backup: ${error}`,
|
||||
restoredFromBackup: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Post-commit hook removed.',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the hooks directory
|
||||
*/
|
||||
getHooksDir(): string {
|
||||
return this.hooksDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the post-commit hook
|
||||
*/
|
||||
getHookPath(): string {
|
||||
return path.join(this.hooksDir, POST_COMMIT_HOOK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a git hooks manager for a project
|
||||
*/
|
||||
export function createGitHooksManager(projectRoot: string): GitHooksManager {
|
||||
return new GitHooksManager(projectRoot);
|
||||
}
|
||||
Reference in New Issue
Block a user