Dot-Net

使所有 Visual Studio 項目與庫保持同步

  • June 3, 2019

設想

我有一個包含項目 A、B 和 C 的庫。

我有兩個解決方案。解決方案 1 包括項目 A 的副本,解決方案 2 包括項目 A 和 B 的副本。


當我建構解決方案 1 時,應該會發生以下情況:

替代文字


當我建構解決方案 2 時,會發生以下情況:

替代文字


我怎樣才能做到這一點?

這是我可以通過版本控制系統或現成的文件同步軟體自動化的東西嗎?還是我需要推出自己的解決方案?

如果我確實建構了自己的解決方案,我會對它的工作方式有一些想法,但我很感激您提供的任何意見:

  • 可以是一個簡單的控制台應用程序,帶有用於指定“源解決方案”的命令行開關,例如:
c:\Program Files\Library Syncronizer\LibSync.exe /solution:Solution 1
  • 用於註冊包含庫項目的活動解決方案的 XML 文件。可能的格式:
<solutions>
 <solution>
   <name>Solution1</name>
   <path>c:\...\Projects\Solution 1</path>
 </solution>
 <solution>
   <name>Solution2</name>
   <path>c:\...\Projects\Solution 2</path>
 </solution>
 <!-- more solutions -->
</solutions>
  • 程序將執行以下操作:

    • 讀入源解決方案
    • 確定它有哪些圖書館項目
    • 將這些項目的文件夾複製到庫中
    • 循環遍歷 XML 文件中的每個解決方案(源除外)
    • 根據需要複製所有庫項目的文件夾
    • 也許也可能發生一些備份操作,以防同步過程覆蓋重要的東西。

這在概念上聽起來相對簡單,但這可能會產生我沒有想到的嚴重的意外後果。希望有人會警告我,如果它這樣做:)


更新 - 我複制項目文件夾的動機是什麼?

一句話——版本控制。

如果我將庫項目保存在一個單獨的文件夾中,並且只在我的各種解決方案中連結到它們(而不是在我的解決方案文件夾中物理定位文件夾),我的版本控制儲存庫最終不會包含我的庫項目的原始碼。所以,如果我更新到“三個版本之前”,並且我需要對我的庫方法之一進行微小的更改,那麼程式碼就不存在了。

我的解決方法是向我的庫儲存庫中的修訂添加標籤,上面寫著“解決方案 1 - 版本 2.5.3”之類的內容,但這非常笨拙。如果我正在研究解決方案 1 的“三個版本之前”和解決方案 2 的目前版本,事情會變得非常尷尬。現在,解決方案 2 將指向庫項目的舊版本,這可能導致不可能使用並測試,直到我完成舊版本的解決方案 1 的工作。

如果我改為使用副本,所有解決方案都將在其儲存庫中包含庫原始碼,我可以在需要時隨時輕鬆返回。

我應該在這裡指出,我一直在使用 Tortoise HG (Mercurial) 進行版本控制。

無論如何,我對這個問題的任何解決方案持開放態度。它不必涉及複製項目文件夾——這是我唯一能想到的,以確保我的所有版本控制儲存庫都是完整的獨立包。


更新 2

首先,只是一個註釋。我使用 Mercurial (TortoiseHG) 進行版本控制,而不是 SVN。如果絕對必要,我可以改變,但我真的更喜歡 Mercurial。

根據到目前為止的回复,我決定放棄“雙向複製”的想法,並回到引用我的圖書館項目。這是一個新的圖表:

替代文字

但是,我仍然有相同的目標:

  1. 每個解決方案的最新版本都使用最新的庫程式碼
  2. 每個儲存庫一個解決方案/應用程序
  3. 每個儲存庫都包含所有原始碼,包括庫項目
  4. 一切都盡可能自動化,以盡量減少出錯的風險

目標 #1 通過引用庫項目而不是使用副本來自動處理,目標 #2 只是我如何設置儲存庫的問題,但目標 #3 和 #4 仍然難以捉摸。

使用 Mercurial,有一個子儲存庫功能似乎可以處理我的情況,但正如文件所示,這仍然被認為是實驗性的/有風險的。

目前,我認為一個好的解決方法可能是將庫項目的備份副本儲存在我的解決方案文件夾中。當我說“備份副本”時,我的意思是字面意思。我仍然會引用庫項目——這些副本僅用於確保所有原始碼最終都在我的儲存庫中(目標 3)。為了滿足目標 4,這些備份可以使用工作室中的後期建構事件來自動化。

我歡迎您對此提出任何想法。

考慮為什麼您的應用程序需要使用不同版本的庫。如果你正確設計你的庫,並確保在升級它們時不會破壞任何東西(使用持續集成和單元測試,以及測試所有依賴項目),那麼在大多數情況下,最好的(最簡單、最乾淨)的方法就是讓所有應用程序執行相同版本的庫。我什至會說,如果您的應用程序不能在相同的庫版本上執行,那就告訴您您的庫沒有正確設計/實現/維護,您應該重新考慮您的方法。

另一種方法是為每個應用程序使用一個分支,因此每個應用程序都有自己獨立的庫副本(使用項目和庫之間的相對引用,然後您可以重新定位分支中的程式碼)。這允許應用程序建構不同版本的庫,但確實具有分支的所有缺點 - 庫的兩個副本,因此您必須小心不要在錯誤的分支中進行編輯;令人討厭的合併的可能性等。

我建議將圖書館項目移入圖書館。您的圖表顯示了應用程序解決方案建構庫程式碼並將其推送到庫中,然後將建構的庫文件吸回到項目中 - 雙向副本,哎呀!只需將庫項目放在庫中並建構庫,然後從您的項目中引用該庫 - 一個單向副本。您可能認為這意味著您必須建構兩個解決方案(庫和應用程序),但實際上您可以隨時在應用程序解決方案中添加/刪除庫項目,因此這種佈局不需要兩階段建構過程。但是庫和應用程序之間的邏輯區別要清晰得多。

我們解決類似問題的方式正是您在更新 2 中描述的,但是您建議“備份副本”的地方,我們使用複製,它們是我們工作流程中不可或缺的一部分。

我的解決方案。

我們使用複製命名分支的組合來允許我們控制何時更新特定應用程序的庫(您的範例中的解決方案)。

我們所做的是為我們的每個庫都有一個核心儲存庫,其中包含該庫的主線分支。當我們創建一個新應用程序時,我們將所有相關庫(每個庫使用一個 mercurial repo,其中一個庫可能包含該庫及其測試應用程序)複製到新應用程序旁邊的目錄中,並引用該應用程序中的庫。

對此應用程序的庫的任何送出都將送出到根據應用程序命名的分支。當一個應用程序完成後,我們審查對庫的更改,然後將適當的更改合併回主線,創建一個新的主線。這還有一個好處是,在未來,您可以通過查看更改送出到哪個分支來輕鬆辨識哪個應用程序導致了對庫的特定更改。

每當我們接觸一個應用程序時,我們可以選擇是繼續使用舊的庫,還是更新到該庫的更新的主線版本(甚至是另一個項目開發版本)。庫更改不會推送到每個使用它們的應用程序(有些可能是多年未觸及的遺留應用程序,並且與它們提供的庫一起工作),它們被需要新的應用程序拉入給定版本的庫中的設施。

為什麼我要這樣做?

我在這裡試圖避免的問題是我在以前的公司經常遇到的問題。

我會讓我的應用程序與給定的庫一起工作。其他人會為他們的應用程序更改庫,以便它完成他們需要的工作,而下次我去編輯我的項目時,它不會編譯。然後我將不得不花時間修復我的項目以按照圖書館現在想要的方式乞求,或者花時間恢復對圖書館所做的不適當的更改(然後將級聯回給其他開發人員)。

通過本地項目複製,每個應用程序都可以選擇何時更新到更新的庫版本,並且從機會管理的角度來看,我們可以在將庫合併回主線之前審查由於應用程序需求而對庫所做的更改。

這是一個使用像 SourceSafe 這樣的傳統 VCS 永遠不可能實現的工作流,但使用像 Hg 這樣的 DVCS 可以很好地工作。

針對那些難以實現的目標的具體解決方案。

嘗試並回答你難以捉摸的目標

.3. 每個儲存庫都包含所有原始碼,包括庫項目

通過將庫複製到靠近您的應用程序的目錄中,您可以獲得一組可以一起管理的儲存庫,並且最終可能會很好地轉換為“應用程序”超級儲存庫的子儲存庫。

.4. 一切都盡可能自動化,以盡量減少出錯的風險

我使用儲存在我的應用程序目錄中的一堆批處理文件來執行此操作。

例如,給定的應用程序“_projects.bat”可能包含:

@echo off
@shift
set APPDIR=%CD%
cd ..\Library1
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd ..\Library2
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd ..\Library3
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

cd %APPDIR%
%0 %1 %2 %3 %4 %5 %6 %7 %8 %9

pause

然後我有批處理文件來做有用的同步事情,比如檢查哪些文件將被“__incoming.bat:

@echo off
call _projects hg incoming

並檢查“__outgoing.bat”會推送什麼:

@echo off
call _projects hg outgoing

或者實際上使用“__push.bat”進行這些操作:

@echo off
call _projects hg push

和“__pull.bat”:

@echo off
call _projects hg pull

而“__update.bat”將所有內容更新到最新版本(在同一個分支中,您仍然必須在目前分支之外顯式更新):

@echo off
call _projects hg update

我最喜歡的一個是“__ids.bat”,它顯示了目前正在使用的變更集(和分支),並且重要的是,它們是否有未送出的未完成更改:

@echo off
call _projects hg id

每當我開始進行應用程序更新時,我都會檢查是否有更新的庫,下拉所有合適的內容,更新到我想要的版本,然後繼續開發。

請注意,文件名中的下劃線只是為了將它們推到目錄列表的頂部,以便更容易找到它們。*8')

未來的選擇。

最終我想通過使用子儲存庫來完全自動化這個工作流程(所以整個應用程序的狀態和所有它的庫都記錄在一個應用程序變更集中),但是雖然它在 Mercurial 中變得相當穩定,但 TortoiseHG 集成並沒有似乎是一個優先事項。上次嘗試(大約 0.8.3)時,我無法讓 THG 送出工具做任何有用的事情。我真的應該用 0.9.3 重新測試,但我不記得在變更日誌中看到任何關於子回購的註釋,所以除非人們告訴我 THG 子回購支持已被默默添加,否則這是不值得的。

事實上,批處理文件工作得很好。我的待辦事項清單上的下一件事是“__clone.bat”,它應該使複製應用程序及其所有庫變得容易得多,但我沒有時間讓它工作。

如果有人想嘗試一下,我很想在這個文章中看到回复。*8')

保重,希望對你有幫助

標記……….

引用自:https://stackoverflow.com/questions/2076791