/ opencodehub / cli / src / lib / progress.ts
swadhinbiswas docs: complete documentation overhaul and changelog update · 1/21/2026
bba9bff
114 lines · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
 * Progress Indicators - GitHub-like output
 */

import chalk from "chalk";
import ora, { Ora } from "ora";
import cliProgress from "cli-progress";

/**
 * GitHub-style object enumeration output
 */
export function showObjectEnumeration(count: number): void {
    console.log(chalk.dim(`  Enumerating objects: ${count}, done.`));
}

/**
 * GitHub-style object counting with progress
 */
export function showObjectCounting(current: number, total: number): void {
    const percentage = Math.floor((current / total) * 100);
    console.log(chalk.dim(`  Counting objects: ${percentage}% (${current}/${total}), done.`));
}

/**
 * GitHub-style compression progress
 */
export function showCompression(objects: number, threads: number = 20): void {
    console.log(chalk.dim(`  Delta compression using up to ${threads} threads`));
    console.log(chalk.dim(`  Compressing objects: 100% (${objects}/${objects}), done.`));
}

/**
 * GitHub-style writing objects
 */
export function showWritingObjects(count: number, size: string, speed: string): void {
    console.log(chalk.dim(`  Writing objects: 100% (${count}/${count}), ${size} | ${speed}, done.`));
    console.log(chalk.dim(`  Total ${count} (delta 0), pack-reused 0`));
}

/**
 * Remote resolution message
 */
export function showRemoteResolving(operation: string, percentage: number, current: number, total: number): void {
    console.log(chalk.dim(`remote: ${operation}: ${percentage}% (${current}/${total}), done.`));
}

/**
 * Create a spinner for long operations
 */
export function createSpinner(text: string): Ora {
    return ora({
        text,
        color: "cyan",
        spinner: "dots",
    });
}

/**
 * Create a progress bar
 */
export function createProgressBar(): cliProgress.SingleBar {
    return new cliProgress.SingleBar({
        format: chalk.cyan("  {bar}") + " | {percentage}% | {value}/{total} {stage}",
        barCompleteChar: "█",
        barIncompleteChar: "░",
        hideCursor: true,
    });
}

/**
 * Format bytes to human-readable string
 */
export function formatBytes(bytes: number): string {
    if (bytes === 0) return "0 B";

    const k = 1024;
    const sizes = ["B", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}

/**
 * Format speed (bytes/second) to human-readable string
 */
export function formatSpeed(bytesPerSecond: number): string {
    return `${formatBytes(bytesPerSecond)}/s`;
}

/**
 * Show ref update (like GitHub push output)
 */
export function showRefUpdate(oldSha: string, newSha: string, ref: string, status: "new" | "updated" | "deleted"): void {
    const shortOld = oldSha.substring(0, 7);
    const shortNew = newSha.substring(0, 7);

    let symbol = " ";
    let color = chalk.white;

    if (status === "new") {
        symbol = "*";
        color = chalk.green;
    } else if (status === "updated") {
        symbol = " ";
        color = chalk.cyan;
    } else if (status === "deleted") {
        symbol = "-";
        color = chalk.red;
    }

    const range = status === "new" ? `[new branch]` : `${shortOld}..${shortNew}`;
    console.log(color(`${symbol} ${range.padEnd(20)} ${ref}`));
}