Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All spawn() "node" calls use current node version, not specified version #577

Closed
cb1kenobi opened this issue May 24, 2017 · 2 comments
Closed

Comments

@cb1kenobi
Copy link

Expected Behavior

When running nyc using Node 7.10.0, my code should be able to spawn() Node.js 6.9.5 executable.

Observed Behavior

All spawned Node.js versions use whatever version is running nyc. In other words, the spawned subprocess always uses process.execPath instead of the original filename to execute.

Bonus Points! Code (or Repository) that Reproduces Issue

# version.js
console.log(process.version);
# test.js
const spawnSync = require('child_process').spawnSync;
console.log(process.version);
spawnSync('/path/to/some/other/node', ['version.js'], { stdio: 'inherit' });

Assuming you have 2 different Node.js executables, the versions displayed should differ.

Forensic Information

Operating System: macOS 10.12.5
Environment Information: Node.js 7.10.0 and 6.9.5. NPM version is irrelevant.

Root Problem

The bug is in [email protected], the version nyc uses. [email protected] is almost a year old. The latest version 1.3.5, which was published in May 2017, appears to fix this problem. Simply updating to [email protected] will resolve this ticket.

Workaround

In my gulp file, instead of running nyc directly, I run the following bootstrap:

# run-nyc.js
const fs = require('fs');
const Module = require('module');
const originalLoader = Module._extensions['.js'];
const spawnSwapRE = /\/spawn-wrap\/index\.js$/;

Module._extensions['.js'] = function (module, filename) {
	if (spawnSwapRE.test(filename)) {
		filename = require.resolve('spawn-wrap');
		module._compile(fs.readFileSync(filename, 'UTF-8'), filename);
	} else {
		originalLoader(module, filename);
	}
};

// remove this file from argv
process.argv.splice(1, 1);

// run nyc
require(process.argv[1]);
const args = [
    'run-nyc.js',
    '/path/to/node_modules/.bin/nyc',
    ...
];
spawnSync(process.execPath, args, { stdio: 'inherit' });

Note

I found another bug in spawn-wrap when nyc spawns mocha. spawn-wrap attempts to find out if the file being executed is Node.js so it can wrap it. In the case of mocha, it will detect it as a file with a shebang, namely #!/usr/bin/env node. The problem is spawn-wrap will only test the first part #!/usr/bin/env to see if it's Node and in this case it will fail and proceed to spawn mocha without wrapping it. To fix it, simply need to call nyc node mocha <...>. I've filed istanbuljs/spawn-wrap#54 in hopes it may get resolved.

@bcoe
Copy link
Member

bcoe commented Jun 2, 2017

@cb1kenobi mind trying:

npm i nyc@next

I believe this should solve your problems.

@cb1kenobi
Copy link
Author

@bcoe Totally works now. Much thanks to you and @isaacs the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants