gitlify
Version:
A powerful CLI tool to analyze uncommitted git changes with detailed reports, function detection, and beautiful terminal output
132 lines (105 loc) • 3.62 kB
JavaScript
const termcolorized = require('termcolorized');
class ProgressReporter {
constructor(total, options = {}) {
this.total = total;
this.current = 0;
this.startTime = Date.now();
this.options = {
showPercentage: true,
showBar: true,
showSpeed: true,
showETA: true,
barWidth: 40,
...options
};
this.lastUpdateTime = Date.now();
this.lastCurrent = 0;
}
update(increment = 1, message = '') {
this.current += increment;
const now = Date.now();
// Calculate speed (items per second)
const timeDiff = (now - this.lastUpdateTime) / 1000;
const itemsDiff = this.current - this.lastCurrent;
const speed = timeDiff > 0 ? itemsDiff / timeDiff : 0;
// Calculate ETA
const remaining = this.total - this.current;
const eta = speed > 0 ? remaining / speed : 0;
// Calculate percentage
const percentage = Math.round((this.current / this.total) * 100);
// Build progress string
let progressStr = '';
if (this.options.showBar) {
progressStr += this.buildProgressBar(percentage);
}
if (this.options.showPercentage) {
progressStr += ` ${percentage}%`;
}
if (this.options.showSpeed && speed > 0) {
progressStr += ` (${speed.toFixed(1)}/s)`;
}
if (this.options.showETA && eta > 0) {
progressStr += ` ETA: ${this.formatTime(eta)}`;
}
if (message) {
progressStr += ` - ${message}`;
}
// Update display
process.stdout.write(`\r${progressStr}`);
// Update tracking
this.lastUpdateTime = now;
this.lastCurrent = this.current;
}
buildProgressBar(percentage) {
const barWidth = this.options.barWidth;
const filledWidth = Math.round((percentage / 100) * barWidth);
const emptyWidth = barWidth - filledWidth;
const filled = '█'.repeat(filledWidth);
const empty = '░'.repeat(emptyWidth);
return `[${filled}${empty}]`;
}
formatTime(seconds) {
if (seconds < 60) {
return `${Math.round(seconds)}s`;
} else if (seconds < 3600) {
const minutes = Math.floor(seconds / 60);
const remainingSeconds = Math.round(seconds % 60);
return `${minutes}m ${remainingSeconds}s`;
} else {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
return `${hours}h ${minutes}m`;
}
}
complete(message = 'Complete!') {
const totalTime = (Date.now() - this.startTime) / 1000;
const avgSpeed = this.total / totalTime;
let completionStr = `\n✅ ${message}`;
if (this.options.showSpeed) {
completionStr += ` (avg: ${avgSpeed.toFixed(1)}/s)`;
}
completionStr += ` - Total time: ${this.formatTime(totalTime)}`;
console.log(completionStr);
}
error(message) {
console.log(`\n❌ ${message}`);
}
// Static method for simple progress
static simple(total, callback) {
const progress = new ProgressReporter(total, {
showBar: true,
showPercentage: true,
showSpeed: false,
showETA: false
});
return {
update: (increment, message) => {
progress.update(increment, message);
if (callback) callback(progress.current, progress.total);
},
complete: (message) => progress.complete(message),
error: (message) => progress.error(message)
};
}
}
module.exports = ProgressReporter;