1. ホーム
  2. nuget

[解決済み] いくつかのプロジェクトが複数のソリューションに含まれている場合、すべてのソリューションに共通のnugetパッケージフォルダを設定する

2022-05-07 04:52:39

質問

NuGetを使って、外部や内部のパッケージソースからパッケージを取得していますが、とても便利です。しかし、パッケージはデフォルトでソリューションごとに保存されることに気づきました。これは、NuGetリファレンスを持ついくつかのプロジェクトが複数のソリューションに含まれている場合、非常にフラストレーションがたまるものです。そして、その参照は他のソリューションのパッケージフォルダに変更され、他の開発者やビルドマシンが実際に利用できなくなる可能性があります。

NuGetのリリース2.1では、共通のパッケージの場所(おそらくプロジェクトのルートレベル、私たちはTFSソースコントロールを使用しています)を指摘する方法があることを確認しました、以下を参照してください。 リリースノート . 私はNuGet v2.7を使用しています。

しかし、私はこれの効果を見ずにnuget.configファイルを追加しようとしました。パッケージはソリューションフォルダに保存されたままです。私が見逃している何かがありますか? その質問に答える人によって、nuget.configファイルに追加するxmlノードの構造が異なるようです。 Schwarzieは次のように提案しています。 別のStackoverflowのスレッド :

<settings>
  <repositoryPath>..\..\[relative or absolute path]</repositoryPath>
</settings>

NuGet 2.1 のリリースノート(上記リンク参照)では、この形式を提案しています。

<configuration>
  <config>
    <add key="repositoryPath" value="..\..\[relative or absolute path]" />
  </config>
</configuration>

最終的にどれが、あるいはどれが、あるいは両方がうまくいくのかわからない。私はソリューションレベルで両方を試しました。 nuget.configファイルはTFSプロジェクトのルートレベルに置くことができますか、それともソリューションディレクトリに置かなければなりませんか?NuGetはこれらのファイルから特定の順序で設定を読み取り、適用するようです。なぜ、ソリューションレベルのnuget.configファイルがTFSプロジェクトルートレベルのものを上書きする、いくつかのレベルでそれらを追加することが理にかなっていると思われます。これを明確にすることができますか?

これらのリファレンスが機能する前に、インストールされているすべてのパッケージを削除する必要がありますか? ソリューション固有のnugetの使用から、複数のソリューションに属するプロジェクトが必要なnugetパッケージを見つけることができる共通のパッケージフォルダに移行するためのステップバイステップの手順を誰かが提供してくれるなら、私はとてもうれしいです。

どのように解決するのですか?

私は、複数のソリューションで参照されるプロジェクトの外部および内部パッケージソースについて、同様の状況を持っています。今日、私たちのコードベースの1つでこれを動作させたところ、開発者のワークステーションと私たちのビルドサーバーで動作しているようです。以下のプロセスは、このシナリオを念頭に置いています(ただし、共通のパッケージフォルダを他の場所に置くように適応するのは難しくありません)。

  • コードベース
    • プロジェクトA
    • プロジェクトB
    • プロジェクトC
    • ソリューション
      • 解決策1
      • 解決策2
      • 解決策3
      • パッケージ(これはすべてのソリューションに共通するものです。)

NuGet 3.5.0.1484 時点で Visual Studio 2015 Update 3 で回答を更新しました。

この作業は、私が最初に取り組んだときよりも少し簡単になり、これを更新する時期が来たと思いました。一般的には、手順が少なくなっただけで作業は同じです。その結果、以下のようなことを解決したり、提供したりすることができるようになりました。

  • ソースコード管理にコミットする必要があるものはすべて、ソリューションの中で可視化され、追跡されます。
  • Visual Studio のパッケージマネージャを使用して新しいパッケージをインストールしたり、パッケージを更新すると、正しいリポジトリパスが使用されます。
  • 初期設定後、.csprojファイルのハッキングはありません。
  • 開発者のワークステーションを変更しない(チェックアウト時にコードがビルドできる状態になっている)

デメリットもあるので注意が必要です(私はまだ体験していないのでYMMV)。参照 ベノルの の回答やコメントがあります。

NuGet.Configを追加する

NuGet.Configファイルを \Solutions フォルダのルートに作成します。UTF-8でエンコードされたファイルを作成する必要があります。NuGet.Configに以下を追加します。

<?xml version="1.0" encoding="utf-8"?>
<configuration>  
  <config>
    <add key="repositoryPath" value="$\..\Packages" />
  </config>
</configuration>

repositoryPath の設定には、$ トークンを使用して、絶対パスまたは相対パス(推奨)を指定できます。トークンは、NuGet.Config が置かれている場所を基準とします ($ トークンは、実際には 一段下 NuGet.Configの場所)。つまり、もし私が \SolutionsNuGet.Config を持っていて、 \SolutionsPackages が欲しいなら、その値として $..\Packages を指定する必要があります。

次に、ソリューションに "NuGet" のような名前のソリューションフォルダを追加します(ソリューション上で右クリックし、Add->New Solution Folder)。ソリューションフォルダは、Visual Studioソリューション内にのみ存在する仮想フォルダで、ドライブ上に実際のフォルダを作成することはありません(そして、どこからでもファイルを参照することができます)。NuGetソリューションフォルダを右クリックし、Add->Existing Itemを選択し、 \SolutionsNuGet.Config.

このようにする理由は、ソリューションで見えるようにし、ソースコードコントロールに適切にコミットされていることを確認するのに役立つはずです。このステップは、共有プロジェクトに参加しているコードベース内の各ソリューションに対して行うとよいでしょう。

NuGet.Config ファイルを .sln ファイルの上の \Solutions に配置することで、NuGet が使用する NuGet.Config ファイルを探すために "current working directory" から上のフォルダ構造を再帰的にナビゲートするという事実を利用しています。ここでいうquot;current working directory"とは、NuGet.exeの実行パスと.slnファイルの位置という2つの異なるものを意味します。

packages フォルダの切り替え

まず、各ソリューションフォルダーを確認し、存在する \Packages フォルダーを削除することを強くお勧めします(最初に Visual Studio を閉じる必要があります)。これにより、NuGet が新しく設定した \Packages フォルダーをどこに配置するかがわかりやすくなり、間違った \Packages フォルダーへのリンクは失敗し、修正できるようになります。

Visual Studioでソリューションを開き、Rebuild Allを実行します。この時点で予想されるビルドエラーをすべて無視します。これは、ビルドプロセスの開始時にNuGetパッケージの復元機能を起動させる必要があります。깨깨깨깨깨깨깨깨깨 もし、作成されていない場合は、設定を見直してください。

次に、ソリューション内の各プロジェクトについて、次のことを行います。

  1. プロジェクトを右クリックし、プロジェクトのアンロードを選択します。
  2. プロジェクト上で右クリックし、Edit your-xxx.csprojを選択します。
  3. \packages の参照を探し、新しい場所に更新します。
    • これらのほとんどは、<HintPath> の参照になりますが、すべてではありません。例えば、WebGreaseとMicrosoft.Bcl.Buildは、それぞれ別のパス設定を持っており、それを更新する必要があります。
  4. .csprojを保存し、プロジェクトを右クリックし、プロジェクトの再読み込みを選択します。

すべての.csprojファイルが更新されたら、もう一度Rebuild Allを実行すると、リファレンスが見つからないというビルドエラーが発生しなくなるはずです。この時点で、NuGet が共有 Packages フォルダーを使用するように設定され、完了となります。

NuGet 2.7.1 (2.7.40906.75) と VStudio 2012 の組み合わせの場合

まず、注意しなければならないのは、nuget.configはnugetパッケージシステムのパス設定のすべてをコントロールしているわけではない、ということです。これは特に分かりにくかったです。具体的には、msbuild と Visual Studio (msbuild を呼び出す) が nuget.config のパスを使用せず、nuget.targets ファイルでオーバーライドしていることが問題なのだそうです。

環境の準備

まず、ソリューションのフォルダーを調べて、存在するすべての \packages フォルダーを削除します。これは、すべてのパッケージが正しいフォルダーにインストールされていることを確認し、ソリューション全体の不正なパス参照を発見するのに役立ちます。 次に、最新のnuget Visual Studioエクステンションがインストールされていることを確認します。 また、各ソリューションに最新のnuget.exeがインストールされていることを確認します。コマンドプロンプトを開き、各$(SolutionDir) \.nuget フォルダに移動し、以下のコマンドを実行します。

nuget update -self

NuGetの共通パッケージフォルダパスの設定

各$(SolutionDir) \.nugetNuGet.Config を開き、<configuration> セクション内に以下を追加してください。

<config>
    <add key="repositorypath" value="$\..\..\..\Packages" />
</config>

絶対パスと相対パスのどちらを使ってもかまいません。相対パスを$で指定する場合は、$に対する相対パスであることに注意してください。 1つ下の階層 NuGet.Configの場所(これはバグだと信じています)。

MSBuildとVisual Studioの共通パッケージフォルダパスの設定

各$(SolutionDir) \ .nugetNuGet.targets を開き、以下のセクションを修正します(Windows以外の場合、その下に別のセクションがあることに注意してください)。

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
    <!-- Windows specific commands -->
    <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
    <PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
    <PackagesDir>$([System.IO.Path]::Combine($(SolutionDir), "packages"))</PackagesDir>
</PropertyGroup>

PackagesDir を次のように更新します。

<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>

GetFullPathは、相対パスを絶対パスに解決してくれます。

すべてのnugetパッケージを共通フォルダにリストアする

コマンドプロンプトを開き、$(SolutionDir) \.nuget をそれぞれ取得し、以下のコマンドを実行します。

nuget restore ..\YourSolution.sln

この時点で、共通ロケーションに1つの \packages フォルダがあり、どのソリューションフォルダ内にもないはずです。もしそうでなければ、パスを確認してください。

プロジェクトの参照先を修正する

.csproj ファイルをテキストエディタで開き、"the \packages" を参照している箇所を探し、正しいパスに更新してください。ほとんどの場合、<HintPath>参照になりますが、すべてではありません。また、"Select "コマンドを使用して、"Select "コマンドを実行することもできます。

ソリューションの構築

Visual Studioでソリューションを開き、ビルドを開始します。パッケージが見つからないので復元する必要があると表示された場合、パッケージが見つからないので復元する必要があると判断しないでください (エラーは誤解を招く可能性があります)。.csprojファイルに不正なパスがある可能性があります。パッケージをリストアする前に、まずそれを確認してください。

パッケージが見つからないというビルドエラーが発生しましたか?

.csprojファイルのパスが正しいことをすでに確認している場合、2つのオプションを試すことができます。ソースコード管理からコードを更新した結果である場合、クリーンコピーをチェックアウトし、それをビルドしてみることができます。これは私たちの開発者の一人で、.suoファイルかそれに似たものにアーティファクトがあったと思います。もう一つの選択肢は、問題のソリューションの .nuget フォルダでコマンドラインを使用して手動でパッケージの復元を強制することです。

nuget restore ..\YourSolution.sln