简体   繁体   中英

Gradle Task from Plugin Doesn't Run on “Build”, But Does Run on “Clean”

We have an Android project which requires a certain Gradle Plugin Task to run before we build the APK. (The plugin is written by us)

We want to run the task automatically before every build .

If we use the deprecated task.execute() then we get a warning that it will be unavailable starting with version 5.0 or something like that.

If we use the dependsOn as recommended, then testTask1 is not before BUILD, but only after CLEAN. (all explained in the comments below)

I've been over the gradle docs, and many other SO threads, but I have yet to find a solution.

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {

    repositories {
        flatDir { dirs 'libs' }
        jcenter()
        google()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:3.1.3"

        // our platform-tools plugin, in charge of some gradle tasks
        classpath 'sofakingforevre:test-plugin:1.0-SNAPSHOT'
    }
}


apply plugin: 'test-plugin'


allprojects {
    repositories {
        jcenter()
        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


// OPTION 1 - USING EXECUTE()

// this task works as expected when calling "clean", but also when calling "assemble".
// the problem here is that the "execute" method has been deprecated, and we want to prepare for Gradle 5.0

// CLEAN - testTask1 is called :)
// BUILD - testTask1 is called :)
// DEPRECATION WARNING :(
task buildPlatformExecute {

    println("executing")

    // this task is created by the plugin
    tasks.getByName("testTask1").execute()


}

clean.dependsOn buildPlatformExecute

// OPTION 2 - USING DEPENDSON()

// this tasks works as expected when calling "clean", but DOES NOT WORK when calling "assemble".
// If we call we call assemble, the "executing" text does print, but "testTask1" would not run.

// CLEAN - testTask1 is called :)
// BUILD - testTask1 is NOT CALLED :(
task buildPlatformDependency {

    println("executing")

    // this task is created by the plugin
    dependsOn 'testTask1'
}

clean.dependsOn buildPlatformDependency

Issues with your OPTION 1 solution

  • you are using deprecated task.execute() API (you are already aware of that)
  • you are mixing configuration and execution phases (a common Gradle mistake...):

Since you did not wrap tasks.getByName("testTask1").execute() in a doLast {} of doFirst {} block in buildPlatformExecute task : the testTask1 task will always be executed, whatever task you will invoke. You do not even need to create dependency between clean task and your custom task ( eg: try to execute simple "help" task with ./gradlew help you will see that testTask1 is also executed: this is certainly not what you want)

More information here : https://docs.gradle.org/current/userguide/build_lifecycle.html

Issue with your OPTION2 solution

You created a dependency between clean task and buildPlatformDependency task :

  • when executing clean tasks, testTask1 task will be executed as expected, but
  • there is no dependency between build (or assemble ) task and clean task: that's why when you execute build task, clean task is not executed (so testTask1 won't be triggered)

Solution

The best approach would be to hook you custom task testTask1 in the correct place in your project build lifecycle, using Task.dependsOn API. The "correct" place depends on what your task is responsible for in the build process: for example if your task needs to be executed BEFORE assemble task, simply create dependency assemble.dependsOn testTask1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM