test a bash script with gradle - bash

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.

Related

Gradle: How to pipe into a Exec task

I need to provide a default "yes" to a command I try to execute with Gradle.
So the moment I run:
./gradlew mytask
it should execute something like:
yes | <path-to-script-or-command>
How would I do that?
If there is only one input to the command, you can do:
task mytask(type: Exec) {
commandLine "my-command"
standardInput = new ByteArrayInputStream("yes".getBytes())
}
If you need it to be interactive, use standardInput = System.in.
I am not aware of a way to provide multiple fixed inputs though (e.g. the command first asks for one input, and after that another).

How to suppress output of 'rm -rf' in Jenkins shell script?

I've a big Jenkins pipeline and when build is run, lot of console output is generated which causes space issue on Jenkins master.
I've following code in Jenkins pipeline with Shell Script, which logs every file being removed. I've lots of log files that cause lot of console output -
stage('Logs Cleanup') {
steps {
script {
sh '''rm -rf /home/oracle/test/logs1/* /home/oracle/test/logs2/*'''
}
}
}
Is there any way I can suppress output of that command?
NOTE: If same command it run from Terminal, it logs nothing in output.
For your specific delete using Jenkins only:
stage('Logs Cleanup') {
steps {
dir ('/home/oracle/test/logs1/') {
deleteDir()
}
dir ('/home/oracle/test/logs2/') {
deleteDir()
}
}
}
Looks like there are some comments that solve the problem for you, but no one mentioned that you can control the output of sh commands through the command itself.
The sh command has some optional parameters that can be used; one of them is returnStdout. In your case, you can suppress stdout like this:
stage('Logs Cleanup') {
steps {
script {
sh script: 'rm -rf /home/oracle/test/logs1/* /home/oracle/test/logs2/*', returnStdout: false
}
}
}
There are some other useful parameters, for example returnStatus will return the status code of the command for use in the pipeline.

Gradle exec commandLine does not work as expected

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.

Run gradle task and save its return value to shell script variable

Is there a way to run a gradle task and save it output to shell variable ?
For example lets consider a gradle task that prints module version :
task getVersion << {
println '2.2.0'
}
I run this task in the shell like this :
$./gradlew getVersion
Is it possible to save output of gradle task getVersion into shell variable. For example:
VERSION=`./gradlew getVersion`
echo "Module Version is $VERSION"
In bash, you can do it like this:
VERSION=$(./gradlew -q getVersion | tail -n 1)
-q : set gradle output to quit
| tail -n 1 : only use the last line of the output in your variable. Might not need this part, but sometime gradle outputs warnings/errors before printing the actual output. I personally experienced this while upgrading to gradle4.1. After the upgrade it also showed Configuration 'compile' in project ':app' is deprecated. Use 'implementation' instead.
If you are using the Kotlin DSL to write the task, you can do it without printing the newline. In your build.gradle.kts:
tasks.register("getVersion") {
doLast {
print(project.version)
}
}
And then you can execute from your terminal:
VERSION=$(./gradlew -q getVersion)
try this
exec {
commandLine "./gradlew getVersion"
standardOutput = output
}
VERSION = output.toString().trim()

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.

Resources