gradle-node-plugin icon indicating copy to clipboard operation
gradle-node-plugin copied to clipboard

Fixed path to node binary

Open henrik242 opened this issue 5 years ago • 14 comments

If I configure node like this:

configure<NodeExtension> {
  version = "12.13.0"
  download = true
  workDir = file("${rootDir}/build/nodejs")
}

.. the node binary will end up in build/nodejs/node-v12.13.0-darwin-x64/bin/node, which is dependent on both OS and version.

Is it possible to have it end up in a predetermined folder, like build/nodejs/foo/bin/node?

henrik242 avatar Dec 18 '19 12:12 henrik242

It'd probably be pretty easy to add a finalizer for nodeSetup which does this locally, but I guess your intended use-case is to add it to the path for easier local development?

deepy avatar Dec 19 '19 08:12 deepy

@deepy Yeah, the use-case is to add it to the path for easier local development and CI builds

henrik242 avatar Dec 19 '19 09:12 henrik242

If you're ok with some extra space taken you could try creating a gradle Copy and tell nodeSetup that it's finalizedBy that task, which would just move it one step up.

But I guess this is something we do want to fix, although I can't say for certain where it is on the backlog.

deepy avatar Dec 19 '19 09:12 deepy

@deepy Space is not a problem. Do we have a property pointing to the folder, or do I have to use a File handle to search for it?

henrik242 avatar Dec 19 '19 11:12 henrik242

Something like this, it'd make sure that there's always a node folder with the content of nodeSetup, all the tasks would still use the build/nodejs/version/bin/node but you'd have an easy alias for developers

def fixed = tasks.register("fixed", Copy) {
    from nodeSetup
    into 'node'
}
tasks.named("nodeSetup").configure { finalizedBy fixed }

deepy avatar Feb 05 '20 07:02 deepy

I was able to reference the exact path to the node executable in my build.gradle using "$node.variant.nodeExec"

node-gradle-plugin version: 2.2.4

I hope that helps :)

ryparker avatar Oct 07 '20 22:10 ryparker

Is it possible to access this path to the node executable with node-gradle-plugin version 3.0.1 "$node.variant.nodeExec" does not work anymore

vibpe avatar Feb 19 '21 16:02 vibpe

This (dead?) issue is the closest I've found to my problem:

I'm using nvm to manage node versions locally. And this plugin detects a different version than what's set with nvm use (and that the terminal and all other processes are using). As a result, when I'm using npm link, the symlinks end up in a location different from what this plugin ends up using. I presume this is some local hiccup on my system that causes non-typical behaviour, but I can't figure it out so far.

The workaround above would likely not work for me, because of the build sequence and when the symlinks appear (and the fact that npm link in a second project wouldn't be able to access a locally installed node in the first project, without adding too much acrobatics in the dev-builds).

If it's not possible to enforce a node workdir, could you please tell me how (or where in the source code) the workdir/nodeversion is detected (or configured)? Then I could probably use that to loosen up whatever it is that locks me to the wrong version.

espen42 avatar Aug 05 '21 10:08 espen42

The way that this plugin picks binaries is the same way that most things do, it gets the first one on PATH

If you're starting your build from command-line it should get the same npm as you get, I guess a simple way to figure out what's going on is by creating a Gradle task that prints PATH and see if it matches your shell.

This issue isn't dead and while it is high on the wishlist it's also a little trickier to solve

deepy avatar Aug 05 '21 10:08 deepy

Can't link to the code as I'm on phone, but if you look at my last PR, the one about improving BSD support it's affecting the relevant places

deepy avatar Aug 05 '21 11:08 deepy

Good tip - and fast! 👍 Thanks, I'll try to see if some inner path is somehow different from the system/terminal path (if it is, any hint on where that might stem from? On macOS 11.5...)

espen42 avatar Aug 05 '21 11:08 espen42

We would also appreciate to get some way to get the actually used/downloaded node exec path as was previously available through project.extensions.node.variant.nodeExec in version 2.2.4.

We use it to set the nodejs executable path on the sonarqube plugin, because we don't even HAVE any node/npm on the PATH on the buildserver. Our rules state that every build must be self-sufficient (with the exception of a JRE, that we need to bootstrap gradle...)

For now I just reverted to 2.2.4 to avoid workarounds like copying around the node binary.

sambernet avatar Oct 07 '21 15:10 sambernet

Since NodeSetup only has a single output and files()/layout.files() can accept tasks and FileCollections support filter() maybe you'd be able to do something like:

files(tasks.named('nodeSetup')).filter { it.name == 'node' && it.executable == true }.getSingleFile()

This should work on Linux/macOS and when we open more of our internal classes in #190 then you could make use of our OS detection if you want Windows support

deepy avatar Oct 11 '21 10:10 deepy

Technically our goal (see comment above) was not to force node binary into a fixed folder (as the original author of this issue requested), but to get the path to the actual binary that is used according to the extension configuration (especially when using download = true).

This is now possible again since 3.2.1 when #213 was resolved. The approach suggested there works fine for our case.

sambernet avatar May 24 '22 16:05 sambernet