Est-il possible de changer l'emplacement des packages pour NuGet?

283

J'ai la convention suivante pour la plupart de mes projets:

/src
    /Solution.sln
    /SolutionFolder
        /Project1
        /Project2
        /etc..
/lib
    /Moq
        moq.dll
        license.txt
    /Yui-Compressor
        yui.compressor.dll
/tools
    /ILMerge
        ilmerge.exe

Vous remarquerez que je ne garde pas les bibliothèques externes dans le dossier source. Je suis également très intéressé par l'utilisation de NuGet, mais je ne veux pas que ces bibliothèques externes se trouvent dans le dossier source. NuGet a-t-il un paramètre pour changer le répertoire dans lequel tous les packages sont chargés?

TheCloudlessSky
la source
10
Oui oui oui! C'est exactement la structure du projet que j'utilise (ou très très près), et je me suis toujours demandé avec NuGet pourrait le supporter ...
Noldorin
Je suis entré dans les détails sur la façon de le faire avec cette réponse suivante: stackoverflow.com/a/19466173/564726 . Vous devez souvent supprimer l'option solutionDir de la commande de restauration pour qu'elle fonctionne correctement.
BrutalDev
2
J'ai mis le .sln au même niveau que vos dossiers de niveau supérieur. :)
Ian Warburton

Réponses:

242

Il est désormais possible de contrôler dans quel dossier les packages sont installés.

http://nuget.codeplex.com/workitem/215

Edit: Voir le commentaire de Phil Haack le 10 décembre 2010 à 23h45 (dans l'élément de travail / le lien ci-dessus). Le support est partiellement implémenté dans 1.0, mais n'est pas documenté.

Selon @dfowler: Ajoutez un fichier nuget.config à côté de la solution avec ceci:

<settings>
<repositoryPath>{some path here}</repositoryPath>
</settings>

Il existe un package nuget pour créer la substitution du dossier du package.

Mise à jour pour la version 2.1

Comme l'a commenté Azat, il existe maintenant une documentation officielle sur la façon de contrôler l'emplacement des paquets. Les notes de publication pour 2.1 spécifient la configuration suivante dans un fichier nuget.config (voir les notes de publication pour une description des emplacements valides pour placer les fichiers de configuration et comment fonctionne le modèle de configuration hiérarchique):

<configuration>
  <config>
    <add key="repositoryPath" value="C:\thePathToMyPackagesFolder" />
  </config>
  ... 
</configuration>

Cela changerait le dossier des packages pour le niveau de configuration dans lequel vous placez le fichier (solution si vous le placez dans le répertoire de la solution, projet dans le répertoire du projet, etc.). Notez que les notes de version indiquent:

[...] si vous avez un dossier de packages existant sous la racine de votre solution, vous devrez le supprimer avant que NuGet ne place les packages dans le nouvel emplacement.

PHeiberg
la source
5
Il est en fait possible d'utiliser le fichier de configuration ci-dessus. La raison pour laquelle il a été mis en évidence est que nous n'avons pas encore réfléchi au processus d'activation via l'interface utilisateur et d'autres moyens, alors attendez-vous à une certaine bizarrerie.
davidfowl
5
Voir reviewboard.nupack.com/r/131 pour une description complète par @dfowler du fonctionnement de nuget.config. Par exemple, un nuget.config valide ressemblerait à ceci: <settings><repositoryPath>lib</repositoryPath> </settings>
Lee Harold
5
docs.nuget.org/docs/release-notes/nuget-2.1 Voir le paragraphe "Spécifier l'emplacement du dossier 'packages'"
Azat
1
Je peux confirmer que la nouvelle façon de faire les choses dans 2.1+ ne fonctionne pas. Et il y a des bugs à ce sujet sur codeplex: nuget.codeplex.com/workitem/2921 .
Affaire
5
La deuxième version fonctionne pour moi, j'utilise la dernière NuGet, et maintenant deux solutions peuvent partager le même référentiel. Je pense que cela peut ne pas fonctionner pour certaines personnes car elles pourraient utiliser des chemins absolus? Il semble que le chemin absolu par rapport au chemin relatif soit important.
Csaba Toth
63
  1. Créé un fichier appelé "nuget.config".
  2. Ajout de ce fichier à mon dossier de solutions

Cela n'a pas fonctionné pour moi:

<configuration>
  <config>
    <add key="repositoryPath" value="..\ExtLibs\Packages" />
  </config>
  ... 
</configuration>

cela a fonctionné pour moi:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>
ShaneKm
la source
Pareil ici. La configuration> config n'a pas fonctionné, mais les paramètres> repositoryPath l'ont fait.
Gene Reddick
Seule la deuxième solution fonctionne: docs.nuget.org/docs/reference/nuget-config-file
cheesemacfly
15
Cela dépend de la version de NuGet que vous utilisez.
Bronumski
1
Notez que les chemins relatifs sont relatifs à la solution, donc si vos projets sont à différents niveaux, cela ne fonctionnera pas.
Nine Tails
2
Cela fonctionne bien pour VIsual Studio 2013, mais si j'utilise Visual Studio 2015, il installe toujours les packages dans le dossier packages près du fichier sln,
fhnaseer
40

D'accord pour le bien de quiconque lisant cet article - voici ce que je comprends de la myriade de réponses ci-dessus:

  1. Le fichier nuget.config dans le dossier .nuget est relatif à ce dossier. Ceci est important car si votre nouveau dossier est quelque chose comme '../Packages' qui le mettra là où il sort toujours de la boîte. Comme le dit @ bruce14, vous devez plutôt faire '../../Packages'

  2. Je n'ai pas pu obtenir le dernier nuget (2.8.5) pour trouver un dossier de packages en dehors de l'emplacement standard sans activer la restauration des packages. Ainsi, une fois que vous avez activé la restauration des packages, les éléments suivants doivent être ajoutés au fichier nuget.config à l'intérieur du dossier .nuget pour modifier l'emplacement:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
  3. (Ceci est important) Si vous apportez des modifications à l'emplacement du dossier du package à l'intérieur des fichiers nuget.config, vous devez redémarrer Visual Studio ou fermer / recharger la solution pour que les modifications prennent effet

Robert Petz
la source
5
Croyez-moi, votre point n ° 3 m'a sauvé la journée. J'étais fou des 3 dernières heures jusqu'à ce que je lise votre point # 3. : '(Merci beaucoup mon frère!
hellodear
24

Une solution pour Nuget 3.2 sur Visual Studio 2015 est:

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

Utilisation de la barre oblique pour le dossier parent. Enregistrez le fichier ci-dessus (nuget.config) dans le dossier de la solution.

La référence est disponible ici

phuongnd
la source
Parfait! Travailler pour Visual Studio 2015 et Nuget version 3.2.0.10516
Anon Dev
Vous semblez avoir voulu dire une barre oblique .. mais si la solution est sur Windows, peut-être que cette barre oblique se transforme en une barre oblique inverse, ou peut-être que la barre oblique avant était la faute de frappe et devrait changer en une barre oblique inversée.
Gerard ONeill
Je suis en 2015 et j'ai besoin d'utiliser .. \ .. \ Packages pour qu'il monte dans un dossier.
Rhyous
1
../libC'est une barre oblique, pas une barre arrière. Que voulez-vous dire?
jpmc26
Oui, c'est exactement une barre oblique. Réponse mise à jour
phuongnd
15

La solution proposée dans les notes de publication pour 2.1 ne fonctionne pas prête à l'emploi. Ils ont oublié de mentionner qu'il y a du code:

internal string ResolveInstallPath()
{
    if (!string.IsNullOrEmpty(this.OutputDirectory))
    {
        return this.OutputDirectory;
    }
    ISettings settings = this._configSettings;

    ...
}

ce qui l'empêche de fonctionner. Pour résoudre ce problème, vous devez modifier votre fichier NuGet.targets et supprimer le paramètre «OutputDirectory»:

    <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(RequireConsentSwitch)</RestoreCommand>

Alors maintenant, si vous ajoutez la configuration 'repositoryPath' quelque part dans NuGet.config (voir les notes de publication pour une description des endroits valides pour placer les fichiers de configuration), il restaure tous les packages en un seul emplacement, mais ... Votre .csproj reste contient des conseils sur les assemblages écrits sous forme de chemins relatifs ...

Je ne comprends toujours pas pourquoi ils sont allés si dur au lieu de changer PackageManager afin d'ajouter des chemins d'indication par rapport à PackagesDir. C'est ainsi que je fais manuellement pour avoir différents emplacements de packages localement (sur mon bureau) et sur l'agent de build.

<Reference Include="Autofac.Configuration, Version=2.6.3.862, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
  <Private>True</Private>
  <HintPath>$(PackagesDir)\Autofac.2.6.3.862\lib\NET40\Autofac.Configuration.dll</HintPath>
</Reference>
Dmitry Naumov
la source
1
Tu as tout à fait raison. Dans ma société, nous utilisons en fait une version de NuGet que nous avons nous-mêmes modifiée et qui fait exactement ce que vous décrivez, c'est-à-dire qu'elle ajoute des HintPaths par rapport au dossier Packages et non par rapport à l'emplacement du fichier de projet. Cela fonctionne parfaitement bien. Malheureusement, nous n'avons jamais réussi à apporter les modifications que nous avons apportées à NuGet à la version officielle, mais il est peut-être temps de le faire maintenant ...
afrischke
1
@afrischke: ce serait génial si vous pouviez faire ça. Merci. Une idée quand cela pourrait arriver?
sgtz
11

En plus de la réponse de Shane Kms, si vous avez activé la restauration de packages Nuget, vous modifiez le NuGet.config situé dans le dossier .nuget comme suit:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <repositoryPath>..\..\ExtLibs\Packages</repositoryPath>
</configuration>

Notez le ".. \" supplémentaire, car il revient en arrière du dossier .nuget et non du dossier de la solution.

utilisateur
la source
9

Aucune de ces réponses ne fonctionnait pour moi (Nuget 2.8.6) en raison du manque de quelques conseils, j'essaierai de les ajouter ici car cela pourrait être utile pour d'autres.

Après avoir lu les sources suivantes:
https://docs.nuget.org/consume/NuGet-Config-Settings
https://github.com/NuGet/Home/issues/1346
Il apparaît que

  1. Pour que le package d'installation fonctionne correctement avec différents chemins de référentiel, vous devez utiliser des barres obliques, car ils utilisent l'objet Uri pour analyser l'emplacement.
  2. Sans $ au début, il ignorait toujours mes paramètres.
  3. NuGet met en cache le fichier de configuration, donc après les modifications, vous devez recharger la solution / VS.
  4. J'ai également eu un problème étrange lors de l'utilisation de la commande de NuGet.exe pour définir cette option, car il a modifié mon NuGet.exe global sous AppData \ Roaming \ NuGet et a commencé à restaurer les packages là-bas (puisque ce fichier a une priorité plus élevée, juste deviner).

Par exemple

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

Vous pouvez également utiliser la commande NuGet pour vous assurer que la syntaxe sera correcte comme ceci:

NuGet.exe config -Set repositoryPath=$/../../../Common/packages -ConfigFile NuGet.Config
Roman Badiornyi
la source
8

Pour les projets .NET Core et Visual Studio 2017, j'ai pu restaurer tous les packages sur un chemin relatif en fournissant cette configuration:

<configuration>
  <config>
    <add key="globalPackagesFolder" value="lib" />
  </config>
  ... 
</configuration>

D'après mon expérience, le dossier lib a été créé au même niveau que celui où Nuget.config a été trouvé, peu importe où se trouvait le fichier sln. J'ai testé et le comportement est le même pour la restauration dotnet en ligne de commande et la reconstruction de Visual Studio 2017

Kirill Chilingarashvili
la source
J'ai essayé ça. J'ai défini la globalPackagesFolderclé du dossier de package de mon projet. J'ai essayé d'ajouter un seul paquet avec dotnet add package MyPackage. nuget.exetéléchargé l'intégralité du framework de 83 packages .NET dans ce dossier. Ce n'est pas ce que je voulais. Je voulais juste mon unique MyPackage dans mon dossier de package local contrôlé par la source.
Wallace Kelly
NE FAITES PAS CELA! Cela submergera votre disque dur assez rapidement car les packages de cadre entiers seront téléchargés chaque fois que vous créez une nouvelle application.
Alaa Masoud
1
selon cette réponse à une autre question: stackoverflow.com/a/47407399/4572240 "respositoryPath est utilisé pour les projets packages.config, globalPackagesFolder est utilisé pour les projets PackageReference".
Siderite Zackwehdex
7

Le fichier de configuration dans la réponse acceptée fonctionne pour moi dans VS2012. Cependant, pour moi, cela ne fonctionne que lorsque je fais ce qui suit:

  1. Créez un nouveau projet dans VS.
  2. Quittez VS - cela semble être important.
  3. Copiez les fichiers de configuration dans le dossier du projet.
  4. Redémarrez VS et ajoutez des packages.

Si je suis ces étapes, je peux utiliser un dossier de package partagé.

Harald
la source
Le redémarrage de VS est le seul moyen pour que cela fonctionne. Je suppose que le gestionnaire de packages le met en cache.
Filip
6

Afin de changer le chemin des projets utilisant PackageReference au lieu de packages.config, vous devez utiliser globalPackagesFolder

Depuis https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file

globalPackagesFolder (projets utilisant PackageReference uniquement)

Emplacement du dossier des packages globaux par défaut. La valeur par défaut est% userprofile% .nuget \ packages (Windows) ou ~ / .nuget / packages (Mac / Linux). Un chemin relatif peut être utilisé dans les fichiers nuget.config spécifiques au projet. Ce paramètre est remplacé par la variable d'environnement NUGET_PACKAGES, qui a priorité.

repositoryPath (packages.config uniquement)

L'emplacement dans lequel installer les packages NuGet au lieu du dossier par défaut $ (Solutiondir) / packages. Un chemin relatif peut être utilisé dans les fichiers nuget.config spécifiques au projet. Ce paramètre est remplacé par la variable d'environnement NUGET_PACKAGES, qui a priorité.

<config>
    <add key="globalPackagesFolder" value="c:\packageReferences" />
    <add key="repositoryPath" value="c:\packagesConfig" />
</config>

J'ai mis Nuget.config à côté de mon fichier de solution et cela a fonctionné.

Manny
la source
5

Encore une petite friandise que je viens de découvrir. (Cela peut être si basique que certains ne l'ont pas mentionné, mais c'était important pour ma solution.) Le dossier "packages" se retrouve dans le même dossier que votre fichier .sln.

Nous avons déplacé notre fichier .sln puis corrigé tous les chemins à l'intérieur pour trouver les différents projets et le tour est joué! Notre dossier de packages s'est retrouvé là où nous le voulions.

NickNuke
la source
4

MISE À JOUR pour VS 2017:

Apparemment, les gens de l'équipe Nuget ont finalement commencé à utiliser Nuget eux-mêmes, ce qui les a aidés à trouver et à corriger plusieurs choses importantes. Alors maintenant (si je ne me trompe pas, comme je n'ai toujours pas migré vers VS 2017), ce qui suit n'est plus nécessaire. Vous devriez pouvoir définir le "repositoryPath" dans un dossier local et cela fonctionnera. Même vous pouvez le laisser comme emplacement de restauration par défaut déplacé des dossiers de solution au niveau de la machine. Encore une fois - je ne l'ai toujours pas testé par moi-même

VS 2015 et versions antérieures

Juste un conseil pour d'autres réponses (en particulier ceci ):

L'emplacement du dossier NuGet Package peut être modifié via la configuration, mais VisualStudio fait toujours référence aux assemblys de ce dossier:

<HintPath>..\..\..\..\..\..\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

Pour contourner cela (jusqu'à une meilleure solution), j'ai utilisé la commande subst pour créer un lecteur virtuel qui pointe vers un nouvel emplacement du dossier Packages:

subst N: C:\Development\NuGet\Packages

Maintenant, lors de l'ajout d'un nouveau package NuGet, la référence du projet utilise son emplacement absolu:

<HintPath>N:\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath>

Remarque:

  1. Un tel lecteur virtuel sera supprimé après le redémarrage, alors assurez-vous de le gérer
  2. N'oubliez pas de remplacer les références existantes dans les fichiers de projet.
Kamarey
la source
Est-ce toujours le cas aujourd'hui? Je veux dire que nous ne pouvons pas utiliser l'emplacement absolu pour les nouveaux packages ajoutés? cette solution de lecteur virtuel me semble lourde
batmaci
Oui, toujours un cas car rien n'a changé
Kamarey
2
En fait, je préfère un chemin relatif - de cette façon, il n'y a pas de conflit dans le contrôle de code source si différents développeurs ont différents emplacements racine pour le code.
2017
Je me demande pourquoi vous ne pouvez pas faire <HintPath>$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath> au lieu d'utilisersubst
Vinod Srivastav
Je voulais que tous les paquets soient au même endroit, pas par solution
Kamarey
3

Mise à jour avec Nuget 2.8.3. Pour modifier l'emplacement des packages installés, j'ai activé la restauration des packages à partir de la solution de clic droit. Modifié NuGet.Config et ajouté ces lignes:

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

Puis reconstruit la solution, il a téléchargé tous les packages dans mon dossier souhaité et mis à jour les références automatiquement.

amarnath chatterjee
la source