fix(notices): resolve current installed dependency versions

This commit is contained in:
Dudu-0223
2026-08-27 12:00:02 +08:00
parent 5a5e1b7373
commit a5cc8a2186
3 changed files with 66 additions and 14 deletions
+18
View File
@@ -114,6 +114,24 @@ describe('virtualManifest', () => {
}
})
it('selects the requested version when the store retains historical copies', () => {
const root = mkdtempSync(join(tmpdir(), 'dsh-notices-version-'))
try {
const name = '@scope/pkg'
const store = join(root, 'store')
for (const version of ['1.0.0', '2.0.0']) {
const manifestDir = join(store, `${name.replace('/', '+')}@${version}`, 'node_modules', name)
mkdirSync(manifestDir, { recursive: true })
writeFileSync(join(manifestDir, 'package.json'), JSON.stringify({ name, version, license: 'MIT' }))
}
expect(virtualManifest(store, name, '2.0.0')).toMatchObject({ name, version: '2.0.0' })
expect(virtualManifest(store, name, '3.0.0')).toBeUndefined()
} finally {
rmSync(root, { recursive: true, force: true })
}
})
it('returns undefined when neither the prefix nor the content scan finds the package', () => {
const root = mkdtempSync(join(tmpdir(), 'dsh-notices-miss-'))
try {
+47 -13
View File
@@ -9,7 +9,7 @@
*/
import { existsSync, globSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { dirname, resolve } from 'node:path'
import * as yaml from 'js-yaml'
import { parse as parseToml, type TomlTableWithoutBigInt, type TomlValueWithoutBigInt } from 'smol-toml'
import parseSpdx from 'spdx-expression-parse'
@@ -248,38 +248,72 @@ export function claudeDistributionFromManifest(
*
* @param virtual - the `.pnpm` virtual store directory to scan.
* @param name - the external package name, exactly as `node_modules` spells it.
* @param expectedVersion - exact version required when the store retains more than one.
* @returns the parsed manifest, or `undefined` when neither the prefix match
* nor the content scan finds the package's `package.json`.
* nor the content scan finds the requested package version.
*/
export function virtualManifest(virtual: string, name: string): VirtualManifest | undefined {
export function virtualManifest(
virtual: string,
name: string,
expectedVersion?: string,
): VirtualManifest | undefined {
const prefix = `${name.replace('/', '+')}@`
const entry = readdirSync(virtual).find(dir => dir.startsWith(prefix))
if (entry !== undefined) {
return JSON.parse(readFileSync(resolve(virtual, entry, 'node_modules', name, 'package.json'), 'utf8')) as VirtualManifest
const entries = readdirSync(virtual)
for (const entry of entries.filter(dir => dir.startsWith(prefix))) {
const manifest = JSON.parse(readFileSync(resolve(virtual, entry, 'node_modules', name, 'package.json'), 'utf8')) as VirtualManifest
if (expectedVersion === undefined || manifest.version === expectedVersion) return manifest
}
for (const dir of readdirSync(virtual)) {
for (const dir of entries) {
const candidate = resolve(virtual, dir, 'node_modules', name, 'package.json')
if (existsSync(candidate)) {
return JSON.parse(readFileSync(candidate, 'utf8')) as VirtualManifest
const manifest = JSON.parse(readFileSync(candidate, 'utf8')) as VirtualManifest
if (expectedVersion === undefined || manifest.version === expectedVersion) return manifest
}
}
return undefined
}
const workspaceLinkedManifestCache = new Map<string, VirtualManifest | undefined>()
/**
* Resolve the package version selected for a declaring workspace instead of an
* unrelated historical version that still occupies the shared virtual store.
* @param name - external package identity.
* @returns the first current workspace link for that package, when installed.
*/
function workspaceLinkedManifest(name: string): VirtualManifest | undefined {
if (workspaceLinkedManifestCache.has(name)) return workspaceLinkedManifestCache.get(name)
for (const [path, manifest] of loadWorkspaceManifests().manifests) {
if (!ALL_KINDS.some(kind => name in (manifest[kind] ?? {}))) continue
const linked = resolve(root, dirname(path), 'node_modules', name, 'package.json')
if (!existsSync(linked)) continue
const found = JSON.parse(readFileSync(linked, 'utf8')) as VirtualManifest
workspaceLinkedManifestCache.set(name, found)
return found
}
workspaceLinkedManifestCache.set(name, undefined)
return undefined
}
/** Resolve one installed external package manifest from either pnpm store. */
function installedManifest(name: string): VirtualManifest | undefined {
function installedManifest(name: string, expectedVersion?: string): VirtualManifest | undefined {
const linked = workspaceLinkedManifest(name)
if (linked !== undefined && (expectedVersion === undefined || linked.version === expectedVersion)) return linked
let manifest: (Manifest & { license?: string; repository?: string | { url?: string }; homepage?: string }) | undefined
// Workspace-local link farms can expose a dependency that is not linked at
// the repository root; both are backed by the root workspace's lockfile.
for (const store of ['node_modules', 'native/landlock-run/node_modules']) {
const direct = resolve(root, store, name, 'package.json')
if (existsSync(direct)) {
manifest = JSON.parse(readFileSync(direct, 'utf8')) as typeof manifest
break
const candidate = JSON.parse(readFileSync(direct, 'utf8')) as typeof manifest
if (expectedVersion === undefined || candidate?.version === expectedVersion) {
manifest = candidate
break
}
}
const virtual = resolve(root, store, '.pnpm')
if (!existsSync(virtual)) continue
manifest = virtualManifest(virtual, name)
manifest = virtualManifest(virtual, name, expectedVersion)
if (manifest !== undefined) break
}
return manifest
@@ -308,7 +342,7 @@ function collectClaudeDistribution(): ClaudeDistribution {
const distribution = claudeDistributionFromManifest(manifest)
let installedPayloads = 0
for (const payload of distribution.payloads) {
const installed = installedManifest(payload.name)
const installed = installedManifest(payload.name, payload.version)
if (installed === undefined) continue
installedPayloads += 1
if (