如果你曾经使用过build.xml文件或者一些Jelly脚本,并且发现自己被那些尖括号所限制,或者发现使用XML作为一种脚本语言会有点怪异,并且想使用更清晰和更直接的方式,那么使用Groovy来编写Ant脚本可能就是你一直在寻找的。
Groovy有一个叫做AntBuilder的助手类,它使编写Ant任务脚本变得非常容易;它允许使用真正的脚本语言来对构件(变量、方法、循环、逻辑分支、类等)进行编程。这看起来还是像Ant的XML的一个简洁明了的版本,而没有那些尖括号;然而你可以把这些标记混合在你的脚本中。Ant本身是一些jar文件的集合。把它们加到你的classpath中之后,你可以容易的在Groovy中使用它们。我们相信使用AntBuilder可以带来更简明和容易理解的语法。
下面是一些例子(大多数来自于Groovy本身的AntBuilder的测试),它们演示了:
def ant = new AntBuilder() // 就让我们称之为一个任务 ant.echo("hello") // 这里是在GroovyMarkup中的一个Ant代码块的一个例子 ant.sequential { echo("inside sequential") myDir = "target/AntTest/" mkdir(dir:myDir) copy(todir:myDir) { fileset(dir:"src/test") { include(name:"**/*.groovy") } } echo("done") } // 现在让我们再写一些一般的Groovy代码 file = new File("target/AntTest/groovy/util/AntTest.groovy") assert file.exists()
def ant = new AntBuilder() // 创建一个fileset的扫描器(scanner) scanner = ant.fileScanner { fileset(dir:"src/test") { include(name:"**/Ant*.groovy") } } // 现在让我们对它进行迭代 def found = false for (f in scanner) { println("Found file $f") found = true assert f instanceof File assert f.name.endsWith(".groovy") } assert found
def ant = new AntBuilder() ant.junit { test(name:'groovy.util.SomethingThatDoesNotExist') }
def ant = new AntBuilder() value = ant.path { fileset(dir:"xdocs") { include(name:"*.wiki") } } assert value != null println "Found path of type ${value.class.name}" println value
def ant = new AntBuilder() def taskContainer = ant.parallel(){ // "Parallel"充当一个TaskContainer的例子 ant.echo() // "Echo"没有带消息,从而使测试不会被消息干扰 } // 不是很优雅,但是是获取ant内部的最简单的方式... assert taskContainer.dump() =~ /nestedTasks=\[org.apache.tools.ant.taskdefs.Echo@\w+\]/
编译和运行一个Java文件:
def ant = new AntBuilder() ant.echo(file:'Temp.java', ''' class Temp { public static void main(String[] args) { System.out.println("Hello"); }} ''') ant.javac(srcdir:'.', includes:'Temp.java', fork:'true') ant.java(classpath:'.', classname:'Temp', fork:'true') ant.echo('Done') // => // [javac] Compiling 1 source file // [java] Hello // [echo] Done
嗅探…
def ant = new AntBuilder() SpoofTaskContainer.spoof.length = 0 def PATH = 'task.path' ant.path(id:PATH){ant.pathelement(location:'classes')} ['spoofcontainer':'SpoofTaskContainer', 'spoof':'SpoofTask'].each{ pair -> ant.taskdef(name:pair.key, classname:'groovy.util.'+pair.value, classpathref:PATH) } ant.spoofcontainer(){ ant.spoof() } expectedSpoof = "SpoofTaskContainer ctor\n"+ "SpoofTask ctor\n"+ "in addTask\n"+ "begin SpoofTaskContainer execute\n"+ "begin SpoofTask execute\n"+ "end SpoofTask execute\n"+ "end SpoofTaskContainer execute\n" assertEquals expectedSpoof, SpoofTaskContainer.spoof.toString()