Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/standalone/runtime.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { expect } from "chai";
import * as childProcess from "child_process";
import * as sinon from "sinon";

import * as runtime from "../../standalone/runtime";

describe("standalone runtime", () => {
let sandbox: sinon.SinonSandbox;

beforeEach(() => {
sandbox = sinon.createSandbox();
});

afterEach(() => {
delete (globalThis as any).appendToPath;
delete (globalThis as any).getSafeCrossPlatformPath;
sandbox.restore();
});

describe("normalizeShellScriptArgs", () => {
it("strips npm's -- sentinel after -c", () => {
expect(runtime.normalizeShellScriptArgs(["-c", "--", "npm install"])).to.deep.equal([
"npm install",
]);
});

it("preserves a leading -- when it is not the -c sentinel", () => {
expect(runtime.normalizeShellScriptArgs(["--", "npm install"])).to.deep.equal([
"--",
"npm install",
]);
});

it("preserves arguments after the command string", () => {
expect(
runtime.normalizeShellScriptArgs(["-c", "--", "node ./script.js", "--flag", "value"]),
).to.deep.equal(["node ./script.js", "--flag", "value"]);
});
});

describe("Script_ShellJS", () => {
it("uses normalized shell args when invoking node commands", async () => {
const originalArgv = process.argv;
const fakeChild = { on: sandbox.stub().returnsThis() };
const forkStub = sandbox.stub(childProcess, "fork").returns(fakeChild as any);
const spawnStub = sandbox.stub(childProcess, "spawn").returns(fakeChild as any);

(globalThis as any).appendToPath = sandbox.stub();
(globalThis as any).getSafeCrossPlatformPath = sandbox.stub().resolvesArg(1);

process.argv = [
process.execPath,
"shell.js",
"-c",
"--",
`${process.execPath} ./script.js --flag value`,
];

try {
await runtime.Script_ShellJS();
} finally {
process.argv = originalArgv;
}

expect(forkStub).to.have.been.calledOnceWithExactly(
"./script.js",
["--flag", "value"],
{
env: process.env,
cwd: process.cwd(),
stdio: "inherit",
},
);
expect(spawnStub).not.to.have.been.called;
});
});
});
2 changes: 1 addition & 1 deletion standalone/firepit.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ async function createRuntimeBinaries() {
node "${FindTool("npm/bin/npm-cli")[0]}" ${npmArgs.join(" ")} %*`,

/* Runtime scripts */
"shell.js": `${appendToPath.toString()}\n${getSafeCrossPlatformPath.toString()}\n(${runtime.Script_ShellJS.toString()})()`,
"shell.js": `${appendToPath.toString()}\n${getSafeCrossPlatformPath.toString()}\nconst normalizeShellScriptArgs = ${runtime.normalizeShellScriptArgs.toString()};\n(${runtime.Script_ShellJS.toString()})()`,
"node.js": `(${runtime.Script_NodeJS.toString()})()`,

/* Config files */
Expand Down
24 changes: 18 additions & 6 deletions standalone/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,23 @@ exports.Script_NodeJS = function() {
});
};

function normalizeShellScriptArgs(args) {
args = [...args];

const index = args.indexOf("-c");
if (index !== -1) {
args.splice(index, 1);

if (args[index] === "--") {
args.splice(index, 1);
}
}

return args;
}

exports.normalizeShellScriptArgs = normalizeShellScriptArgs;

/*
-------------------------------------
"sh" Command
Expand All @@ -74,18 +91,13 @@ exports.Script_ShellJS = async function() {
const path = require("path");
const child_process = require("child_process");
const isWin = process.platform === "win32";
const args = process.argv.slice(2);
const args = normalizeShellScriptArgs(process.argv.slice(2));

appendToPath(isWin, [
__dirname,
path.join(process.cwd(), "node_modules/.bin")
]);

let index;
if ((index = args.indexOf("-c")) !== -1) {
args.splice(index, 1);
}

args[0] = args[0].replace(process.execPath, "node");
let [cmdRuntime, cmdScript, ...otherArgs] = args[0].split(" ");

Expand Down
Loading