@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.
209 lines (182 loc) ⢠6.2 kB
text/typescript
import * as plugins from './mod.plugins.js';
import { logger } from '../gitzone.logging.js';
export interface IModuleStats {
name: string;
filesProcessed: number;
executionTime: number;
errors: number;
successes: number;
filesCreated: number;
filesModified: number;
filesDeleted: number;
}
export interface IFormatStats {
totalExecutionTime: number;
startTime: number;
endTime: number;
moduleStats: Map<string, IModuleStats>;
overallStats: {
totalFiles: number;
totalCreated: number;
totalModified: number;
totalDeleted: number;
totalErrors: number;
cacheHits: number;
cacheMisses: number;
};
}
export class FormatStats {
private stats: IFormatStats;
constructor() {
this.stats = {
totalExecutionTime: 0,
startTime: Date.now(),
endTime: 0,
moduleStats: new Map(),
overallStats: {
totalFiles: 0,
totalCreated: 0,
totalModified: 0,
totalDeleted: 0,
totalErrors: 0,
cacheHits: 0,
cacheMisses: 0
}
};
}
startModule(moduleName: string): void {
this.stats.moduleStats.set(moduleName, {
name: moduleName,
filesProcessed: 0,
executionTime: 0,
errors: 0,
successes: 0,
filesCreated: 0,
filesModified: 0,
filesDeleted: 0
});
}
moduleStartTime(moduleName: string): number {
return Date.now();
}
endModule(moduleName: string, startTime: number): void {
const moduleStats = this.stats.moduleStats.get(moduleName);
if (moduleStats) {
moduleStats.executionTime = Date.now() - startTime;
}
}
recordFileOperation(moduleName: string, operation: 'create' | 'modify' | 'delete', success: boolean = true): void {
const moduleStats = this.stats.moduleStats.get(moduleName);
if (!moduleStats) return;
moduleStats.filesProcessed++;
if (success) {
moduleStats.successes++;
this.stats.overallStats.totalFiles++;
switch (operation) {
case 'create':
moduleStats.filesCreated++;
this.stats.overallStats.totalCreated++;
break;
case 'modify':
moduleStats.filesModified++;
this.stats.overallStats.totalModified++;
break;
case 'delete':
moduleStats.filesDeleted++;
this.stats.overallStats.totalDeleted++;
break;
}
} else {
moduleStats.errors++;
this.stats.overallStats.totalErrors++;
}
}
recordCacheHit(): void {
this.stats.overallStats.cacheHits++;
}
recordCacheMiss(): void {
this.stats.overallStats.cacheMisses++;
}
finish(): void {
this.stats.endTime = Date.now();
this.stats.totalExecutionTime = this.stats.endTime - this.stats.startTime;
}
displayStats(): void {
console.log('\nš Format Operation Statistics:');
console.log('ā'.repeat(50));
// Overall stats
console.log('\nOverall Summary:');
console.log(` Total Execution Time: ${this.formatDuration(this.stats.totalExecutionTime)}`);
console.log(` Files Processed: ${this.stats.overallStats.totalFiles}`);
console.log(` ⢠Created: ${this.stats.overallStats.totalCreated}`);
console.log(` ⢠Modified: ${this.stats.overallStats.totalModified}`);
console.log(` ⢠Deleted: ${this.stats.overallStats.totalDeleted}`);
console.log(` Errors: ${this.stats.overallStats.totalErrors}`);
if (this.stats.overallStats.cacheHits > 0 || this.stats.overallStats.cacheMisses > 0) {
const cacheHitRate = this.stats.overallStats.cacheHits /
(this.stats.overallStats.cacheHits + this.stats.overallStats.cacheMisses) * 100;
console.log(` Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
console.log(` ⢠Hits: ${this.stats.overallStats.cacheHits}`);
console.log(` ⢠Misses: ${this.stats.overallStats.cacheMisses}`);
}
// Module stats
console.log('\nModule Breakdown:');
console.log('ā'.repeat(50));
const sortedModules = Array.from(this.stats.moduleStats.values())
.sort((a, b) => b.filesProcessed - a.filesProcessed);
for (const moduleStats of sortedModules) {
console.log(`\n${this.getModuleIcon(moduleStats.name)} ${moduleStats.name}:`);
console.log(` Execution Time: ${this.formatDuration(moduleStats.executionTime)}`);
console.log(` Files Processed: ${moduleStats.filesProcessed}`);
if (moduleStats.filesCreated > 0) {
console.log(` ⢠Created: ${moduleStats.filesCreated}`);
}
if (moduleStats.filesModified > 0) {
console.log(` ⢠Modified: ${moduleStats.filesModified}`);
}
if (moduleStats.filesDeleted > 0) {
console.log(` ⢠Deleted: ${moduleStats.filesDeleted}`);
}
if (moduleStats.errors > 0) {
console.log(` ā Errors: ${moduleStats.errors}`);
}
}
console.log('\n' + 'ā'.repeat(50));
}
async saveReport(outputPath: string): Promise<void> {
const report = {
timestamp: new Date().toISOString(),
executionTime: this.stats.totalExecutionTime,
overallStats: this.stats.overallStats,
moduleStats: Array.from(this.stats.moduleStats.values())
};
await plugins.smartfile.memory.toFs(JSON.stringify(report, null, 2), outputPath);
logger.log('info', `Statistics report saved to ${outputPath}`);
}
private formatDuration(ms: number): string {
if (ms < 1000) {
return `${ms}ms`;
} else if (ms < 60000) {
return `${(ms / 1000).toFixed(1)}s`;
} else {
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
return `${minutes}m ${seconds}s`;
}
}
private getModuleIcon(module: string): string {
const icons: Record<string, string> = {
'packagejson': 'š¦',
'license': 'š',
'tsconfig': 'š§',
'cleanup': 'š®',
'gitignore': 'š',
'prettier': 'āØ',
'readme': 'š',
'templates': 'š',
'npmextra': 'āļø',
'copy': 'š'
};
return icons[module] || 'š';
}
}