Czy można zmienić lokalizację pakietów dla NuGet?

283

Dla większości moich projektów mam następującą konwencję:

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

Zauważysz, że nie przechowuję bibliotek zewnętrznych w folderze źródłowym. Jestem również bardzo zainteresowany korzystaniem z NuGet, ale nie chcę tych zewnętrznych bibliotek w folderze źródłowym. Czy NuGet ma ustawienie umożliwiające zmianę katalogu, w którym ładowane są wszystkie pakiety?

TheCloudlessSky
źródło
10
Tak tak tak! To jest właśnie struktura projektu, której używam (lub bardzo bardzo), i zawsze zastanawiałem się, czy NuGet może ją obsługiwać ...
Noldorin
Omówiłem szczegółowo, jak to zrobić, korzystając z następującej odpowiedzi: stackoverflow.com/a/19466173/564726 . Często trzeba usunąć opcję solutionDir z polecenia restore, aby działała poprawnie.
BrutalDev,
2
Umieszczam plik .sln na tym samym poziomie, co foldery najwyższego poziomu. :)
Ian Warburton,

Odpowiedzi:

242

Teraz można kontrolować, w którym folderze są zainstalowane pakiety.

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

Edycja: Zobacz komentarz Phila Haacka z 10 grudnia 2010 o 23.45 (w elemencie pracy / linku powyżej). Wsparcie jest częściowo zaimplementowane w wersji 1.0, ale nie jest udokumentowane.

Według @dfowler: Dodaj plik nuget.config obok rozwiązania w ten sposób:

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

Istnieje pakiet nuget do tworzenia zastąpienia folderu pakietu.

Aktualizacja do wersji 2.1

Jak skomentował Azat, istnieje teraz oficjalna dokumentacja na temat kontrolowania lokalizacji paczek. Informacje o wersji 2.1 zawierają następującą konfigurację w pliku nuget.config (informacje o wersji zawierają opis prawidłowych miejsc do umieszczenia plików konfiguracji i działania hierarchicznego modelu konfiguracji):

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

Spowoduje to zmianę folderu pakietów dla poziomu konfiguracji, w którym umieścisz plik (rozwiązanie, jeśli umieścisz go w katalogu rozwiązania, projekt w katalogu projektu i tak dalej). Zauważ, że informacje o wydaniu stanowią:

[...] jeśli masz folder pakietów pod katalogiem głównym rozwiązania, musisz go usunąć, zanim NuGet umieści pakiety w nowej lokalizacji.

PHeiberg
źródło
5
W rzeczywistości jest to możliwe przy użyciu powyższego pliku konfiguracyjnego. Powodem, dla którego nie podkreślono, jest to, że nie zastanawialiśmy się przez cały proces włączania tego za pomocą interfejsu użytkownika i innych środków, więc spodziewaj się dziwactwa.
davidfowl
5
Zobacz reviewboard.nupack.com/r/131, aby uzyskać pełny opis @dfowler na temat działania nuget.config. Na przykład poprawny plik nuget.config mógłby wyglądać następująco: <zestawienia><repositoryPath>lib</repositoryPath> </settings>
Lee Harold
5
docs.nuget.org/docs/release-notes/nuget-2.1 Patrz akapit „Określanie lokalizacji folderów z pakietami”
Azat,
1
Mogę potwierdzić, że nowy sposób robienia rzeczy w wersji 2.1+ nie działa. Są też błędy w codeplex: nuget.codeplex.com/workitem/2921 .
Sprawa
5
Druga wersja działa dla mnie, używam najnowszego NuGet, a teraz dwa rozwiązania mogą współdzielić to samo repo. Myślę, że niektórzy ludzie mogą nie działać, ponieważ mogą korzystać ze ścieżek bezwzględnych? Wygląda na to, że ścieżka bezwzględna i względna ma znaczenie.
Csaba Toth
63
  1. Utworzono plik o nazwie „nuget.config”.
  2. Dodano ten plik do mojego folderu rozwiązań

to NIE działało dla mnie:

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

to zadziałało dla mnie:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>
ShaneKm
źródło
To samo tutaj. Konfiguracja> config nie działała, ale ustawienia> repositoryPath działały.
Gene Reddick
Tylko drugie rozwiązanie działa: docs.nuget.org/docs/reference/nuget-config-file
cheesemacfly
15
To zależy od używanej wersji NuGet.
Bronumski
1
Pamiętaj, że ścieżki względne są względne w stosunku do rozwiązania, więc jeśli Twoje projekty są na różnych poziomach, to nie zadziała.
Dziewięć ogonów
2
Działa to dobrze dla VIsual Studio 2013, ale jeśli używam Visual Studio 2015, to nadal instaluję pakiety w folderze pakietów w pobliżu pliku sln,
fhnaseer
40

Okej, ze względu na każdego, kto czyta ten post - oto, co rozumiem z niezliczonej liczby powyższych odpowiedzi:

  1. Plik nuget.config w folderze .nuget jest względny w stosunku do tego folderu. Jest to ważne, ponieważ jeśli twój nowy folder to coś w rodzaju „../Packages”, umieści go tam, gdzie zawsze wychodzi po wyjęciu z pudełka. Jak stwierdza @ bruce14, musisz zamiast tego zrobić „../../Pakiety”

  2. Nie mogłem pobrać najnowszego nugetu (2.8.5), aby znaleźć folder paczek poza standardową lokalizacją bez włączenia przywracania pakietu. Dlatego po włączeniu przywracania pakietu należy dodać do pliku nuget.config w folderze .nuget, aby zmienić lokalizację:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
  3. (Jest to ważne) Jeśli wprowadzisz DOWOLNE zmiany w lokalizacji folderu pakietu w plikach nuget.config, musisz ponownie uruchomić program Visual Studio lub zamknąć / ponownie załadować rozwiązanie, aby zmiany zostały wprowadzone

Robert Petz
źródło
5
Zaufaj mi, twój punkt 3 uratował mi dzień. Byłem szalony przez ostatnie 3 godziny, dopóki nie przeczytałem twojego punktu 3. : „(Dziękuję bardzo bracie!
hellodear
24

Rozwiązaniem dla Nuget 3.2 w Visual Studio 2015 jest:

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

Używanie ukośnika dla folderu nadrzędnego. Zapisz powyższy plik (nuget.config) w folderze rozwiązania.

Referencje są dostępne tutaj

phuongnd
źródło
Idealny! Praca dla Visual Studio 2015 i Nuget w wersji 3.2.0.10516
Anon Dev,
Wydaje się, że miałeś na myśli ukośnik do przodu .. ale jeśli rozwiązaniem jest system Windows, być może ukośnik zamienia się w odwrotny, a może ukośnik był literówką i powinien zmienić się na odwrotny.
Gerard ONeill
Jestem w 2015 roku i muszę użyć .. \ .. \ Pakiety, aby przejść o jeden folder w górę.
Rhyous,
1
../libTo jest ukośnik do przodu, a nie do tyłu. Co masz na myśli
jpmc26,
Tak, to jest dokładnie ukośnik. Zaktualizowana odpowiedź
phuongnd
15

Rozwiązanie zaproponowane w informacjach o wersji 2.1 nie działa od razu po wyjęciu z pudełka. Zapomnieli wspomnieć, że istnieje kod:

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

    ...
}

co uniemożliwia mu działanie. Aby to naprawić, musisz zmodyfikować plik NuGet.targets i usunąć parametr „OutputDirectory”:

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

Więc teraz, jeśli dodasz konfigurację „repositoryPath” gdzieś w NuGet.config (zobacz uwagi do wydania, aby znaleźć opis prawidłowych miejsc do umieszczenia plików konfiguracyjnych), przywróci wszystkie pakiety w jedną lokalizację, ale ... Twój .csproj nadal zawiera wskazówki do zespołów zapisanych jako ścieżki względne ...

Nadal nie rozumiem, dlaczego przeszli ciężką drogę zamiast zmiany PackageManagera, aby dodać ścieżki wskazówek względem PackagesDir. W ten sposób robię ręcznie, aby lokalnie mieć różne lokalizacje pakietów (na pulpicie) i agenta kompilacji.

<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>
Dmitrij Naumow
źródło
1
Masz absolutną rację. W mojej firmie faktycznie korzystamy z wersji NuGet, którą sami zmodyfikowaliśmy, która robi dokładnie to, co opisujesz, tj. Dodaje ścieżki HintPath względem katalogu pakietów nie zależne od położenia pliku projektu. Działa to doskonale. Niestety, nigdy nie próbowaliśmy wprowadzić zmian, które wprowadziliśmy w NuGet do oficjalnej wersji, ale może już czas to zrobić ...
afrischke
1
@afrischke: byłoby świetnie, gdybyś mógł to zrobić. dzięki. Masz pomysł, kiedy to się stanie?
sgtz
11

Oprócz odpowiedzi Shane Kms, jeśli aktywowałeś Przywracanie pakietu Nuget, edytujesz NuGet.config znajdujący się w folderze .nuget w następujący sposób:

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

Zwróć uwagę na dodatkowy „.. \”, ponieważ jest on odtwarzany z folderu .nuget, a nie z folderu rozwiązania.

użytkownik
źródło
9

Żadna z tych odpowiedzi nie działała dla mnie (Nuget 2.8.6) z powodu braku niektórych wskazówek, postaram się je tutaj dodać, ponieważ mogą być przydatne dla innych.

Po przeczytaniu następujących źródeł:
https://docs.nuget.org/consume/NuGet-Config-Settings
https://github.com/NuGet/Home/issues/1346
Wygląda na to, że

  1. Aby działający pakiet instalacyjny działał poprawnie z inną ścieżką repozytorium, musisz użyć forward ukośników , ponieważ używają obiektu Uri do analizowania lokalizacji.
  2. Bez $ początku wciąż ignorowało moje ustawienia.
  3. NuGet buforuje plik konfiguracyjny, więc po modyfikacji należy ponownie załadować rozwiązanie / VS.
  4. Miałem również dziwny problem podczas używania polecenia NuGet.exe, aby ustawić tę opcję, ponieważ zmodyfikowałem mój globalny NuGet.exe w AppData \ Roaming \ NuGet i zacząłem tam przywracać pakiety (ponieważ ten plik ma wyższy priorytet, po prostu zgaduję).

Na przykład

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

Możesz także użyć polecenia NuGet, aby upewnić się, że składnia będzie poprawna w następujący sposób:

NuGet.exe config -Set repositoryPath=$/../../../Common/packages -ConfigFile NuGet.Config
Roman Badiornyi
źródło
8

W przypadku projektów .NET Core i Visual Studio 2017 udało mi się przywrócić wszystkie pakiety do ścieżki względnej, podając tę ​​konfigurację:

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

Z mojego doświadczenia wynika, że ​​folder lib został utworzony na tym samym poziomie, na którym znaleziono Nuget.config, bez względu na to, gdzie był plik SLN. Przetestowałem i zachowanie jest takie samo w przypadku przywracania dotnet z wiersza poleceń i przebudowywania programu Visual Studio 2017

Kirill Chilingarashvili
źródło
Próbowałem tego. Ustawiam globalPackagesFolderklucz do folderu pakietu mojego projektu. Próbowałem dodać jeden pakiet z dotnet add package MyPackage. nuget.exepobrałem całą strukturę 83 pakietów .NET do tego folderu. Nie o to mi chodziło. Chciałem tylko mój pojedynczy MyPackage w moim lokalnym, kontrolowanym przez źródło folderze pakietu.
Wallace Kelly,
NIE RÓB TEGO! To dość szybko przytłoczy twój dysk twardy, ponieważ całe pakiety frameworka będą pobierane za każdym razem, gdy tworzysz nową aplikację.
Alaa Masoud
1
zgodnie z odpowiedzią na inne pytanie: stackoverflow.com/a/47407399/4572240 „ścieżka repositoryPath jest używana dla projektów packages.config, globalPackagesFolder jest używany dla projektów PackageReference”.
Siderite Zackwehdex
7

Plik konfiguracyjny w zaakceptowanej odpowiedzi działa dla mnie w VS2012. Jednak dla mnie działa to tylko wtedy, gdy wykonuję następujące czynności:

  1. Utwórz nowy projekt w VS.
  2. Wyjdź VS - wydaje się to ważne.
  3. Skopiuj pliki konfiguracyjne do folderu projektu.
  4. Uruchom ponownie VS i dodaj pakiety.

Jeśli wykonam te kroki, mogę użyć udostępnionego folderu pakietu.

Harald
źródło
Ponowne uruchomienie VS to jedyny sposób, w jaki udało mi się to zrobić. Zgadnij, że menedżer pakietów to buforuje.
Filip
6

Aby zmienić ścieżkę dla projektów korzystających z PackageReference zamiast paczek.config, musisz użyć globalPackagesFolder

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

globalPackagesFolder (projekty wykorzystujące tylko PackageReference)

Lokalizacja domyślnego folderu pakietów globalnych. Domyślnie jest to% userprofile% .nuget \ packages (Windows) lub ~ / .nuget / packages (Mac / Linux). Ścieżka względna może być używana w specyficznych dla projektu plikach nuget.config. To ustawienie jest zastępowane przez zmienną środowiskową NUGET_PACKAGES, która ma pierwszeństwo.

repositoryPath (tylko pakiety.config)

Miejsce, w którym należy zainstalować pakiety NuGet zamiast domyślnego folderu $ (Solutiondir) / packages. Ścieżka względna może być używana w specyficznych dla projektu plikach nuget.config. To ustawienie jest zastępowane przez zmienną środowiskową NUGET_PACKAGES, która ma pierwszeństwo.

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

Nuget.config umieściłem obok mojego pliku rozwiązania i zadziałało.

Manny
źródło
5

Jeszcze jeden mały smakołyk, który właśnie odkryłem. (Może to być tak podstawowe, że niektórzy o tym nie wspomnieli, ale było to ważne dla mojego rozwiązania.) Folder „paczki” kończy się w tym samym folderze, co plik .sln.

Przenieśliśmy nasz plik .sln, a następnie naprawiliśmy wszystkie ścieżki wewnątrz, aby znaleźć różne projekty i voila! Nasz folder paczek znalazł się tam, gdzie chcieliśmy.

NickNuke
źródło
4

AKTUALIZACJA VS VS 2017:

Wygląda na to, że ludzie w zespole Nuget w końcu zaczęli używać Nuget, co pomogło im znaleźć i naprawić kilka ważnych rzeczy. Więc teraz (jeśli się nie mylę, ponieważ nadal nie migrowałem do VS 2017) poniżej nie jest już konieczne. Powinieneś być w stanie ustawić „repositoryPath” na folder lokalny i to zadziała. Nawet Ty możesz go w ogóle zostawić, ponieważ domyślnie przywrócono lokalizację przeniesioną z folderów rozwiązania na poziom komputera. Znowu - wciąż nie testowałem tego sam

VS 2015 i wcześniejsze

Tylko wskazówka do innych odpowiedzi (szczególnie tego ):

Położenie folderu pakietu NuGet można zmienić poprzez konfigurację, ale VisualStudio nadal odwołuje się do zestawów w tym folderze względnie:

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

Aby obejść to (do lepszego rozwiązania), użyłem polecenia subst, aby utworzyć dysk wirtualny, który wskazuje na nową lokalizację folderu Packages:

subst N: C:\Development\NuGet\Packages

Teraz podczas dodawania nowego pakietu NuGet odwołanie do projektu używa jego bezwzględnej lokalizacji:

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

Uwaga:

  1. Taki dysk wirtualny zostanie usunięty po ponownym uruchomieniu, więc upewnij się, że sobie z nim poradzisz
  2. Nie zapomnij zastąpić istniejących odniesień w plikach projektu.
Kamarey
źródło
Czy nadal tak jest dzisiaj? Mam na myśli to, że nie możemy użyć lokalizacji absoulute dla nowych dodanych pakietów? to rozwiązanie dla wirtualnych napędów wydaje mi się kłopotliwe
batmaci,
Tak, wciąż sprawa, ponieważ nic się nie zmieniło
Kamarey
2
Właściwie wolę ścieżkę względną - w ten sposób nie ma konfliktu w kontroli źródła, jeśli różni programiści mają różne lokalizacje root dla kodu.
jbyrd
Zastanawiam się, dlaczego nie możesz zrobić <HintPath>$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath> zamiast używaćsubst
Vinod Srivastav
Chciałem, aby wszystkie paczki były w jednym miejscu, a nie w jednym rozwiązaniu
Kamarey
3

Właśnie aktualizuję za pomocą Nuget 2.8.3. Aby zmienić lokalizację zainstalowanych pakietów, włączyłem przywracanie pakietów z poziomu rozwiązania klikając prawym przyciskiem myszy. Edytowałem NuGet.Config i dodałem następujące linie:

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

Następnie przebudowałem rozwiązanie, pobrałem wszystkie pakiety do mojego pożądanego folderu i automatycznie zaktualizowałem referencje.

amarnath chatterjee
źródło