ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 01.01.2026

Просмотров: 1149

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

52.1. Inherited properties and methods

Any method or property defined in a project build script is also visible to all the sub-projects. You can use this to define common configurations, and to extract build logic into methods which can be reused by the sub-projects.

Example 52.1. Using inherited properties and methods

build.gradle

srcDirName = 'src/java'

def getSrcDir(project) {

return project.file(srcDirName)

}

child/build.gradle

task show << {

// Use inherited property

println 'srcDirName: ' + srcDirName

// Use inherited method

File srcDir = getSrcDir(project)

println 'srcDir: ' + rootProject.relativePath(srcDir)

}

Output of gradle -q show

> gradle -q show srcDirName: src/java srcDir: child/src/java

52.2. Injected configuration

You can use the configuration injection technique discussed in Section 49.1, “Cross proje configuration” and Section 49.2, “Subproject configuration”to inject properties and methods into various projects. This is generally a better option than inheritance, for a number of reasons: The injection is explicit in the build script, You can inject different logic into different projects, And you can inject any kind of configuration such as repositories, plug-ins, tasks, and so on. The following sample shows how this works.

Page 313 of 343

Example 52.2. Using injected properties and methods

build.gradle

subprojects {

//Inject a property and method srcDirName = 'src/java'

srcDir = { file(srcDirName) }

//Inject a task

task show << {

println 'project: ' + project.path println 'srcDirName: ' + srcDirName File srcDir = srcDir()

println 'srcDir: ' + rootProject.relativePath(srcDir)

}

}

// Inject special case configuration into a particular project project(':child2') {

srcDirName = "$srcDirName/legacy"

}

child1/build.gradle

// Use injected property and method. Here, we override the injected value srcDirName = 'java'

def dir = srcDir()

Output of gradle -q show

> gradle -q show project: :child1 srcDirName: java srcDir: child1/java project: :child2

srcDirName: src/java/legacy srcDir: child2/src/java/legacy

52.3. Build sources in the buildSrc project

When you run Gradle, it checks for the existence of a directory called buildSrc. Gradle then automatically compiles and tests this code and puts it in the classpath of your build script. You don't need to provide any further instruction. This can be a good place to add your custom task and plugins.

For multi-project builds there can be only one buildSrc directory, which has to be in the root project directory.

Listed below is the default build script that Gradle applies to the buildSrc project:

Page 314 of 343


Figure 52.1. Default buildSrc build script

apply plugin: 'groovy' dependencies {

compile gradleApi() groovy localGroovy()

}

This means that you can just put you build source code in this directory and stick to the layout convention for a Java/Groovy project (see Table 23.4, “Java plugin - default project layou)t”.

If you need more flexibility, you can provide your own build.gradle. Gradle applies the default build script regardless of whether there is one specified. This means you only need to declare the extra things you need. Below is an example. Notice that this example does not need to declare a dependency on the Gradle API, as this is done by the default build script:

Example 52.3. Custom buildSrc build script

buildSrc/build.gradle

repositories { mavenCentral()

}

dependencies {

testCompile group: 'junit', name: 'junit', version: '4.8.2'

}

The buildSrc project can be a multi-project build. This works like any other regular Gradle multi-project build. However, you need to make all of the projects that you wish be on the classpath of the actual build runtime dependencies of the root project in buildSrc. You can do this by adding this to the configuration of each project you wish to export:

Example 52.4. Adding subprojects to the root buildSrc project

buildSrc/build.gradle

rootProject.dependencies { runtime project(path)

}

Note: The code for this example can be found at samples/multiProjectBuildSrc which

is in both the binary and source distributions of Gradle.

52.4. Running another Gradle build from a build

You can use the GradleBuild task. You can use either of the dir or buildFile properties to specify which build to execute, and the tasks property to specify which tasks to execute.

Page 315 of 343

Example 52.5. Running another build from a build

build.gradle

task build(type: GradleBuild) { buildFile = 'other.gradle' tasks = ['hello']

}

other.gradle

task hello << {

println "hello from the other build."

}

Output of gradle -q build

> gradle -q build

hello from the other build.

52.5. External dependencies for the build script

If your build script needs to use external libraries, you can add them to the script's classpath in th build script itself. You do this using the buildscript() method, passing in a closure which declares the build script classpath.

Example 52.6. Declaring external dependencies for the build script

build.gradle

buildscript { repositories {

mavenCentral()

}

dependencies {

classpath group: 'commons-codec', name: 'commons-codec', version: '1.2

}

}

The closure passed to the buildscript() method configures a ScriptHandler instance. You declare the build script classpath by adding dependencies to the classpath configuration. This is the same way you declare, for example, the Java compilation classpath. You can use any of the dependency types described in Section 43.4, “How to declare your dependencies”,except project dependencies.

Having declared the build script classpath, you can use the classes in your build script as you would any other classes on the classpath. The following example adds to the previous example, and uses classes from the build script classpath.

Page 316 of 343



[24]

Example 52.7. A build script with external dependencies

build.gradle

import org.apache.commons.codec.binary.Base64

buildscript { repositories {

mavenCentral()

}

dependencies {

classpath group: 'commons-codec', name: 'commons-codec', version: '1.2

}

}

task encode << {

def byte[] encodedString = new Base64().encode('hello world\n'.getBytes()) println new String(encodedString)

}

Output of gradle -q encode

> gradle -q encode aGVsbG8gd29ybGQK

For multi-project builds, the dependencies declared in the a project's build script, are available t the build scripts of all sub-projects.

52.6. Ant optional dependencies

For reasons we don't fully understand yet, external dependencies are not picked up by Ant optional tasks. But you can easily do it in another way.

Page 317 of 343

Example 52.8. Ant optional dependencies

build.gradle

configurations { ftpAntTask

}

dependencies { ftpAntTask("org.apache.ant:ant-commons-net:1.8.2") {

module("commons-net:commons-net:1.4.1") { dependencies "oro:oro:2.0.8:jar"

}

}

}

task ftp << { ant {

taskdef(name: 'ftp',

classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP', classpath: configurations.ftpAntTask.asPath)

ftp(server: "ftp.apache.org", userid: "anonymous", password: "me@myorg fileset(dir: "htdocs/manual")

}

}

}

This is also nice example for the usage of client modules. The pom.xml in maven central for the ant-commons-net task does not provide the right information for this use case.

52.7. Summary

Gradle offers you a variety of ways of organizing your build logic. You can choose what is right for your domain and find the right balance between unnecessary indirections, and avoiding redundancy and a hard to maintain code base. It is our experience that even very complex custom build logic is rarely shared between different builds. Other build tools enforce a separation of this build logic into a separate project. Gradle spares you this unnecessary overhead and indirection.

[23] Which might range from a single class to something very complex.

[24] In fact, we think this is anyway the nicer solution. Only if your buildscript and Ant's option task need the same library you would have to define it two times. In such a case it would be nice, if Ant's optional task would automatically pickup the classpath defined in thegradesettings.

Page 318 of 343

53

Initialization Scripts

Gradle provides a powerful mechanism to allow customizing the build based on the current environment. This mechanism also supports tools that wish to integrate with Gradle.

53.1. Basic usage

Initialization scripts (a.k.a. init scripts) are similar to other scripts in Gradle. These scripts, however, are run before the build starts. Here are several possible uses:

Set up enterprise-wide configuration, such as where to find custom plugins.

Set up properties based on the current environment, such as a developer's machine vs. continuous integration server.

Supply personal information about the user that is required by the build, such as repository or database authentication credentials.

Define machine specific details, such as where JDKs are installed.

Register build listeners. External tools that wish to listen to Gradle events might find this useful.

Register build loggers. You might wish to customise how Gradle logs the events that it generates.

One main limitation of init scripts is that they cannot access classes in the buildSrc project (see Section 52.3, “Build sources in thebuildSrc project” for details of this feature).

53.2. Using an init script

There are several ways to use an init script:

Specify a file on the command line. The command line option is -I or --init-script followed by the path to the script. The command line option can appear more than once, each time adding another init script.

Put a file called init.gradle in the USER_HOME/.gradle/ directory.

Page 319 of 343