Replacement for task.execute()


(Willie) #1

I have a task that i want to run at the very end of the build, i have this model

project.gradle.addListener new DependencyCheckListener() {
      def allTasks

      @Override
      void graphPopulated(TaskExecutionGraph graph) {
        allTasks = graph.allTasks
      }

      @Override
      void buildFinished(BuildResult result) {
          println("trying to fire the dependency check")
          dependencyCheck.execute()
      }
    }

Now, this code runs perfectly fine, but i get the nag saying that the execute method is going to be eliminated in 5. so i change it to this:

project.gradle.addListener new DependencyCheckListener() {
      def allTasks

      @Override
      void graphPopulated(TaskExecutionGraph graph) {
        allTasks = graph.allTasks
      }

      @Override
      void buildFinished(BuildResult result) {
          println("trying to fire the dependency check")
          dependencyCheck.dependencyUpdate() //this is the @TaskAction annotated method of the task
      }
    }

and the task blows up. about 5 classes deep, i get class not found errors for ivy version comparator initialization.

what is different between these two methods? How am i supposed to execute a task in the buildFinished event in v5?


(Schalk Cronjé) #2

If the code has to run at the end of a build, but not just run it, without it being a task?


(Willie) #3

unfortunately it does. This isn’t my code, and i can’t refactor it. But the task needs access to gradles configuration system, ivy systems and such. Basically its checking the dependencies of the project once a day and printing a report to alert of things being out of date.


(Stefan Wolf) #4

Hi Willie,

Why does the check task need to run at the end of the build? Does it fail when it runs while other tasks are running? Or is it just so that the output does not get lost?

If it really depends on all the other task you could just add a dependency on those tasks - so the dependencyCheck will run after all the other tasks.

Cheers,
Stefan


(Schalk Cronjé) #5

What about using something like

check.finalizedBy dependencyCheck

or

dependencyCheck.mustRunAfter check

instead?

The two suggestions have different behaviours but depending on how your buld is setup, might achieve the necessary.


(Willie) #6

This is in the same class as nebula gradle lint. When the code is done, I want this task to run once a day to notify the developer that their libs are out of date. Just like autolint from nebula, I want this as a depends on the build, not another task because not all tasks are avail in all builds in my shop. The ultimate would be

Project.tasks.finalizeBuild(“dependencyUpdate”)

But I don’t have that api, I have this listener


(Willie) #7

is check avail in all builds? even ones without the java plugin applied? if its a native app, without the java plugin applied, is check still avail? what about the Cobol plugin i have an intern writing, he is starting from scratch on it and not using the java plugin as a base because its so radically different, does that have the check task?

the goal is to make this dependency check task universal across the 20 or so languages we have. I have no guarantee that many of these tasks will be available. for example our cobol plugin won’t have a build task because the concept of build doesn’t exist, thats a mainframe function. all the plugin is going to do is static analysis.

I also love the fact that in nebula, the lint is the last thing displayed on the screen. I find that a lot of my developers prefer to use the --console=plain command so they can see exactly whats going on. a typical build in my shop has over 150 tasks in it. this dependency report would get lost in the output.

but the issue comes a little deeper, what is the point of the listener system if you can’t use it to execute a task?


(Schalk Cronjé) #8

apply plugin : 'base'. You should really include in any plugin to make the basic lifecycle tasks available.


(Stefan Wolf) #9

@scphantm The check task is added by the LifecycleBasePlugin which is added by the BasePlugin. All language plugins should apply the base plugin, so check should be available.

Regarding displaying the interesting information at the end: You can still add an action to buildFinished which prints out the result of the check task. The task itself can run any time.


(Schalk Cronjé) #10

It breaks the philosophy of tasks being functional. It can also interfere with the DAG .


(Willie) #11

Ok, we may be on to something here. does check get fired every time in the workflow? Regardless of what task is run? Meaning if I create mytask, is the check task executed as well?


(uklance) #12

Take a look at the following task diagram from the java plugin documentation

The “check” task is a lifecycle task and is usually only fired by the “build” task (also a lifecycle task).

If you want to understand your task hierarchy better I suggest you add the task tree plugin to your project. Eg:

plugins {
    id "com.dorongold.task-tree" version "1.3"
}

You can then try “gradle xxx taskTree” where xxx is a task name. Eg “gradle build taskTree” in a java project

:build
+--- :assemble
|    \--- :jar
|         \--- :classes
|              +--- :compileJava
|              \--- :processResources
\--- :check
     \--- :test
          +--- :classes
          |    +--- :compileJava
          |    \--- :processResources
          \--- :testClasses
               +--- :compileTestJava
               |    \--- :classes
               |         +--- :compileJava
               |         \--- :processResources
               \--- :processTestResources

(Stefan Wolf) #13

You can add a task you want to execute via

gradle.startParameter.taskNames << “endTask”

You should probably add you task when the conditions are met (once a day).