Gradle exec commandLine does not work as expected - macos

I'm currently working on a Gradle project in OSX
My function in a .gradle file looks like this
ext.MyFunction = {
def fastlaneCommand = [
'fastlane',
'-version'
]
def stdout = new ByteArrayOutputStream()
exec {
ignoreExitValue true
standardOutput stdout
workingDir PathsModel.instance.GetDeployerRoot()
commandLine fastlaneCommand
LOG.WARN("YOUR CLI COMMAND: " + commandLine)
}
println "Output:\n$stdout"
}
And then in 'build.gradle'
task jenkins_deploy() {
doFirst {
MyFunction()
}
}
When it comes time for commandLine to be executed
This outputs:
W A R N I N G: YOUR CLI COMMAND: [fastlane, -version]
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jenkins_deploy'.
> A problem occurred starting process 'command 'fastlane''
I know for a fact that fastlane is in my path as '$HOME/.fastlane/bin' which is where the executable is located. And if I simply open Terminal and type
'fastlane -version'
from any directory, fastlane tools start-up and do what they're supposed to be doing.
I suppose my question is:
What are the possible differences between me opening a terminal and inputting the command manually, and me asking Gradle to do the exact same thing using 'exec'?
Am I misunderstanding what 'exec' and 'commandLine' actually do?
Some info on 'fastlane' is that it's using Ruby, which i don't know a lot about. This may prove relevant.
EDIT: I have attempted 'version' the 2nd element in the fastlaneCommand array, as both 'version' and '-version'
EDIT 2 (ACTUAL SOLUTION): Although the marked answer below is a definite workaround, the solution Actual solution has the full reason as to why this happens and why it works.

TL;DR
I suppose it should be:
['sh', 'fastlane', '-version']
Explanation:
Have not the link under my arm, but if you omit sh it would be executed as a script located in current directory (or directory configured as the second argument). If you prefix it with sh it will be executed with shell and $PATH variable.

Related

Is it possible to run commandLine in gradle with bash -c?

I have a task in a build.gradle file, in which I'd like to run this command:
(export ENV_VAR=/my/path ; /path/to/build.sh)
I tried running this in gradle:
task myTask {
doLast {
exec {
commandLine ['bash', '-c', '"(export ENV_VAR=/my/path ; /path/to/build.sh)"']
}
}
}
Unfortunately, I have an error that says
Successfully started process 'command 'bash''
bash: (export ENV_VAR=/my/path ; /path/to/build.sh): No such file or directory
Now I'm sure the file exists and the specified paths are correct. Running this command manually in the terminal works.
Is there something in gradle that makes a bash -c like this not work? I can't think of another way to make an export like this otherwise.
Try without the extra quotes:
commandLine ['bash', '-c', '(export ENV_VAR=/my/path ; /path/to/build.sh)']
When you run that in the command line, your shell needs the quotes to pass to the command (which happens to be bash) as a single argument, but gradle is already doing that with that syntax, so bash is receiving literally one argument "(export ENV_VAR=/my/path ; /path/to/build.sh)" and since it does not recognize this as internal syntax, tries to run a command with this name.

Gradle won't run the shell commandLines I want

I've done a lot of Android dev never needing to understand gradle well.
Ideally I'd be running a python script after setting up a virtualenv, but for this question I'm happy with a MWE.
task rem(type: Exec) {
doLast {
exec {
workingDir '.'
commandLine 'dir'
}
}
}
Results in:
> Task :app:rem FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:rem'.
> execCommand == null!
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
1 actionable task: 1 executed
Let's say I go back to how I was declaring my tasks before shelling out:
task rem {
without (type: Exec) I get:
> A problem occurred starting process 'command 'dir''
where before I had
> execCommand == null!
I have only got the following commandLine to work:
task rem(type: Exec) {
commandLine 'python', '--version'
}
replacing body with commandLine 'dir' fails with
...
> A problem occurred starting process 'command 'dir''
...
Eventually stumbled on https://stackoverflow.com/a/37871837/866333 for running windows scripts and found chaining, https://stackoverflow.com/a/50394682/866333, more easily.
task rem(type: Exec) {
commandLine 'cmd', '/c', "cd && virtualenv --python=\"C:\Program Files\Python38\python.exe\" C:\Users\XXX\AndroidStudioProjects\YYY\virtualenvs\ZZZ"
}
Had good success with the above snippet (using double quotes so I could substitute XXX YYY ZZZ from earlier computations. It isn't pretty but the python script will be.
Hopefully this will save another gradle newbie the hours I needed.
Note the cd to begin the (nominal) chain. I was not in the directory I expected.

test a bash script with gradle

we're using gradle as build tool and for our java and ansible projects. Now I would like to test a bash script from within gradle as well.
Do you have any tipps/resources or better even an example how I can test a bash script using gradle? It can be as simple as executing the script and having the "test" pass, if the return value of the bash script under test is 0 or if the stdout or stderr contain certain strings (or don't contain them).
Thanx a lot in advance for your help!
Here's an example of a Gradle task which stops tomcat server:
task stopTomcat(type:Exec) {
workingDir '../tomcat/bin'
//on windows:
commandLine 'cmd', '/c', 'stop.bat'
//on linux
commandLine './stop.sh'
//store the output instead of printing to the console:
standardOutput = new ByteArrayOutputStream()
//extension method stopTomcat.output() can be used to obtain the output:
ext.output = {
return standardOutput.toString()
}
}
It's also a good example because there are a few useful directives in it.
In your case it would be something like:
task testFile(type:Exec) {
workingDir '/home/user'
commandLine './test.sh'
}
More information can be found here.

Gradle exec commandLine not working for me

I am trying to run an executable with arguments from gradle:
task deploy(dependsOn: jar) {
exec {
commandLine "javafxpackager -deploy -native -outdir ${deployDirName} -outfile ${jarBaseName} -srcfiles ./${project.buildDir}/${project.libsDirName}/${jarBaseName}-${project.version}.jar -appclass ${mainClass} -name ${jarBaseName} -title '${project.description}'"
}
}
Gradle complains that the process ended up with non-zero return code, but if I copy the command and run it within bash terminal, it works flawlessly.
So what am I doing wrong?
Regards,
There are two problems with this code: First, the exec call happens outside a task action (doLast { ... }). As a result, exec will get called for every single build invocation (even when typing gradle help), in the configuration phase of the build. Second, commandLine accepts a list of command line arguments, not a single string.
It's almost always better to use a task type than the corresponding method, so this becomes:
task deploy(type: Exec) {
dependsOn jar
commandLine "javafxpackager", "-deploy", "-native", ...
}
To find out how to configure a particular task (type), check the Gradle Build Language Reference.

How can I run new gradle task?

I have created a new gradle task in build.gradle:
task callCL(type: Exec) {
println "hello"
commandLine './rerun.sh'
}
Which suppose to run rerun.sh:
#!/bin/bash
cucumber -f rerun --out rerun.txt
file="rerun.txt"
if [ -f "$file" ] then
cucumber #rerun.txt
rm $file
fi
I'm using IntelliJ as an IDE. How can I run this task?
I have tried to run in the zshell console and got this error:
gradle callCL
zsh: command not found: gradle
But in the IDE I use gradle all the time so it must be installed.
How can I fix this? And is my writing ok?
Try this:
1. Make sure GRADLE_HOME, GRADLE_OPTS are set.
2. Make sure $PATH has GRADLE_HOME/bin in it.
3. which gradle should return you a valid output.
4. then, see below, if this works on command prompt, then your IDE setting just need to know where's is GRADLE_HOME aka its installed / executable (either gradle or gradle.bat)
NOTE: I have used my own dummy rerun.sh file, you can you use build.gradle (as shown below).
$ cat rerun.sh
#!/bin/bash
echo Im re-running a command echo
echo something
echo ...
echo
$ cat build.gradle
task callCL(type: Exec) {
println "-----"
println "hello"
println "-----"
executable "bash"
args "-c", "bash ./rerun.sh"
//The following will do as well as magic number in bash is already set to #!/bin/bash
//args "-c", "./rerun.sh"
}
$ /cygdrive/c/gradle-2.0/bin/gradle callCL
-----
hello
-----
:callCL
Im re-running a command echo
something
...
BUILD SUCCESSFUL
Total time: 2.006 secs
This looks like problem with gradle not being found on path (in your shell).
You may use GVM to easily install gradle so that its available on your PATH.

Resources