Skip to content

Commit a789738

Browse files
authored
fix: windows node spawn einval error (#77)
* fix: windows node spawn einval error * fix: quote windows command line arguments
1 parent ae60903 commit a789738

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

packages/nx/src/utils/executors.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { resolve as nodeResolve } from 'path';
44
import { parse, build } from 'plist';
55
import { parseString, Builder } from 'xml2js';
66
import { readFileSync, writeFileSync } from 'fs-extra';
7+
import { quoteString } from './helpers';
8+
9+
const isWindows = process.platform === 'win32';
710

811
export interface BuildExecutorSchema {
912
debug?: boolean;
@@ -126,7 +129,7 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
126129
}
127130
}
128131

129-
const nsOptions = [];
132+
let nsOptions = [];
130133
if (isTesting) {
131134
nsOptions.push('test');
132135
}
@@ -228,7 +231,7 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
228231
};
229232
// additional cli flags
230233
// console.log('projectTargetCmdIndex:', projectTargetCmdIndex)
231-
const additionalArgs = [];
234+
let additionalArgs = [];
232235
if (options.flags) {
233236
// persisted flags in configurations
234237
additionalArgs.push(...options.flags.split(' '));
@@ -259,6 +262,11 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
259262
icon = '🥽';
260263
}
261264
}
265+
if (isWindows) {
266+
// https://github.com/NativeScript/nativescript-cli/pull/5808
267+
nsOptions = nsOptions.map((arg) => quoteString(arg));
268+
additionalArgs = additionalArgs.map((arg) => quoteString(arg));
269+
}
262270
console.log(`―――――――――――――――――――――――― ${icon}`);
263271
console.log(`Running NativeScript ${isTesting ? 'unit tests' : 'CLI'} within ${projectCwd}`);
264272
console.log(' ');
@@ -272,6 +280,7 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
272280
const child = childProcess.spawn(/^win/.test(process.platform) ? 'ns.cmd' : 'ns', [...nsOptions, ...additionalArgs], {
273281
cwd: projectCwd,
274282
stdio: 'inherit',
283+
shell: isWindows ? true : undefined,
275284
});
276285
child.on('close', (code) => {
277286
console.log(`Done.`);
@@ -282,8 +291,13 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
282291

283292
const checkAppId = function () {
284293
return new Promise((resolve) => {
285-
const child = childProcess.spawn(/^win/.test(process.platform) ? 'ns.cmd' : 'ns', ['config', 'get', `id`], {
294+
let args = ['config', 'get', `id`];
295+
if (isWindows) {
296+
args = args.map((arg) => quoteString(arg));
297+
}
298+
const child = childProcess.spawn(/^win/.test(process.platform) ? 'ns.cmd' : 'ns', args, {
286299
cwd: projectCwd,
300+
shell: isWindows ? true : undefined,
287301
});
288302
child.stdout.setEncoding('utf8');
289303
child.stdout.on('data', function (data) {
@@ -304,9 +318,14 @@ export function commonExecutor(options: BuildExecutorSchema | TestExecutorSchema
304318
checkAppId().then((id) => {
305319
if (options.id !== id) {
306320
// set custom app bundle id before running the app
307-
const child = childProcess.spawn(/^win/.test(process.platform) ? 'ns.cmd' : 'ns', ['config', 'set', `${options.platform}.id`, options.id], {
321+
let args = ['config', 'set', `${options.platform}.id`, options.id];
322+
if (isWindows) {
323+
args = args.map((arg) => quoteString(arg));
324+
}
325+
const child = childProcess.spawn(/^win/.test(process.platform) ? 'ns.cmd' : 'ns', args, {
308326
cwd: projectCwd,
309327
stdio: 'inherit',
328+
shell: isWindows ? true : undefined,
310329
});
311330
child.on('close', (code) => {
312331
child.kill('SIGKILL');

packages/nx/src/utils/helpers.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,3 +733,29 @@ export namespace PluginFeatureHelpers {
733733
return moveTo;
734734
}
735735
}
736+
737+
// Copied from: https://github.com/NativeScript/nativescript-cli/blob/16064affee98c837e8cbe0865254dcb5b81f0bbe/lib/common/helpers.ts#L246C1-L268C2
738+
// For https://github.com/NativeScript/nativescript-cli/pull/5808
739+
function bashQuote(s: string): string {
740+
if (s[0] === "'" && s[s.length - 1] === "'") {
741+
return s;
742+
}
743+
// replace ' with '"'"' and wrap in ''
744+
return "'" + s.replace(/'/g, "'\"'\"'") + "'";
745+
}
746+
747+
function cmdQuote(s: string): string {
748+
if (s[0] === '"' && s[s.length - 1] === '"') {
749+
return s;
750+
}
751+
// replace " with \" and wrap in ""
752+
return '"' + s.replace(/"/g, '\\"') + '"';
753+
}
754+
755+
export function quoteString(s: string): string {
756+
if (!s) {
757+
return s;
758+
}
759+
760+
return process.platform === 'win32' ? cmdQuote(s) : bashQuote(s);
761+
}

0 commit comments

Comments
 (0)