blob: 71f7afa6a571991ad31eb2406b173a09bc7c1390 [file] [log] [blame]
// this does not actually patch child_process
// but adds support to ensure the registered loader is included in all nested executions of nodejs.
const fs = require('fs');
const path = require('path');
export const patcher = (requireScriptName: string, nodeDir?: string) => {
requireScriptName = path.resolve(requireScriptName);
nodeDir = nodeDir || path.join(path.dirname(requireScriptName), '_node_bin');
const file = path.basename(requireScriptName);
try {
fs.mkdirSync(nodeDir, {recursive: true});
} catch (e) {
// with node versions that don't have recursive mkdir this may throw an error.
if (e.code !== 'EEXIST') {
throw e;
}
}
if (process.platform == 'win32') {
const nodeEntry = path.join(nodeDir, 'node.bat');
if (!fs.existsSync(nodeEntry)) {
fs.writeFileSync(nodeEntry, `@if not defined DEBUG_HELPER @ECHO OFF
set NP_SUBPROCESS_NODE_DIR=${nodeDir}
set Path=${nodeDir};%Path%
"${process.execPath}" --require "${requireScriptName}" %*
`);
}
} else {
const nodeEntry = path.join(nodeDir, 'node');
if (!fs.existsSync(nodeEntry)) {
fs.writeFileSync(
nodeEntry, `#!/bin/bash
export NP_SUBPROCESS_NODE_DIR="${nodeDir}"
export PATH="${nodeDir}":\$PATH
if [[ ! "\${@}" =~ "${file}" ]]; then
exec ${process.execPath} --require "${requireScriptName}" "$@"
else
exec ${process.execPath} "$@"
fi
`,
{mode: 0o777});
}
}
if (!process.env.PATH) {
process.env.PATH = nodeDir;
} else if (process.env.PATH.indexOf(nodeDir + path.delimiter) === -1) {
process.env.PATH = nodeDir + path.delimiter + process.env.PATH;
}
// fix execPath so folks use the proxy node
if (process.platform == 'win32') {
// FIXME: need to make an exe, or run in a shell so we can use .bat
} else {
process.argv[0] = process.execPath = path.join(nodeDir, 'node');
}
// replace any instances of require script in execArgv with the absolute path to the script.
// example: bazel-require-script.js
process.execArgv.map(v => {
if (v.indexOf(file) > -1) {
return requireScriptName;
}
return v;
});
};