Issue with node exec target


(Karl Krasnowsky) #1

First post here so forgive me if it’s not posting to the proper location.
I’m using gradle in my intellij project.
I have a task that’s defined as this:
task updateGrunt(type:Exec) {
commandLine ‘npm’, ‘install’
}

and when executed:
fails with -
Caused by: java.io.IOException: Cannot run program “npm” (in directory “”): CreateProcess error=2, The system cannot find the file specified
at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)

environment details:

Gradle 2.2.1

Build time: 2014-11-24 09:45:35 UTC
Build number: none
Revision: 6fcb59c06f43a4e6b1bcb401f7686a8601a1fb4a

Groovy: 2.3.6
Ant: Apache Ant™ version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_74 (Oracle Corporation 25.74-b02)
OS: Windows 7 6.1 amd64


(Karl Krasnowsky) #2

So this issue seems very obvious. Node installs a (I’m assuming) linux npm executable named, simply ‘npm’ while also installing an npm.cmd script for windows.
If I simply add cmd to the following:

task updateGrunt(type:Exec) {
commandLine 'npm.cmd', 'install'
} 

this works fine. Unfortunately I can’t simply edit this since I’ll break it for devs on non windows platforms. How can I adjust this so it is platform neutral?


(James Justinic) #3

Since there’s not a single canonical way that works on both Linux and Windows platforms, you can’t really do this in a platform neutral way. You’ll have to explicitly test for the OS so that the task can be configured in a platform specific way. You can use the Os class from Ant as a helper, which is already available on the Gradle classpath.

import org.apache.tools.ant.taskdefs.condition.Os

task updateGrunt(type: Exec) {
    String npmCommand = (Os.isFamily(Os.FAMILY_WINDOWS)) ? 'npm.cmd' : 'npm'
    commandLine npmCommand, 'install'
}

There’s also the Gradle Node Plugin that can handle this for you, allowing you to work with Node/NPM commands at a higher level of abstraction.