125 lines
3.1 KiB
TypeScript
125 lines
3.1 KiB
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;
|
|
}
|
|
}
|