Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle's mustRunAfter/finalizedBy only for a specific task?

Tags:

gradle

I'm trying to get Gradle's mustRunAfter and finalizedBy to work only for a specific task. Take this example build.gradle:

task removeTestDatabaseContainer {
  doLast {
    println '\ninside removeTestDatabaseContainer\n'
  }
}

task startTestDatabaseContainer {
  doLast {
    println '\ninside startTestDatabaseContainer\n'
  }
  finalizedBy removeTestDatabaseContainer
}

task flywayMigrate { t->
  doLast {
    println '\n inside flywayMigrate\n'
  }
}

task flywayClean { t->
  doLast {
    println '\n inside flywayClean\n'
  }
}

task testEverything {
    dependsOn startTestDatabaseContainer
    dependsOn flywayMigrate
    dependsOn flywayClean

    flywayMigrate.mustRunAfter startTestDatabaseContainer
    flywayMigrate.finalizedBy flywayClean

    flywayClean.mustRunAfter flywayMigrate
    flywayClean.finalizedBy removeTestDatabaseContainer
}

I'm happy with how testEverything works. I want the output I'm getting from that task:

➜  gradle testEverything
Parallel execution is an incubating feature.
:startTestDatabaseContainer

inside startTestDatabaseContainer

:flywayMigrate

 inside flywayMigrate

:flywayClean

 inside flywayClean

:removeTestDatabaseContainer

inside removeTestDatabaseContainer

:testEverything

BUILD SUCCESSFUL

Total time: 0.597 secs

However, when I run only flywayMigrate I get unexpected problems. This is the output:

➜  gradle flywayMigrate                
Parallel execution is an incubating feature.
:flywayMigrate

 inside flywayMigrate

:flywayClean

 inside flywayClean

:removeTestDatabaseContainer

inside removeTestDatabaseContainer


BUILD SUCCESSFUL

Total time: 0.605 secs

This is not the output I want. I would like only flywayMigrate to run. Question 1) How can I make testEverything work as it does and at the same time have gradle flywayMigrate invoke only the flywayMigrate-task?

Question 2)
I'm told this has something to do with the fact that everything inside the brackets of task testEverything {} is configuration, which is always processed by Gradle. So any mustRunAfter/finalizedBy I set within a task will have "global effect". But in that case, why doesn't gradle flywayMigrate invoke startTestDatabaseContainer? (Because of the line flywayMigrate.mustRunAfter startTestDatabaseContainer inside the testEverything task.)

Edit: I was directed to Ordering tasks and Finalizer tasks in the Gradle documentation and they answer question 2: mustRunAfter only takes effect when both tasks are ran. finalizedBy on the other hand takes effect when only the task it is set on is ran. That answers why flywayClean and removeTestDatabasContainer are ran when I execute gradle flywayMigrate.

I'm still struggling to make gradle testEverything work as it does above and at the same time get gradle flywayMigrate to just execute flywayMigrate.

like image 338
L42 Avatar asked Sep 25 '17 08:09

L42


People also ask

How do I debug a task in Gradle?

To do that, just pick the Gradle Remote Debug configuration and then click the Debug icon on the project to be debugged. For more info, you can read the Gradle documentation. Follow us for more productivity tools & ideas for Android, Kotlin & Gradle projects.

How do I run multiple tasks in Gradle?

With just a simple build script, we already discussed that we have a couple of default tasks besides our own task that we can execute. To execute multiple tasks, we only have to add each task name to the command line.

What does Gradle use to determine the order in which tasks can be run?

Gradle determines the subset of the tasks, created and configured during the configuration phase, to be executed. The subset is determined by the task name arguments passed to the gradle command and the current directory. Gradle then executes each of the selected tasks.


1 Answers

Thanks to the help of eskatos on #gradle on Freenode I found a solution. It was simply to remove the finalizedBy-lines i had. Updated build.gradle that works:

task removeTestDatabaseContainer {
  doLast {
    println '\ninside removeTestDatabaseContainer\n'
  }
}

task startTestDatabaseContainer {
  doLast {
    println '\ninside startTestDatabaseContainer\n'
  }
  finalizedBy removeTestDatabaseContainer
}

task flywayMigrate { t->
  doLast {
    println '\n inside flywayMigrate\n'
  }
}

task flywayClean { t->
  doLast {
    println '\n inside flywayClean\n'
  }
}

task testEverything {
    dependsOn startTestDatabaseContainer
    dependsOn flywayMigrate
    dependsOn flywayClean

    flywayMigrate.mustRunAfter startTestDatabaseContainer
    //flywayMigrate.finalizedBy flywayClean

    flywayClean.mustRunAfter flywayMigrate
    //flywayClean.finalizedBy removeTestDatabaseContainer
}
like image 195
L42 Avatar answered Sep 28 '22 15:09

L42