diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 9e06074..e4dba15 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -20,7 +20,7 @@ jobs: - name: Verify package behavior run: node scripts/verify.mjs - name: Verify process observation - run: node --test scripts/observe-process.test.mjs scripts/verify-native-web.test.mjs + run: node --test scripts/command.test.mjs scripts/observe-process.test.mjs scripts/verify-native-web.test.mjs - name: Verify native applications if: github.event_name == 'workflow_dispatch' diff --git a/scripts/command.mjs b/scripts/command.mjs new file mode 100644 index 0000000..2d1ccc6 --- /dev/null +++ b/scripts/command.mjs @@ -0,0 +1,14 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; + +export function runCommand(args, cwd, cli) { + const script = process.platform === 'win32' && /\.(bat|cmd)$/i.test(cli); + const result = spawnSync(script ? process.env.ComSpec : cli, + script ? ['/d', '/c', 'call', cli, ...args] : args, + { cwd, encoding: 'utf8', timeout: 1200000, windowsHide: true }); + if (result.error) throw result.error; + assert.equal(result.status, 0, result.stderr + result.stdout); + process.stdout.write(result.stdout); + process.stderr.write(result.stderr); + return { stdout: result.stdout, stderr: result.stderr }; +} diff --git a/scripts/command.test.mjs b/scripts/command.test.mjs new file mode 100644 index 0000000..e52178e --- /dev/null +++ b/scripts/command.test.mjs @@ -0,0 +1,15 @@ +import assert from 'node:assert/strict'; +import { test } from 'node:test'; +import { runCommand } from './command.mjs'; + +test('retains build diagnostics on stderr separately from program output', () => { + const result = runCommand(['-e', 'process.stdout.write("program output\\n"); process.stderr.write("Build report: report-directory\\n");'], + process.cwd(), process.execPath); + assert.equal(result.stdout, 'program output\n'); + assert.equal(result.stderr, 'Build report: report-directory\n'); +}); + +test('command failures include both real process streams', () => { + assert.throws(() => runCommand(['-e', 'process.stdout.write("out details"); process.stderr.write("err details"); process.exitCode = 3;'], + process.cwd(), process.execPath), /err detailsout details/); +}); diff --git a/scripts/verify-native-web.mjs b/scripts/verify-native-web.mjs index 3183f2e..dcdc18e 100644 --- a/scripts/verify-native-web.mjs +++ b/scripts/verify-native-web.mjs @@ -26,7 +26,7 @@ export async function verifyNativeWeb(repository, build, measure) { `${configuration}\nmicronaut: Micronaut(server: Server(port: 0)),`) + '\n' + verification); const buildOutput = build(['build', source, '--diagnostics'], directory); const executable = process.platform === 'win32' ? `${source}.exe` : resolve(directory, 'web'); - const reports = [...buildOutput.matchAll(/Build report: ([^\r\n]+)/g)]; + const reports = [...buildOutput.stderr.matchAll(/Build report: ([^\r\n]+)/g)]; if (reports.length !== 1) throw new Error('Expected one native build report'); const evidenceRoot = resolve(repository, 'build/reports/native'); mkdirSync(evidenceRoot, { recursive: true }); diff --git a/scripts/verify.mjs b/scripts/verify.mjs index a4c37c6..0ec4059 100644 --- a/scripts/verify.mjs +++ b/scripts/verify.mjs @@ -1,6 +1,5 @@ -import assert from 'node:assert/strict'; -import { spawnSync } from 'node:child_process'; import { resolve } from 'node:path'; +import { runCommand } from './command.mjs'; import { verifyNativeWeb } from './verify-native-web.mjs'; const root = resolve(import.meta.dirname, '..'); @@ -16,12 +15,5 @@ if (process.argv.includes('--native')) { } function run(args, cwd = root) { - const script = process.platform === 'win32' && /\.(bat|cmd)$/i.test(cli); - const result = spawnSync(script ? process.env.ComSpec : cli, - script ? ['/d', '/c', 'call', cli, ...args] : args, - { cwd, encoding: 'utf8', timeout: 1200000, windowsHide: true }); - if (result.error) throw result.error; - assert.equal(result.status, 0, result.stderr + result.stdout); - console.log(result.stdout); - return result.stdout; + return runCommand(args, cwd, cli); }