Gradle disable task - gradle

Can I disable the task, only for one task?
For example
flywayMigrate {
doFirst {
gradle.startParameter.excludedTaskNames += "test"
// test.enabled = false
}
dependsOn flywayClean
dependsOn build
}
I want you to do flywayMigrate
The tests were turned off.
But when I run clean build tests were run also.

I think you can do it with the task graph of the build as follows:
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(flywayMigrate)) {
test.enabled = false
}
}
Here is a closure executed then the task graoh is built, just before task are configured or executed. It check's whether flywayMigrate task will be executed and if yes, it disables test task.
Here is how it's described in the official docs.

Related

Ordering depended tasks for a gradle task

I have a gradle task which has dependencies on the subproject task. For example.
task bigTask(type: JacocoReport, dependsOn: [":module1:task",
":module2:task",
":module3:task",
":module4:task",
":module5:task"]) {
....
.....
}
I want to order the depended tasks in a specific way. So that at a time only one task get exeuted. I did like this in the root project. But it is not working.
task (":module1:task") { mustRunAfter (":module2:task") }
task (":module2:task") { mustRunAfter (":module3:task") }
task (":module3:task") { mustRunAfter (":module4:task") }
task (":module4:task") { mustRunAfter (":module5:task") }
Is there some way to order the dependent task in gradle.

Creating a task that runs before all other tasks in gradle

I need to create an initialize task that will run before all other task when I execute it.
task A {
println "Task A"
}
task initializer {
println "initialized"
}
If I execute gradle -q A, the output will be:
>initialized
>Task A
Now if i'll add:
task B {
println "Task B"
}
Execute gradle -q B, and I get:
>initialized
>Task B
So it doesn't matter which task I execute, it always get "initialized" first.
You can make every Task who's name is NOT 'initializer' depend on the 'initializer' task. Eg:
task initializer {
doLast { println "initializer" }
}
task task1() {
doLast { println "task1" }
}
// make every other task depend on 'initializer'
// matching() and all() are "live" so any tasks declared after this line will also depend on 'initializer'
tasks.matching { it.name != 'initializer' }.all { Task task ->
task.dependsOn initializer
}
task task2() {
doLast { println "task2" }
}
Or you could add a BuildListener (or use one of the convenience methods eg: Gradle.buildStarted(...))
Seems like you aim execution phase, and you want a task precursing each task or just run as a first task in the execution phase?
If you want a task to always execute in every project before each other task after its being evaluated you can add a closure to he main build.gradle:
allprojects {
afterEvaluate {
for(def task in it.tasks)
if(task != rootProject.tasks.YourTask)
task.dependsOn rootProject.tasks.YourTask
}
}
or
tasks.matching {it != YourTask}.all {it.dependsOn YourTask}
You can also use the Task Execution Graph to define the lifecycle. There are few ways of achieving your goal, depending on your needs and a project structure.
The previously suggested solution with dependsOn works fine, but I don't like about it that it changes and clutters the task dependencies. The first solution coming to my mind is using Gradle Initialization Scripts. They are really cool. But, the usage is a bit tedious: currently there is no way to have a default project-local Gradle init script. You have to either explicitly specify the script(s) on command line, or place them in USER_HOME/GRADLE_HOME.
So another solution (already briefliy mentioned by #lance-java) which can be used to run some initialization, like a init task/script, is "build listeners". Depending on how early/late the initialization code should run, I use one of these two:
gradle.afterProject {
println '=== initialized in afterProject'
}
or
gradle.taskGraph.whenReady {
println '=== initialized in taskGraph.whenReady'
}
Here the docs of the Gradle interface and of BuildListener.
Note that some of the events occur very early, and you probably can't use them because of that, like e.g. beforeProject and buildStarted (explanations here and there).

How to execute 'clean' task in the end of my custom task?

I've create my own simple task so I want to clean before test
task cleanTest (group: 'test setup', description: 'clean then test.'){
dependsOn 'clean'
dependsOn 'test'
tasks.findByName('test').mustRunAfter 'clean'
}
After my task is finished I want to run clean task
Iv'e tried
configure(subprojects) {
task clean << {
println "Do clean " + project.name
}
task test(dependsOn: clean)<<{
println 'test ' + project.name
}
task cleanTest(dependsOn: cleanTest)<<{
parent.cleanTest.execute()
}
}
All I want is to run 'clean task in the end of my custom task
This is not possible. You cannot run a task multiple times in one Gradle run. So if you want to do the same actions before and after your task, define a method that you run before and after the task. Using Task.execute() is not cleanly possible. Never ever do or even try this. It is a purely internal method that should never-ever-ever be called directly by any build ever. It is prone to produce strange and unpredictible results.
What you want is probably something around the lines of
subprojects {
def cleanIt = {
println "Do clean " + project.name
}
clean.doLast {
cleanIt()
}
task test(dependsOn: clean) {
doLast {
println 'test ' + project.name
}
}
task cleanTest(dependsOn: cleanTest) {
doLast {
cleanIt()
}
}
}
If you want to clean before test then simply make test depend on clean. That makes sure that before every test, clean is executed. This is how gradle does stuff.
task clean() {}
task test(dependsOn: clean) {}
There is also question how to run clean after mytask.. To run clean task after mytask you can use thirdtask depending on both and specify forced order between clean and mytask
task clean() {}
task mytask() {}
task thirdtask(dependsOn: [clean, mytask]){}
clean.mustRunAfter mytask
If the question was whether you can run clean task multiple times in a single build then that is not possible and see answer from Vampire to share the code.

How do I alias gradle task as if it were called with -x parameter?

I want instead of gradle cleanIdea idea -x compileJava -x compileTestJava
call something like gradle ideaNoRecompile
You can use TaskExecutionGraph to do it. First of all, you need to provide a custom task, named ideaNoRecompile, when during the configuration phase, you need to check, whether this graph contains ideaNoRecompile task (that means, that this task will be executed. And if this task should be executed, then you can use a closгre to skip all the tasks, you don't want to be executed. Something like this:
task ideaNoRecompile(dependsOn:idea) {
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(ideaNoRecompile)) {
compileJava.enabled = false
compileTestJava.enabled = false
}
}
}
I've found another similar answer:
task ideaNoRecompile {
finalizedBy allprojects*.tasks*.idea
doFirst {
def skipTasks = ['compileJava', 'compileMirah', 'processResources', 'classes', 'compileTestJava', 'compileTestMirah', 'processTestResources', 'testClasses', 'jar', 'mergeProperties', 'generateModuleManifest' ] as Set
allprojects*.tasks*.each {
if (skipTasks.contains(it.name))
it.enabled = false
}
}
}

Gradle: exclude (not skip) a task when it's up to date

I'm looking for a way to avoid running dependencies of a task that is up to date (while still running any tasks that are dependencies of other, not up-to-date tasks).
Take the following structure:
task stopService {}
task startService {}
task doUpdateA { // change something about the service }
task doUpdateB { // change something else about the service }
task updateA {
inputs.files <some inputs>
output.upToDateWhen { true }
// i.e. run whenever inputs changed from previous run
dependsOn stopService
dependsOn doUpdateA
dependsOn startService
// ensure the service is stopped while it's being modified
doUpdateA.mustRunAfter stopService
startService.mustRunAfter doUpdateA
}
task updateB {
inputs.files <some inputs>
output.upToDateWhen { true }
// i.e. run whenever inputs changed from previous run
dependsOn stopService
dependsOn doUpdateB
dependsOn startService
// ensure the service is stopped while it's being modified
doUpdateB.mustRunAfter stopService
startService.mustRunAfter doUpdateB
}
task updateAll {
dependsOn updateA
dependsOn updateB
}
The desired execution flow for ./gradlew updateAll:
If both updateA and updateB are up to date, do nothing
If one of them is not up to date, stopService -> doUpdateX -> startService
If both of them are not up to date, stopService -> doUpdateA -> doUpdateB -> startService (or B before A).
Is this possible, perhaps by hooking into the task execution graph and manually running upToDate on all tasks, then excluding them if they are up to date? Assume no task makes another task out of date.
---- Half-solutions:
If I ignore the third requirement, this can be somewhat solved by doing:
task updateB {
inputs.files
output.upToDateWhen { true }
// i.e. run whenever inputs changed from previous run
doLast {
stopService.execute()
doUpdateB.execute()
startService.execute()
}
}
but that's suboptimal for a couple reasons - dependencies / finalisers (i think?) of stop/startService won't be ran, each update will cause a separate stop/start (making the build much longer), etc.
If you ignore requirement 1, something like:
task updateAll {
inputs.files <some inputs>
output.upToDateWhen { true }
// i.e. run whenever inputs changed from previous run
dependsOn stopService
dependsOn doUpdateA
dependsOn doUpdateB
dependsOn startService
doUpdateB.mustRunAfter stopService
startService.mustRunAfter doUpdateB
doUpdateA.mustRunAfter stopService
startService.mustRunAfter doUpdateA
}
with up-to-date checks moved to doUpdateX works, but again is suboptimal for reasons this margin is too short to contain.
Thanks in advance for any suggestions,

Resources