現在、私はレガシーバージョン管理システムから移行し、グループのプロジェクトをMercurialに移行しています。移動するコードの種類の一例として、25以上のプロジェクトのVisual Studioソリューションがあり、すべて共通のコードに依存するいくつかの個別のアプリケーション領域が含まれています。Stack Overflowを見ると、私が見つけた最も近い質問はこれでしたが、バージョン管理についてのみ言及していました。Mercurialを使用してこれらの依存関係を管理する特定の実装手法について、もう少しアドバイスを探しています。
依存関係の簡略化されたビューは、次のようになります。(これは説明と例にすぎません。実際の依存関係はかなり複雑ですが、本質的に類似しています。)
Common Lib 1
/ | \
---- | -----
/ | \ \
App 1 Common Lib 2 \ App 2
/ | \ \
------- | ------ |
/ | \|
App 3 App 4 App 5
Common Libモジュールは共有コードになります-これは、コンパイル時と実行時の両方で、すべてのアプリ間で同時に使用されるDLLまたはSOまたはその他のライブラリになります。そうでなければ、アプリケーションは互いに独立して実行できます。
Mercurialリポジトリの設定にはいくつかの目標があります。
- 重要な各アプリケーションまたはコンポーネントグループに独自のリポジトリを提供します。
- 各リポジトリを自己完結型にします。
- プロジェクトの合計を自己完結型にします。
- コードベース全体を一度に簡単に構築できるようにします。(最終的に、これらのプログラムとライブラリはすべて1つのインストーラーになります。)
- 単純にする。
もう1つのポイントは、これらのプロジェクトごとに個別のリポジトリがあるサーバーをセットアップしていることです。
これらのプロジェクトをレイアウトする方法はいくつかあります。
1.すべてを含む「シェル」リポジトリを作成します。
これは、URLベースのサブリポジトリを使用します(たとえば、.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 | |
| +---------------------+ |
+---------------------------+
シェルリポジトリの各メインフォルダには、プロジェクト領域ごとに1つずつサブリポジトリが含まれます。依存関係は相対的です。たとえば、App4はCommonLib 2を必要とするため、相対パスを使用してその共通ライブラリを参照します。
このアプローチの長所:
- 各ライブラリは一度だけプルダウンされます。
- Mercurialのサブレオは、同じバージョンのライブラリがすべてのプロジェクトで自動的に使用されるようにします。これは、そのサブリポジトリの1つのバージョンのみがプロジェクトに存在するためです。
- 各リソースを見つけるのは簡単です。
このアプローチの短所:
- アプリを単独で操作することはできません。たとえば、アプリ2で作業していて、共通ライブラリを変更する必要がある場合、他のすべてのアプリは今すぐそれらの変更を行う必要があります。
- アプリリポジトリを単独でプルする場合、それを構築する場合は、他にどのような依存リポジトリが必要かを手動で把握(または把握)する必要があります。
- 依存関係は強く分離されていません。すべての機能を簡単に取得できるため、どこにでも新しい機能を挿入したくなるでしょう。
2.依存するサブリポジトリを完全に封じ込めます。
このアプローチでは、各アプリケーションは(以前と同様に)独自のリポジトリを持ちますが、今回はサブリポジトリも含まれます。1つは独自のソース用で、もう1つは依存するサブリポジトリごとです。全体的なリポジトリには、これらの各プロジェクトリポジトリが含まれ、ソリューション全体を構築する方法がわかります。これは次のようになります。
+-----------------------------------------------------------------------+
| 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サブリポジトリを同期するためのツールを作成する必要があるかもしれません。Eww。)
- ソース全体を構築したい場合は、共有ライブラリを複数回プルダウンすることになります。Common Lib 1の場合、8回(!)プルする必要があります。
3.依存関係をサブリポジトリとして含めないでください-ビルドの一部としてそれらを取り込みます。
このアプローチは、共通ライブラリがビルドの一部としてのみプルされることを除いて、アプローチ1とよく似ています。各アプリは、必要なリポジトリを認識し、それらを共通の場所に配置します。
長所:
- 各アプリはそれ自体で構築できます。
- 共通のライブラリは一度だけプルする必要があります。
短所:
- 各アプリで現在使用されているライブラリのバージョンを追跡する必要があります。これはサブレポ機能を複製します。
- これをサポートするインフラストラクチャを構築する必要があります。つまり、ビルドスクリプトにさらに多くのものを投入する必要があります。うーん。
4.他に何がありますか?
それを処理する別の方法はありますか?より良い方法は?どのように試みて成功しましたか、どのように試みましたが嫌いでしたか?私は現在1に傾いていますが、アプリケーションの独立性の欠如は、それが可能であるはずなのに、本当に私を悩ませています。(オプション3のように)それを処理するためのスクリプトを書く必要がなく、大規模な重複コードのプルと依存関係の維持の悪夢なしにメソッド2をうまく分離する方法はありますか?