dsh --profile <name> replaces the fixed entry modes: --config and -p are removed, --patch adds overlays over the composed profile, a positional task selects one-shot mode (requires the headless-runner row), and dsh web stays as the alias for --profile web carrying the Web flag family as patches. dsh plugin --profile <name> forwards verbatim to pnpm in the profile directory, initializes on first use, and reconciles the dsh.plugins layer list after add/remove (patch-less packages warn and stay plain dependencies). Config dumps and the keyless web e2e scaffold compose the same bundle layers over the same empty root as the boot.
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
import { fileURLToPath } from 'node:url'
|
|
import { execa } from 'execa'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
/**
|
|
* Keyless smoke for the SOURCE `dsh` launcher: run `apps/cli/src/bin.ts`
|
|
* with the exact production launch vector (`node --import tsx/esm`, the same
|
|
* shape as `bin/dsh` and the root `dsh`/`demo:web` scripts) and assert the
|
|
* required-config diagnostic. The Node compatibility matrix runs this
|
|
* WHOLE file, so a Node release changing module hooks or TypeScript handling
|
|
* breaks this gate instead of every developer's `pnpm dsh`; the built-bin
|
|
* suite covers the published `lib/` entry, not this source chain.
|
|
*/
|
|
|
|
const repoRoot = fileURLToPath(new URL('../../../', import.meta.url))
|
|
const dshSourceBin = 'apps/cli/src/bin.ts'
|
|
|
|
describe('dsh SOURCE launcher (node --import tsx/esm)', () => {
|
|
it('boots the source entry and requires a profile', async () => {
|
|
const result = await execa(process.execPath, ['--import', 'tsx/esm', dshSourceBin], {
|
|
cwd: repoRoot,
|
|
input: '',
|
|
timeout: 25_000,
|
|
killSignal: 'SIGKILL',
|
|
reject: false,
|
|
})
|
|
if (result.timedOut) {
|
|
throw new Error(`dsh source launch did not exit within 25s. stdout:\n${result.stdout}\nstderr:\n${result.stderr}`)
|
|
}
|
|
expect(result.exitCode).not.toBe(0)
|
|
expect(result.stderr).toContain('--profile <name> is required')
|
|
expect(result.stdout).toBe('')
|
|
}, 30_000)
|
|
})
|