Ant学习

一、简单介绍
1. 基本概念

Ant又叫Apache Ant, 是一款“构建”工具,即将软件编译,测试,部署等步骤联系起来并加以优化的一款工具。 形象的说,构建就是将代码从某处拿来,编译,再拷贝到另一处去的操作。
Ant可以从Apache官网直接下载得到,解压即可使用,体积小,简单方便。
之所以用ant,是因为他相比其他的组织构建工具,如Eclipse,更小且垮平台,这样更加灵活,在开展自动化测试的时候,这种灵活的方式更能发挥优势。

2. ant脚本

脚本是由一个xml文件构成的,其中核心元素如下:

project: 每个构建文件包含一个工程
depends: 每个工程包含若干个目标(target),且目标可以【依赖】其他目标
task: 目标包含一个或多个任务(task)

我们可以从后面的例子里来分析这些元素的意义和用法

24161805_qWaN.jpg
3. ant项目目录结构

ant的目录结构可以很简单,如下:

工程主目录:C:\course\ant\demo
源代码目录:C:\course\ant\demo\src
编译后的class文件目录:C:\course\ant\demo\classes
打包好的jar文件目录:C:\course\ant\demo
工程配置文件目录:C:\course\ant\demo

先分析一下build.xml
24161805_185Q.jpg
一段一段的分析:
<project name="HelloWorld" default="run" basedir=".">
Ant的全部内容都要包含在<project></project>里
name: 项目名称
default:代表默认要做的事情,即如果你输入的ant命令行里没有指定操作,则他会默认执行run
basedir:工作的根目录,这里的“.”其实是xml的一个表示xpath,代表当前目录
  <property name="src" value="src" />
  <property name="dest" value="classes" />
  <property name="hello_jar" value="hello.jar" />
property类似于程序中的变量
src:源代码的文件夹名称
dest:编译后的目标文件夹名称,用来放compile之后的class文件
hello_jar:打包后的jar文件名称

<target name="init">
  <mkdir dir="${dest}" />
  </target>
每一个target等于是我们想做的每一件事,比如这个target的名称是init,想做的事情是
mkdir dir="${dest}" 即在根目录下创建一个文件夹,根据前面定义的property,我们知道这个文件夹叫做classes
<target name="compile" depends="init">
  <javac srcdir="${src}" destdir="${dest}" />
  </target>

这个target叫做compile,就是编译,他比上面一个target还多了一个属性,即depends。 depends属性是一个依赖选项,当target存在depends属性时,在执行这个target时,会优先检查他依赖的target有没有执行,如果没有,会先执行依赖的target,然后再执行这个target。
这里,依赖的target就是init。
<javac>是默认调用Ant本身的JVM编译器,里面指定了需要编译的源代码的路径(src)以及编译好后的类存放的路径(dest),而这些路径在前面已经被定义好了
<target name="jar" depends="compile">
  <jar jarfile="${hello_jar}" basedir="${dest}" />
  </target>
如果我想指定jar包保存的路径,则可以加上destfile属性:
<target name="jar" depends="compile">
<jar jarfile="${hello_jar}" basedir="${dest}" destfile="${lib}/{hello_jar}" />
</target>

这里是说,我定义了一个lib文件夹,把jar文件放到lib里。 这个target叫做jar,依赖compile,也就是说,需要编译后才行执行,作用是打jar包。 也是指定了jar包的名字,jar包所需类的路径dest
<target name="run" depends="jar">
  <java classname="test.ant.HelloWorld" classpath="${hello_jar}" />
  </target>

这个target叫做run,就是运行,依赖jar,即要打好包才能运行。 指定了运行的类名和jar包的路径
<target name="clean">
  <delete dir="${dest}" />
  <delete file="${hello_jar}" />
  </target>
这个target叫做clean,即删除生成的文件
<target name="rerun" depends="clean, run">
  <ant target="clean" />
  <ant target="run" />
  </target>

这个target叫做rerun,依赖项是clean和run,即run过并清除过后再run一次,里面嵌套调用了2个target

二、初步总结

1. Ant很小巧,无需安装
2. Ant可以做很多事情,将源程序编译,打包,运行,还可以管理项目文件夹(新建删除)
3. Ant是依靠一个xml文件来做这些事情的,默认叫做build.xml,你也可以在命令行里输入参数来指定ant编译器运行某一个xml文件
4. xml文件中是由几大块组成的,project等于是一个主函数,然后property是函数定义的变量,target就是函数执行的一件件task,这些task有的是用来编译源程序的(compile),有的是用来打包的(jar),有的是用来运行jar包的(run),还有的是用来删除文件/文件夹的(clean)
5. Ant的运行也很简单,在cmd里输入指定的command就行,如下:
  • 如果不指定路径和操作,直接输入ant,则Ant会在当前文件夹下寻找build.xml并执行
  • 如果你想运行指定路径下的指定脚本,就需要使用-buildfile,如 ant -buildfile D:\test\OK.xml
  • 如果你想运行指定脚本下的指定某个/某几个target,就需要在命令后面加上target的名称,如你只想运行build.xml中的compile,那么可以这样:ant -buildfile D:\test\build.xml compile
  • 如果你没有在命令行后加上你想运行的操作,那么ant将查看build.xml中project的default属性,看看default是值是哪个target,就会执行这个操作,如果没有default属性,那么就不会执行任何操作。
  • target的名字是自定义的,关键还是看task是什么,比如你可以把compile写成cop,只要里面是<javac>的task就可以

三、属性列表
1. <project>



24161805_2sAd.jpg

2. <property>


前面我们说property就和变量一样,属性就是变量名和给变量赋的值。 一个project可以有很多变量,这些变量可以在buildfile中用property task来设定,也可以在ant外面设定。这就方便我们以后做参数化和数据分离。

Attribute
Description
Required
name
变量名称,可以自由定义
value
变量赋值

ant引用变量时的方式是这样的:${变量名称}
比如我们定义了一个property叫src,值为./src
build=“${src}/build ” 就是将./src/build这个路径值赋给build

除了我们自定义的属性之外,还有一些是内置属性,这里面包括JAVA本身的内置属性,和ANT自身的内置属性如下:

24161805_ryAz.jpg

3. <target>


24161805_6ebQ.jpg

在例子里我们学过了name和depends,其余的几个我们在下面举实例来学习
这里还要提到的是depends,比如有这样一个依赖关系:
target A,B,C,D。project默认target是D,D依赖C,C依赖B,B依赖A,则执行顺序为A,B,C,D,且B,C,D这3个target后的depends都要定义相对于的依赖target。
也可以写成另一种形式:<target name="D" depends="C,B,A" >
最后,每一个target只能执行一次,即使是多个target依赖他,也只能执行一次。

if、unless的用法
如果你执行某个target,是由某些属性是否被设定来决定的,比如我们在windows和unix 2种系统上执行脚本,要区别不同的target,就可以像下面这样:

24161805_9Kx6.jpg
当命令行设定了osfamily-windows属性时,才执行这个target,而当命令行设定了osfamily-unix时,执行另一个target。

4. task


task并不是一个<task>,而是target的真正内容,即一段可执行的代码:

比如- <target name="compile" depends="init">
  <javac srcdir="${src}" destdir="${dest}" />
  </target>

这里面<javac srcdir="${src}" destdir="${dest}" />就是一个task,他里面也可以包含很多属性。

task一般的构造形式是:
<name attribute1=”value1” attribute2=”value2” … />

task可以自己编写task,也可以使用内置的task.

四、task
1.    设置classpath

classpath是用来指定类路径的。下面的例子用了4种方式来设置classpath

<path id="project.classpath"> 
    <pathelement data-path="${basedir}/lib/aa.jar"/> <!--
1-->
    <pathelement location="aa.jar"/>  
<!--2与1的区别在于location可以去当前路径,当然也可以使用绝对路径 -->
    <filelist id="file" dir="${basedir}/lib">
<!--3-->
          <file name="a.jar"/> 
          <file name="d:/lib/b.jar"/> 
    </filelist> 
    <fileset dir="d:/lib">
<!--4-->
           <include name="**/*.jar"/> 
     </fileset> 
     <!-- 手册上说了dirset也好用,但是我测试了还是不要用的-->
</path>   
  1. 使用path属性设置
  2. 使用location属性设置
  3. 使用filelist设置
  4. 使用fileset设置
第1种,调用的需要设置绝对路径适合第三方jar包 
第2种,则适合jar包和build.xml文件在同一目录下的情况,但是我觉得两个文件放在一起本身就不合理,估计是用的情况不多。这两种都是设置单个jar包 
第3种,是一个文件集合适合引入不同路径的jar包,但是需要输入每个jar包的名字,比较繁琐,适合于jar包属于不同位置,比较分散但是不多的情况 
第4种,是一个文件夹,可以采用匹配模式来引入,这个适合在同一个文件夹下,文件名字比较多的情况下

其实classpath就是指定当运行这个java程序的时候,那些个class的路径

2. 输出信息

输出信息使用的是echo,方法如下:
1.     输入一段话
<echo>Compile has been completed!!!</echo>
<echo message="Init has been completed!!!" />

2.    输出一段XML


...
<target name="run" depends="jar">
<java classname="test.ant.HelloWorld" classpath="${hello_jar}" />
<echoxml file="subbuild.xml">
<project default="foo">
<target name="foo">
<echo>foo</echo>
</target>
</project>
</echoxml>
</target>
...

3.    设置property

我们实际上在前面已经说到了,property即可以在xml里定义,也可以引用外部的文件。这里就做一个简单的介绍:

1. 在xml内定义
<property name="src" value="src" />

2. 读取属性文件中的属性配置
<property file="foo.properties"/>

3. 读取网络中的属性文件配置
<property url="http://www.mysite.com/bla/props/foo.properties"/>

4. 读取文件中的属性配置
<property resource="foo.properties"/>

5. 读取环境变量
<property environment="env"/>

6. 读取属性文件中的属性,并作为全局引用
<property file="/Users/antoine/.ant-global.properties"/>

4.    引入property

以属性文件为例,先建立一个属性文件,如build.properties

之前的例子里,我们的属性是这样设置的:

  <property name="src" value="src" />
  <property name="dest" value="classes" />
  <property name="hello_jar" value="hello.jar" />

现在,我们在属性文件里对这些属性进行赋值:

src_path=src
dest_path=classes
jar_filename=helloMETOTO.jar

然后,在build.xml里就引入这个属性文件


  <property file="./Config/build.properties" />
  <property name="src" value="${src_path}" />
  <property name="dest" value="${dest_path}" />
  <property name="hello_jar" value="${jar_filename}" />

这里的./Config/build.properties" 是用xpath表示的build.properties的文件路径
下面的3个property的value都不是直接赋值,而是先赋的属性文件中的变量名的引用:${srcpath}

5.  引入XML文件(TBD)
比如说要读取XML中的属性配置

6.    复制文件与目录
file表示要复制的文件
tofile表示要复制到当前目录并重命名
todir表示复制到指定目录
dir表示当前文件夹的目录

1. 复制文件到当前文件夹,并重命名
<copy file="myfile.txt" tofile="mycopy.txt"/>

2. 复制指定路径下的文件到指定文件夹,并重命名
<copy file="./Config/build.properties" tofile="./src/build_cp1.properties" />

3. 复制指定路径下的文件到指定文件夹
<copy file="./Config/build_include.xml" todir="./src" />

4. 复制指定文件夹下的所有文件到指定目录(复制src下的所有文件去Config文件夹)
<copy todir="./Config">
<fileset dir="./src"/>
</copy>

5. 复制文件到指定文件夹(使用copyfile)
<copyfile src="test.java" dest="subdir/test.java"/>
现在copyfile已经成为废弃的task了,所以这里只做介绍,不要使用

6. 复制指定文件夹下的部分文件到指定目录
其实就是在4的基础上,加一个约束exclude
<copy todir="./src">
<fileset dir="./Config"/>
                <exclude name="test.txtl"/>
                <include  name ="*.txt" />
</copy>

或者直接写成:

<copy todir="./src">
<fileset dir="./Config" excludes="test.txt" includes="*.txt" />
</copy>

7. 删除文件和目录
file表示要删除的文件。
dir表示要删除的目录。
includeEmptyDirs 表示指定是否要删除空目录,默认值是删除。
failonerror 表示指定当碰到错误是否停止,默认值是自动停止。

1. 删除文件
<delete file="./src/build_cp1.properties" />

2. 删除目录,包括其下的所有文件
<delete dir="${dest}" />或者  <delete dir="./classes" />

3. 删除目录下的部分文件
<delelte>
    <fileset dir="./Config" excludes="test.txt" includes="*.txt" />
</delete>

8. 剪切文件,文件集合和目录
<move todir="./src">
    <fileset dir="./Config" excludes="test.txt" includes="*.txt" />
</move>
<>
9. 在Target中调用其他Target

有几种方式来调用
1)使用<ant target=”***”>调用另外一个target
<target name="rerun">
    <<ant target="clean" />
  <ant target="run" />
</target>

2) 使用antcall调用另外一个target

<target name="default">
    <antcall target="isInvoked" >
    <param name="param1" value ="value" />
  </antcall>
</target>

<target name="isInvoked">
    <echo message="param1=${param1}" />
</target>

转载于:https://my.oschina.net/u/242764/blog/470293

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值