From c108002dead3b7397aa2f39d9081eb605b2b42f6 Mon Sep 17 00:00:00 2001 From: outslept <135520429+outslept@users.noreply.github.com> Date: Sat, 9 Aug 2025 11:56:36 +0300 Subject: [PATCH 1/2] feat: accept directory path or tarball; clarify invalid-path error --- src/commands/analyze.ts | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/commands/analyze.ts b/src/commands/analyze.ts index 984ec69..4423ccf 100644 --- a/src/commands/analyze.ts +++ b/src/commands/analyze.ts @@ -30,9 +30,10 @@ function formatBytes(bytes: number) { } export async function run(ctx: CommandContext) { - const root = ctx.positionals[1]; + const [_commandName, providedPath] = ctx.positionals; let pack: PackType = ctx.values.pack; const logLevel = ctx.values['log-level']; + let root: string | undefined = undefined; // Enable debug output based on log level if (logLevel === 'debug') { @@ -48,29 +49,35 @@ export async function run(ctx: CommandContext) { process.exit(1); } - // If a path is passed, it must be a tarball file - if (root) { + // Path can be a directory (analyze project) or a tarball file (analyze tarball) + if (providedPath) { + let stat: import('node:fs').Stats | null = null; try { - const stat = await fs.stat(root); - if (stat.isFile()) { - const buffer = await fs.readFile(root); - pack = {tarball: buffer.buffer as ArrayBuffer}; - } else { - // Not a file, exit - prompts.cancel( - `When '--pack file' is used, a path to a tarball file must be passed.` - ); - process.exit(1); - } - } catch (error) { + stat = await fs.stat(providedPath); + } catch { + stat = null; + } + + if (!stat || (!stat.isFile() && !stat.isDirectory())) { prompts.cancel( - `Failed to read tarball file: ${error instanceof Error ? error.message : String(error)}` + `Path must be a tarball file or a directory: ${providedPath}` ); process.exit(1); } + + if (stat.isFile()) { + const buffer = await fs.readFile(providedPath); + const tarball = buffer.buffer.slice( + buffer.byteOffset, + buffer.byteOffset + buffer.byteLength + ) as ArrayBuffer; + pack = {tarball}; + } else { + root = providedPath; // analyze this directory (respecting --pack) + } } - // Then analyze the tarball + // Analyze const {stats, messages} = await report({root, pack}); prompts.log.info('Summary'); From af4dcc0418e340f94932d1be17ae640a04bb8057 Mon Sep 17 00:00:00 2001 From: outslept <135520429+outslept@users.noreply.github.com> Date: Tue, 12 Aug 2025 02:51:43 +0300 Subject: [PATCH 2/2] fix: top level type import --- src/commands/analyze.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/analyze.ts b/src/commands/analyze.ts index 4423ccf..ceb7f03 100644 --- a/src/commands/analyze.ts +++ b/src/commands/analyze.ts @@ -1,5 +1,5 @@ import {type CommandContext} from 'gunshi'; -import fs from 'node:fs/promises'; +import {promises as fsp, type Stats} from 'node:fs'; import * as prompts from '@clack/prompts'; import c from 'picocolors'; import {meta} from './analyze.meta.js'; @@ -51,9 +51,9 @@ export async function run(ctx: CommandContext) { // Path can be a directory (analyze project) or a tarball file (analyze tarball) if (providedPath) { - let stat: import('node:fs').Stats | null = null; + let stat: Stats | null = null; try { - stat = await fs.stat(providedPath); + stat = await fsp.stat(providedPath); } catch { stat = null; } @@ -66,7 +66,7 @@ export async function run(ctx: CommandContext) { } if (stat.isFile()) { - const buffer = await fs.readFile(providedPath); + const buffer = await fsp.readFile(providedPath); const tarball = buffer.buffer.slice( buffer.byteOffset, buffer.byteOffset + buffer.byteLength