|
1 | 1 | import chalk from "chalk";
|
2 | 2 | import { execa } from "execa";
|
3 |
| -import ora from "ora"; |
4 |
| -import { getUserPkgManager } from "~/utils/getUserPkgManager.js"; |
| 3 | +import ora, { Ora } from "ora"; |
| 4 | +import { |
| 5 | + getUserPkgManager, |
| 6 | + PackageManager, |
| 7 | +} from "~/utils/getUserPkgManager.js"; |
5 | 8 | import { logger } from "~/utils/logger.js";
|
6 | 9 |
|
7 | 10 | type Options = {
|
8 | 11 | projectDir: string;
|
9 | 12 | };
|
10 | 13 |
|
| 14 | +/*eslint-disable @typescript-eslint/no-floating-promises*/ |
| 15 | +const runInstallCommand = async ( |
| 16 | + pkgManager: PackageManager, |
| 17 | + projectDir: string, |
| 18 | +): Promise<Ora | null> => { |
| 19 | + switch (pkgManager) { |
| 20 | + // When using npm, inherit the stderr stream so that the progress bar is shown |
| 21 | + case "npm": |
| 22 | + await execa(pkgManager, ["install"], { |
| 23 | + cwd: projectDir, |
| 24 | + stderr: "inherit", |
| 25 | + }); |
| 26 | + |
| 27 | + return null; |
| 28 | + // When using yarn or pnpm, use the stdout stream and ora spinner to show the progress |
| 29 | + case "pnpm": |
| 30 | + const pnpmSpinner = ora("Running pnpm install...").start(); |
| 31 | + const pnpmSubprocess = execa(pkgManager, ["install"], { |
| 32 | + cwd: projectDir, |
| 33 | + stdout: "pipe", |
| 34 | + }); |
| 35 | + |
| 36 | + await new Promise<void>((res, rej) => { |
| 37 | + pnpmSubprocess.stdout?.on("data", (data: Buffer) => { |
| 38 | + const text = data.toString(); |
| 39 | + |
| 40 | + if (text.includes("Progress")) { |
| 41 | + pnpmSpinner.text = text.includes("|") |
| 42 | + ? text.split(" | ")[1] ?? "" |
| 43 | + : text; |
| 44 | + } |
| 45 | + }); |
| 46 | + pnpmSubprocess.on("error", (e) => rej(e)); |
| 47 | + pnpmSubprocess.on("close", () => res()); |
| 48 | + }); |
| 49 | + |
| 50 | + return pnpmSpinner; |
| 51 | + case "yarn": |
| 52 | + const yarnSpinner = ora("Running yarn...").start(); |
| 53 | + const yarnSubprocess = execa(pkgManager, [], { |
| 54 | + cwd: projectDir, |
| 55 | + stdout: "pipe", |
| 56 | + }); |
| 57 | + |
| 58 | + await new Promise<void>((res, rej) => { |
| 59 | + yarnSubprocess.stdout?.on("data", (data: Buffer) => { |
| 60 | + yarnSpinner.text = data.toString(); |
| 61 | + }); |
| 62 | + yarnSubprocess.on("error", (e) => rej(e)); |
| 63 | + yarnSubprocess.on("close", () => res()); |
| 64 | + }); |
| 65 | + |
| 66 | + return yarnSpinner; |
| 67 | + } |
| 68 | +}; |
| 69 | +/*eslint-enable @typescript-eslint/no-floating-promises*/ |
| 70 | + |
11 | 71 | export const installDependencies = async ({ projectDir }: Options) => {
|
12 | 72 | logger.info("Installing dependencies...");
|
13 | 73 | const pkgManager = getUserPkgManager();
|
14 |
| - const spinner = |
15 |
| - pkgManager === "yarn" |
16 |
| - ? ora("Running yarn...\n").start() |
17 |
| - : ora(`Running ${pkgManager} install...\n`).start(); |
18 |
| - |
19 |
| - // If the package manager is yarn, use yarn's default behavior to install dependencies |
20 |
| - if (pkgManager === "yarn") { |
21 |
| - await execa(pkgManager, [], { cwd: projectDir }); |
22 |
| - } else { |
23 |
| - await execa(pkgManager, ["install"], { cwd: projectDir }); |
24 |
| - } |
25 | 74 |
|
26 |
| - spinner.succeed(chalk.green("Successfully installed dependencies!\n")); |
| 75 | + const installSpinner = await runInstallCommand(pkgManager, projectDir); |
| 76 | + |
| 77 | + // If the spinner was used to show the progress, use succeed method on it |
| 78 | + // If not, use the succeed on a new spinner |
| 79 | + (installSpinner || ora()).succeed( |
| 80 | + chalk.green("Successfully installed dependencies!\n"), |
| 81 | + ); |
27 | 82 | };
|
0 commit comments