1. 程式人生 > >Building and Testing with Gradle筆記3——Ant and Gradle

Building and Testing with Gradle筆記3——Ant and Gradle

Hello Ant

可以將Ant理解為Java世界的make,正如使用make需要編寫Makefile。Ant也有類似Makefile的構建檔案,只不過是使用xml來描述的。建立一個檔案build.xml,內容如下:

<project>
    <target name="helloViaAttribute">
        <echo message="hello from Ant"/>
    </target>
</project>

然後進入該目錄執行ant helloViaAttribute。即可輸出hello from Ant

helloViaAttribute是build檔案中定義的一個target,類似於Gradle中的task,或者make中的目標。echo是ant中的一個內建task。事實上Gradle是Ant的一個超集,可以在Gradle中直接使用Ant的內建task。如下:

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

Ant中的property類似於Gradle中的變數。如下分別是Ant和Gradle的構建檔案:

<project>
    <property
name="buildoutput" location="output"/>
<property name="appversion" value="2.1"/> </project>
def helloName = "Fird Birfle"
int personAge = 43

task hello << {
    println "Hello ${helloName}. I believe you are ${personAge} years of age."
}

Gradle中匯入Ant的自定義Task

task checkTheStyle << {
    //Load the custom task
ant.taskdef(resource: 'checkstyletask.properties') { classpath { fileset(dir: 'libs/checkstyle', includes: '*.jar') } } //Use the custom task ant.checkstyle(config: 'src/tools/sun_checks.xml') { fileset(dir: 'src') } }

ant.taskdef方法載入jar檔案中的一個屬性檔案,內容如下:

checkstyle=com.puppycrawl.tools.checkstyle.CheckStyleTask

前面的checkstyle是Ant中自定義的一個Task名稱,後面則是具體的實現。這個地方和Gradle中自定義Task的方法類似。
接下來ant.checkstyle就開始直接使用這個自定的Task了。由於Ant缺乏對dependencies的管理,需要將自己下載jar包放入到libs裡面。正如前面的checkstyle.jar。
使用Gradle的依賴管理方法,還可以這樣載入和執行Ant的自定義Task。

configurations {
    myPmd
}

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

repositories {
    mavenCentral()
}

task checkThePMD << {
    ant.taskdef(name: 'myPmdTask', classname: 'net.sourceforge.pmd.ant.PMDTask',
        classpath: configurations.myPmd.asPath)

    ant.myPmdTask(shortFilenames: 'true', failonruleviolation: 'true',
        rulesetfiles: file('src/tools/pmd-basic-rules.xml').toURI().toString()) {
            formatter(type: 'text', toConsole: 'true')
            fileset(dir: 'src/main/java')
    }
}

複雜的Ant配置

如下build.xml將samples目錄中所有txt檔案壓縮成一個zip檔案

<project>
    <target name="zipsourceInAnt">
        <zip destfile='samples-from-ant.zip'>
            <fileset dir= 'samples'>
                <include name='**.txt'/>
            </fileset>
        </zip>
    </target>
</project>

對應的Gradle寫法如下:

task zipsourceInGradle << {
    ant.zip(destfile: 'samples-from-gradle.zip') {
        fileset(dir: 'samples') {
            include(name: '**.txt')
        }
    }
}

匯入整個Ant建構檔案

在build.gradle檔案頭部,新增如下一行,將整個ant建構檔案匯入Gradle

ant.importBuild 'build.xml'

然後build.xml檔案中所有定義的target都可以當作Gradle中的task使用,如,gradle helloViaAttribute

Ant Target和Gradle相互依賴

沒啥好說的,直接看程式碼:

<project>
    <target name="antStandAloneHello">
        <echo message="A standalone hello from an Ant target"/>
    </target>

    <target name="antHello" depends="beforeTheAntTask">
        <echo message="A dependent hello from the Ant target"/>
    </target>
</project>
ant.importBuild 'build.xml'

defaultTasks = ['antStandAloneHello', 'afterTheAntTask']

task beforeTheAntTask << {
    println "A Gradle task that precedes the Ant target"
}

task afterTheAntTask(dependsOn: "antHello") << {
    println "A Gradle task that precedes the Ant target"
}

直接執行gradle,預設執行defaultTasks列表中的task,結果輸出:

:antStandAloneHello
[ant:echo] A standalone hello from an Ant target

:beforeTheAntTask
A Gradle task that precedes the Ant target

:antHello
[ant:echo] A dependent hello from the Ant target

:afterTheAntTask
A Gradle task that precedes the Ant target

使用AntBuilder

掃描目錄檔案

task echoDirListViaAntBuilder() {
    description = 'Uses the built-in AntBuilder instance to echo and list files'

    //Docs: http://ant.apache.org/manual/Types/fileset.html
    //Echo the Gradle project name via the ant echo plugin
    ant.echo(message: project.name)
    ant.echo(path)
    ant.echo("${projectDir}/samples")

    //Gather list of files in a subdirectory
    ant.fileScanner{
        fileset(dir:"samples")
    }.each{
        //Print each file to screen with the CWD (projectDir) path removed.
        println it.toString() - "${projectDir}"
    }
}

注意,Groovy中的字串可以相減。

使用正則表示式

task echoSystemPropertiesWithRegEx() {
    description = "Uses Groovy's regex matching to find a match in System properties"

    def charsToFind = 'sun'
    println "SYSTEM PROPERTIES"
    System.properties.each{
        ant.echo("Does '${it}' contain '${charsToFind}': " + (it ==~ ".*${charsToFind}.*"))
    }
}