2011-02-26 49 views
6

我在一個小組中工作,我們生產許多小應用程序,並使用ANT來構建流程。什麼是一些很好的方式來分發一個通用的ant文件以包含在構建中?

我們希望有一些我們常用的常用指令。目前,我們需要一個映射驅動器到一個共同的位置,並使用

<import file="${env.MAPPED_DRIVE}/common_directive.xml"> 

必須有一個更好的辦法來分配一個共同的Ant文件在很多項目中,包括無需映射驅動器。你有什麼其他的建議?

導入是一個「頂級」指令,這意味着它不會在目標內工作。因此,我不能簡單地創建下載文件的目標,然後導入它。

回答

4

如果您使用ANT 1.8+, you could specify a URL並在網站上承載公共構建片段。

由於螞蟻1.8.0任務也可以從網址或 的classpath資源 進口資源(這是網址, 真的)。如果您需要了解當前構建文件的來源是否 已經 是一個文件或URL你可以諮詢 屬性ant.file.type.projectname (使用相同的例子如上 ant.file.type.builddocs)其中 的值爲「file」或「url」。

+0

非常感謝!我正在尋找錯誤的任務。難怪我找不到它。一些例子的鏈接也會有很大的幫助:如果你有一些好的,你可以隨意使用。 – nrobey 2011-02-26 17:30:56

+4

如果您想要可重複構建,這是一個糟糕的主意。 – 2011-02-27 18:29:09

+0

@Dominic Mitchell - 好點。如果common_directive.xml不是靜態的,最好是更好地管理該依賴關係。 – 2011-02-27 22:13:47

1

Dominic Mitchell是關於URL引用是一個糟糕的主意,如果你想重複的評論建立讓我想...

另一種解決方案來考慮,如果你正在使用SVN版本控制,是創建一個指向common_directive.xmlSVN Externals Definition

然後,只需使用相對路徑爲您的ANT導入文件引用。

有時是構造是開出了 數量不同檢出的 工作副本非常有用。對於 的示例,您可能希望不同的 子目錄來自不同的存儲庫中的 位置或可能來自不同存儲庫 的 。你當然可以通過手動使用svn checkout來創建 這種嵌套的 工作副本結構,您嘗試使用 來實現。但是,如果此佈局對使用您的 存儲庫的所有人都很重要,則每個其他用戶都需要 才能執行您執行的相同結帳操作 。

幸運的是,Subversion提供了 支持外部定義。 An 外部定義是一個 本地目錄到版本 目錄的URL(理想情況下爲 特定版本)的映射。在Subversion中,您使用 屬性svn:externals屬性聲明 組中的外部定義。您可以使用 svn propset或svn propedit創建或修改此屬性(請參閱 部分,名稱爲「Manipulating Properties」)。它可以在任何 版本化的目錄中設置,其值 描述位置應該是 檢出的位置和客戶端目錄 的外部存儲庫 。

svn:externals 屬性的方便之處在於,一旦它被設置在 版本的目錄,大家誰 檢查出與 目錄的工作拷貝,同樣得到 外部定義的好處。換句話說, 一旦一個人做出的努力,以 定義嵌套的工作副本 結構,沒有其他人有 麻煩,Subversion會,檢查 了原先的工作拷貝後, 也自動檢查出 外部工作副本。

+0

我愛你的建議,並有我自己的建議。不幸的是,由於過去svn:外部濫用,這個部門被這種方法「燒燬」,並且對此非常厭惡。不過,我會再試一次,因爲你提出了這個問題。謝謝! – nrobey 2011-03-06 02:03:04

+1

@nrobey - 如果你的團隊關心構建的可重複性和可靠性,看起來好像SVN外部將比使用映射驅動器更好。 externals屬性受版本控制,如果您指向常見構建路徑的SVN位置,則該內容也受版本控制。您可以指向常見構建回購的特定標記。 – 2011-03-06 02:31:39

+1

如果你關心可重複構建,那麼使用svn:external通常是不好的。更經常的是,不是svn:external沒有修訂(AKA unpinned),這意味着你不知道什麼版本被用於任何特定的構建。您可以制定一項政策,要求指定修訂版,但這很難執行,否則難以維護。 – 2011-03-07 06:13:36

2

我已經計算出創建包含在目錄中我們可重複使用的構建腳本一個jar文件的解決方案,比如COM /例子/ ANT/sharedbuild,它可以在1.8螞蟻進口:

<project> 
    <import> 
     <javaresource name="com/example/ant/sharedbuild/java.xml"> 
      <classpath location="../../../../target/ant-shared-build.jar" /> 
     </javaresource> 
    </import> 
</project> 

在我的情況下,它定義了項目的所有「公共」目標,以執行基於Java的構建。

語法有點冗長,特別是當我添加了越來越多的包含文件(比如添加創建OSGi jar的能力)。通過將一個包含macrodef和scriptdef組合的antlib.xml添加到jar文件(與共享構建腳本位於同一目錄中),構建文件現在可以如下所示(現在也可以創建OSGi jar包):

<project xmlns:build="antlib:com.example.ant.sharedbuild"> 
    <taskdef uri="antlib:com.example.ant.sharedbuild" 
      classpath="../../../../target/ant-shared-build.jar" /> 
    <build:build using="java, jar, bundle" /> 
</project> 

不幸的是,我不能共享代碼的macrodef或scriptdef,但實際上它並不難:一些JavaScript解析使用屬性和循環每個,從中獲取文件名,並導入。

我在硬盤上的固定位置(相對於我的項目)引用jar文件。我認爲我們可以做得更好。理想情況下,我想從中央位置獲取(版本化!)jar文件。既然我們已經使用艾維(與HTTP資料庫),我們可以發佈的jar文件有(再次,一個版本),並且直接從那裏取,

<project xmlns:build="antlib:com.example.ant.sharedbuild"> 
    <property name="ant.shared.build.jar.file" 
       location="${user.home}/ant/ant-shared-build-1.5.3.jar" /> 
    <get src="http://repo.example.com/.../ant-shared-build-1.5.3.jar" 
     dest="${ant.shared.build.jar.file}" 
     skipexisting="true" /> 
    <taskdef uri="antlib:com.example.ant.sharedbuild" 
      classpath="${ant.shared.build.jar.file}" /> 
    <build:build using="java, jar, bundle" /> 
</project> 

有一些問題是:

  1. 它再次變得冗長。
  2. 每個build.xml都會重複詳細程度。
  3. 有很多重複的樣板,特別是版本號。

爲了緩解這些問題,在每個包含build.xml的目錄中,我還有一個bootstrap.xml(名稱並不重要)。每個版本。XML然後包括本文件:

<project xmlns:build="antlib:com.example.ant.sharedbuild"> 
    <include file="bootstrap.xml" /> 
    <build:build using="java, jar, bundle" /> 
</project> 

每個bootstrap.xml,在最低限度,包括它的父的bootstrap.xml:

<project> 
    <include file="../bootstrap.xml" /> 
</project> 

頂層bootstrap.xml(根),然後不獲得jar文件並創建自定義任務,如上面的工作:

<project> 
    <property name="ant.shared.build.version" 
       value="1.5.3" /> 
    <property name="ant.shared.build.jar.filename" 
       value="ant-shared-build-${ant.shared.build.version}.jar" /> 
    <property name="ant.shared.build.jar.file" 
       location="${user.home}/ant/${ant.shared.build.jar.filename}" /> 
    <get src="http://repo.example.com/.../${ant.shared.build.jar.filename}" 
     dest="${ant.shared.build.jar.file}" 
     skipexisting="true" /> 
    <taskdef uri="antlib:com.example.ant.sharedbuild" 
      classpath="${ant.shared.build.jar.file}" /> 
</project> 

雖然沒有直接關係的問題,實際上我再處理macrodef和scriptdef成定製Ant任務,因爲我希望能夠支持語法看起來像這樣:

<project xmlns:build="antlib:com.example.ant.sharedbuild"> 
    <include file="bootstrap.xml" /> 
    <build:build> 
     <using> 
      <java /> 
      <bundle> 
       <manifest> 
        Import-Package: *,org.joda.time;version="[1.6.0,1.6.0]" 
        Bundle-Activator: com.example.time.impl.Activator 
       </manifest> 
      </bundle> 
     </using> 
    </build:build> 
</project> 

我應該指出,僅僅建立一個可再發行組件構建並不意味着它將會是有用的。您仍然需要投入時間和精力來創建符合類似特徵設計的凝聚力,模塊化,一致的實施方案。這是更重要的,因爲您需要跨項目,跨團隊,跨組織邊界等共享腳本。

總之,通過創建一個jar文件,其版本號可獨立於特定文件位置或SCM工具,我們可以獲得真正的共享但可重複的構建。

+0

時間,冗長,樂於助人+1。我希望更多的人像這樣回答!謝謝! – nrobey 2011-03-06 01:31:51

+0

你有沒有特別的原因使用'get'而不是'ivy:retrieve'? – 2011-03-07 06:16:03

+0

@Tom:共享構建是引導常春藤的方法,因此試圖用常青藤來獲取常春藤的東西將會在循環邏輯中完全扭曲你的大腦。 – 2011-03-07 20:38:53

相關問題