can't run gradle task from other task - android

I have a Jenkins Job that is running some gradle task:
gradle clean -Pendpoint=qab assembleFromJenkinsJob
Here is the task itself:
task assembleFromJenkinsJob << {
logger.lifecycle("Value of 'endpoint': ${endpoint}")
if (String.valueOf(endpoint).equalsIgnoreCase('qab')) {
assembleJenkinsQa
} else if (String.valueOf(endpoint).equalsIgnoreCase('prod')) {
assembleRelease
}
else
assembleJenkinsQa
}
The task assembleFromJenkinsJob is running:
:app:assembleFromJenkinsJob
Value of 'endpoint': qab
but assembleJenkinsQa or assembleRelease are not running.
I even tried to do it like this assembleRelease.execute()
but nothing is happening.

You should never call a task directly. Also you don't need to call a task but rather define a dependency. And, finally, in an action (<<) it's too late for running a task.
Let me know it this works:
task assembleFromJenkinsJob {
logger.lifecycle("Value of 'endpoint': ${endpoint}")
if (String.valueOf(endpoint).equalsIgnoreCase('qab')) {
dependsOn assembleJenkinsQa
} else if (String.valueOf(endpoint).equalsIgnoreCase('prod')) {
dependsOn assembleRelease
} else
dependsOn assembleJenkinsQa
}

I would advice the use of finalizedBy
task assembleFromJenkinsJob {
def ep = String.valueOf(endpoint).toLowerCase()
logger.lifecycle("Value of 'endpoint': ${ep}")
switch (ep) {
case 'qab':
finalizedBy 'assembleJenkinsQa'
break
case 'prod':
finalizedBy 'assembleRelease'
break
default:
finalizedBy 'assembleJenkinsQa'
}
}

Related

define alias for gradle task with custom argument

I want to run
./gradlew extractMyDeps
instead of
./gradlew :app:dependencies --configuration productionDebugRuntimeClasspath
but I can't pass args to this task via dependOn
How to achieve my goal?
task("extractMyDeps") {
dependsOn(":app:dependencies") // how pass --configuration
}
I think you can't pass the command line arguments to another task. But if you want to make an alias for a task you can use Exec Tasks like this:
task('extractMyDeps', type: Exec) {
workingDir '..'
def arguments = ['cmd', '/c', 'gradlew', ':app:dependencies', '--configuration', 'testCompileClasspath']
commandLine arguments
}
By using this task, you can run:
> gradlew extractMyDeps
Also you can make it more dynamic by passing the configuration name like this:
task('extractMyDeps', type: Exec) {
workingDir '..'
def arguments = ['cmd', '/c', 'gradlew', ':app:dependencies']
if (project.hasProperty("conf")) {
def conf = project.property("conf")
arguments.add('--configuration')
arguments.add(conf.toString())
}
commandLine arguments
}
This way these commands are valid:
> gradlew extractMyDeps
> gradlew extractMyDeps -Pconf=testCompileClasspath
I hope it will help you.

Stop gradle under condition

I am facing an issue when I try to stop gradle when a condition is not met.
I want when I execute a specific task and a file is not present to throw a GradleException but instead it fails to sync with Android Studio.
My code:
def mapFile = project.rootProject.file('../../maps.json')
buildConfigField "error", "BUILD_ERROR", '"maps.json is missing"'
if(!mapFile.exists()) throw new GradleException("File does not exist")
I have found this solution(don't really like it) with code:
buildConfigField "error", "BUILD_ERROR", '"maps.json is missing"'
so the BuildConfig will generate an error variable and the gradle will stop. Any other options of actually throwing an exception and the sync does not fail?
To let the task fail and not the whole build, you must raise the exception at task execution:
task myTask(type: MyType) {
def mapFile = project.rootProject.file('../../maps.json')
// do some configuration ...
doFirst {
if(!mapFile.exists()) throw new GradleException("File does not exist")
}
}

How to make a new dependency task executes first than all other existed dependency tasks of the base task

I writes a demo build.gradle below:
task a << {
println "this is task ${name}"
}
task b << {
println "this is task ${name}"
}
task c << {
println "this is task ${name}"
}
task d << {
println "this is task ${name}"
}
task e << {
println "this is task ${name}"
}
a.dependsOn(b)
e.dependsOn(a,d)
task f << {
println "this is task ${name}"
}
e.dependsOn(f)
I run gradle e in cmd, the output is :
:b
this is task b
:a
this is task a
:d
this is task d
:f
this is task f
:e
this is task e
The task e depends on task a and d, then I add task f to e's dependencies. Now the problem is how to make task f executes first. The expected output is like this:
:f
this is task f
:b
this is task b
:a
this is task a
:d
this is task d
:e
this is task e
I know here I can add b.dependsOn(f) to make task f execuse first. But assume I don't know what task e actually depends on, I only know the task e itself, can I make task f execuse first just through e's methods?
I had refer the Task API document, but I still don't know how to do.
Resolved by myself.
add this block to the end of build.gradle
e.taskDependencies.getDependencies(e).each { task ->
if (task != f) {
task.mustRunAfter f
}
}

gradle Exec block should not fail for non zero output in

I am writing a gradle task. The task it invokes returns 3 for successful run instead of 3. How do I go about doing this ?
task copyToBuildShare(){
def robocopySourceDir = "build\\outputs\\apk"
def cmd = "robocopy "+ robocopySourceDir + " C:\\TEST *.* /MIR /R:5 2>&1"
exec {
ignoreExitValue = true
workingDir '.'
commandLine "cmd", "/c", cmd
if (execResult.exitValue == 3) {
println("It probably succeeded")
}
}
}
It gives the error:
Could not find property 'execResult' on task
I don't want to create a separate task. I want it to be in the exec block. What am I doing wrong?
project.exec() has a return value typed ExecResult.
def result = exec {
ignoreExitValue true
executable "cmd"
args = ["/c", "exit", "1"]
}
println "exit value:"+result.getExitValue()
Reference here:
https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:exec(groovy.lang.Closure)
You're going to need to specify that this task is of type Exec. This is done by specifying the task type like so
task testExec(type: Exec) {
}
In your specific case, You'll also want to make sure you don't try to get the execResult until the exec has finished this can be done by wrapping the check in a doLast.
task testExec(type: Exec) {
doLast {
if (execResult.exitValue == 3) {
println("It probably succeeded")
}
}
}
Here's an example of executing ls and checking its return value
task printDirectoryContents(type: Exec) {
workingDir '.'
commandLine "sh", "-c", "ls"
doLast{
if (execResult.exitValue == 0) {
println("It probably succeeded")
}
}
}

Execute task after another. doFirst, doLast Groovy/Gradle

I'm new in gradle. How can I run exec one task after another? I've got a problem that task test1 runs before android.applicationVariants.all, and property test is empty,how to change it?
project A
String test = ''
android {
android.applicationVariants.all.doFirst {
test = 'vasya'
}
task test1.doLast{
println "$test"
}
But I've got the following output:
* Where:
Build file '/home/build.gradle' line: 57
* What went wrong:
A problem occurred evaluating project ':ProjectA'.
> No signature of method: java.util.ArrayList.doFirst() is applicable for argument types: (build_6g09fl113rl613 iaq870b0hod0$_run_closure1_closure12_closure18) values: [build_6g09fl113rl613iaq870b0hod0$_run_closure1_closure12_closure18#5f81a4ab]
Possible solutions: first(), toList(), asList(), sort(), sort(groovy.lang.Closure), sort(boolean)
1) Use dependsOn to handle hierarchy:
task helloTask1 << {
println "hello task 1"
}
task helloTask2(dependsOn: helloTask1) {
println "hello task 2"
}
then, calling helloTask2 execustion will trigger helloTask1 first
2) Use mustRunAfter() if needed (this method is in incubating mode):
task helloTask1 {
println "hello task 1"
}
task helloTask2 {
mustRunAfter helloTask1
println "hello task 2"
}
Given two tasks defined:
task mainTask {
println "main"
}
task nextTask {
println "next task"
}
the following code
mainTask << {
nextTask.execute()
}
executes nextTask after mainTask is run:
> gradle mainTask
main
next task
Have a look at task's mustRunAfter method.

Categories

Resources