First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-221  评论-1047  文章-0  trackbacks-0
Ant的威力在Java界无人不知,无人不晓。可惜想在Ant的build.xml中处理逻辑很不方便,幸好在Groovy界出现了Gant(Groovy + Ant),使我们能够像写普通程序那样编写脚本。本文讲解了如何将您所拥有的Ant知识应用到Gant中,并利用Gant大大提高开发效率。

0,安装Groovy( Groovy轻松入门——搭建Groovy开发环境 )
1,
下载Gant,访问http://gant.codehaus.org (目前最新版的下载地址:http://dist.codehaus.org/gant/distributions/gant-1.1.0_groovy-1.5.2.zip,该版本依赖Groovy1.5.2+)
2,安装Gant,将zip文件中的bin目录和lib目录中的文件分别解压到%GROOVY_HOME%\bin和
%GROOVY_HOME%\lib下
3,验证是否安装成功,打开命令行,运行‘gant’(命令本身不带‘’),如果您看到“Cannot open file build.gant”那就说明您安装成功了
4,小试牛刀,新建GantTest目录,在新建的GantTest目录下再新建build.gant和build.properties,并将下面的build.gant和build.properties内容分别复制到您刚刚新建的文件中,保存。在GantTest目录下运行‘gant’命令,运行结果如下所示:
D:\_DEV\groovy_apps\GantTest>gant
     [echo] running build.gant
     [echo] Executing init target
     [echo] hello, Daniel

D:\_DEV\groovy_apps\GantTest>

build.gant
Ant.echo(message : 'running build.gant')

Ant.property(file : 
'build.properties')
def antProperty 
= Ant.project.properties

target(init : 
'init target') {
    echo(message : 
'Executing init target')
}

target(hello : 
'say hello target') {
    depends(init)

    echo(message : antProperty.
'echo.msg')
}

setDefaultTarget(hello)

build.properties

echo.msg=hello, Daniel

与build.gant等同的build.xml如下所示
<?xml version="1.0" encoding="UTF-8"?>

<project name="test" default="hello">
    
<echo message="running build.xml which is equivalent to build.gant"/>

    
<property file="build.properties"/>
    
    
<target name="init"  description="init target" > 
        
<echo message="Executing init target"/>
    
</target>
    
    
<target name="hello" depends="init" description="say hello target"> 
        
<echo message="${echo.msg}"/>
    
</target>
</project>
顺便提一下,我将build.gant,build.properties,build.xml三个文件放于同一目录下

在Gant中调用Ant中的task是很简单的,只要将元素名改为方法名,将属性名和属性值改写为方法的参数名和参数方法,子元素改写为子闭包(改写子元素稍后进行讲解)即可。以上述例子为例,<echo message="Executing init target..."/>改写为echo(message: 'Executing init target...')。

下面一个例子展现了如何在Gant的脚本中表达逻辑,如你所看到那样,与平常所写代码并无两样:
Ant.echo(message : 'running build.gant')

Ant.property(file : 
'build.properties')
def antProperty 
= Ant.project.properties

target(init : 
'init target') {
    echo(message : 
'Executing init target')
}

target(hello : 
'say hello target') {
    depends(init)

    
//echo(message : antProperty.'echo.msg')
    int alt = new Random().nextInt(3)
    
if (0 == alt) {
        echo(message : 
'hello world')
    } 
else if (1 == alt) {
        echo(message : 
'hello gant')
    } 
else {
        echo(message : 
'hello Daniel')
    }
}

setDefaultTarget(hello)


我们也可以将一些常用的target放在一些文件中,需要时将它们引入:
比如我将常用的target放在了build.ext.gant中
target(ext : 'ext target') {
    echo(message : 
"I'm an ext target")
}
在需要的时候,我们通过includeTargets << new File('build.ext.gant')语句将其引入:
includeTargets << new File('build.ext.gant')

Ant.echo(message : 
'running build.gant')

Ant.property(file : 
'build.properties')
def antProperty 
= Ant.project.properties

def binDir 
= 'bin'
def srcDir 
= 'src'

target(init : 
'init target') {
    echo(message : 
'Executing init target')
    
    delete(dir : 
"${binDir}")
    mkdir(dir : 
"${binDir}")

    copy (todir : 
"${binDir}") {
        fileset(dir : 
"${srcDir}") {
            include(name : 
"**/*.xml")
        }
    }

}

target(hello : 
'say hello target') {
    depends(init, ext)

    
//echo(message : antProperty.'echo.msg')
    int alt = new Random().nextInt(3)
    
if (0 == alt) {
        echo(message : 
'hello world')
    } 
else if (1 == alt) {
        echo(message : 
'hello gant')
    } 
else {
        echo(message : 
'hello Daniel')
    }
}

setDefaultTarget(hello)



最后再看一下Gant调用Ant中包含子元素的task:
新建src和bin目录,在src目录下新建几个xml文件以作测试之用
Ant.echo(message : 'running build.gant')

Ant.property(file : 
'build.properties')
def antProperty 
= Ant.project.properties

def binDir 
= 'bin'
def srcDir 
= 'src'

target(init : 
'init target') {
    echo(message : 
'Executing init target')
    
    delete(dir : 
"${binDir}")
    mkdir(dir : 
"${binDir}")

    copy (todir : 
"${binDir}") {
        fileset(dir : 
"${srcDir}") {
            include(name : 
"**/*.xml")
        }
    }

}

target(hello : 
'say hello target') {
    depends(init)

    
//echo(message : antProperty.'echo.msg')
    int alt = new Random().nextInt(3)
    
if (0 == alt) {
        echo(message : 
'hello world')
    } 
else if (1 == alt) {
        echo(message : 
'hello gant')
    } 
else {
        echo(message : 
'hello Daniel')
    }
}

setDefaultTarget(hello)

如你所看到的,上面例子中的
delete(dir : "${binDir}")
mkdir(dir : 
"${binDir}")
copy (todir : 
"${binDir}") {
    fileset(dir : 
"${srcDir}") {
        include(name : 
"**/*.xml")
    }
}
改写自
<delete dir="${binDir}"/>
<mkdir dir="${binDir}"/>
<copy todir="${binDir}">
    
<fileset dir="${srcDir}">
         
<include name="**/*.xml" />
    
</fileset>
</copy>

改写过程很简单,仅仅是将子元素改写为子闭包就可以了。

请注意,build.gant本质上就是一个groovy程序,仅仅是文件后缀改为gant罢了,所以您可以将自己所有的Groovy知识应用到build.gant的编写中。


如果您想进一步学习研究Gant,请访问官方网站:http://gant.codehaus.org/


参考文献:
Groovy-power automated builds with Gant - Enhance your build process with Groovy plus Ant By Klaus P. Berg

附:朝花夕拾——Groovy & Grails

posted on 2008-02-16 17:58 山风小子 阅读(4238) 评论(5)  编辑  收藏 所属分类: Groovy & Grails