feat: add package count summary to pnpm list tree output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Zoltan Kochan
2026-02-14 13:52:10 +01:00
parent 297aac363a
commit 5bb934ebb5
3 changed files with 37 additions and 1 deletions

View File

@@ -117,6 +117,7 @@ export async function listForPackages (
modulesDir?: string
virtualStoreDirMaxLength: number
finders?: Finder[]
showSummary?: boolean
}
): Promise<string> {
const opts = { ...DEFAULTS, ...maybeOpts }
@@ -130,6 +131,7 @@ export async function listForPackages (
long: opts.long,
search: Boolean(packages.length),
showExtraneous: opts.showExtraneous,
showSummary: opts.showSummary,
})
}
@@ -150,6 +152,7 @@ export async function list (
modulesDir?: string
virtualStoreDirMaxLength: number
finders?: Finder[]
showSummary?: boolean
}
): Promise<string> {
const opts = { ...DEFAULTS, ...maybeOpts }
@@ -193,6 +196,7 @@ export async function list (
long: opts.long,
search: false,
showExtraneous: opts.showExtraneous,
showSummary: opts.showSummary,
})
}
@@ -202,6 +206,7 @@ type Printer = (packages: PackageDependencyHierarchy[], opts: {
long: boolean
search: boolean
showExtraneous: boolean
showSummary?: boolean
}) => Promise<string>
function getPrinter (reportAs: 'parseable' | 'tree' | 'json'): Printer {

View File

@@ -21,6 +21,7 @@ export interface RenderTreeOptions {
long: boolean
search: boolean
showExtraneous: boolean
showSummary?: boolean
}
export async function renderTree (
@@ -33,7 +34,9 @@ export async function renderTree (
)
.filter(Boolean)
.join('\n\n')
return `${(opts.depth > -1 && output ? LEGEND : '')}${output}`
const legend = opts.depth > -1 && output ? LEGEND : ''
const summary = opts.showSummary && opts.depth > -1 && output ? `\n\n${listSummary(packages)}` : ''
return `${legend}${output}${summary}`
}
async function renderTreeForPackage (
@@ -206,3 +209,30 @@ function findMultiPeerPackages (packages: PackageDependencyHierarchy[]): Map<str
return filterMultiPeerEntries(hashesPerPkg)
}
function listSummary (packages: PackageDependencyHierarchy[]): string {
let total = 0
function walk (nodes: PackageNode[]): void {
for (const node of nodes) {
total++
if (node.dependencies) {
walk(node.dependencies)
}
}
}
for (const pkg of packages) {
for (const field of DEPENDENCIES_FIELDS) {
if (pkg[field]) {
walk(pkg[field])
}
}
}
const parts: string[] = [`${total} package${total === 1 ? '' : 's'}`]
if (packages.length > 1) {
parts.push(`${packages.length} projects`)
}
return chalk.dim(parts.join(' in '))
}

View File

@@ -214,6 +214,7 @@ export async function render (
onlyProjects: opts.onlyProjects,
reportAs: (opts.parseable ? 'parseable' : (opts.json ? 'json' : 'tree')) as ('parseable' | 'json' | 'tree'),
showExtraneous: false,
showSummary: true,
modulesDir: opts.modulesDir,
virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,
finders,