ケース2:VCSで必要なソースファイルのみ管理する
システム開発を進める上で、GitやMercurial、Subversionなどのバージョン管理システム(VCS)は今や欠かせないツールです。VCSにはソースファイルだけでなく、ドキュメントや各種のバイナリファイルも一緒に登録し、共にバージョン管理することが一般的になっています。
ライブラリのdllについてもこの例に漏れず、VCSで一緒に登録して管理している場合もよく見られます。先ほど紹介したフォルダー構成例でいえば、libフォルダーもVCSに登録している形です。
この時、VCSを利用したライブラリ管理作業手順は、次のようになります(図3)。
1. dll配置用フォルダーをリポジトリに登録する
ケース1で紹介したフォルダー構成でいえば、libフォルダーとsrcフォルダーを含む、システムrootフォルダーを丸ごとVCSのリポジトリに登録します。
2. 必要なdllを配置してコミットする
ライブラリ提供者は、ライブラリのソースファイルとともに、ビルドしてできたdllファイルを上記libフォルダーにコピーしてコミットします。
3. ライブラリ利用者がソースファイルとdllファイルをまとめてチェックアウトする
1.で登録したシステムルートフォルダーごとVCSからチェックアウトします。ライブラリの変更をライブラリ提供者から連絡されたら、libフォルダーをVCSから最新化します。
dll直接配布の問題点
このやり方で起こりうる問題として、以下の2つが考えられます。
1)チェックアウト対象ファイルが多い
適度にモジュール化されたシステムでは、作業者は全ソースファイルのうち特定の機能の分だけをチェックアウトして作業することが可能です。例えば、「受注入力」という機能のソリューションフォルダーだけをチェックアウトする、というイメージです。
しかし、dllファイルもVCSで管理すると、少なくとも作業対象とは別にライブラリ用フォルダーもチェックアウトする必要があります。場合によっては、全ソースファイルをチェックアウトしないといけないようなこともあるでしょう。
規模が小さければこの運用でも問題ありません。しかし、業務システムのようなものは、機能数だけでも数百に及ぶ場合もあり、全ソースファイルをチェックアウトすると作業効率が大きく下がってしまうことがあります。
なお、特定フォルダーだけチェックアウトするという方法は、VCSによってはサポートしてない場合もあります。例えば、最近特にメジャーになったGitでは、リポジトリの一部分だけをチェックアウトすることはできません。その代りsubmodule(サブモジュール)等の機能で代替する必要があります(Git - サブモジュール )。
2)ソースファイルとライブラリの同期が行われない恐れがある
dllファイルのコミット、並びに作業コピーへの反映はあくまで手作業により行われます。したがって、ライブラリ提供者、利用者双方の操作漏れにより、ソースファイルとdllファイル間のバージョン同期が保たれなくなる恐れがあります。
3)異なるバージョンが同居できない
これはケース1の時と全く同じ問題です。ライブラリ用フォルダーでdllを管理するので、新たなバージョンを作成したら新たなdllファイルで上書きコピーしてコミットすることになります。
NuGetを使った解決法
NuGetを使うことで、VCSの利用手順が次のようになります(図4)。
1. ライブラリのソースをVCSのリポジトリに登録、コミットする
VCSに登録するのはライブラリのソースファイルだけにします。これにより、少なくともリポジトリ内では、管理すべきライブラリのバージョンが1か所で済むようになります。
2. ソースファイルからNuGetパッケージを作成し、プライベート・リポジトリに配置する
ライブラリのdllファイルをVCSで管理しないため、最新のソースファイルからNuGetパッケージを作成し、NuGetのプライベート・リポジトリに配置します。この作業は手作業でもできますが、CI(継続的インテグレーション)ツールやVCSのコミット・フック等を使い、自動的に行うようにしたほうがよいでしょう。
3. NuGetパッケージをインストールする
利用者側でアプリ用ソリューションを作成し、NuGetパッケージをインストールします。
4. ソリューションで「パッケージの復元」を有効にする
別の利用者がアプリ用ソリューションをチェックアウトする際、ソースファイルだけをチェックアウトできるよう、ソリューションの「パッケージの復元」設定を行います。これにより、packagesフォルダーはVCS管理対象外にできるため、VCSにて除外設定を行います。
5. アプリ用ソリューションをVCSに登録する
ライブラリを使用するアプリケーションのソリューションをVCSに登録します。
6. 作業対象機能のソリューションフォルダーをチェックアウトする
本来必要な最小限のファイル、つまりソリューションフォルダーだけVCSからチェックアウトします。
7. ビルドすると自動的にNuGetパッケージが復元される
4.で「パッケージの復元」の設定をしているため、初回のビルド時に自動的にライブラリのNuGetパッケージがインストールされます。これにより、作業対象ソリューションのビルドが無事行われます。
この方法により、dllをVCSに登録するやり方の問題点が次のように解消されます。
1)必要最小限のファイルをチェックアウトすればよい
ライブラリはVCSとは別のところで管理されているため、作業対象機能のソリューションだけチェックアウトすることが可能になります。また、「パッケージの復元」を有効にしておけば、ビルドを行うだけで必要なNuGetパッケージを自動的にインストールしてくれます。
パッケージの復元を有効にする方法は、参考資料7)、8)の記事を参考にしてください。
2)ライブラリはソースファイルだけバージョン管理すればよい
ライブラリはVCSに登録された最新のソースファイルを元にNuGetパッケージとして作成され、プライベート・リポジトリに配置されます。したがって、バージョンの同期が崩れることはありません。
まとめ
NuGetを活用することで、次のようなライブラリ配布の問題点を解消できることを説明してきました。
-
NuGetパッケージで配布することで次に効果が見込める
- ライブラリ導入手順の簡略化
- 複数バージョンの同居
-
NuGetパッケージで配布する際は、以下のことに気を付ける
- ライブラリのバージョンを適切に管理する必要がある
- デバッグ・シンボルは別途用意する必要がある
-
NuGetパッケージを活用することで、VCSでは必要最小限のものだけ管理すればよい
- NuGetパッケージの作成、配置はVCSの最新ソースファイルから自動で行う
- 「パッケージの復元」を使うと、NuGetパッケージのインストールを自動で行える
- 作業対象機能の必要最小限のソースファイルのみチェックアウトして操作できる
次回はライブラリの変更作業について、NuGetをどのように活用できるか紹介します。お楽しみに。
参考資料
- 1).NET開発の新標準「NuGet」入門(前編) - @IT
- 2)NuGet で MsBuild ターゲットが展開できるのが便利すぎて全俺が(ry | kazuk は null に触れてしまった
- 3)社内の開発環境の改善&効率化のためにNuGetを活用しよう - Build Insider
- 4)@IT:.NET TIPS アセンブリにバージョン情報を設定するには? - C# VB.NET VS.NET
- 5)セマンティック バージョニング 2.0.0
- 6)プライべートなNuGetリポジトリでプライベートなシンボルサーバーを使う - きよくらの備忘録
- 7)ASP.NET でソース管理システムへの NuGet パッケージのコミットを不要とする
- 8)NuGet 2.7 と Visual Studio におけるパッケージ復元機能の強化