UNPKG

dna-template-cli

Version:

DNA Template CLI v0.3.4 - Enhanced Commands Added (enhanced-create, enhanced-list, enhanced-validate)

221 lines (220 loc) 8.02 kB
"use strict"; /** * @fileoverview Git Automation Mock - Simplified implementation for CLI commands */ Object.defineProperty(exports, "__esModule", { value: true }); exports.gitQualityIntegration = exports.GitQualityIntegration = exports.GitAutomationSystem = void 0; const child_process_1 = require("child_process"); const util_1 = require("util"); const execAsync = (0, util_1.promisify)(child_process_1.exec); class GitAutomationSystem { constructor(config = {}) { this.config = { autoCommit: false, pushRemote: false, requireTests: true, conventionalCommits: true, ...config, }; } async createFeatureBranch(name, epic, story) { try { let branchName = name; if (epic && story) { branchName = `feature/${epic}/${story}`; } else if (epic) { branchName = `feature/${epic}`; } await execAsync(`git checkout -b ${branchName}`); return { success: true, branchName, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', }; } } async validateCommitMessage(message) { const errors = []; const warnings = []; if (!this.config.conventionalCommits) { return { valid: true, errors, warnings }; } // Conventional commit pattern: type(scope): description const conventionalPattern = /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,50}/; if (!conventionalPattern.test(message)) { errors.push('Commit message must follow conventional commits format: type(scope): description'); errors.push('Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert'); } if (message.length > 72) { warnings.push('Commit message is longer than 72 characters'); } return { valid: errors.length === 0, errors, warnings, }; } async commit(message, options = {}) { try { // Validate commit message const validation = await this.validateCommitMessage(message); if (!validation.valid) { return { success: false, error: validation.errors.join(', '), }; } // Run tests if required if (this.config.requireTests) { const testResult = await this.runTests(); if (!testResult.success) { return { success: false, error: 'Tests failed - commit blocked', }; } } // Stage files if requested if (options.all) { await execAsync('git add .'); } // Commit const commitCommand = options.amend ? `git commit --amend -m "${message}"` : `git commit -m "${message}"`; const { stdout } = await execAsync(commitCommand); // Extract commit hash const hashMatch = stdout.match(/\[.+\s([a-f0-9]+)\]/); const hash = hashMatch ? hashMatch[1] : undefined; return { success: true, hash, message, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', }; } } async push(remote = 'origin', branch) { try { const currentBranch = branch || await this.getCurrentBranch(); await execAsync(`git push ${remote} ${currentBranch}`); return { success: true, message: `Pushed to ${remote}/${currentBranch}`, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Unknown error', }; } } async getStatus() { try { const { stdout: statusOutput } = await execAsync('git status --porcelain'); const { stdout: branchOutput } = await execAsync('git branch --show-current'); const modified = []; const untracked = []; const staged = []; statusOutput.split('\n').forEach(line => { if (line.trim()) { const status = line.substring(0, 2); const file = line.substring(3); if (status[0] === 'M' || status[0] === 'A' || status[0] === 'D') { staged.push(file); } if (status[1] === 'M') { modified.push(file); } if (status === '??') { untracked.push(file); } } }); return { branch: branchOutput.trim(), modified, untracked, staged, ahead: 0, // Simplified behind: 0, // Simplified clean: modified.length === 0 && untracked.length === 0 && staged.length === 0, }; } catch (error) { throw new Error(`Failed to get git status: ${error}`); } } async autoCommitOnTestSuccess(testResults) { if (!this.config.autoCommit) { return { success: false, error: 'Auto-commit disabled' }; } const status = await this.getStatus(); if (status.clean) { return { success: false, error: 'No changes to commit' }; } const message = this.generateCommitMessage(testResults); return await this.commit(message, { all: true }); } async commitQualityUpdate(data) { const message = `test: update quality metrics and test results - Coverage: ${data.coverageReport?.lines || 0}% - Quality Gates: ${data.qualityResults?.passed ? 'PASSED' : 'FAILED'} - Tests: ${data.testResults?.length || 0} frameworks tested`; return await this.commit(message, { all: true }); } async getCurrentBranch() { const { stdout } = await execAsync('git branch --show-current'); return stdout.trim(); } async runTests() { try { // Simple test runner check await execAsync('npm test -- --passWithNoTests', { timeout: 60000 }); return { success: true }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Tests failed', }; } } generateCommitMessage(testResults) { const passedCount = testResults.filter(r => r.success).length; const totalCount = testResults.length; if (passedCount === totalCount) { return `test: all tests passing (${totalCount} frameworks)`; } else { return `test: ${passedCount}/${totalCount} frameworks passing`; } } } exports.GitAutomationSystem = GitAutomationSystem; class GitQualityIntegration { constructor(config = {}) { this.gitSystem = new GitAutomationSystem(config); } async autoCommitOnTestSuccess(testResults) { return await this.gitSystem.autoCommitOnTestSuccess(testResults); } async commitQualityUpdate(data) { return await this.gitSystem.commitQualityUpdate(data); } } exports.GitQualityIntegration = GitQualityIntegration; exports.gitQualityIntegration = new GitQualityIntegration(); //# sourceMappingURL=git-automation.js.map