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

Allow overridding the Node.js version #108

Closed
ehmicky opened this issue Sep 23, 2019 · 6 comments
Closed

Allow overridding the Node.js version #108

ehmicky opened this issue Sep 23, 2019 · 6 comments

Comments

@ehmicky
Copy link

ehmicky commented Sep 23, 2019

I maintain a library called nve which allows running commands using a specific Node.js version (like nvm run). The way nve does this is by:

  • downloading the node binary from https://nodejs.org/dist/
  • saving it to a global cache directory, e.g. C:\\Users\\ehmic\\AppData\\Local\\nve\\Cache\\8.16.0 for Node 8.16.0 on Windows with user ehmic
  • calling child_process.spawn() but with a different PATH (so that the right node gets selected).

For example running nve 8.16.0 node --version will end up calling something like this:

const { spawn } = require('child_process')
spawn('node', ['--version'], {
  env: { PATH: `C:\\Users\\ehmic\\AppData\\Local\\nve\\Cache\\8.16.0${path.delimiter}${process.env.PATH}` }
})

My problem is that this does not work with nyc.
nve 8.16.0 nyc node --version does work (it prints 8.16.0).
But nyc nve 8.16.0 node --version does not work (it prints whatever the current Node.js
version is).

This is because spawn-wrap is doing something similar to nve, i.e. creating its own Node.js wrapper and prepending it to the PATH. The two libraries are competing for the priority on the PATH and whichever of those two libraries gets called first (nve nyc vs nyc nve) gets the priority.

Is there a way for me to enforce that the node executable downloaded by nve always get used?

@coreyfarrell
Copy link
Member

I don't think this is possible with spawn-wrap. If the spawn-wrap node.js wrapper was not executed then nyc would not be run in the child process (you'd get no coverage). istanbuljs/nyc#1169 is still in the works but I think this could be a solution to this conflict in the future. Note that this will not be considered for nyc@14 since the node-preload module will require node.js 8.x (this is when support for NODE_OPTIONS was added).

@ehmicky
Copy link
Author

ehmicky commented Sep 23, 2019

Oh I see. I am not understand the code very well but it seems to me that:

  • PATH resolution is used to ensure the Node.js wrapper is called (which makes sense if you want to make sure code coverage is done)
  • but the Node.js wrapper itself is using the original process.execPath (the node binary that called nyc). If that's the case, wouldn't it be more proper for the Node.js wrapper to let the OS do the PATH resolution instead (using the current PATH minus workingDir)? Or at least allow users to override the path to the node binary using an environment variable?

@coreyfarrell
Copy link
Member

I'm not sure I'm comfortable with this. spawn-wrap is very prone to failure. My goal is to stop using it entirely. Can you test istanbuljs/nyc#1169 to see if it can solve your issue? You can test this by setting your package.json nyc dependency to git://github.com/coreyfarrell/nyc#set-node-options. Note this requires node.js 8 (for all node processes involved).

The big benefit with this PR I'm pointing you to is that it avoids spawn-wrap entirely. This has two major effects: we don't touch the PATH and we don't use shim scripts. The shim scripts are especially problematic in Windows. The PATH is the problematic part for you.

@ehmicky
Copy link
Author

ehmicky commented Sep 24, 2019

nyc --set-node-options would unfortunately not solve my issue because nyc is run by my users not by me. So I cannot force any nyc option on them.

@coreyfarrell
Copy link
Member

The --set-node-options is disabled by default (this is a recent change to the PR). My goal that nyc@15 will not use spawn-wrap unless you set an option.

@ehmicky
Copy link
Author

ehmicky commented Sep 24, 2019

This seems like this should fix my issue when nyc@15 is released then!

I understand you want to bypass spawn-wrap with nyc. It seems to me this repository is doing lots of monkey patching.

I'll mark this issue as resolved and just wait for nyc@15 to be released. Thanks for your help!

@ehmicky ehmicky closed this as completed Sep 24, 2019
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