2011-05-16 18 views
60

目前,我正在從傳統的版本控制系統轉移到我的小組項目,並將其移至mercurial。作爲我正在移動的代碼類型的一個例子,我有一個25+項目的Visual Studio解決方案,其中包含幾個獨立的應用程序區域,這些應用程序區域都依賴於通用代碼。回顧Stack Overflow,我發現的最接近的問題是this one,但它僅僅提到了版本控制。我正在尋找進一步的建議,關於使用Mercurial來管理這些依賴關係的具體實現技術。在Mercurial中組織具有共享依賴項目的項目的好方法是什麼?

依賴關係的簡化視圖如下所示。 (這是爲了說明和示例僅;實際依賴關係是顯著更復雜,但是在本質上相似的。)

     Common Lib 1 
        / |  \ 
       ----  |  ----- 
      /   |  \ \ 
      App 1 Common Lib 2 \ App 2 
        / | \  \ 
       ------- | ------ | 
      /   |   \| 
      App 3  App 4  App 5 

通用庫模塊將被共享的代碼 - 這將是一個DLL或SO或一些其它庫將在所有應用程序之間同時使用 - 無論是在編譯時還是運行時。否則應用程序可以獨立運行。

我有幾個目標,與建立我的善變庫:

  • 給每個顯著應用程序或組件組自己的倉庫。
  • 使每個存儲庫自成一體。
  • 使項目自成總計。
  • 一次構建整個代碼庫很容易。 (最終,所有這些程序和庫最終都會放在一個安裝程序中。)
  • 保持簡單。

另一個問題是我有一個服務器設置,我爲這些項目中的每一個都有單獨的存儲庫。

我看到一些將這些項目鋪設的方法。

1.創建一個包含所有內容的「Shell」存儲庫。

這將使用基於URL的subrepos(例如,在.hgsub,我會做這樣的事情App1 = https://my.server/repo/app1)擺出來,它看起來像下面這樣:

+---------------------------+ 
| Main Repository   | 
| | +---------------------+ | 
| +-| Build    | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| Common Lib 1  | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| Common Lib 2  | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| App 1    | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| App 2    | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| App 3    | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| App 4    | | 
| | +---------------------+ | 
| | +---------------------+ | 
| +-| App 5    | | 
| +---------------------+ | 
+---------------------------+ 

在每個主文件夾shell存儲庫將包含一個子項目,每個項目區域一個。依賴關係是相對的:例如,由於應用程序4需要公共庫2,它將簡單地使用相對路徑來引用該公共庫。這種方法的

優點:

  • 每個庫一次且僅一次拉下來。
  • Mercurial的subreos將確保自動在所有項目中使用相同版本的庫,因爲項目中只存在該子報告的一個版本。
  • 很容易找到每個資源。這種方法的

缺點:

  • 我不能在一個應用程序獨立工作。例如,如果我在App 2上工作,並且需要更改公共庫,則所有其他應用都必須立即進行這些更改。
  • 如果我自己拉一個應用程序回購,我必須弄清楚(或知道)如果我想要構建它,還需要手動獲取其他哪些依賴回購。
  • 依賴關係並沒有很強的分離 - 因爲很容易獲得所有功能,所以很容易在任何地方插入新功能。

2.有依賴subrepos完全包含。

在這種方法中,每個應用程序都有自己的存儲庫(與以前一樣),但是這次也包含子存儲庫:一個用於其自己的源,另一個用於每個從屬子庫。然後整個資源庫將包含這些項目資源庫中的每一個,並知道如何構建整個解決方案。這將如下所示:

+-----------------------------------------------------------------------+ 
| Main Repository              | 
| +--------------------+ +--------------------+ +--------------------+ | 
| | Build    | | Common Lib 1  | | Common Lib 2  | | 
| +--------------------+ | | +--------------+ | | | +--------------+ | | 
|      | +-| Lib 1 Source | | | +-| Common Lib 1 | | | 
|      | +--------------+ | | | +--------------+ | | 
|      |     | | | +--------------+ | | 
|      |     | | +-| Lib 2 Source | | | 
|      |     | | +--------------+ | | 
|      +--------------------+ +--------------------+ | 
| +--------------------+ +--------------------+ +---------------------+ | 
| | App 1    | | App 2    | | App 3    | | 
| | | +--------------+ | | | +--------------+ | | | +--------------+ | | 
| | +-| Common Lib 1 | | | +-| Common Lib 1 | | | +-| Common Lib 2 | | | 
| | | +--------------+ | | | +--------------+ | | | +--------------+ | | 
| | | +--------------+ | | | +--------------+ | | | +--------------+ | | 
| | +-| App 1 Source | | | +-| App 2 Source | | | +-| App 3 Source | | | 
| | +--------------+ | | +--------------+ | | +--------------+ | | 
| +--------------------+ +--------------------+ +---------------------+ | 
| +--------------------+ +--------------------+       | 
| | App 4    | | App 5    |       | 
| | | +--------------+ | | | +--------------+ |       | 
| | +-| Common Lib 2 | | | +-| Common Lib 1 | |       | 
| | | +--------------+ | | | +--------------+ |       | 
| | | +--------------+ | | | +--------------+ |       | 
| | +-| App 4 Source | | | +-| Common Lib 2 | |       | 
| | +--------------+ | | | +--------------+ |       | 
| +--------------------+ + | +--------------+ |       | 
|      | +-| App 5 Source | |       | 
|      | +--------------+ |       | 
|      +--------------------+       | 
+-----------------------------------------------------------------------+ 

優點:

  • 每個應用程序都可以單獨建造,相互獨立的。
  • 庫的相關版本可以按每個應用程序進行跟蹤,而不是全局跟蹤。它需要在項目中插入子報表以添加新的依賴關係。

缺點:

  • 在做最終版本,每個應用程序可能會使用不同版本的共享庫。 (可能需要編寫工具來同步常用的lib子目錄。)
  • 如果我想構建整個源代碼,我最終會多次下拉共享庫。在Common Lib 1的情況下,我必須把它拉八(!)次。

3.不要包含依賴關係作爲subrepos - 將它們作爲構建的一部分引入。

這種方法看起來非常像方法1,只是通用庫只會作爲構建的一部分被提取。每個應用程序都會知道它需要什麼回購,並將它們放在公共位置。

優點:

  • 每個應用程序都可以通過自身建設。
  • 通用庫只需要拉一次。

缺點:

  • 我們不得不跟蹤當前使用的每個應用程序庫的版本。這複製了subrepo功能。
  • 我們不得不建立一個基礎架構來支持這個,這意味着更多的東西進入構建腳本。啊。

4.還有什麼?

有沒有處理它的另一種方法?更好的方法?你嘗試和成功的方式有哪些,你嘗試過但討厭的方式?我目前傾向於1,但是應用程序獨立性的缺乏在它應該能夠真正困擾我的時候。有沒有辦法得到方法2的良好分離而沒有大量的重複代碼拉和依賴維護的噩夢,而不必編寫腳本來處理它(如在選項3中)?

+0

最近在開發人員郵件列表中有關於此主題的討論:http://news.gmane.org/find-root.php?message_id=%3c1302811240.12395.36.camel%40calx%3e – Rudi 2011-05-17 07:41:38

+1

您使用了什麼工具用來創建這些ASCII圖? – 2011-05-17 19:11:19

+3

@caveman:油滑編輯。一個非常時髦的文本編輯器。在該編輯器中右鍵單擊選擇對於移動您喜歡它們的文本列非常有用。 :) – 2011-05-17 21:08:42

回答

5

依賴性管理是項目組織的一個重要方面,在我眼中。基於Mercurial的subrepos功能,您可以詳細瞭解各種解決方案,並且我同意您提供的所有優點/缺點。

我認爲SCMs不太適合依賴管理。我更喜歡有一個專門的工具(這將是你的解決方案n°3)。

我目前的項目是在Java中。它是用Apache Ant構建的,我首先將Apache Ivy設置爲依賴關係管理工具。最後,該設置包含一個共享目錄中的一些Ivy配置文件,以及一個XML文件,其中列出了項目中每個模塊的依賴關係。常春藤可以被Ant目標調用,所以我在每個模塊中添加了兩個新操作:「解決依賴關係」和「部署構建的工件」。部署將buid(稱爲工件)的結果添加到共享目錄中。依賴關係解析意味着可以及時解析模塊的依賴關係,並將解析後的構件複製到模塊源文件的「lib」文件夾中。

該解決方案適用於C++項目,因爲Ivy並不特定於管理Java依賴項:工件可以是任何東西。在C++中,由模塊所產生的僞像將是:

  1. 一個這樣/ DLL在運行時
  2. 在編譯時的頭文件。

這不是一個完美的解決方案:常春藤是不容易建立,你還是要告訴你的構建腳本中使用什麼樣的依賴,你沒有爲調試目的直達依賴的來源。但是你最終會得到獨立的SCM存儲庫。

在我們的項目中,我們將Ant + Ivy轉換爲Apache Maven,它負責構建和依賴關係管理。工件被部署在Apache Archiva而不是共享文件夾中。這是一個巨大的改進,但它僅適用於Java項目。

+0

看起來這正是我們將要進入​​的方向。謝謝你的想法。 :) – 2011-05-31 22:25:10

2

你想要做的是讓每個項目都在自己的目錄中,就像在(1)中一樣。然後你標記的工作你的依賴版本,並保存標籤在一些文件中生成,如:

 
App1/.dependencies: 
CommonLib1 tag-20100515 
CommonLib2 tag-20100510 

App2/.dependencies: 
CommonLib1 tag-20100510 
CommonLib2 tag-20100510 

然後你用你的構建腳本來構建基於特定的標籤庫和包括建庫作爲派生的對象你的應用。如果構建時間是一個問題,那麼可以將這些庫的標記版本預先構建並保存在某個位置。

注(設計原理是相同的,如果設計數據庫模式,對象模型或產品版本):

  • 不要鏈接到其他項目的代碼(休息封裝)
  • 沒有多個副本您的資源庫中的庫(模塊化)
0

我們使用subversion解決了類似的問題。

每個應用程序和每個Common Lib都有自己的存儲庫。

每個應用程序都有一個包含依賴dll的目錄Libs

因此,如果提供了一組新的dll,該應用程序僅獲得Common Lib的更新。

但是,升級lib文件夾並不是微不足道的,因爲依賴的子dll必須匹配正確的版本。

+7

像dll這樣的派生對象不應該在版本控制中檢查,而應該是構建的結果。 – 2011-05-18 17:17:36

相關問題