@git.zone/cli
Version:
A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.
108 lines (88 loc) • 3.11 kB
text/typescript
import * as plugins from './mod.plugins.js';
import type { IPlannedChange } from './interfaces.format.js';
import { logger } from '../gitzone.logging.js';
export class DiffReporter {
private diffs: Map<string, string> = new Map();
async generateDiff(filePath: string, oldContent: string, newContent: string): Promise<string> {
const diff = plugins.smartdiff.createDiff(oldContent, newContent);
this.diffs.set(filePath, diff);
return diff;
}
async generateDiffForChange(change: IPlannedChange): Promise<string | null> {
if (change.type !== 'modify') {
return null;
}
try {
const exists = await plugins.smartfile.fs.fileExists(change.path);
if (!exists) {
return null;
}
const currentContent = await plugins.smartfile.fs.toStringSync(change.path);
// For planned changes, we need the new content
if (!change.content) {
return null;
}
return await this.generateDiff(change.path, currentContent, change.content);
} catch (error) {
logger.log('error', `Failed to generate diff for ${change.path}: ${error.message}`);
return null;
}
}
displayDiff(filePath: string, diff?: string): void {
const diffToShow = diff || this.diffs.get(filePath);
if (!diffToShow) {
logger.log('warn', `No diff available for ${filePath}`);
return;
}
console.log(`\n${this.formatDiffHeader(filePath)}`);
console.log(this.colorDiff(diffToShow));
console.log('━'.repeat(50));
}
displayAllDiffs(): void {
if (this.diffs.size === 0) {
logger.log('info', 'No diffs to display');
return;
}
console.log('\nFile Changes:');
console.log('═'.repeat(50));
for (const [filePath, diff] of this.diffs) {
this.displayDiff(filePath, diff);
}
}
private formatDiffHeader(filePath: string): string {
return `📄 ${filePath}`;
}
private colorDiff(diff: string): string {
const lines = diff.split('\n');
const coloredLines = lines.map(line => {
if (line.startsWith('+') && !line.startsWith('+++')) {
return `\x1b[32m${line}\x1b[0m`; // Green for additions
} else if (line.startsWith('-') && !line.startsWith('---')) {
return `\x1b[31m${line}\x1b[0m`; // Red for deletions
} else if (line.startsWith('@')) {
return `\x1b[36m${line}\x1b[0m`; // Cyan for line numbers
} else {
return line;
}
});
return coloredLines.join('\n');
}
async saveDiffReport(outputPath: string): Promise<void> {
const report = {
timestamp: new Date().toISOString(),
totalFiles: this.diffs.size,
diffs: Array.from(this.diffs.entries()).map(([path, diff]) => ({
path,
diff
}))
};
await plugins.smartfile.memory.toFs(JSON.stringify(report, null, 2), outputPath);
logger.log('info', `Diff report saved to ${outputPath}`);
}
hasAnyDiffs(): boolean {
return this.diffs.size > 0;
}
getDiffCount(): number {
return this.diffs.size;
}
}