1、簡單介紹
1. 基本概念
Ant又叫Apache Ant, 是一款「構建」工具,即將軟件編譯,測試,部署等步驟聯繫起來並加以優化的一款工具。
形象的說,構建就是將代碼從某處拿來,編譯,再拷貝到另外一處去的操做。
Ant能夠從Apache官網直接下載獲得,解壓便可使用,體積小,簡單方便。
之因此用ant,是由於他相比其餘的組織構建工具,如Eclipse,更小且垮平臺,這樣更加靈活,在開展自動化測試的時候,這種靈活的方式更能發揮優點。
2. ant腳本
腳本是由一個xml文件構成的,其中核心元素以下:
project: 每一個構建文件包含一個工程
depends: 每一個工程包含若干個目標(target),且目標能夠【依賴】其餘目標
task: 目標包含一個或多個任務(task)
咱們能夠從後面的例子裏來分析這些元素的意義和用法
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
一段一段的分析:
<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等因而咱們想作的每一件事,好比這個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 file="${hello_jar}" />
</target>
這個target叫作clean,即刪除生成的文件
- <target name="rerun" depends="clean, run">
這個target叫作rerun,依賴項是clean和run,即run過並清除事後再run一次,裏面嵌套調用了2個target
3、屬性列表
1. <project>
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自身的內置屬性以下:
3. <target>
在例子裏咱們學過了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,就能夠像下面這樣:
當命令行設定了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.
4、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>
- 使用path屬性設置
- 使用location屬性設置
- 使用filelist設置
- 使用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>
<move todir="./src">
<fileset dir="./Config" excludes="test.txt" includes="*.txt" />
</move>
<>
有幾種方式來調用
1)使用<ant target=」***」>調用另一個target
<target name="rerun">
<<ant target="clean" />
</target>
2) 使用antcall調用另一個target
<target name="default">
<antcall target="isInvoked" >
<param name="param1" value ="value" />
</target>
<target name="isInvoked">
<echo message="param1=${param1}" />
</target>