Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is correct way to define tasks in Gradle plugin?

Tags:

plugins

gradle

I'm trying to create my first Gradle plugin.
1. Add extension for properties: project.extensions.create("abc", AbcExtension)
2. Define copy task. When I define task following way

project.task("abcTask", type: Copy) {
  from project.abc.fromPath
  into project.abc.intoPath
}

project.abc.fromPath equals to AbcExtension.fromPath value - it doesn't read values from build.gradle.
When I define task following way

project.task("abcTask", type: Copy) << {
  from project.abc.fromPath
  into project.abc.intoPath
}

it always print UP-TO-DATE and doesn't run task.

Pls explain this behaviour and tell me what is correct way to define tasks in Gradle plugins (with type and dependsOn functionallity)

like image 266
fedor.belov Avatar asked Apr 26 '13 10:04

fedor.belov


1 Answers

Plugins have to defer every read of a mutable build model value (i.e. anything that can be set from a build script) until at least the end of the configuration phase. There are several ways to achieve this goal. Among them are:

  • Using a Gradle API that accepts closures as values (e.g. Copy.from)
  • Using callbacks like project.afterEvaluate {} or gradle.projectsEvaluated {}
  • Using the convention mapping mechanism (note that this is not considered a public feature)

Choosing the best option for the job at hand requires some expertise. (It may help to study some of the plugins in the Gradle codebase.) In your case, I might do the following:

project.task("abcTask", type: Copy) {
    from { project.abc.fromPath }
    into { project.abc.intoPath }
}

Your << version doesn't work because it configures the Copy task too late. Generally speaking, all configuration should take place in the configuration phase, rather than the execution phase. You can learn more about Gradle build phases in the Gradle User Guide.

like image 145
Peter Niederwieser Avatar answered Sep 30 '22 08:09

Peter Niederwieser