mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(fs-search): address the second-round #1119 review
- inline the collect() identity wrapper now that both streams use the seam's diagnostic-tail shape - resolve the packaged rg path lazily at the first call (memoized): @vscode/ripgrep resolves its platform package at module evaluation, so a static import turned a missing/corrupt platform package into a Loader composition failure instead of the documented per-call SEARCH_FAILED - classify synchronous spawn-creation throws (a NUL in argv, an abort racing the pre-check, a rejected resolution) into SEARCH_FAILED / SEARCH_ABORTED instead of leaking raw errors - correct the stderrMaxBytes contract: the stderr excerpt is embedded in SEARCH_* error messages, not hidden from the model - export virtualManifest and pin its three acceptance paths (prefix hit, pnpm-11 truncated-name content-scan fallback, both miss) with fixture unit tests Tests: rg-path.spec.ts (resolution failure + memoized rejection), tools.spec.ts spawn-creation classification, notices spec virtualManifest.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { readdirSync, readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { collectPythonDependencies, isPermissive, type Manifest, manifestPatterns, parsePyprojectRequirements, parseVendoredRows, render, tierExternalDeps } from './gen-third-party-notices.ts'
|
||||
import { collectPythonDependencies, isPermissive, type Manifest, manifestPatterns, parsePyprojectRequirements, parseVendoredRows, render, tierExternalDeps, virtualManifest } from './gen-third-party-notices.ts'
|
||||
|
||||
const root = resolve(import.meta.dirname, '..')
|
||||
|
||||
@@ -63,6 +64,56 @@ describe('tierExternalDeps', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('virtualManifest', () => {
|
||||
it('resolves a manifest from an ordinary prefix-matching store directory', () => {
|
||||
const root = mkdtempSync(join(tmpdir(), 'dsh-notices-prefix-'))
|
||||
try {
|
||||
const name = '@scope/pkg'
|
||||
const version = '1.0.0'
|
||||
const store = join(root, 'store')
|
||||
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)).toMatchObject({ name, version, license: 'MIT' })
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it('falls back to a content scan when pnpm 11 truncates the store directory name', () => {
|
||||
const root = mkdtempSync(join(tmpdir(), 'dsh-notices-truncated-'))
|
||||
try {
|
||||
const name = '@scope/pkg'
|
||||
const version = '2.0.0'
|
||||
const store = join(root, 'store')
|
||||
// The truncated name no longer starts with `@scope+pkg@`, so only the
|
||||
// whole-store content scan can find the package.
|
||||
const manifestDir = join(store, '@scope+pkg_9f1c2d3e4a5b6c7d8e9f0a1b2c3d4e5f', 'node_modules', name)
|
||||
mkdirSync(manifestDir, { recursive: true })
|
||||
writeFileSync(join(manifestDir, 'package.json'), JSON.stringify({ name, version, license: 'Apache-2.0' }))
|
||||
|
||||
expect(virtualManifest(store, name)).toMatchObject({ name, version, license: 'Apache-2.0' })
|
||||
} 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 {
|
||||
const store = join(root, 'store')
|
||||
const other = join(store, 'other-pkg@1.0.0', 'node_modules', 'other-pkg')
|
||||
mkdirSync(other, { recursive: true })
|
||||
writeFileSync(join(other, 'package.json'), JSON.stringify({ name: 'other-pkg', version: '1.0.0' }))
|
||||
|
||||
expect(virtualManifest(store, '@scope/missing')).toBeUndefined()
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseVendoredRows', () => {
|
||||
it('reads the committed vendor manifest table', () => {
|
||||
const rows = parseVendoredRows(readFileSync(resolve(root, 'vendor/README.md'), 'utf8'))
|
||||
|
||||
@@ -172,8 +172,13 @@ type VirtualManifest = Manifest & { license?: string; repository?: string | { ur
|
||||
* long names (a peer-suffixed name past the length limit becomes
|
||||
* `<prefix>_<hash>`), so a content scan falls back over the whole store when
|
||||
* the prefix misses.
|
||||
*
|
||||
* @param virtual - the `.pnpm` virtual store directory to scan.
|
||||
* @param name - the external package name, exactly as `node_modules` spells it.
|
||||
* @returns the parsed manifest, or `undefined` when neither the prefix match
|
||||
* nor the content scan finds the package's `package.json`.
|
||||
*/
|
||||
function virtualManifest(virtual: string, name: string): VirtualManifest | undefined {
|
||||
export function virtualManifest(virtual: string, name: string): VirtualManifest | undefined {
|
||||
const prefix = `${name.replace('/', '+')}@`
|
||||
const entry = readdirSync(virtual).find(dir => dir.startsWith(prefix))
|
||||
if (entry !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user