69 lines
2.7 KiB
JavaScript
69 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Link the harness's own packages into this checkout so `npm test` can import
|
|
* them, the way a plugin resolves them once installed into a profile.
|
|
*
|
|
* ## Why this exists
|
|
*
|
|
* The plugin imports `@deepseek-ai/dsh-tools` and `@deepseek-ai/schemastery`.
|
|
* Once installed into a profile those resolve from the profile's own
|
|
* `node_modules`, which is where the harness lives — but a bare checkout has no
|
|
* such tree, so the tests cannot even load the module under test.
|
|
*
|
|
* The alternative is declaring them as dependencies, and for `@deepseek-ai/cordis`
|
|
* that would be a genuine bug rather than untidiness: a second copy of Cordis
|
|
* means a second `Context` class, two service registries in one process, and a
|
|
* plugin whose services are invisible to the harness that loaded it. So the
|
|
* packages are linked, not installed.
|
|
*
|
|
* Idempotent, and safe to re-run after the harness is upgraded.
|
|
*/
|
|
|
|
import { existsSync, mkdirSync, readdirSync, rmSync, symlinkSync } from 'node:fs'
|
|
import { dirname, join, resolve } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
/** Packages this checkout imports at runtime, and which the harness must supply. */
|
|
const NEEDED = ['cordis', 'schemastery', 'dsh-tools']
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url))
|
|
const packageRoot = resolve(here, '..')
|
|
|
|
/** Where a dsh installation keeps the scope, newest layout first. */
|
|
function findHarnessScope() {
|
|
const candidates = [
|
|
process.env.DSH_HARNESS_NODE_MODULES,
|
|
resolve(process.env.DSH_HOME ?? join(process.env.HOME ?? '', '.dsh'), 'profiles', 'node_modules'),
|
|
'/usr/local/lib/node_modules/@deepseek-ai/dsh/node_modules',
|
|
]
|
|
for (const candidate of candidates) {
|
|
if (typeof candidate === 'string' && existsSync(join(candidate, '@deepseek-ai', 'cordis'))) return candidate
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
const scope = findHarnessScope()
|
|
if (scope === undefined) {
|
|
console.error('dev-links: no dsh installation found. Set DSH_HARNESS_NODE_MODULES to its node_modules directory.')
|
|
process.exit(1)
|
|
}
|
|
|
|
const target = join(packageRoot, 'node_modules')
|
|
mkdirSync(join(target, '@deepseek-ai'), { recursive: true })
|
|
|
|
let linked = 0
|
|
for (const name of NEEDED) {
|
|
const source = join(scope, '@deepseek-ai', name)
|
|
if (!existsSync(source)) {
|
|
console.error(`dev-links: ${name} is not in ${scope}; skipping`)
|
|
continue
|
|
}
|
|
const link = join(target, '@deepseek-ai', name)
|
|
if (existsSync(link)) rmSync(link, { recursive: true, force: true })
|
|
symlinkSync(source, link, 'dir')
|
|
linked += 1
|
|
}
|
|
|
|
const scopeLabel = readdirSync(join(scope, '@deepseek-ai')).length
|
|
console.log(`dev-links: linked ${linked}/${NEEDED.length} packages from ${scope} (${scopeLabel} available)`)
|