fix: flush CLI stdio before forced exit
This commit is contained in:
parent
ac1e1125f8
commit
fb24965011
@ -1,5 +1,6 @@
|
||||
import { spawn } from 'node:child_process';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import type { ServerDefinition, ServerSource } from './config.js';
|
||||
|
||||
export type CliArtifactKind = 'template' | 'bundle' | 'binary';
|
||||
@ -98,7 +99,8 @@ export async function readCliMetadata(artifactPath: string): Promise<CliArtifact
|
||||
|
||||
async function readMetadataFromCli(artifactPath: string): Promise<CliArtifactMetadata> {
|
||||
return await new Promise<CliArtifactMetadata>((resolve, reject) => {
|
||||
const child = spawn(artifactPath, ['__mcporter_inspect'], {
|
||||
const inspectCommand = resolveMetadataInspectCommand(artifactPath);
|
||||
const child = spawn(inspectCommand.command, inspectCommand.args, {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
});
|
||||
let stdout = '';
|
||||
@ -139,6 +141,18 @@ async function readMetadataFromCli(artifactPath: string): Promise<CliArtifactMet
|
||||
});
|
||||
}
|
||||
|
||||
function resolveMetadataInspectCommand(artifactPath: string): { readonly command: string; readonly args: string[] } {
|
||||
if (process.platform === 'win32' && shouldRunArtifactWithNode(artifactPath)) {
|
||||
return { command: process.execPath, args: [artifactPath, '__mcporter_inspect'] };
|
||||
}
|
||||
return { command: artifactPath, args: ['__mcporter_inspect'] };
|
||||
}
|
||||
|
||||
function shouldRunArtifactWithNode(artifactPath: string): boolean {
|
||||
const extension = path.extname(artifactPath).toLowerCase();
|
||||
return extension === '' || extension === '.js' || extension === '.mjs' || extension === '.cjs' || extension === '.ts';
|
||||
}
|
||||
|
||||
function isErrno(error: unknown, code: string): error is NodeJS.ErrnoException {
|
||||
return Boolean(error && typeof error === 'object' && (error as NodeJS.ErrnoException).code === code);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { metadataPathForArtifact, readCliMetadata } from '../src/cli-metadata.js';
|
||||
|
||||
describe('readCliMetadata', () => {
|
||||
@ -22,6 +22,28 @@ describe('readCliMetadata', () => {
|
||||
server: { name: 'embedded' },
|
||||
});
|
||||
});
|
||||
|
||||
it('reads embedded metadata from extensionless JavaScript artifacts on Windows', async () => {
|
||||
const platformSpy = vi.spyOn(process, 'platform', 'get').mockReturnValue('win32');
|
||||
try {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'mcporter-metadata-win-'));
|
||||
const artifact = path.join(tempDir, 'artifact');
|
||||
const embedded = metadataPayload('embedded');
|
||||
const sidecar = metadataPayload('sidecar');
|
||||
await fs.writeFile(
|
||||
artifact,
|
||||
`#!/usr/bin/env node\nconsole.log(${JSON.stringify(JSON.stringify(embedded))});\n`,
|
||||
'utf8'
|
||||
);
|
||||
await fs.writeFile(metadataPathForArtifact(artifact), JSON.stringify(sidecar), 'utf8');
|
||||
|
||||
await expect(readCliMetadata(artifact)).resolves.toMatchObject({
|
||||
server: { name: 'embedded' },
|
||||
});
|
||||
} finally {
|
||||
platformSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function metadataPayload(name: string) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user