UNPKG

woaru

Version:

Universal Project Setup Autopilot - Analyze and automatically configure development tools for ANY programming language

166 lines 5.76 kB
import { spawn } from 'child_process'; import * as path from 'path'; import fs from 'fs-extra'; export class GitDiffAnalyzer { projectPath; constructor(projectPath) { this.projectPath = projectPath; } async isGitRepository() { return await fs.pathExists(path.join(this.projectPath, '.git')); } async getChangedFilesSince(baseBranch = 'main') { if (!(await this.isGitRepository())) { throw new Error('Not a git repository'); } return new Promise((resolve, reject) => { const gitProcess = spawn('git', ['diff', '--name-only', `${baseBranch}...HEAD`], { cwd: this.projectPath, stdio: 'pipe', }); let stdout = ''; let stderr = ''; gitProcess.stdout.on('data', (data) => { stdout += data.toString(); }); gitProcess.stderr.on('data', (data) => { stderr += data.toString(); }); gitProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Git command failed: ${stderr}`)); return; } const changedFiles = stdout .trim() .split('\n') .filter(file => file.length > 0) .map(file => path.resolve(this.projectPath, file)) .filter(file => fs.existsSync(file)); // Only include files that still exist resolve({ changedFiles, baseBranch, totalChanges: changedFiles.length, }); }); gitProcess.on('error', error => { reject(new Error(`Failed to execute git command: ${error.message}`)); }); }); } async getCurrentBranch() { return new Promise((resolve, reject) => { const gitProcess = spawn('git', ['branch', '--show-current'], { cwd: this.projectPath, stdio: 'pipe', }); let stdout = ''; let stderr = ''; gitProcess.stdout.on('data', (data) => { stdout += data.toString(); }); gitProcess.stderr.on('data', (data) => { stderr += data.toString(); }); gitProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Failed to get current branch: ${stderr}`)); return; } resolve(stdout.trim()); }); }); } async getCommitsSince(baseBranch = 'main') { return new Promise((resolve, reject) => { const gitProcess = spawn('git', ['log', '--oneline', `${baseBranch}...HEAD`], { cwd: this.projectPath, stdio: 'pipe', }); let stdout = ''; let stderr = ''; gitProcess.stdout.on('data', (data) => { stdout += data.toString(); }); gitProcess.stderr.on('data', (data) => { stderr += data.toString(); }); gitProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Failed to get commits: ${stderr}`)); return; } const commits = stdout .trim() .split('\n') .filter(line => line.length > 0); resolve(commits); }); }); } filterFilesByExtension(files, extensions) { return files.filter(file => { const ext = path.extname(file).toLowerCase(); return extensions.includes(ext); }); } categorizeChangedFiles(files) { const result = { source: [], config: [], tests: [], docs: [], other: [], }; files.forEach(file => { const filename = path.basename(file); const ext = path.extname(file).toLowerCase(); const relativePath = path.relative(this.projectPath, file); // Configuration files if ([ 'package.json', 'tsconfig.json', 'requirements.txt', 'Cargo.toml', 'go.mod', ].includes(filename) || ['.eslintrc', '.prettierrc', 'jest.config', 'pyproject.toml'].some(config => filename.includes(config))) { result.config.push(file); } // Test files else if (relativePath.includes('test') || relativePath.includes('spec') || filename.includes('.test.') || filename.includes('.spec.')) { result.tests.push(file); } // Documentation else if (['.md', '.txt', '.rst'].includes(ext) || relativePath.includes('docs')) { result.docs.push(file); } // Source files else if ([ '.js', '.jsx', '.ts', '.tsx', '.py', '.rs', '.go', '.java', '.cs', '.php', '.rb', ].includes(ext)) { result.source.push(file); } // Everything else else { result.other.push(file); } }); return result; } } //# sourceMappingURL=GitDiffAnalyzer.js.map