Gradle 出色的集成了 Ant. 你可以在 Gradle 构建时使用单独的 Ant 任务或完整的 Ant 构建. 事实上, 你会发现在 Gradle 构建脚本中使用Ant任务远比直接使用 Ant 的 XML 格式更加容易和强大. 你甚至可以将 Gradle 仅仅作为一个强大的 Ant 脚本工具.
Ant 可以分为两层. 第一层是 Ant 语言. 它给 build.xml 文件, 处理目标, 像 macrodefs 的特殊构造等提供语法支持. 换句话说, 除了 Ant 任务和类型, 其余一切都支持. Gradle 了解这种语言, 并允许用户直接导入 Ant 的 build.xml 到 Gradle 的项目下. 然后, 你可以 像 Gradle 任务一样直接使用这些 Ant 构建.
第二层是 Ant 丰富的任务和类型, 如 javac, copy 或 jar. Gradle 提供了基于 Groovy 的集成以及梦幻般的 AntBuilder.
最后,由于构建脚本是 Groovy 脚本, 你总是可以执行一个 Ant 构建作为一个外部进程. 构建脚本可能会含有类似的语句:“ant clean compile”.execute().[7]
你可以使用 Gradle 的 Ant 集成,作为迁移路径将构建 Ant 迁移到 Gradle. 例如, 你可以从通过导入现有的 Ant 构建开始, 然后将你的依赖声明从 Ant 脚本迁移到你的 build 文件. 最后, 你可以将任务迁移到你的构建文件, 或者用一些 Gradle 插件代替他们. 随着时间的推移, 这部分工作会一步一步地完成, 并且你可以在整个进程中有一个运行良好的 Gradle 构建.
在构建脚本中, Ant 属性是由 Gradle提供的. 这是一个用于参考的 AntBuilder 实例. AntBuilder 用于从构建脚本访问 Ant 任务, 类型和属性. 下面的例子解释了从 Ant 的 build.xml
格式到 Grooy 的映射.
你可以通过调用 AntBuilder 实例的方法执行 Ant 任务. 你可以使用任务名称作为方法名, 比如, 可以通过调用 anto.echo()
任务执行 Ant echo
任务. Ant 任务属性通过 Map 参数传递给方法. 下面是一个 echo
任务的例子, 注意我们也可以混合使用 Groovy 代码和 Ant 任务标记, 这点个功能非常强大.
例 16.1.使用 Ant 任务
build.gradle
task hello << {
String greeting = 'hello from Ant'
ant.echo(message: greeting)
}
gradle hello
的输出
>\> gradle hello
>:hello
>[ant:echo] hello from Ant
>
>BUILD SUCCESSFUL
>
>Total time: 1 secs
你可以添加嵌套元素添加到一个封闭的 Ant 任务的内部. 定义嵌套元素跟定义任务的方式相同, 通过与调用我们要定义的元素名相同的方法.
例 16.3.添加嵌套元素到一个Ant任务
build.gradle
task zip << {
ant.zip(destfile: 'archive.zip') {
fileset(dir: 'src') {
include(name: '**.xml')
exclude(name: '**.java')
}
}
}
你可以像访问任务一样访问 Ant type,只需要将 type 名作为方法名即可. 该方法调用返回的 Ant 数据类型,可以直接在构建脚本中使用.下面的例子中,我们创建了一个ant path
对象,然后遍历他的内容.
例 16.4.使用 Ant 类型
build.gradle
task list << {
def path = ant.path {
fileset(dir: 'libs', includes: '*.jar')
}
path.list().each {
println it
}
}
更多关于 AntBuilder 的信息可以参考 'Groovy in Action'8.4 或者Groovy Wiki.
为了让你的构建可以自定义任务, 你可以使用 taskdef(通常更容易)
或者 typedef
Ant 任务, 就像你在一个build.xml
文件中一样. 然后,你可以参考内置 Ant 任务去定制 Ant 任务.
例 16.5.使用自定义 Ant 任务
build.gradle
task check << {
ant.taskdef(resource: 'checkstyletask.properties') {
classpath {
fileset(dir: 'libs', includes: '*.jar')
}
}
ant.checkstyle(config: 'checkstyle.xml') {
fileset(dir: 'src')
}
}
你可以使用 Gradle 的依赖管理去组装你自定义任务所需要的 classpath. 要做到这一点, 你需要定义一个自定义配置类路径, 然后添加一些依赖配置.在Section 51.4, “How to declare your dependencies”部分有更详细的说明.
例 16.6.声明类路径的自定义 Ant 任务
build.gradle
configurations {
pmd
}
dependencies {
pmd group: 'pmd', name: 'pmd', version: '4.2.5'
}
要使用 classpath 配置, 使用自定义配置的asPath
属性。
例 16.7.一起使用自定义Ant任务和依赖管理
build.gradle
task check << {
ant.taskdef(name: 'pmd',
classname: 'net.sourceforge.pmd.ant.PMDTask',
classpath: configurations.pmd.asPath)
ant.pmd(shortFilenames: 'true',
failonruleviolation: 'true',
rulesetfiles: file('pmd-rules.xml').toURI().toString()) {
formatter(type: 'text', toConsole: 'true')
fileset(dir: 'src')
}
}
你可以在你的gradle项目中通过ant.importBuild()
来导入一个ant构建,当你导入了一个ant构建,每一个ant target
都会被视为一个Gradle任务.这意味着你可以像操作,执行gradle任务一样操作,执行ant target
例 16.8.导入ant构建
build.gradle
ant.importBuild 'build.xml'
build.xml
<project>
<target name="hello">
<echo>Hello, from Ant</echo>
</target>
</project>
gradle hello
的输出
>\> gradle hello
>:hello
>[ant:echo] Hello, from Ant
>
>BUILD SUCCESSFUL
>
>Total time: 1 secs
你可以添加一个依赖于ant target
的任务:
例 16.9.依赖于ant target的任务
build.gradle
ant.importBuild 'build.xml'
task intro(dependsOn: hello) << {
println 'Hello, from Gradle'
}
gradle intro
的输出 > gradle intro :hello [ant:echo] Hello, from Ant :intro Hello, from GradleBUILD SUCCESSFUL
Total time: 1 secs
或者,你可以为ant target
添加动作
例 16.10.为Ant target添加动作
build.gradle
ant.importBuild 'build.xml'
hello << {
println 'Hello, from Gradle'
}
gradle hello
的输出
> gradle hello :hello [ant:echo] Hello, from Ant Hello, from Gradle
BUILD SUCCESSFUL
Total time: 1 secs
当然,一个ant target
也可以依赖于gradle的任务
例 16.11.为Ant target添加动作
build.gradle
ant.importBuild 'build.xml'
task intro << {
println 'Hello, from Gradle'
}
build.xml
<project>
<target name="hello" depends="intro">
<echo>Hello, from Ant</echo>
</target>
</project>
gradle hello
的输出
> gradle hello :intro Hello, from Gradle :hello [ant:echo] Hello, from Ant
BUILD SUCCESSFUL
Total time: 1 secs
有时候可能需要'重命名'ant target
以避免与现有的gradle任务冲突.需要使用AntBuilder.importBuilder()方法.
例 16.12.重命名导入的ant target
build.gradle
ant.importBuild('build.xml') { antTargetName ->
'a-' + antTargetName
}
build.xml
<project>
<target name="hello">
<echo>Hello, from Ant</echo>
</target>
</project>
gradle a-hello
的输出
> gradle a-hello :a-hello [ant:echo] Hello, from Ant
BUILD SUCCESSFUL
Total time: 1 secs
注意,方法的二个参数应该是一个TransFormer,在Groovy编程的时候,由于Groovy的支持自动闭包单抽象方法的类型。我们可以简单地使用闭包取代匿名内部类,
有许多方法可以设定 Ant 属性,可以通过Ant任务使用属性.您可以直接在AntBuilder
的实例设置属性。Ant的属性也可以作为一个可改变的Map
.也可以使用Ant的任务属性,如下例所示:
例16.13.设置Ant属性
build.gradle
ant.buildDir = buildDir
ant.properties.buildDir = buildDir
ant.properties['buildDir'] = buildDir
ant.property(name: 'buildDir', location: buildDir)
build.xml
<echo>buildDir = ${buildDir}</echo>
许多任务会在执行时设置属性.下面有几种方法来获取属性值,可以直接从AntBuilder
实例获得属性,如下所示,ant的属性仍然是作为一个map:
例16.14.获取Ant属性
build.xml
<property name="antProp" value="a property defined in an Ant build"/>
build.gradle
println ant.antProp
println ant.properties.antProp
println ant.properties['antProp']
设置一个ant引用的方法:
例16.15.设置一个Ant引用
build.gradle
ant.path(id: 'classpath', location: 'libs')
ant.references.classpath = ant.path(location: 'libs')
ant.references['classpath'] = ant.path(location: 'libs')
build.xml
<path refid="classpath"/>
获取Ant引用的方法:
例16.16.获取一个Ant引用
build.xml
<path id="antPath" location="libs"/>
build.gradle
println ant.references.antPath
println ant.references['antPath']
Ant 集成是由 AntBuilder 提供的.git