使用Gradle引导旧式Ant构建

Gradle提供了几种不同的方式来利用您现有的对Ant的投资,包括积累的知识和您已经放入构建文件中的时间。 这可以极大地方便将Ant生成的项目移植到Gradle的过程,并为您提供逐步进行此操作的路径。 Gradle文档在描述如何在Gradle构建脚本中使用Ant方面做得很好,但是这里有一个快速概述以及我遇到的一些细节。

Gradle AntBuilder

每个Gradle项目都包含一个AntBuilder实例,从而使您的构建文件中可以使用任何和所有Ant功能。 Gradle提供了对现有Groovy AntBuilder的简单扩展,它增加了一种与现有Ant构建文件交互的简单而强大的方法: importBuild(Object antBuildFile)方法。 在内部,此方法利用Ant ProjectHelper解析指定的Ant构建文件,然后将所有目标包装在Gradle任务中,以使它们在Gradle构建中可用。 以下是用于说明的简单Ant构建文件,其中包含一些属性和几个相关的目标。

<?xml version='1.0'?>
<project name='build' default='all'>
    <echo>Building ${ant.file}</echo>

    <property file='build.properties'/>
    <property name='root.dir' location='.'/>

    <target name='dist' description='Build the distribution'>
        <property name='dist.dir' location='dist'/>
        <echo>dist.dir=${dist.dir}, foo=${foo}</echo>
    </target>

    <target name='all' description='Build everything' depends='dist'/>
</project>

使用Gradle导入此构建文件是一种方法。

ant.importBuild('src/main/resources/build.xml')

gradle任务的输出–全部在命令行上显示,目标已添加到构建任务中。

$ gradle tasks --all
...
Other tasks
-----------
all - Build everything
    dist - Build the distribution
...

Ant构建文件中使用的属性可以在Gradle构建或命令行中指定,并且与通常的Ant属性行为不同,Ant或命令行上设置的属性可能被Gradle覆盖。 给定一个简单的build.properties文件,其中的foo = bar为单个条目,这里有一些组合来演示覆盖行为。

命令行调用 Gradle构建配置 影响 结果
gradle dist ant.importBuild('src / main / resources / build.xml') 使用从ant build加载的build.properties值 foo = bar
gradle dist -Dfoo = NotBar ant.importBuild('src / main / resources / build.xml') 使用命令行属性 foo = NotBar
gradle dist -Dfoo = NotBar ant.foo ='NotBarFromGradle'
ant.importBuild('src / main / resources / build.xml')
使用Gradle build属性 foo = NotBarFromGradle
gradle dist -Dfoo = NotBar ant.foo ='NotBarFromGradle'
ant.importBuild('src / main / resources / build.xml')
ant.foo ='NotBarFromGradleAgain'
使用Gradle构建属性覆盖 foo = NotBarFromGradleAgain

如何处理任务名称冲突

由于Gradle坚持任务名称的唯一性,因此尝试导入包含与现有Gradle任务名称相同的目标的Ant构建会失败。 我遇到的最常见的冲突是Gradle BasePlugin提供的clean任务。 借助一些间接的帮助,我们仍然可以通过使用GradleBuild任务来导入和使用任何冲突目标,以在独立的Gradle项目中引导Ant构建导入。 让我们在导入的Ant构建中向混合添加一个新任务,并对all任务依赖于蚂蚁清理目标添加另一个依赖。

<!-- excerpt from buildWithClean.xml Ant build file -->
    <target name='clean' description='clean up'>
        <echo>Called clean task in ant build with foo = ${foo}</echo>
    </target>
    <target name='all' description='Build everything' depends='dist,clean'/>

还有一个简单的Gradle构建文件,它将处理导入。

ant.importBuild('src/main/resources/buildWithClean.xml')

最后,在主gradle构建文件中,我们添加了一个任务来运行所需的目标。

task importTaskWithExistingName(type: GradleBuild) { GradleBuild antBuild ->
    antBuild.buildFile ='buildWithClean.gradle'
    antBuild.tasks = ['all']
}

这行得通,但不幸的是遇到了一个小问题 。 当Gradle导入这些任务时,它没有正确遵守依赖项的声明顺序。 而是按字母顺序执行从属蚂蚁目标。 在这种特殊情况下,Ant希望在clean之前执行dist目标,而Gradle则以相反的顺序执行它们。 可以通过明确说明任务顺序来解决此问题,该任务顺序绝对不理想,但可行。 这个Gradle任务将按照我们需要的方式执行底层的Ant目标。

task importTasksRunInOrder(type: GradleBuild) { GradleBuild antBuild ->
    antBuild.buildFile ='buildWithClean.gradle'
    antBuild.tasks = ['dist', 'clean']
}


其余的Gradle规则

最后,您可以使用Gradle Rule来允许在GradleBuild自举导入中调用任意目标。

tasks.addRule('Pattern: a-<target> will execute a single <target> in the ant build') { String taskName ->
    if (taskName.startsWith('a-')) {
        task(taskName, type: GradleBuild) {
            buildFile = 'buildWithClean.gradle'
            tasks = [taskName - 'a-']
        }
    }
}

在此特定示例中,这还可以使您将调用串联在一起,但要警告它们在完全隔离的环境中执行。

$ gradle a-dist a-clean


源代码

如果您想仔细看一看,本文中引用的所有代码都可以在github上找到。

相关文章:

  1. 为什么我喜欢Gradle?
  2. 一个Groovy / Gradle JSLint插件
  3. 使用Groovy脚本可以做的五件事

参考:The Kaptain on…内容博客中, 使用Gradle从我们的JCG合作伙伴 Kelly Robinson 引导您的Legacy Ant构建


翻译自: https://www.javacodegeeks.com/2012/08/using-gradle-to-bootstrap-your-legacy.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值