ANT脚本快速入门

写在前面

最近因为项目原因,笔者现学现用了一波ANT脚本。在这个过程中,愈加觉得它是一个很犀利的脚本工具,上手难度低,实现简单粗暴,功能也很强大,于是写了这样一篇文章,将其推荐给大家,希望能对大家有所帮助。

ANT安装

  1. 下载ANT包

    1
     http://www-us.apache.org/dist//ant/binaries/apache-ant-1.9.7-bin.zip
    
  2. 解压压缩包到任意目录
  3. 配置环境变量

    例:

    1
     D:\Software\apache-ant-1.9.7
    
  4. 测试ANT可用性

    打开cmd,输入:

    1
     ant -verrsion
    

    如果ANT功能正常,可以得到如下输出:

    1
     Apache Ant(TM) version 1.9.7 compiled on April 9 2016
    

Hello World

ANT主要由一系列XML文件组成,每一个都是他的执行脚本,其每一个执行单元为一个task标签,与HTML十分类似。话不多说,上示例:

HelloWorld.xml:

1
2
3
4
5
6
7
8
    <?xml version="1.0" ?>
    <project name="HelloWorld" default="main" basedir=".">
        <target name="main">
            <echo>
                Hello World
            </echo>
        </target>
    </project>

执行上诉脚本便可以得到编程入门惯例输出:

1
2
3
4
5
6
7
8
9
ant -buildfile HelloWorld.xml

main:
     [echo]
     [echo]             Hello World
     [echo]

BUILD SUCCESSFUL
Total time: 0 seconds

ANT标签

从上面的示例中大家可以发现,一个ANT脚本就是由一系列标签所组成。使用者大可不必去关心这些标签背后的实现,只需在需要的时候调取对应功能的标签即可,笔者认为这也是ANT简单粗暴的源头。

<project>标签

每一个ANT脚本对应了一个Project,<project>标签为ANT脚本的根标签,它可以有多个内在属性:

  • name: 该Project的名字
  • default: 表示Project默认运行的Target,即入口Target
  • basedir: 表示Project的基准目录,通常使用”.”,即当前目录

<property>标签

一个<project>标签可以定义多个<property>标签,有点类似Maven的用法。该标签的作用是定义Project的一些属性,达到属性复用的效果。<property>标签中定义的属性可以用在其它任何标签中。

HelloWorldWithProperties.xml:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" ?>
<project name="HelloWorldWithProperties" default="main" basedir=".">
    <property name="helloworld" value="Hello World" />
    <property name="helloworld2" value="${helloworld}" />
    <property name="helloworld3" value="${helloworld}${helloworld}" />
    <target name="main">
        <echo>
            ${helloworld3}
        </echo>
    </target>
</project>

执行该脚本后可以得到如下结果:

1
2
3
4
5
6
7
main:
     [echo]
     [echo]             Hello WorldHello World
     [echo]

BUILD SUCCESSFUL
Total time: 0 seconds

<target>标签

一个<project>标签可以有一个或多个<target>标签。<target>标签可以理解为一个工作目标,一个工作目标可以由一个或者多个任务来完成,即一个<target>标签为一系列task标签组成,上文中的<echo>即为一个task标签,代表了一个输出字符串到Console的任务。

一个<target>标签可以依赖于另一个<target>标签,如此,系统就会先执行被依赖的target,ANT脚本正是简单的通过这样一环扣一环的类似多诺米骨牌的<target>标签运作起来的。

HelloWorldWithTargetDepends.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" ?>
<project name="HelloWorldWithTargetDepends" default="main" basedir=".">
    <property name="helloworld" value="Hello World" />
    <property name="helloworld2" value="${helloworld}" />
    <property name="helloworld3" value="${helloworld}${helloworld}" />
    <target name="main" depends="target1">
        <echo>
            ${helloworld3}
        </echo>
    </target>
    <target name="target1">
        <echo>
            ${helloworld2}
        </echo>
    </target>
</project>

执行该脚本后可以得到如下结果:

1
2
3
4
5
6
7
8
9
10
11
12
target1:
     [echo]
     [echo]                     Hello World
     [echo]

main:
     [echo]
     [echo]             Hello WorldHello World
     [echo]

BUILD SUCCESSFUL
Total time: 0 seconds

Task标签

从上文中大家可以发现,真正去执行动作的将永远只是task标签,而别的标签都只是对行为的修饰和封装。ANT脚本为我们预置了大量常用的task标签,对于大多数情况而言,这些标签已经足够完成自动化脚本的使命了。接笔者下来为大家简单介绍几个常用的标签,如果需要了解更多,可以查阅ANT官网。

<mkdir>标签

<mkdir>标签用于创建一个目录。

示例:

1
2
3
4
5
...
<target name="myMkdir">
    <mkdir dir="${basedir}/test" />
</target>
...

许多task标签都利用属性作为其具体的参数,当然也有一些比较复杂的标签利用了一些子标签作为参数,不过总的来说标签的使用手段都是非常简单粗暴的,直接用就行了。

<ant>标签

<ant>标签用于执行一个ANT脚本,该标签简单的实现了ANT脚本级别的级联。将一个ANT脚本根据功能拆分成多个ANT脚本,大大降低了脚本的维护难度,有点类似Shell。与Shell不同的是,<ant>标签可以通过属性控制NT脚本其属性(即<property>标签)的继承性,减少了一些重复的代码。

示例:

1
<ant antfile="antTest.xml" dir="${basedir}/HelloWorld.xml" inheritall="true" inheritrefs="false" />

其中inheritall属性为true即表示将属性覆盖到被调用的ANT脚本,关于inheritrefs属性就不在这里进行发散了,毕竟时间有限,感兴趣的朋友可以在ANT官网上进行查阅。

<macrodef>标签

相对于上文,<macrodef>标签已经算是ANT工程的进阶应用了,不过因为其使用频繁,且能大幅降低代码冗余,笔者就将其纳入介绍了。

macrodef,即ANT世界的宏,我们可以使用它简单的封装task标签,形成一个自己的标签(与更高阶应用中自己开发标签有所不同),以实现ANT脚本代码的复用。

HelloWorldWithMacrodef.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" ?>
<project name="PAAS" default="main" basedir=".">
    <macrodef name="myEcho">
        <attribute name="echoString" default="Hello World" />
        <sequential>
            <echo>
                @{echoString}
            </echo>
        </sequential>
    </macrodef>

    <target name="main">
        <myEcho />
        <myEcho echoString="Hello World Again" />
    </target>
</project>

执行该脚本后可以得到如下结果:

1
2
3
4
5
6
7
8
9
10
main:
     [echo]
     [echo]                             Hello World
     [echo]
     [echo]
     [echo]                             Hello World Again
     [echo]

BUILD SUCCESSFUL
Total time: 0 seconds

<macrodef>标签基本原理其实非常简单,<attribute>标签简单的定义了新标签的属性,同时<sequential>标签定义了新标签的动作,即一个task列表,类似一个target,同样的,它也可以使用<property>标签中定义的属性。

写在后面

经过了短暂的学习以及不厌其烦的Hello World,笔者相信大多数读者都已经掌握到了ANT脚本的基本要领,接下来就只是一个task标签的储备量了,笔者认为ANT脚本的魔力就在这里,其语法要素可以说非常的少,除了最外层的几个标签外,其它基本都是一个一个封装好的task标签的堆叠,其学习成本之低,另笔者十分敬仰。反思现在的许多编程语言,其使用及学习过程之晦涩,让人难以接受,对于一门语言来说,尽量减少约定,可以极大地减轻大家的学习负担,为了一些微不足道的事情去使用约定的语言,笔者实在难以觉得它是一门优秀精炼的语言。

废话就扯到这里,希望各位读者们在技术的尖塔上一步一步迈向更高、更强。