Ant學習

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 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

2、初步總結

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就能夠

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>   
  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>
相關文章
相關標籤/搜索