Skip to content

Commit 2e21b79

Browse files
committed
Add CLI spinner
1 parent 59284be commit 2e21b79

File tree

6 files changed

+62
-20
lines changed

6 files changed

+62
-20
lines changed

Diff for: index.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import * as fs from "node:fs";
44
import * as path from "node:path";
55

66
import { generateKeypair } from "./utils/generateKeypair";
7-
import { logBanner, logDone, logErrorAndExit, logStep } from "./utils/getLogs";
7+
import {
8+
logBanner,
9+
logDone,
10+
logErrorAndExit,
11+
logStep,
12+
spinner,
13+
} from "./utils/getLogs";
814
import { RenderContext, getRenderContext } from "./utils/getRenderContext";
915
import { renderTemplate } from "./utils/renderTemplates";
1016

@@ -17,18 +23,19 @@ import { renderTemplate } from "./utils/renderTemplates";
1723

1824
// Generate a keypair if needed.
1925
if (!ctx.hasCustomProgramAddress) {
20-
logStep(ctx.language.infos.generatingKeypair);
21-
await generateKeypair(ctx);
26+
await logStep(ctx.language.infos.generateKeypair, () =>
27+
generateKeypair(ctx)
28+
);
2229
}
2330

2431
// Render the templates.
25-
logStep(
26-
ctx.language.infos.scaffolding.replace(
32+
await logStep(
33+
ctx.language.infos.scaffold.replace(
2734
"$targetDirectory",
2835
ctx.targetDirectoryName
29-
)
36+
),
37+
() => renderTemplates(ctx)
3038
);
31-
renderTemplates(ctx);
3239

3340
// Done.
3441
logDone(ctx);

Diff for: locales/en-US.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@
6060
"multiselect": "[↑/↓]: Select / [space]: Toggle selection / [a]: Toggle all / [enter]: Submit answer"
6161
},
6262
"infos": {
63-
"scaffolding": "Scaffolding project in $targetDirectory...",
64-
"generatingKeypair": "Generating program keypair...",
63+
"scaffold": "Scaffold project in $targetDirectory",
64+
"generateKeypair": "Generate program keypair",
6565
"done": "Done. Now run:"
6666
}
6767
}

Diff for: locales/fr-FR.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@
6363
"multiselect": "[↑/↓]: Sélectionner / [espace]: Basculer la sélection / [a]: Basculer tout / [entrée]: Valider"
6464
},
6565
"infos": {
66-
"scaffolding": "Génération du projet dans $targetDirectory...",
67-
"generatingKeypair": "Génération de la paire de clés du program...",
66+
"scaffold": "Génére le projet dans $targetDirectory",
67+
"generateKeypair": "Génére la paire de clés du program",
6868
"done": "Terminé. Exécutez maintenant\u00a0:"
6969
}
7070
}

Diff for: utils/generateKeypair.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { logErrorAndExit } from "./getLogs";
21
import { RenderContext } from "./getRenderContext";
32
import {
43
spawnCommand,
@@ -10,7 +9,7 @@ import {
109
export async function generateKeypair(ctx: RenderContext): Promise<string> {
1110
const hasSolanaKeygen = await hasCommand("solana-keygen");
1211
if (!hasSolanaKeygen) {
13-
logErrorAndExit(ctx.language.errors.solanaKeygenNotFound);
12+
throw new Error(ctx.language.errors.solanaKeygenNotFound);
1413
}
1514

1615
// Run the solana-keygen command to generate a new keypair.

Diff for: utils/getLanguage.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export interface Language {
4242
multiselect: string;
4343
};
4444
infos: {
45-
scaffolding: string;
46-
generatingKeypair: string;
45+
scaffold: string;
46+
generateKeypair: string;
4747
done: string;
4848
};
4949
}

Diff for: utils/getLogs.ts

+41-5
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,29 @@ export function logBanner() {
77
console.log(`\n${getBanner()}\n`);
88
}
99

10-
export function logErrorAndExit(message: string) {
11-
logError(message);
12-
process.exit(1);
10+
export function logSuccess(message: string) {
11+
console.log(chalk.green("✔︎") + ` ${message}`);
1312
}
1413

1514
export function logError(message: string) {
1615
console.log(chalk.red("✖") + ` ${message}`);
1716
}
1817

19-
export function logStep(message: string) {
20-
console.log(chalk.blue("➤") + ` ${message}`);
18+
export function logErrorAndExit(message: string) {
19+
logError(message);
20+
process.exit(1);
21+
}
22+
23+
export async function logStep<T>(title: string, callback: () => T): Promise<T> {
24+
try {
25+
const result = await spinner(`${title}...`, callback);
26+
logSuccess(`${title}.`);
27+
return result;
28+
} catch (e) {
29+
logError(`${title}.\n`);
30+
console.log(e);
31+
process.exit(1);
32+
}
2133
}
2234

2335
export function logDone(ctx: RenderContext) {
@@ -41,6 +53,30 @@ export function logDone(ctx: RenderContext) {
4153
console.log();
4254
}
4355

56+
export async function spinner<T>(callback: () => T): Promise<T>;
57+
export async function spinner<T>(title: string, callback: () => T): Promise<T>;
58+
export async function spinner<T>(
59+
title: string | (() => T),
60+
callback?: () => T
61+
): Promise<T> {
62+
if (typeof title == "function") {
63+
callback = title;
64+
title = "";
65+
}
66+
let i = 0;
67+
const spin = () =>
68+
process.stderr.write(` ${"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"[i++ % 10]} ${title}\r`);
69+
const id = setInterval(spin, 100);
70+
let result: T;
71+
try {
72+
result = await callback!();
73+
} finally {
74+
clearInterval(id as NodeJS.Timeout);
75+
process.stderr.write(" ".repeat(process.stdout.columns - 1) + "\r");
76+
}
77+
return result;
78+
}
79+
4480
function getBanner() {
4581
const textBanner = "Create Solana Program";
4682
const gradientBanner = chalk.bold(

0 commit comments

Comments
 (0)