第17章 Using Ant from Gradle 從 Gradle 使用 Ant

2018-02-24 15:56 更新

Gradle 提供了對(duì) Ant 的優(yōu)秀集成。可以在你的 Gradle 構(gòu)建中,使用單獨(dú)的 Ant 任務(wù)或整個(gè) Ant 構(gòu)建。事實(shí)上,你會(huì)發(fā)現(xiàn)在 Gradle 中使用 Ant 任務(wù)比使用 Ant 的 XML 格式更容易也更強(qiáng)大。你甚至可以只把 Gradle 當(dāng)作一個(gè)強(qiáng)大的 Ant 任務(wù)腳本的工具。

Ant 可以分為兩層。第一層是 Ant 的語(yǔ)言。它提供了用于 build.xml,處理的目標(biāo),特殊的構(gòu)造方法比如宏,還有其他等等的語(yǔ)法。換句話說(shuō),除了 Ant 任務(wù)和類型之外全部都有。Gradle 理解這種語(yǔ)言,并允許您直接導(dǎo)入你的 Ant build.xml 到 Gradle 項(xiàng)目中。然后你可以使用你的 Ant 構(gòu)建中的 target,就好像它們是 Gradle task 一樣。

Ant 的第二層是其豐富的 Ant 任務(wù)和類型,如 javac、copy或jar。這一層 Gradle 只靠 Groovy 和非常棒的 AntBuilder,對(duì)其提供了集成。

最后,由于構(gòu)建腳本是 Groovy 腳本,所以您始終可以作為一個(gè)外部進(jìn)程來(lái)執(zhí)行 Ant 構(gòu)建。你的構(gòu)建腳本可能包含有類似這樣的語(yǔ)句:"ant clean compile".execute()?(在 Groovy 中,你可以執(zhí)行字符串。了解更多關(guān)于執(zhí)行外部進(jìn)程,請(qǐng)查看 9.3.2 的'Groovy in Action'或者 Groovy wiki)

你可以把 Gradle 的 Ant 集成當(dāng)成一個(gè)路徑,將你的構(gòu)建從 Ant 遷移至 Gradle 。例如,你可以通過(guò)導(dǎo)入您現(xiàn)有的 Ant 構(gòu)建來(lái)開(kāi)始。然后,可以將您的依賴聲明從 Ant 腳本移到您的構(gòu)建文件。最后,您可以將整個(gè)任務(wù)移動(dòng)到您的構(gòu)建文件,或者把它們替換為一些 Gradle 插件。這個(gè)過(guò)程可以隨著時(shí)間一點(diǎn)點(diǎn)完成,并且在這整個(gè)過(guò)程當(dāng)中你的 Gradle 構(gòu)建都可以使用用。

17.1. Using Ant tasks and types in your build 在你的構(gòu)建中使用 Ant 的任務(wù)和類型

在構(gòu)建腳本中,Gradle 提供了一個(gè)名為 ant 的屬性。它指向一個(gè)?AntBuilder?實(shí)例。AntBuilder 用于從你的構(gòu)建腳本中訪問(wèn) Ant 任務(wù)、 類型和屬性。從 Ant 的 build.xml 格式到 Groovy 之間有一個(gè)非常簡(jiǎn)單的映射,下面解釋。

通過(guò)調(diào)用 AntBuilder 實(shí)例上的一個(gè)方法,可以執(zhí)行一個(gè) Ant 任務(wù)。你可以把任務(wù)名稱當(dāng)作方法名稱使用。例如,你可以通過(guò)調(diào)用 ant.echo() 方法執(zhí)行 Ant 的 echo 任務(wù)。Ant 任務(wù)的屬性會(huì)作為 Map 參數(shù)傳給該方法。下面是執(zhí)行 echo 任務(wù)的例子。請(qǐng)注意我們還可以混合使用 Groovy 代碼和 Ant 任務(wù)標(biāo)記。這將會(huì)非常強(qiáng)大。

Example 17.1. Using an Ant task

build.gradle

task hello << {
    String greeting = 'hello from Ant'
    ant.echo(message: greeting)
}

執(zhí)行 gradle hello

> gradle hello
:hello
[ant:echo] hello from Ant

BUILD SUCCESSFUL

Total time: 1 secs

你可以把一個(gè)嵌套文本,通過(guò)作為任務(wù)方法調(diào)用的參數(shù),把它傳給一個(gè) Ant 任務(wù)。在此示例中,我們將把作為嵌套文本的消息傳給 echo 任務(wù):

Example 17.2. Passing nested text to an Ant task

build.gradle

task hello << {
    ant.echo('hello from Ant')
}

執(zhí)行 gradle hello

> gradle hello
:hello
[ant:echo] hello from Ant

BUILD SUCCESSFUL

Total time: 1 secs

你可以在一個(gè)閉包里把嵌套的元素傳給一個(gè) Ant 任務(wù)。嵌套元素的定義方式與任務(wù)相同,通過(guò)調(diào)用與我們要定義的元素一樣的名字的方法

Example 17.3. Passing nested elements to an Ant task

build.gradle

task zip << {
    ant.zip(destfile: 'archive.zip') {
        fileset(dir: 'src') {
            include(name: '**.xml')
            exclude(name: '**.java')
        }
    }
}

您可以用訪問(wèn)任務(wù)同樣的方法,把類型名字作為方法名稱,訪問(wèn) Ant 類型。方法調(diào)用返回 Ant 數(shù)據(jù)類型,然后可以在構(gòu)建腳本中直接使用。在以下示例中,我們創(chuàng)建一個(gè) Ant 的 path 對(duì)象,然后循環(huán)訪問(wèn)它的內(nèi)容。

Example 17.4. Using an Ant type

build.gradle

task list << {
    def path = ant.path {
        fileset(dir: 'libs', includes: '*.jar')
    }
    path.list().each {
        println it
    }
}

更多有關(guān) AntBuilder 見(jiàn) 8.4 的'Groovy in Action' 或者?Groovy Wiki

17.1.1. Using custom Ant tasks in your build 在構(gòu)建中使用自定義的 Ant 任務(wù)

要使自定義任務(wù)在您的構(gòu)建中可用,你可以使用 Ant 任務(wù) taskdef(通常更容易) 或 typedef,就像在 build.xml 文件中一樣。然后,您可以像引用內(nèi)置的 Ant 任務(wù)一樣引用自定義 Ant 任務(wù)。

Example 17.5. Using a custom Ant task

build.gradle

task check << {
    ant.taskdef(resource: 'checkstyletask.properties') {
        classpath {
            fileset(dir: 'libs', includes: '*.jar')
        }
    }
    ant.checkstyle(config: 'checkstyle.xml') {
        fileset(dir: 'src')
    }
}

你可以使用 Gradle 的依賴管理組合類路徑,以用于自定義任務(wù)。要做到這一點(diǎn),你需要定義一個(gè)自定義配置的類路徑中,然后將一些依賴項(xiàng)添加到配置中。這在 50.4章節(jié),“如何聲明你的依賴”有更詳細(xì)的描述。

Example 17.6. Declaring the classpath for a custom Ant task

build.gradle

configurations {
    pmd
}

dependencies {
    pmd group: 'pmd', name: 'pmd', version: '4.2.5'
}

若要使用類路徑配置,請(qǐng)使用自定義配置里的 asPath 屬性。

Example 17.7. Using a custom Ant task and dependency management together

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') } }

17.2. Importing an Ant build 導(dǎo)入 Ant 的構(gòu)建

你可以使用 ant.importBuild() 方法來(lái)向 Gradle 項(xiàng)目導(dǎo)入一個(gè) Ant 構(gòu)建。當(dāng)您導(dǎo)入一個(gè) Ant 構(gòu)建時(shí),每個(gè) Ant 目標(biāo)被視為一個(gè) Gradle 任務(wù)。這意味著你可以用與 Gradle 任務(wù)完全相機(jī)的方式操縱和執(zhí)行 Ant 目標(biāo)。

Example 17.8. Importing an Ant build

build.gradle

ant.importBuild 'build.xml'

build.xml

<project>
    <target name="hello">
        <echo>Hello, from Ant</echo>
    </target>
</project>

執(zhí)行 gradle hello

> gradle hello
:hello
[ant:echo] Hello, from Ant

BUILD SUCCESSFUL

Total time: 1 secs

您可以添加一個(gè)依賴于 Ant 目標(biāo)的任務(wù):

build.gradle

ant.importBuild 'build.xml'

task intro(dependsOn: hello) << {
    println 'Hello, from Gradle'
}

執(zhí)行 gradle intro

> gradle intro
:hello
[ant:echo] Hello, from Ant
:intro
Hello, from Gradle

BUILD SUCCESSFUL

Total time: 1 secs

或者,您可以將行為添加到 Ant 目標(biāo)中:

Example 17.10. Adding behaviour to an Ant target

build.gradle

ant.importBuild 'build.xml'

hello << {
    println 'Hello, from Gradle'
}

執(zhí)行 gradle hello

> gradle hello
:hello
[ant:echo] Hello, from Ant
Hello, from Gradle

BUILD SUCCESSFUL

Total time: 1 secs

它也可以用于一個(gè)依賴于 Gradle 任務(wù)的 Ant 目標(biāo):

Example 17.11. Ant target that depends on Gradle task

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>

執(zhí)行 gradle hello

> gradle hello
:intro
Hello, from Gradle
:hello
[ant:echo] Hello, from Ant

BUILD SUCCESSFUL

Total time: 1 secs‘

有時(shí)可能需要“改名”來(lái)避免 Ant target 生成的 task 與現(xiàn)有的 Gradle task 在命名上沖突。使用?AntBuilder.importBuild()?方法

Example 17.12. Renaming imported Ant targets

build.gradle

ant.importBuild('build.xml') { antTargetName ->
    'a-' + antTargetName
}

build.xml

<project>
    <target name="hello">
        <echo>Hello, from Ant</echo>
    </target>
</project>

執(zhí)行 gradle a-hello

> gradle a-hello
:a-hello
[ant:echo] Hello, from Ant

BUILD SUCCESSFUL

Total time: 1 secs

請(qǐng)注意,雖然這個(gè)方法的第二個(gè)參數(shù)應(yīng)該是一個(gè)?Transformer,在 Groovy 編程時(shí)可以使用簡(jiǎn)單的閉包而不是一個(gè)匿名內(nèi)部類(或類似的),因?yàn)?Groovy 的支持自動(dòng)強(qiáng)制關(guān)閉 single-abstract-method(單一的抽象方法)的類型。

17.3. Ant properties and references 關(guān)于 Ant 的屬性和引用

有幾種方法來(lái)設(shè)置 Ant 屬性,以便使該屬性被 Ant 任務(wù)使用。你可以直接在 AntBuilder 實(shí)例上設(shè)置屬性。Ant 屬性也可以從一個(gè)你可以修改的 Map 中獲得。您還可以使用 Ant property 任務(wù)。下面是一些如何做到這一點(diǎn)的例子。

Example 17.13. Setting an Ant property

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>

有幾種方法可以設(shè)置 Ant 引用:

Example 17.14. Getting an Ant property

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 引用:

Example 17.15. Setting an Ant reference

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 引用:

Example 17.16. Getting an Ant reference

build.xml

<path id="antPath" location="libs"/>

``
build.gradle

println ant.references.antPath
println ant.references['antPath']

17.4. API

AntBuilder?提供 Ant 的集成

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)