É possível alterar a localização dos pacotes para o NuGet?

283

Tenho a seguinte convenção para a maioria dos meus projetos:

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

Você notará que eu não mantenho bibliotecas externas dentro da pasta de origem. Também estou muito interessado em usar o NuGet, mas não quero essas bibliotecas externas dentro da pasta de origem. O NuGet tem uma configuração para alterar o diretório em que todos os pacotes são carregados?

TheCloudlessSky
fonte
10
Sim Sim Sim! Este é exatamente o projeto de uso estrutura I (ou muito quase), e eu sempre quis saber com NuGet poderia apoiá-lo ...
Noldorin
Entrei em detalhes sobre como fazer isso com esta resposta: stackoverflow.com/a/19466173/564726 . Você geralmente precisa remover a opção solutionDir do comando restore para que funcione corretamente.
BrutalDev 19/10
2
Coloquei o .sln no mesmo nível das suas pastas de nível superior. :)
Ian Warburton

Respostas:

242

Agora é possível controlar em qual pasta os pacotes estão instalados.

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

Edit: Veja o comentário de Phil Haack em 10 de dezembro de 2010 às 23:45 (no item de trabalho / no link acima). O suporte é parcialmente implementado na 1.0, mas não está documentado.

De acordo com @dfowler: Adicione um arquivo nuget.config ao lado da solução com este:

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

um pacote de pepitas para criar a substituição da pasta do pacote.

Atualização para a versão 2.1

Como comentou Azat, agora existe documentação oficial sobre como controlar os locais dos pacotes. As notas de versão do 2.1 especificam a seguinte configuração em um arquivo nuget.config (consulte as notas de versão para obter uma descrição dos locais válidos para colocar os arquivos de configuração e como o modelo de configuração hierárquica funciona):

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

Isso alteraria a pasta packages para o nível de configuração em que você colocou o arquivo (solução se você o colocar no diretório da solução, projeto no diretório do projeto e assim por diante). Observe que as notas de versão afirmam:

[...] se você tem uma pasta de pacotes existente sob a raiz da solução, será necessário excluí-la antes que o NuGet coloque os pacotes no novo local.

PHeiberg
fonte
5
Na verdade, é possível usando o arquivo de configuração acima. A razão pela qual foi enfatizada é que, ainda assim, durante o fluxo de trabalho de habilitar isso por meio da interface do usuário e outros meios, esperamos alguma peculiaridade.
Davidfowl
5
Consulte reviewboard.nupack.com/r/131 para obter uma descrição completa, por @dfowler, de como o nuget.config funciona. Por exemplo, um nuget.config válido ficaria assim: <settings><repositoryPath>lib</repositoryPath> </settings>
Lee Harold
5
docs.nuget.org/docs/release-notes/nuget-2.1 Consulte o parágrafo "Especificar 'local da pasta' pacotes '"
Azat
1
Posso confirmar que a nova maneira de fazer as coisas no 2.1+ não funciona. E há bugs sobre isso no codeplex: nuget.codeplex.com/workitem/2921 .
Case
5
A segunda versão funciona para mim, eu uso o NuGet mais recente e agora duas soluções podem compartilhar o mesmo repositório. Eu acho que pode não funcionar para algumas pessoas porque elas podem usar caminhos absolutos? Parece que o caminho absoluto versus o relativo é importante.
Csaba Toth
63
  1. Criou um arquivo chamado "nuget.config".
  2. Adicionado esse arquivo à minha pasta de soluções

Isto não funcionou para mim:

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

isso funcionou para mim:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <repositoryPath>..\ExtLibs\Packages</repositoryPath>
</settings>
ShaneKm
fonte
O mesmo aqui. A configuração> config não funcionou, mas as configurações> repositoryPath funcionaram.
Gene Reddick
Apenas a segunda solução funciona: docs.nuget.org/docs/reference/nuget-config-file
cheesemacfly
15
Depende da versão do NuGet que você está usando.
Bronumski
1
Observe que os caminhos relativos são relativos à solução; portanto, se seus projetos estiverem em níveis diferentes, ele não funcionará.
Nove Tails
2
Esta multa trabalha para o Visual Studio 2013, mas se eu estou usando Visual Studio 2015, em seguida, ele ainda instalar pacotes em pacotes de pasta perto do arquivo sln,
fhnaseer
40

Ok, para o bem de qualquer pessoa que esteja lendo este post - eis o que eu entendo da miríade de respostas acima:

  1. O arquivo nuget.config na pasta .nuget é relativo a essa pasta. Isso é importante porque se a sua nova pasta for algo como '../Packages' que a colocará onde sempre sai da caixa. Como @ bruce14 afirma, você deve fazer '../../Packages'

  2. Não foi possível obter o nuget mais recente (2.8.5) para encontrar uma pasta de pacotes fora do local padrão sem ativar a restauração do pacote. Portanto, depois de ativar a restauração do pacote, o seguinte deve ser adicionado ao arquivo nuget.config dentro da pasta .nuget para alterar o local:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      ...
      <config>
        <add key="repositoryPath" value="..\..\Packages" />
      </config>
      ...
    </configuration>
  3. (Isso é importante) Se você fizer QUALQUER alteração no local da pasta do pacote, dentro dos arquivos nuget.config, deverá reiniciar o visual studio ou fechar / recarregar a solução para que as alterações tenham efeito.

Robert Petz
fonte
5
Confie em mim, seu ponto # 3 salvou meu dia. Eu fiquei louco das últimas 3 horas até ler seu ponto # 3. : '(Muito obrigado mano!
hellodear 18/07/19
24

Uma solução para o Nuget 3.2 no Visual Studio 2015 é:

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

Usando barra para a pasta pai. Salve o arquivo acima (nuget.config) na pasta da solução.

A referência está disponível aqui

phuongnd
fonte
Perfeito! Trabalhando para o Visual Studio 2015 e Nuget versão 3.2.0.10516
Anon Dev
Parece que você quis dizer uma barra para a frente .. mas se a solução estiver no Windows, talvez essa barra para a frente se transforme em uma para trás, ou talvez a barra para a frente tenha sido o erro de digitação e deva mudar para uma para trás.
Gerard ONeill
Estou em 2015 e preciso usar .. \ .. \ Packages para que ele suba uma pasta.
Rhyous
1
../libIsso é uma barra para a frente, não uma barra para trás. O que você quer dizer?
precisa saber é
Sim, é exatamente uma barra. Resposta atualizada
phuongnd
15

A solução proposta nas notas de versão para 2.1 não funciona pronta para uso. Eles esqueceram de mencionar que há código:

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

    ...
}

o que impede que ele funcione. Para corrigir isso, você precisa modificar o arquivo NuGet.targets e remover o parâmetro 'OutputDirectory':

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

Então agora, se você adicionar a configuração 'repositoryPath' em algum lugar no NuGet.config (consulte as notas de versão para obter uma descrição dos locais válidos para colocar os arquivos de configuração), ele restaurará todos os pacotes em um único local, mas ... Seu .csproj ainda contém dicas para montagens escritas como caminhos relativos ...

Ainda não entendo por que eles foram difíceis, em vez de alterar o PackageManager, para adicionar caminhos de dica em relação ao PackagesDir. É assim que faço manualmente para ter diferentes locais de pacotes localmente (na minha área de trabalho) e no agente de compilação.

<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
fonte
1
Você está absolutamente certo. Na minha empresa, na verdade, usamos uma versão do NuGet que modificamos a nós mesmos que faz exatamente o que você está descrevendo, ou seja, adiciona HintPaths em relação ao diretório de pacotes e não ao local do arquivo do projeto. Isso funciona perfeitamente bem. Infelizmente, nunca cheguei a tentar trazer as mudanças que fizemos para NuGet a versão oficial, mas talvez seja a hora de fazer isso agora ...
afrischke
1
@frischke: seria ótimo se você pudesse fazer isso. obrigado. Alguma idéia de quando isso pode acontecer?
sgtz
11

Além da resposta de Shane Kms, se você ativou o Nuget Package Restore, edite o NuGet.config localizado na pasta .nuget da seguinte maneira:

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

Observe o ".. \" extra, que segue da pasta .nuget e não da pasta da solução.

do utilizador
fonte
9

Nenhuma dessas respostas estava funcionando para mim (Nuget 2.8.6), por falta de algumas dicas, tentará adicioná-las aqui, pois pode ser útil para outras pessoas.

Depois de ler as seguintes fontes:
https://docs.nuget.org/consume/NuGet-Config-Settings
https://github.com/NuGet/Home/issues/1346
Parece que

  1. Para tornar o trabalho Instale-Package corretamente com repositoryPath diferente, você precisa usar a frente barras, é porque eles estão usando Uri objeto a localização de análise.
  2. Sem $ no começo, ele ainda estava ignorando minhas configurações.
  3. O NuGet armazena em cache o arquivo de configuração; portanto, após as modificações, você precisa recarregar a solução / VS.
  4. Eu também tive um problema estranho ao usar o comando NuGet.exe para definir essa opção, pois modificou meu NuGet.exe global em AppData \ Roaming \ NuGet e começou a restaurar pacotes lá (já que esse arquivo tem maior prioridade, suponho).

Por exemplo

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

Você também pode usar o comando NuGet para garantir que a sintaxe esteja correta assim:

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

Para projetos .NET Core e Visual Studio 2017, eu era capaz de restaurar todos os pacotes para o caminho relativo, fornecendo esta configuração:

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

Com base na minha experiência, a pasta lib foi criada no mesmo nível em que o Nuget.config foi encontrado, independentemente do arquivo sln. Eu testei e o comportamento é o mesmo para restauração de linha de comando dotnet e reconstrução do Visual Studio 2017

Kirill Chilingarashvili
fonte
Eu tentei isso. Defino a globalPackagesFolderchave da pasta do pacote do meu projeto. Eu tentei adicionar um único pacote com dotnet add package MyPackage. nuget.exebaixou toda a estrutura de 83 pacotes .NET para essa pasta. Não era isso que eu pretendia. Eu só queria meu MyPackage único na minha pasta de pacote local, controlada por fonte.
Wallace Kelly
NÃO FAÇA ISSO! Isso sobrecarregará seu HDD rapidamente, pois todos os pacotes da estrutura serão baixados toda vez que você criar um novo aplicativo.
Alaa Masoud
1
conforme esta resposta a outra pergunta: stackoverflow.com/a/47407399/4572240 "respositoryPath é usado para projetos packages.config, globalPackagesFolder é usado para projetos PackageReference".
Siderite Zackwehdex 09/07/19
7

O arquivo de configuração na resposta aceita funciona para mim no VS2012. No entanto, para mim, funciona quando faço o seguinte:

  1. Crie um novo projeto no VS.
  2. Saída VS - isso parece ser importante.
  3. Copie os arquivos de configuração para a pasta do projeto.
  4. Reinicie o VS e adicione pacotes.

Se eu seguir essas etapas, posso usar uma pasta de pacotes compartilhados.

Harald
fonte
Reiniciar o VS é a única maneira de fazer isso funcionar. Acho que o gerenciador de pacotes o armazena em cache.
8263 Filip
6

Para alterar o caminho para projetos usando PackageReference em vez de packages.config, você precisa usar globalPackagesFolder

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

globalPackagesFolder (projetos usando apenas PackageReference)

A localização da pasta de pacotes globais padrão. O padrão é% userprofile% .nuget \ packages (Windows) ou ~ / .nuget / packages (Mac / Linux). Um caminho relativo pode ser usado nos arquivos nuget.config específicos do projeto. Essa configuração é substituída pela variável de ambiente NUGET_PACKAGES, que tem precedência.

repositoryPath (apenas packages.config)

O local no qual instalar pacotes NuGet em vez da pasta $ (Solutiondir) / packages padrão. Um caminho relativo pode ser usado nos arquivos nuget.config específicos do projeto. Essa configuração é substituída pela variável de ambiente NUGET_PACKAGES, que tem precedência.

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

Coloquei o Nuget.config ao lado do meu arquivo de solução e ele funcionou.

Manny
fonte
5

Mais um pequeno detalhe que eu acabei de descobrir. (Isso pode ser tão básico que alguns não o mencionaram, mas foi importante para a minha solução.) A pasta "packages" termina na mesma pasta que o arquivo .sln.

Nós movemos nosso arquivo .sln e, em seguida, corrigimos todos os caminhos internos para encontrar os vários projetos e pronto! Nossa pasta de pacotes acabou onde queríamos.

NickNuke
fonte
4

ATUALIZAÇÃO para o VS 2017:

Parece que as pessoas da equipe Nuget finalmente começaram a usar o Nuget, o que os ajudou a encontrar e consertar várias coisas importantes. Então agora (se não me engano, como ainda não foi migrado para o VS 2017), o abaixo não é mais necessário. Você deve poder definir o "repositoryPath" como uma pasta local e ele funcionará. Mesmo você pode deixá-lo como um local de restauração padrão movido das pastas da solução para o nível da máquina. Mais uma vez - eu ainda não testei sozinho

VS 2015 e versões anteriores

Apenas uma dica para outras respostas (especificamente isso ):

O local da pasta Pacote NuGet pode ser alterado via configuração, mas o VisualStudio ainda faz referência a assemblies nesta pasta relativamente:

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

Para solucionar isso (até uma solução melhor), usei o comando subst para criar uma unidade virtual que aponta para um novo local da pasta Packages:

subst N: C:\Development\NuGet\Packages

Agora, ao adicionar um novo pacote NuGet, a referência do projeto usa sua localização absoluta:

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

Nota:

  1. Essa unidade virtual será excluída após a reinicialização, portanto, lembre-se de lidar com ela
  2. Não se esqueça de substituir as referências existentes nos arquivos do projeto.
Kamarey
fonte
Ainda é o caso hoje? Quero dizer, não podemos usar a localização privilegiada para novos pacotes adicionados? este virtuais aparência de solução unidade complicado para mim
batmaci
Yep, ainda um caso como nada mudou
Kamarey
2
Na verdade, eu prefiro um caminho relativo - dessa forma, não há conflito no controle de origem se diferentes desenvolvedores tiverem locais de raiz diferentes para o código.
Jbyrd
Eu me pergunto por que você não pode fazer <HintPath>$(SolutionDir)\packages\SomeAssembly\lib\net45\SomeAssembly.dll</HintPath> em vez de usarsubst
Vinod Srivastav
Eu queria que todos os pacotes para estar no único lugar, não por solução
Kamarey
3

Apenas atualizando com o Nuget 2.8.3. Para alterar a localização dos pacotes instalados, ativei a restauração de pacotes com o botão direito do mouse na solução. Editou o NuGet.Config e adicionou estas linhas:

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

Em seguida, reconstruiu a solução, baixou todos os pacotes para a pasta desejada e atualizou as referências automaticamente.

amarnath chatterjee
fonte