<groovy>

Description

Executes a series of Groovy statements. Statements can either be read in from a text file using the src attribute or from between the enclosing Groovy tags.

Required taskdef

Assuming groovy-all-VERSION.jar is in my.classpath you will need to declare this task at some point in the build.xml prior to using this task.

<taskdef name="groovy"
         classname="org.codehaus.groovy.ant.Groovy"
         classpathref="my.classpath"/>

<groovy> attributes

Attribute

Description

Required

src

File containing Groovy statements.
The directory containing the file is added to the classpath

Yes, unless statements enclosed within tags

classpath

the classpath to use

No

classpathref

the classpath to use, given as reference to a PATH defined elsewhere

No

Parameters specified as nested elements

<classpath>

Groovy's classpath attribute is a PATH like structure and can also be set via a nested classpath element.

<arg> (since 1.1)

Arguments can be set via one or more nested <arg> elements using the standard Ant command line conventions.

Available bindings

A number of bindings are in scope for use within your Groovy statements.

Name

Description

ant

an instance of AntBuilder that knows about the current ant project

project

the current ant project

properties

a Map of ant properties

target

the owning target that invoked this groovy script

task

the wrapping task, can access anything needed in org.apache.tools.ant.Task

args

command line arguments, if any

Examples

Hello world, version 1:

<groovy>
println "Hello World"
</groovy>

Hello world, version 2:

<groovy>
ant.echo "Hello World"
</groovy>

List all xml files in the current directory:

<groovy>
xmlfiles = new File(".").listFiles().findAll{ it =~ "\.xml$" }
xmlfiles.sort().each { println it.toString() }
</groovy>

List all xml files within a jar:

<zipfileset id="found" src="foobar.jar"
            includes="**/*.xml"/>
<groovy>
    project.references.found.each {
        println it.name
    }
</groovy>

To run a script:

<groovy src="/some/directory/some/file.groovy">
  <classpath>
    <pathelement location="/my/groovy/classes/directory"/>
  </classpath>
</groovy>

To find all the 'Builder' classes having an 'org.*' package within a directory of jars:

<property name="local.target" value="C:/Projects/GroovyExamples"/>
<groovy>
import java.util.jar.JarFile
def classes = []
def resourceNamePattern = /org\/.*\/.*Builder.class/
def jarNamePattern = /.*(beta|commons).*jar$/

def libdir = new File("${properties['local.target']}/lib")
libdir.listFiles().grep(~jarNamePattern).each { candidate ->
    new JarFile(candidate).entries().each { entry ->
        if (entry.name ==~ resourceNamePattern) classes += entry.name
    }
}
properties["builder-classes"] = classes.join(' ')
</groovy>
<echo message='${builder-classes}'/>

Which might result in something like:

org/apache/commons/cli/PatternOptionBuilder.class org/apache/commons/cli/OptionBuilder.class org/codehaus/groovy/tools/groovydoc/GroovyRootDocBuilder.class org/custommonkey/xmlunit/HTMLDocumentBuilder.class org/custommonkey/xmlunit/TolerantSaxDocumentBuilder.class

FileScanner version of above (with a slight variation on collecting the names):

<groovy>
import java.util.jar.JarFile
def resourceNamePattern = /org\/.*\/.*Builder.class/
def candidates = ant.fileScanner {
    fileset(dir: '${local.target}/lib') {
        include(name: '*beta*.jar')
        include(name: '*commons*.jar')
    }
}
def classes = candidates.collect {
    new JarFile(it).entries().collect { it.name }.findAll {
        it ==~ resourceNamePattern
    }
}.flatten()
properties["builder-classes"] = classes.join(' ')
</groovy>

Here is an example of calling out to a web service from your Ant script:

<?xml version="1.0" encoding="UTF-8"?>
<project name="SOAP example" default="main" basedir=".">
    <property environment="env"/>
    <property name="celsius" value="0"/>
    <target name="main">
        <taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
            <classpath>
                <fileset dir="${env.GROOVY_HOME}" includes="embeddable/groovy-all-*.jar,lib/ivy*.jar"/>
            </classpath>
        </taskdef>
        <groovy>
            @Grab('org.codehaus.groovy.modules:groovyws:0.5.1')
            import groovyx.net.ws.WSClient
            def url = 'http://www.w3schools.com/webservices/tempconvert.asmx?WSDL'
            def proxy = new WSClient(url, this.class.classLoader)
            proxy.initialize()
            ant.echo "I'm freezing at ${properties.celsius} degrees Celsius"
            properties.result = proxy.CelsiusToFahrenheit(properties.celsius)
        </groovy>
        <antcall target="results"/>
    </target>
    <target name="results">
        <echo message="I'm freezing at ${result} degrees Fahrenheit"/>
    </target>
</project>

which will output the following (along with some informational messages):

main:
     ...
     [echo] I'm freezing at 0 degrees Celsius
results:
     [echo] I'm freezing at 32 degrees Fahrenheit

BUILD SUCCESSFUL

Setting arguments

    <target name="run">
        <groovy>
            <arg line="1 2 3"/>
            <arg value="4 5"/>
            println args.size()
            println args[2]
            args.each{ ant.echo(message:it) }
        </groovy>
    </target>
Buildfile: GROOVY-2087.xml

run:
   [groovy] 4
   [groovy] 3
     [echo] 1
     [echo] 2
     [echo] 3
     [echo] 4 5

BUILD SUCCESSFUL

Forking Groovy

Since 1.5.7 and 1.6-beta-2, <groovy> also supports a fork="true" attribute. In fact, many of the attributes from the <java> Ant task are supported. More details to come ...

More examples