Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Gradle.pdf
Скачиваний:
9
Добавлен:
24.03.2015
Размер:
1.4 Mб
Скачать

Example 49.30. Build and Test Dependent Projects

Output of gradle :api:buildDependents

> gradle :api:buildDependents :shared:compileJava :shared:processResources :shared:classes

:shared:jar

:api:compileJava

:api:processResources

:api:classes

:api:jar

:api:assemble

:api:compileTestJava

:api:processTestResources

:api:testClasses

:api:test

:api:check

:api:build

:services:personService:compileJava

:services:personService:processResources

:services:personService:classes

:services:personService:jar

:services:personService:assemble

:services:personService:compileTestJava

:services:personService:processTestResources

:services:personService:testClasses

:services:personService:test

:services:personService:check

:services:personService:build

:services:personService:buildDependents

:api:buildDependents

BUILD SUCCESSFUL

Total time: 1 secs

Finally, you may want to build and test everything in all projects. Any task you run in the root project folder will cause that same named task to be run on all the children. So you can just run gra to build and test all projects.

49.9. Property and method inheritance

Properties and methods declared in a project are inherited to all its subprojects. This is an alternative to configuration injection. But we think that the model of inheritance does not reflect the problem space of multi-project builds very well. In a future edition of this user guide we might write more about this.

Method inheritance might be interesting to use as Gradle'sConfiguration Injection does not support methods yet (but will in a future release).

You might be wondering why we have implemented a feature we obviously don't like that much One reason is that it is offered by other tools and we want to have the check mark in a feature comparison :). And we like to offer our users a choice.

Page 296 of 343

[22]

49.10. Summary

Writing this chapter was pretty exhausting and reading it might have a similar effect. Our final message for this chapter is that multi-project builds with Gradle are usually not difficult. There are five elements you need to remember: allprojects, subprojects, evaluationDependsOn, e and project lib dependencies. With those elements, and keeping in mind that Gradle has a distinct configuration and execution phase, you have already a lot of flexibility. But when you enter steep territory Gradle does not become an obstacle and usually accompanies and carries you to the top of the mountain.

[19] The real use case we had, was using http://lucene.apache.org/solr, where you need a separate war for each index your are accessing. That was one reason why we have created a distribution of webapps. The Resin servlet container allows us, to let such a distribution point to a base installation of the servlet container.

[20] services is also a project, but we use it just as a container. It has no build script and gets nothing injected by another build script.

[21] We do this here, as it makes the layout a bit easier. We usually put the project specific stuff into the build script of the respective projects.

[22] So we are well in the range of the 7 plus 2 Rule :)

Page 297 of 343

50

Writing Custom Task Classes

Gradle supports two types of task. One such type is the simple task, where you define the task with an action closure. We have seen these in Chapter 6, Build Script Basics. For this type of task, the action closure determines the behaviour of the task. This type of task is good for implementing one-off tasks in your build script.

The other type of task is the enhanced task, where the behaviour is built into the task, and the task provides some properties which you can use to configure the behaviour. We have seen these in Chapter 17, More about Tasks. Most Gradle plugins use enhanced tasks. With enhanced tasks, you don't need to implement the task behaviour as you do with simple tasks. You simply declar the task and configure the task using its properties. In this way, enhanced tasks let you reuse a piece of behaviour in many different places, possibly across different builds.

The behaviour and properties of an enhanced task is defined by the task's class. When yo declare an enhanced task, you specify the type, or class of the task.

Implementing your own custom task class in Gradle is easy. You can implement a custom task class in pretty much any language you like, provided it ends up compiled to bytecode. In our examples, we are going to use Groovy as the implementation language, but you could use, for example, Java or Scala. In general, using Groovy is the easiest option, because the Gradle API is designed to work well with Groovy.

50.1. Packaging a task class

There are several places where you can put the source for the task class.

Build script

You can include the task class directly in the build script. This has the benefit that the task class is automatically compiled and included in the classpath of the build script without you having to do anything. However, the task class is not visible outside the build script, and so you cannot reuse the task class outside the build script it is defined in.

buildSrc project

You can put the source for the task class in the rootProjectDir/buildSrc/src/main/ directory. Gradle will take care of compiling and testing the task class and making it available on the classpath of the build script. The task class is visible to every build script used by the

Page 298 of 343

build. However, it is not visible outside the build, and so you cannot reuse the task class outside the build it is defined in. Using the buildSrc project approach keeps separate the task declaration - that is, what the task should do - from the task implementation - that is, how the task does it.

See Chapter 52, Organizing Build Logic for more details about the buildSrc project.

Standalone project

You can create a separate project for your task class. This project produces and publishes a JAR which you can then use in multiple builds and share with others. Generally, this JAR might include some custom plugins, or bundle several related task classes into a single library. Or some combination of the two.

In our examples, we will start with the task class in the build script, to keep things simple. Then we will look at creating a standalone project.

50.2. Writing a simple task class

To implement a custom task class, you extend DefaultTask.

Example 50.1. Defining a custom task

build.gradle

class GreetingTask extends DefaultTask {

}

This task doesn't do anything useful, so let's add some behaviour. To do so, we add a method the task and mark it with the TaskAction annotation. Gradle will call the method when the task executes. You don't have to use a method to define the behaviour for the task. You could, fo instance, call doFirst() or doLast() with a closure in the task constructor to add behaviour.

Example 50.2. A hello world task

build.gradle

task hello(type: GreetingTask)

class GreetingTask extends DefaultTask { @TaskAction

def greet() {

println 'hello from GreetingTask'

}

}

Output of gradle -q hello

> gradle -q hello

hello from GreetingTask

Let's add a property to the task, so we can customize it. Tasks are simply POGOs, and when yo

Page 299 of 343

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]