tmori3y2のブログ

主にWindowsのプログラムなど

NuGet Local Package Sourceを使って分かってきたこと

VS2013.5/NuGet 2.8.6

tmori3y2.hatenablog.com

自家製NuGet Packageを活用できないかを模索中。

取りあえずゼロからのスタートなので、NuGet Packageプロジェクトのコードだけをソースコード管理ツールリポジトリに入れて、開発者のローカルフォルダに自分でビルドしてパッケージを配置する方法から試しています。

大まかですが、ローカルで使用する場合の注意点も見えてきました。

フォルダ構成は、例えば以下のようにします。

  • プロダクトルート

    • Deploy

      • NuGetPackages (Local Package Source)
    • 自家製 NuGet Packagesルート

      • 自家製 NuGet Packageソリューション1

        • 自家製 NuGet Packageプロジェクト1

        • 自家製 NuGet Packageプロジェクト2

      • 自家製 NuGet Packageソリューション2

      • packages (Package Repository)

      • Nuget.config

      • nuget.exe

    • プロジェクトルート

      • ソリューション1

        • プロジェクト1

        • プロジェクト2

      • ソリューション2

      • packages (Package Repository)

      • Nuget.config

      • nuget.exe

  1. ZipArchive化されたパッケージはグローバル、および、ローカルなパッケージソースに置かれている
  2. パッケージソースはNuGet Package ManagerのPackage Sources設定画面でロケーションと問い合わせ順が管理されている
  3. プロジェクトにインストールされたパッケージは、最初にパッケージソースからパッケージリポジトリに展開される
  4. パッケージリポジトリは、ソリューションフォルダのpackagesフォルダか、NuGet.configが指定したフォルダになる
  5. パッケージは、インストールプロジェクトがなくなったら、パッケージリポジトリから削除される
  6. パッケージリポジトリに指定パッケージId、指定バージョンが見つかったら、パッケージソースには問い合わせにはいかない
  7. 更にグローバルパッケージは、パッケージキャッシュに指定パッケージId、指定バージョンが見つかったら、パッケージソースには問い合わせにはいかない
  8. 指定パッケージId、指定バージョンが見つからないと、インストール、復元はおろか、アンインストールも失敗する
  9. インストールされた参照アセンブリはなくても復元出来るが、インストールされたコンテンツがないと復元に失敗する
  10. インストールされたコンテンツを編集するとアンインストールされず、再インストール時に上書きするか確認される

まず、ローカルパッケージソースで、よくやっちゃうのが、修正した時にバージョンを上げずに、アンインストールしてインストールし直すパターン。

「ちょっとだけよ」

と軽い気持ちでやっちゃうけど、複数プロジェクトでインストールしてる状態で、1つのプロジェクトだけでアンインストールしてインストールし直すと、5と6が原因でパッケージリポジトリに残った古いパッケージをもう一度インストールしてしまうので、.pdb付きでパッケージされていてステップインでも出来ない限り、直ってないのはバグが原因かと早合点する事が多い。

だから、

  • ローカルであっても、デバッグ中であっても、インストールしたらバージョンは常に上げる
  • バージョンを上げなければ、ローカルパッケージソースにコピー出来ないようにする

のが正解だ。

ちなみに、 シンボルなし通常パッケージと、シンボル付きパッケージを同じパッケージソースに置くと、パッケージマネージャーのGUIでは通常パッケージしか選択できない ので、

  • シンボルサーバー無しでも、ステップイン出来るように、リリースビルドで.pdbファイルを<file>で追加する

と良い。

7は、

「新しいバージョンが手に入るなら良きに計らってくれれば良いのに・・・」

と、ついつい素人は思ってしまうが、構成が変わる事もあるので、その期待は叶えられない。

結果として、パッケージがロストしたら、手動編集でプロジェクトから項目を削除する羽目になるので、

  • ローカルパッケージソースの中身は、ソースコード管理ツールで管理するか、バックアップを取る
  • グローバルパッケージは、ユーザ単位でパッケージキャッシュにダウンロードされているので、グローバルパッケージソースのトラブルに備えて、パッケージキャッシュをローカルパッケージソースに指定して、出来ればバックアップを取る

blogs.msdn.microsoft.com

というのが、転ばぬ先の杖。

9をやってくれるなら、8でも復元してほしいところだが、現状は、

  • インストールしたコンテンツは、ソースコード管理ツールで管理する必要がある
  • インストール先のプロジェクトローカルで改変されることを想定して、改変が好ましく無いなら最低限コメントを入れておく

「意味ないじゃん・・・」

と思うなかれ。コピー&ペーストや、プロジェクト間でのコンテンツの共有リンク程、影響範囲が読めず、いい加減なものは無い。

「コンテンツを自家製パッケージプロジェクトでバージョン管理して、テスト済みコンテンツをプロジェクトにインストールしているという構成に意味がある」

プロジェクト間で依存パッケージのバージョンを揃えるのも、大規模プロジェクトでは大変。署名アセンブリでもない限り複数バージョンの共存は出来ないし、アセンブリをかき集めた時のバージョン上書きも怖い。

  • パッケージの依存バージョンをコントロールするための自家製パッケージを作ると、特定バージョンの自家製パッケージをインストールする事で、他のパッケージのバージョンコントロールがしやすくなる

番外:

  • パッケージの復元は、package.configがプロジェクトに含まれているか否かに係わらず、プロジェクトフォルダに見つかったら実行されるので、アンインストールに失敗して手動修正した時の消し忘れに注意

以下は過去記事報告済みトラブル事例。

tmori3y2.hatenablog.com

tmori3y2.hatenablog.com