web-dev-qa-db-ja.com

一部のプロジェクトが複数のソリューションに含まれる場合、すべてのソリューションに共通のNugetパッケージフォルダーを設定する

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パッケージを見つけることができる共通のパッケージフォルダーに移行するためのステップバイステップの指示を誰かが提供できればと思います。

127
Mats Isaksson

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

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

Visual Studio 2015 Update 3でNuGet 3.5.0.1484の時点で更新された回答

このプロセスは、最初にこれに取り組み、これを更新するときだと思っていたときよりも少し簡単になりました。一般に、プロセスは手順が少ないだけで同じです。結果は、以下を解決または提供するプロセスです。

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

知っておくべき潜在的なマイナス面がいくつかあります(YMMVではまだ経験していません)。 Benol's の回答とコメントを参照してください。

NuGet.Configを追加します

\ Solutions \フォルダーのルートにNuGet.Configファイルを作成します。これが作成するUTF-8エンコードファイルであることを確認します。これを行う方法がわからない場合は、Visual Studioの[ファイル]> [新規]> [ファイル]メニューを使用して、XMLファイルテンプレートを選択します。次をNuGet.Configに追加します。

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

RepositoryPath設定では、$トークンを使用して絶対パスまたは相対パス(推奨)を指定できます。 $トークンは、NuGet.Configの場所に基づいています($トークンは、実際には1レベル下 NuGet.Configの場所に相対的です)。したがって、\ Solutions\NuGet.Configがあり、\ Solutions\Packagesが必要な場合は、値として$\..\Packagesを指定する必要があります。

次に、「NuGet」などのソリューションにソリューションフォルダーを追加します(ソリューションを右クリックし、[追加]-> [新しいソリューションフォルダー])。ソリューションフォルダーは、Visual Studioソリューションにのみ存在する仮想フォルダーであり、ドライブ上に実際のフォルダーを作成しません(また、どこからでもファイルを参照できます)。 「NuGet」ソリューションフォルダーを右クリックし、[追加]-> [既存のアイテム]を選択して、\ Solutions\NuGet.Configを選択します。

これを行う理由は、それがソリューションに表示され、ソースコード管理に適切にコミットされるようにするためです。共有プロジェクトに参加しているコードベース内のソリューションごとにこの手順を実行できます。

NuGet.Configファイルを.slnファイルの上の\ Solutions \に配置することにより、NuGetが使用するNuGet.Configファイルを探して「現在の作業ディレクトリ」からフォルダー構造を再帰的にナビゲートするという事実を利用しています。ここでいう「現在の作業ディレクトリ」とは、NuGet.exeの実行パスと.slnファイルの場所の2つを意味します。

パッケージフォルダーの切り替え

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

Visual Studioでソリューションを開き、すべて再構築を開始します。発生するすべてのビルドエラーを無視します。これはこの時点で予想されています。ただし、ビルドプロセスの開始時に、NuGetパッケージの復元機能を開始する必要があります。\Solutions\Packages \フォルダーが目的の場所に作成されていることを確認します。そうでない場合は、構成を確認します。

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

  1. プロジェクトを右クリックして、プロジェクトのアンロードを選択します
  2. プロジェクトを右クリックし、「your-xxx.csprojを編集」を選択します
  3. \ packages \への参照を見つけて、新しい場所に更新します。
    • これらのほとんどは<HintPath>参照になりますが、すべてではありません。たとえば、WebGreaseとMicrosoft.Bcl.Buildには、更新する必要のある個別のパス設定があります。
  4. .csprojを保存し、プロジェクトを右クリックして[プロジェクトの再読み込み]を選択します

すべての.csprojファイルが更新されたら、別の[すべて再構築]を開始します。これにより、参照が見つからないことに関する構築エラーがなくなります。この時点で完了し、共有パッケージフォルダーを使用するようにNuGetを構成しました。

NuStudio 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)\ .nuget\NuGet.Configを開き、<configuration>セクション内に以下を追加します。

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

注:絶対パスまたは相対パスを使用できます。 1レベル下 NuGet.Configの場所に関連する$を使用した相対パスを使用している場合は、注意してください(これはバグだと考えてください)。

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

各$(SolutionDir)\ .nuget\NuGet.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

この時点で、共通の場所に単一の\ packages \フォルダーがあり、ソリューションフォルダー内にはないはずです。そうでない場合は、パスを確認してください。

プロジェクト参照の修正

すべての.csprojファイルをテキストエディターで開き、\ packagesへの参照を見つけて、正しいパスに更新します。これらのほとんどは<HintPath>参照になりますが、すべてではありません。たとえば、WebGreaseとMicrosoft.Bcl.Buildには、更新する必要のある個別のパス設定があります。

ソリューションを構築する

Visual Studioでソリューションを開き、ビルドを開始します。復元する必要のあるパッケージの欠落について不平を言う場合、パッケージが欠落しており、復元する必要があると想定しないでください(エラーは誤解を招く可能性があります)。 .csprojファイルの1つの不良パスである可能性があります。パッケージを復元する前に最初に確認してください。

不足しているパッケージに関するビルドエラーがありますか?

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

nuget restore ..\YourSolution.sln
136
Vermis

すべてのプロジェクトに共通のパッケージの場所を設定する代わりに、プロジェクトのHintPathを次のように変更することもできます。

<HintPath>$(SolutionDir)\packages\EntityFramework.6.1.0\lib\net40\EntityFramework.dll</HintPath>

ほとんどの場合、共有プロジェクトには少数のパッケージしかないため、簡単に変更できます。

コードを分岐するとき、共通レポを設定するとき、相対パスを変更する必要があります。このソリューションでは、これを行う必要はありません。

38
Adam Wyżgoł

最新バージョンのNuGet(2.7)およびVS2012でこれを試した私の経験:

  • .nu​​getフォルダーを削除します(ディスク上およびソリューション内)
  • NuGet.Configファイルをすべてのソリューションの共通の親フォルダーに配置する
  • 既存のパッケージフォルダーを削除する
  • すべてのcsprojファイルを調べて、新しい場所を指すようにHintPathsを変更します
  • 利益

私の場合、すべてのパッケージを.packagesに入れたいので、NuGet.Configは次のようになりました。

 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <config>
     <add key="repositorypath" value=".packages" />
   </config>
 </configuration>

発生する可能性のある「奇妙な」ことがいくつかあることに注意してください。

  • あるソリューションからパッケージを「更新」すると、パッケージフォルダーから古いバージョンがすぐに削除されます(そこに指している別のソリューションがあるかどうかはわかりません)。他のソリューションは必要なときに復元するだけなので、これはあまり気にしません。
  • ソリューションを右クリックしてパッケージを追加しようとすると、パッケージが別のソリューションに既に存在する場合、そのパッケージが存在することがわかり、「インストール」ボタンの代わりに「緑色のチェックマーク」が表示されます。私は通常、プロジェクトの右クリックからインストールするので、これはまったく気にしません。

免責事項:私は今日これを試してみましたが、それをバックアップする長期的な経験はありません!

21
Benjol

VS 2013でNuGetバージョン2.8.50926を使用しています。複数のnuget.configファイルを使用したり、複雑なディレクトリ構造を使用したりする必要はありません。ここにあるデフォルトファイルを変更するだけです。

%APPDATA%\Roaming\NuGet\NuGet.Config

ファイルの内容は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="repositoryPath" value="C:\Projects\nugetpackages" />
  </config>
  <activePackageSource>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </activePackageSource>
</configuration>

そのため、ソリューションの場所に関係なく、すべてのパッケージは「C:\ Projects\nugetpackages」フォルダーに移動します。

すべてのソリューションで、既存の「パッケージ」フォルダーを削除するだけです。その後、ソリューションをビルドすると、NuGetは指定された新しい中央ディレクトリに不足しているパッケージを自動的に復元します。

18
Matthieu

Nuget.targetsを変更する必要はすでにありません。 nuget 2.8で修正されました( http://nuget.codeplex.com/workitem/2921 )。リポジトリパスを設定するだけです。

8
daniel

プロジェクト内のすべてのNuGet参照を透過的に$(SolutionDir)相対形式に変換するNuGetパッケージを作成しました。これは、ビルド時のXSLT変換を使用して行われるため、プロジェクトファイルを手動でハッキングする必要はありません。パッケージは自由に更新でき、何も壊れません。

https://www.nuget.org/packages/NugetRelativeRefs

または、Visual Studio 2015 Update 3を使用している場合は、ここで説明されているように、パッケージ参照をproject.jsonフォームに移行できます。 https://oren.codes/2016/02/08/project-json-all-the -things

3
Oleg Tarasov

Visual Studio 2013 Update 4およびNugget Package Managerバージョン> 2.8.5 ...から.

リポジトリのルートにnuget.configファイルを作成します。

ファイルの内容:

<configuration>
  <config>
    <add key="repositoryPath" value="packages" />
  </config>
  <packageSources>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </packageSources>
</configuration>

これにより、すべてのパッケージがnuget.configファイルのレベルのパッケージフォルダーに移動します。

コマンド 'update-package -reinstall'を使用して、各.sln nugetコンソールにアクセスできます。

同じレベルに複数のリポジトリがあり、それらの間で同じパッケージフォルダを共有するものがある場合は、1つのフォルダを上に移動する方法を使用してください。

 <add key="repositoryPath" value="..\packages" />

しかし、この方法で、nugetパッケージがcsprojを参照するようにすると、リポジトリパスの外側にある1つのフォルダーがポイントされます。

3
user

重要なソリューションについては、上記の答えは不十分です。簡単に言うと、異なる相対パス、分岐、共有プロジェクトなどを備えた複雑なTFSワークスペース構造により、単一の中央リポジトリが不可能になります。

($ SolutionDir)を使用することは正しい方向への一歩ですが、($ SolutionDir)を使用してcsprojファイルを手動でコーディングすると、定期的に更新される数百のパッケージを含むコードベースでは非常に退屈になります(更新が発生するたびに、HintPathは上書きされます新しい相対パス)。 Update-Package -Reinstallを実行する必要がある場合はどうなりますか。

NugetReferenceHintPathRewrite と呼ばれる優れたソリューションがあります。ビルドの直前に($ prolutionDir)のHintPathへの挿入を自動化します(csprojファイルを実際に変更することはありません)。自動ビルドシステムに簡単に組み込むことができると思います

2
gravidThoughts

/ packagesを目的の共有場所にハードリンクするだけです。そうすれば、特別なパッケージの場所を持たない他のユーザーのプロジェクトが壊れることはありません。

管理者としてコマンドプロンプトを開き、使用します

mklink /prefix link_path Target_file/folder_path
2
user803469

Nuget 2.8.3での経験を更新します。比較的簡単でした。すべては、右クリックソリューションからパッケージの復元を有効にしました。 NuGet.Configを編集し、これらの行を追加しました:

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

次に、ソリューションを再構築し、すべてのパッケージを目的のフォルダーにダウンロードし、参照を自動的に更新しました。増分パッケージのみがダウンロードされ、既存のパッケージが参照される他のすべてのプロジェクトについても同じことを行いました。したがって、すべてのプロジェクトに共通のパッケージリポジトリが設定されています。

パッケージの復元を有効にする手順をステップごとに示します。

http://blogs.4ward.it/enable-nuget-package-restore-in-visual-studio-and-tfs-2012-rc-to-building-windows-8-metro-apps/ =

2

VS 2013 Professional with NuGetバージョン:2.8.60318.667

これは、パッケージを.nugetフォルダーに相対的なパスに転送する方法です。

<configuration>
  <config>
    <add key="repositoryPath" value="../Dependencies" />
  </config>
</configuration>

たとえば、ソリューション(.slnファイル)がC:\ Projects\MySolutionにある場合、NuGetパッケージの復元を有効にすると、.nugetフォルダーは次のように作成されます:C:\ Projects\MySolution.nugetとパッケージがダウンロードされます次のようなディレクトリに:C:\ Projects\MySolution\Dependencies

注:何らかの理由(不明)により、「repositoryPath」を更新するたびに、変更を有効にするためにソリューションを閉じて再度開く必要があります

1

パッケージマネージャとしてpaketを使用している場合は、依存関係ファイル用の自動シンボリックリンクオプションがあります。

storage: symlink

btw:パッケットはnugetを活用します

参照: https://fsprojects.github.io/Paket/dependencies-file.html

変更をできるだけ少なくしたい場合は、スクリプトを使用して定期的にサブディレクトリをクリーンアップできます。すなわち。 Nugetのデフォルトの動作では、ファイルをグローバルな場所からローカルパッケージフォルダーにコピーするため、これらのファイルは後で削除します。

0
sgtz