Création d'un répertoire commun de paquets nuget pour toutes les solutions lorsque certains projets sont inclus dans plusieurs solutions

J'ai utilisé NuGet pour récupérer des paquets à partir de sources externes et internes, ce qui est très pratique. Mais j'ai réalisé que les paquets sont par défaut stockés par solution, ce qui est très frustrant lorsque certains projets avec des références NuGet sont inclus dans plusieurs solutions. Ensuite, les références sont changées dans un autre dossier package solutions qui peut être indisponible pour un autre développeur ou une autre machine de construction.

j'ai vu qu'il y a moyens de faire ressortir un emplacement commun du paquet (peut-être au niveau de la racine du projet, nous utilisons le contrôle source de TFS) avec la version 2.1 de NuGet, voir notes de version . J'utilise NuGet v2.7

Mais j'ai essayé d'ajouter nuget.fichiers de configuration sans voir aucun effet de cela. Les paquets sont encore stockés dans le dossier solution. Est-il quelque chose que j'ai raté? Il semble y avoir différentes structures du noeud xml à ajouter au nuget.fichier de configuration, selon qui répond à cette question?: Schwarzie suggère sur un autre fil continu :

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

les notes de version pour NuGet 2.1 (voir lien ci-dessus) suggèrent ce format:

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

Je ne sais pas lequel de ceux-ci, ou n'importe lequel, ou les deux fonctionneront à la fin. J'ai essayé les deux, au niveau de la solution. Peut le nuget.le fichier de configuration doit être placé au niveau de la racine du projet TFS, ou doit-il être dans le répertoire solution? Il semble que NuGet lit et applique les paramètres à partir de ces fichiers dans un certain ordre, pourquoi il serait judicieux d'ajouter à plusieurs niveaux, où un nuget.le fichier de configuration au niveau de la solution l'emporterait sur un au niveau de la racine du projet TFS. Cela peut-il être précisé?

Dois-je supprimer tous les paquets installés devant ces références? J'aimerais que quelqu'un puisse fournir une instruction étape par étape pour passer de l'utilisation nuget spécifique à une solution à un dossier de paquet commun où les projets qui appartiennent à plusieurs solutions peuvent trouver leurs packages nuget.

117
demandé sur Community 2013-08-22 13:18:32

13 réponses

j'ai une situation similaire, avec interne et externe des sources de paquets avec des projets référencés dans plus d'une solution. Je viens juste de le faire fonctionner avec une de nos bases de code aujourd'hui et il semble fonctionner avec les postes de travail des développeurs et notre serveur de construction. Le processus ci-dessous a ce scénario à l'esprit (bien qu'il ne soit pas difficile de s'adapter pour avoir le dossier commun des paquets else where).

  • Codebase
    • Projet A
    • Projet B
    • Projet C
    • Solutions
      • Solution 1
      • Solution 2
      • Solution 3
      • Paquets (c'est la commune partagée par toutes les solutions)

mise à jour de la réponse à partir de NuGet 3.5.0.1484 avec Visual Studio 2015 Mise À Jour 3

ce processus est un peu plus facile maintenant que lorsque j'ai abordé à l'origine cette question et j'ai pensé qu'il était temps de le mettre à jour. En général, le processus est le même, juste avec moins d'étapes. Le résultat est un processus qui résout ou fournit ce qui suit:

  • Tout ce qui doit être affecté au contrôle du code source est visible et suivi dans la solution
  • installer de nouveaux paquets ou mettre à jour des paquets en utilisant le Gestionnaire de paquets dans Visual Studio utilisera le chemin correct du dépôt
  • après la configuration initiale, pas de piratage .csproj files
  • aucune modification du poste de travail du développeur (le Code est construit prêt à la sortie)

il y a des inconvénients potentiels dont il faut être conscient (Je ne les ai pas encore vécus, YMMV). Voir Benol's réponse et commentaires ci-dessous.

Ajouter NuGet.Config

vous voulez créer un NuGet.Fichier de configuration dans la racine du dossier \Solutions\. Assurez-vous qu'il s'agit d'un fichier encodé UTF-8 que vous créez, si vous ne savez pas comment le faire, utilisez le menu Fichier->Nouveau - >de Visual Studio et choisissez ensuite le modèle de fichier XML. Ajouter à NuGet.Config suivante:

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

pour le paramètre de chemin de repositoryPath, vous pouvez spécifier un chemin absolu ou un chemin relatif (recommandé) en utilisant le token$. Le $ token est basé sur où est le NuGet?Config est situé (le token $ est en fait relatif à un niveau en dessous de l'emplacement du NuGet.Config). Donc, si j'ai \Solutions\NuGet.Config et je veux \Solutions\Packages j'aurais besoin de spécifier $\..\Packages comme valeur.

ensuite, vous voudrez ajouter un dossier Solution à votre solution appelé quelque chose comme" NuGet " (clic droit sur votre solution, Ajouter->nouveau dossier Solution). Les dossiers de Solution sont des dossiers virtuels qui existe dans la solution Visual Studio et ne créera pas un dossier réel sur le lecteur (et vous pouvez référencer les fichiers de n'importe où). Cliquez avec le bouton droit de la souris sur le dossier de la solution "NuGet", puis ajoutez->L'élément existant et sélectionnez \Solutions\NuGet.Config.

La raison pour laquelle nous le faisons, c'est qu'il est visible dans la solution et devrait aider à s'assurer qu'il est correctement engagé à votre contrôle de code source. Vous pouvez faire cette étape pour chaque solution dans votre base de code qui est participer à vos projets communs.

en plaçant le NuGet.Fichier de Config dans \Solutions\ au-dessus de tout .sln files, nous profitons du fait que NuGet va naviguer récursivement la structure du dossier vers le haut à partir du "répertoire de travail courant" à la recherche d'un NuGet.Fichier de configuration à utiliser. Le "répertoire de travail courant" signifie deux choses différentes ici, l'une est le chemin D'exécution de NuGet.exe et l'autre est la situation de l' .la sln fichier.

changement de dossier de vos paquets

tout d'abord, je vous recommande fortement de parcourir chacun de vos dossiers de solution et de supprimer tout \Packages\ dossiers qui existent (vous aurez besoin de fermer Visual Studio d'abord). Cela permet de voir plus facilement où NuGet place votre nouveau répertoire \Packages et garantit que tout lien vers le mauvais répertoire\ Packages échouera et pourra alors être corrigé.

ouvrez votre solution dans Visual Studio et Tout Reconstruire. Ignorez toutes les erreurs de compilation que vous recevrez, ceci est attendu à ce point. Cela devrait toutefois déclencher la fonction de restauration du paquet NuGet au début du processus de compilation. Vérifiez que votre répertoire \Solutions\Packages\ folder a été créé à l'endroit voulu. Si ce n'est pas le cas, examinez votre configuration.

maintenant, pour chaque projet dans votre solution vous voudrez:

  1. droit-cliquez sur le projet et sélectionnez décharger le projet
  2. faites un clic droit sur le projet et sélectionnez Modifier votre-xxx.1519130920"
  3. trouvez toute référence à \packages\ et mettez-les à jour vers le nouvel emplacement.
    • la plupart de ces références seront , mais pas toutes. Par exemple, WebGrease et Microsoft.Bcl.Build aura des paramètres de chemin séparés qui devront être mis à jour.
  4. Enregistrer la .csproj et puis droit-cliquez sur le projet et sélectionnez Recharger Projet

une fois tous vos .les fichiers csproj ont été mis à jour, lancer une autre reconstruction et vous ne devriez plus avoir d'erreurs de compilation sur les références manquantes. À ce stade, vous avez terminé, et vous avez maintenant NuGet configuré pour utiliser un dossier paquets partagés.

à partir de NuGet 2.7.1 (2.7.40906.75) avec VStudio 2012

la première chose à garder à l'esprit est que nuget.config ne contrôle pas tout des paramètres de chemin dans le système de paquets nuget. C'était particulièrement déroutant à comprendre. Plus précisément, le problème est que msbuild et Visual Studio (appelé msbuild) n'utilisent pas le chemin dans nuget.config mais plutôt primordial dans la nuget.le fichier des cibles.

Préparation De L'Environnement

tout d'abord, je vais parcourir le dossier de votre solution et supprimer tous les \packages\ folders qui existent. Cela permettra de s'assurer que tous les paquets sont visiblement installation dans le bon dossier et pour vous aider à découvrir toutes les références de mauvais chemin à travers vos solutions. Ensuite, je voudrais m'assurer que vous avez la dernière extension de studio visuel nuget installé. Je m'assurerais aussi que vous ayez le dernier nuget.exe installé dans chaque solution. Ouvrez une invite de commande et allez dans chaque $(SolutionDir)\ .nuget \ folder et exécuter la commande suivante:

nuget update -self

définition du chemin du dossier du paquet commun pour NuGet

Ouvrez chaque $(SolutionDir)\ .nuget\NuGet.Config et ajouter ce qui suit dans la section < configuration>:

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

Note: vous pouvez utiliser un chemin absolu ou un chemin relatif. Gardez à l'esprit, si vous utilisez un chemin relatif avec $ qu'il est relatif à un niveau sous l'emplacement du NuGet.Config (croyez que c'est un bug).

définir le dossier de paquet commun chemin pour MSBuild et studio visuel

ouvrir chaque $(SolutionDir)\ .nuget\NuGet.cibler et modifier la section suivante (notez que pour les non-fenêtres il y a une autre section Sous elle):

<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>

mise à Jour PackagesDir être

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

Note: le GetFullPath résoudra notre chemin relatif en un chemin absolu.

restauration de tous les nuget packages dans le dossier commun

ouvrez une invite de commande et allez à chaque $(SolutionDir)\ .nuget et exécuter la commande suivante:

nuget restore ..\YourSolution.sln

à ce stade, vous devriez avoir un seul \packages\ folder dans votre emplacement commun et aucun dans l'un de vos dossiers de solution. Si non, alors vérifiez vos chemins d'accès.

fixation des références du projet

ouvert tous .fichier csproj dans un éditeur de texte et trouver n'importe quel références aux paquets \et mettez-les à jour vers le chemin correct. La plupart d'entre eux seront des références , mais pas tous. Par exemple, WebGrease et Microsoft.Bcl.Build aura des paramètres de chemin séparés qui devront être mis à jour.

Construisez votre solution

ouvrez votre solution dans Visual Studio et démarrez une construction. Si elle se plaint de paquets manquants qui doivent être restaurés, ne supposez pas que le paquet est manquant et doit être restauré (erreur peut être trompeuse). Il pourrait être un mauvais chemin dans un de vos .dossiers csproj. Vérifiez cela avant de restaurer le paquet.

avez-vous une erreur de compilation à propos des paquets manquants?

si vous avez déjà vérifié que les chemins dans votre .csproj fichiers sont corrects, alors vous avez deux options pour essayer. Si c'est le résultat de la mise à jour de votre code à partir du contrôle du code source, alors vous pouvez essayer de vérifier une copie propre et ensuite construire cela. Cela a fonctionné pour l'un de nos développeurs et je pense qu'il y a un artefact dans le .suo file ou quelque chose comme ça. L'autre option consiste à forcer manuellement la restauration d'un paquet en utilisant la ligne de commande dans le .nuget dossier de la solution en question:

nuget restore ..\YourSolution.sln
129
répondu Vermis 2017-05-23 12:02:57

au lieu de définir un emplacement de paquet commun pour tous les projets, il est également possible de changer HintPath dans le projet comme suit:

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

dans la plupart des cas, il n'y a que peu de paquets dans le projet partagé, donc vous pouvez facilement le modifier.

je pense que c'est une meilleure solution, lorsque vous brancher le code, lors de la mise en place repo commune, vous devez changer le chemin relatif, dans cette solution vous n'avez pas besoin de faire cela.

35
répondu Adam Wyżgoł 2014-09-18 11:15:15

mon expérience avec la dernière version de NuGet (2.7) et VS2012:

  • supprimer le .nuget folder (sur disque et en solution)
  • mettez un NuGet.Fichier de configuration dans un dossier parent commun à toutes les solutions
  • supprimer tous les dossiers packages existants
  • parcourir tous les fichiers csproj et changer HintPaths pour pointer vers le nouvel emplacement
  • à but Lucratif

dans mon cas, je voulais mettre tous les paquets dans .packages , donc mon NuGet.Config ressemblait à ci-dessous.

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

notez qu'il y a des choses "étranges" qui peuvent arriver, mais je pense qu'elles sont supportables:

  • si vous "mettez à jour" un paquet à partir d'une solution, il supprimera rapidement l'ancienne version de votre dossier packages (il ne peut pas savoir si vous avez une autre solution qui pointe là). Ce n'est pas dérangez-moi beaucoup, car l'autre solution ne fera que restaurer Quand nécessaire.
  • si vous essayez d'ajouter un paquet à partir du clic-droit sur la solution, si le paquet est déjà présent dans une autre solution, il verra qu'il est là et vous montrera le 'green tick' au lieu du bouton 'install'. J'installe d'habitude à partir du clic droit sur le projet, donc ça ne me dérange pas du tout.

clause de non-responsabilité : je viens d'essayer ceci aujourd'hui, je ne toute l'expérience à long terme pour la sauvegarder!

20
répondu Benjol 2013-12-19 05:33:41

j'ai NuGet version 2.8.50926 avec VS 2013. Vous n'avez pas besoin d'utiliser plusieurs nuget.fichiers de configuration, ou utiliser des structures de répertoires complexes. Il suffit de modifier le fichier par défaut situé ici:

%APPDATA%\Roaming\NuGet\NuGet.Config

Voici le contenu de mon fichier:

<?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>

donc tous les paquets vont à la "C:\Projects\nugetpackages" dossier, peu importe où se trouve la solution.

dans toutes vos solutions, supprimez simplement les dossiers" paquets " existants. Puis construisez votre solution, et NuGet restaurera automatiquement les paquets manquants dans le nouveau répertoire centralisé que vous avez spécifié.

18
répondu Matthieu 2016-04-21 21:22:26

déjà il n'y a pas besoin de modifier nuget.cible. Il a été fixé dans nuget 2.8 ( http://nuget.codeplex.com/workitem/2921 ). Vous n'avez qu'à configurer le chemin de repositorypath.

8
répondu daniel 2014-02-07 14:42:23

j'ai concocté un paquet NuGet qui convertit de manière transparente toutes les références NuGet dans un projet en un format relatif $(SolutionDir). Il le fait en utilisant build-time XSLT transform, de sorte que vous n'avez pas besoin de hacker votre dossier de projet à la main. Vous pouvez mettre à jour vos paquets librement, il cassera rien.

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

ou vous si vous utilisez Visual Studio 2015 Update 3, vous pouvez simplement migrer les références de votre paquet au formulaire project.json tel que décrit ici: https://oren.codes/2016/02/08/projet-json-toutes-les-choses

3
répondu Oleg Tarasov 2016-09-29 11:34:45

mise à jour de mon expérience avec nuget 2.8.3. C'était relativement simple. Tout ce qui a été fait était activé restauration de paquet de la solution de clic droit. Edited NuGet.Config et a ajouté ces lignes:

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

a ensuite reconstruit la solution, il a téléchargé tous les paquets dans mon dossier désiré et mis à jour les références automatiquement. J'ai fait la même chose pour tous mes autres projets, où seuls les paquets incrémentiels ont été téléchargés et les paquets existants ont été référencés. Par conséquent, un référentiel de paquets commun pour tous les projets a été défini.

Voici une procédure étape par étape pour activer la restauration du paquet.

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

2
répondu amarnath chatterjee 2014-11-09 05:56:35

From Visual Studio 2013 Update 4 and Nugget Package Manager version > 2.8.5...

créer nuget.fichier de configuration à la racine du dépôt.

contenu du fichier:

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

cela provoquera que tous les paquets iront dans le dossier packages au niveau de votre nuget.fichier de configuration.

maintenant, vous pouvez choisir chacun .sln nuget console avec la commande 'update-package-reinstall '

si vous comme plusieurs référentiel au même niveau et que de partager le même dossier du package à travers eux, essayez d'utiliser de manière à aller au dossier suivant.

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

mais de cette façon vous provoquez que la référence de paquet nuget csproj pointe un dossier à l'extérieur de votre chemin de repositorys.

2
répondu user 2015-10-02 18:08:17

juste le lien dur /paquets à l'emplacement partagé désiré. Ensuite, votre projet ne sera pas rompu pour d'autres utilisateurs, qui n'ont pas de forfaits spéciaux emplacement.

Ouvrir une invite de commande en tant qu'administrateur et utiliser

mklink /prefix link_path Target_file/folder_path
2
répondu user803469 2016-01-23 19:36:36

pour toute solution significative, les réponses ci-dessus seront insuffisantes. Tout simplement, une structure complexe de l'espace de travail TFS avec des chemins relatifs différents, des ramifications, des projets partagés, etc. rendre impossible un dépôt central unique.

utiliser ($SolutionDir) est un pas dans la bonne direction, mais coder à la main le fichier csproj avec ($SolutionDir) deviendrait assez fastidieux dans une base de code avec des centaines de paquets qui sont mis à jour régulièrement (chaque mise à jour se produit, le HintPath est écrasé par un nouveau chemin relatif). Que se passe-t-il si vous devez exécuter Update-Package-reinstaller.

il y a une grande solution appelée NugetReferenceHintPathRewrite . Il automatise l'injection de ($SolutionDir) dans les HintPaths juste avant la construction (sans changer le fichier csproj). J'imagine qu'il pourrait facilement être intégré dans des systèmes de construction automatisée

2
répondu gravidThoughts 2016-08-08 21:11:07

un court résumé pour ceux sur VS 2013 professionnel avec NuGet Version: 2.8.60318.667

c'est ainsi que vous dirigeriez les paquets vers un chemin relatif à la .dossier nuget:

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

par exemple, si votre solution (.le fichier sln) réside en C:\Projects\MySolution, lorsque vous activez la restauration du paquet NuGet, le .nuget dossier est créé comme: C:\Projects\MySolution.nuget et les paquets seront téléchargés dans un répertoire comme suit: C:\Projects\MySolution\Dependencies

NOTE: pour une raison (inconnue), chaque fois que je mets à jour le "chemin du référencement", je dois fermer et rouvrir la solution pour que les changements entrent en vigueur

1
répondu dotnetguy 2015-06-12 01:39:32

pour ceux qui utilisent paket comme gestionnaire de paquets, il y a une option de lien automatique pour votre fichier de dépendances:

storage: symlink

btw: paket exploite nuget

référence: https://fsprojects.github.io/Paket/dependencies-file.html

si vous voulez modifier le moins possible, vous pouvez simplement nettoyer les sous-répertoires périodiquement avec un script. IE. Le comportement par défaut de Nuget est de copier des fichiers d'un emplacement global à un dossier packages local, supprimez donc ces fichiers après.

0
répondu sgtz 2018-07-12 22:53:58

ce sont les instructions à partir de NuGet 2.1: http://docs.nuget.org/docs/release-notes/nuget-2.1

pas besoin de modifier les fichiers au niveau de la solution.

travaille avec Visual Studio 2013 et trois projets de partage de solutions.

N'oubliez pas de mettre à jour le niveau de solution NuGet (chaque nuget.exe en .nuget dossiers).

-1
répondu user3285954 2014-06-06 14:09:47