From 61c62ec16bd3036edfff27bcced77de38257a206 Mon Sep 17 00:00:00 2001 From: CokaKoala <31664583+AdrianGonz97@users.noreply.github.com> Date: Thu, 14 Nov 2024 18:13:54 -0500 Subject: [PATCH] feat: display package manager output during dependency installs (#305) --- .changeset/fluffy-readers-attend.md | 5 +++ packages/clack-prompts/index.ts | 46 +++++++++++++++++++++++++++ packages/cli/utils/package-manager.ts | 31 +++++++++++------- 3 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 .changeset/fluffy-readers-attend.md diff --git a/.changeset/fluffy-readers-attend.md b/.changeset/fluffy-readers-attend.md new file mode 100644 index 00000000..6e207ac7 --- /dev/null +++ b/.changeset/fluffy-readers-attend.md @@ -0,0 +1,5 @@ +--- +'sv': patch +--- + +feat: display package manager output during dependency installs diff --git a/packages/clack-prompts/index.ts b/packages/clack-prompts/index.ts index 2454104d..2e9c36af 100644 --- a/packages/clack-prompts/index.ts +++ b/packages/clack-prompts/index.ts @@ -603,6 +603,52 @@ function buildBox(message = '', title = '', dimmed = true) { export const note = (message = '', title = ''): void => buildBox(message, title, true); export const box = (message = '', title = ''): void => buildBox(message, title, false); +export const taskLog = (title: string) => { + const BAR = color.dim(S_BAR); + const ACTIVE = color.green(S_STEP_SUBMIT); + const SUCCESS = color.green(S_SUCCESS); + const ERROR = color.red(S_ERROR); + + // heading + process.stdout.write(`${BAR}\n`); + process.stdout.write(`${ACTIVE} ${title}\n`); + + let output = ''; + + // clears previous output + const clear = (buffer = 0): void => { + if (!output) return; + const lines = output.split('\n').length + buffer; + process.stdout.write(erase.lines(lines + 1)); + }; + + // logs the output + const print = (): void => { + const lines = output.split('\n'); + for (const line of lines) { + const msg = color.dim(`${BAR} ${line}\n`); + process.stdout.write(msg); + } + }; + + return { + set text(data: string) { + clear(); + output += data; + print(); + }, + fail(message: string): void { + clear(1); // includes clearing the `title` + process.stdout.write(`${ERROR} ${message}\n`); + // log the output on failure + print(); + }, + success(message: string): void { + clear(1); // includes clearing the `title` + process.stdout.write(`${SUCCESS} ${message}\n`); + } + }; +}; export const cancel = (message = ''): void => { process.stdout.write(`${color.gray(S_BAR_END)} ${color.red(message)}\n\n`); diff --git a/packages/cli/utils/package-manager.ts b/packages/cli/utils/package-manager.ts index ffb3ad1b..0f979fc2 100644 --- a/packages/cli/utils/package-manager.ts +++ b/packages/cli/utils/package-manager.ts @@ -1,5 +1,5 @@ import process from 'node:process'; -import { exec, NonZeroExitError } from 'tinyexec'; +import { exec } from 'tinyexec'; import * as p from '@sveltejs/clack-prompts'; import { AGENTS, @@ -32,22 +32,29 @@ export async function packageManagerPrompt(cwd: string): Promise { - const spinner = p.spinner(); - spinner.start('Installing dependencies...'); + const task = p.taskLog(`Installing dependencies with ${agent}...`); + try { const { command, args } = constructCommand(COMMANDS[agent].install, [])!; - await exec(command, args, { nodeOptions: { cwd }, throwOnError: true }); + const proc = exec(command, args, { + nodeOptions: { cwd, stdio: 'pipe' }, + throwOnError: true + }); - spinner.stop('Successfully installed dependencies'); - } catch (error) { - spinner.stop('Failed to install dependencies', 2); + proc.process?.stdout?.on('data', (data) => { + task.text = data; + }); + proc.process?.stderr?.on('data', (data) => { + task.text = data; + }); - if (error instanceof NonZeroExitError) { - const stderr = error.output?.stderr; - if (stderr) p.log.error(stderr); - } + await proc; - throw error; + task.success('Successfully installed dependencies'); + } catch { + task.fail('Failed to install dependencies'); + p.cancel('Operation failed.'); + process.exit(2); } }