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;
 | 
						|
  }
 | 
						|
}
 |