Eu tenho uma situação semelhante com fontes de pacotes externos e internos com projetos referenciados em mais de uma solução. Acabei de trabalhar com uma de nossas bases de código hoje e parece estar trabalhando com as estações de trabalho do desenvolvedor e com o servidor de compilação. O processo abaixo tem esse cenário em mente (embora não deva ser difícil se adaptar para ter a pasta de pacotes comuns em outro lugar).
- Codebase
- Projeto A
- Projeto B
- Projeto C
- Soluções
- Solução 1
- Solução 2
- Solução 3
- Pacotes (este é o comum compartilhado por todas as soluções)
Resposta atualizada a partir do NuGet 3.5.0.1484 com o Visual Studio 2015 Update 3
Esse processo é um pouco mais fácil agora do que quando eu o resolvi originalmente e pensei que era hora de atualizá-lo. Em geral, o processo é o mesmo apenas com menos etapas. O resultado é um processo que resolve ou fornece o seguinte:
- Tudo o que precisa ser comprometido com o controle do código-fonte é visível e rastreado na solução
- Instalar novos pacotes ou atualizar pacotes usando o Gerenciador de Pacotes no Visual Studio usará o caminho correto do repositório
- Após a configuração inicial, não há invasão de arquivos .csproj
- Nenhuma modificação na estação de trabalho do desenvolvedor (o código está pronto para compilação no check-out)
Existem algumas desvantagens em potencial a serem observadas (ainda não as experimentei, YMMV). Veja a resposta e os comentários de Benol abaixo.
Adicionar NuGet.Config
Você deseja criar um arquivo NuGet.Config na raiz da pasta \ Solutions \. Verifique se este é um arquivo codificado em UTF-8 que você cria, se não tiver certeza de como fazer isso, use o menu Arquivo do Visual Studio-> Novo-> Arquivo e escolha o modelo de arquivo XML. Adicione ao NuGet.Config o seguinte:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="repositoryPath" value="$\..\Packages" />
</config>
</configuration>
Para a configuração repositoryPath, você pode especificar um caminho absoluto ou relativo (recomendado) usando o token $. O token $ baseia-se na localização do NuGet.Config (o token $ é na verdade relativo a um nível abaixo da localização do NuGet.Config). Portanto, se eu tiver \ Solutions \ NuGet.Config e desejar \ Solutions \ Packages, precisarei especificar $ \ .. \ Packages como o valor.
Em seguida, você deseja adicionar uma pasta de solução à sua solução chamada algo como "NuGet" (clique com o botão direito do mouse na sua solução, Adicionar-> Nova pasta de solução). As pastas de solução são pastas virtuais que existem apenas na solução do Visual Studio e não criarão uma pasta real na unidade (e você poderá fazer referência a arquivos de qualquer lugar). Clique com o botão direito do mouse na pasta da solução "NuGet", depois em Adicionar-> Item Existente e selecione \ Solutions \ NuGet.Config.
A razão pela qual estamos fazendo isso é para que fique visível na solução e ajude a garantir que esteja devidamente comprometido com seu controle de código-fonte. Você pode executar esta etapa para cada solução em sua base de código que participa de seus projetos compartilhados.
Ao colocar o arquivo NuGet.Config em \ Solutions \ acima de qualquer arquivo .sln, aproveitamos o fato de o NuGet navegar recursivamente a estrutura de pastas para cima no "diretório de trabalho atual" procurando um arquivo NuGet.Config para usar. O "diretório de trabalho atual" significa algumas coisas diferentes aqui, uma é o caminho de execução do NuGet.exe e a outra é o local do arquivo .sln.
Alternando pela pasta de pacotes
Primeiro, recomendo que você percorra cada uma das pastas da sua solução e exclua as pastas \ Packages \ existentes (será necessário fechar o Visual Studio primeiro). Isso facilita a visualização de onde o NuGet está colocando sua pasta \ Packages \ recém-configurada e garante que todos os links para a pasta \ Packages \ incorreta falhem e possam ser corrigidos.
Abra sua solução no Visual Studio e inicie um Rebuild All. Ignore todos os erros de compilação que você receberá; isso é esperado neste momento. Isso deve iniciar o recurso de restauração do pacote NuGet no início do processo de compilação. Verifique se sua pasta \ Solutions \ Packages \ foi criada no local desejado. Caso contrário, revise sua configuração.
Agora, para cada projeto em sua solução, você desejará:
- Clique com o botão direito do mouse no projeto e selecione Descarregar Projeto
- Clique com o botão direito do mouse no projeto e selecione Editar your-xxx.csproj
- Encontre todas as referências a \ packages \ e atualize-as para o novo local.
- A maioria destes serão referências <HintPath>, mas não todos. Por exemplo, WebGrease e Microsoft.Bcl.Build terão configurações de caminho separadas que precisarão ser atualizadas.
- Salve o .csproj e clique com o botão direito do mouse no projeto e selecione Recarregar Projeto
Depois que todos os seus arquivos .csproj forem atualizados, inicie outro Rebuild All e você não terá mais erros de compilação sobre as referências ausentes. Neste ponto, você está pronto e agora tem o NuGet configurado para usar uma pasta Pacotes compartilhada.
No NuGet 2.7.1 (2.7.40906.75) com o VStudio 2012
Em primeiro lugar, o nuget.config não controla todas as configurações de caminho no sistema de pacotes nuget. Isso foi particularmente confuso para descobrir. Especificamente, o problema é que o msbuild e o Visual Studio (chamando msbuild) não usam o caminho no nuget.config, mas o substituem no arquivo nuget.targets.
Preparação do ambiente
Primeiro, eu examinaria a pasta da sua solução e removeria todas as \ packages \ folders existentes. Isso ajudará a garantir que todos os pacotes estejam sendo instalados visivelmente na pasta correta e ajudará a descobrir quaisquer referências de caminho incorreto nas suas soluções. Em seguida, verifique se você tem a última extensão do Visual Studio do nuget instalada. Também gostaria de garantir que você tenha o nuget.exe mais recente instalado em cada solução. Abra um prompt de comando e vá para cada pasta $ (SolutionDir) \ .nuget \ e execute o seguinte comando:
nuget update -self
Definindo o caminho da pasta do pacote comum para o NuGet
Abra cada $ (SolutionDir) \ .nuget \ NuGet.Config e adicione o seguinte dentro da seção <configuração>:
<config>
<add key="repositorypath" value="$\..\..\..\Packages" />
</config>
Nota: Você pode usar um caminho absoluto ou um caminho relativo. Lembre-se de que, se você estiver usando um caminho relativo com $, ele é relativo a um nível abaixo da localização do NuGet.Config (acredite que seja um erro).
Definindo o caminho da pasta de pacote comum para o MSBuild e o Visual Studio
Abra cada $ (SolutionDir) \ .nuget \ NuGet.targets e modifique a seção a seguir (observe que para não-Windows, há outra seção abaixo):
<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>
Update PackagesDir para ser
<PackagesDir>$([System.IO.Path]::GetFullPath("$(SolutionDir)\..\Packages"))</PackagesDir>
Nota: O GetFullPath resolverá nosso caminho relativo em um caminho absoluto.
Restaurando todos os pacotes de nuget na pasta comum
Abra um prompt de comando e vá para cada $ (SolutionDir) \ .nuget e execute o seguinte comando:
nuget restore ..\YourSolution.sln
Nesse momento, você deve ter uma única pasta \ packages \ no local comum e nenhuma em nenhuma das pastas da solução. Caso contrário, verifique seus caminhos.
Corrigindo referências de projeto
Abra todos os arquivos .csproj em um editor de texto e encontre referências a \ packages e atualize-os para o caminho correto. A maioria destes serão referências <HintPath>, mas não todos. Por exemplo, WebGrease e Microsoft.Bcl.Build terão configurações de caminho separadas que precisarão ser atualizadas.
Crie sua solução
Abra sua solução no Visual Studio e inicie uma compilação. Se ele reclamar de pacotes ausentes que precisam ser restaurados, não assuma que o pacote está ausente e precisa ser restaurado (o erro pode ser enganoso). Pode ser um caminho ruim em um dos seus arquivos .csproj. Verifique isso antes de restaurar o pacote.
Tem um erro de compilação sobre pacotes ausentes?
Se você já verificou se os caminhos nos arquivos .csproj estão corretos, você tem duas opções para tentar. Se esse é o resultado da atualização do seu código do controle do código-fonte, você pode tentar fazer o check-out de uma cópia limpa e criar isso. Isso funcionou para um de nossos desenvolvedores e acho que havia um artefato no arquivo .suo ou algo semelhante. A outra opção é forçar manualmente uma restauração de pacote usando a linha de comando na pasta .nuget da solução em questão:
nuget restore ..\YourSolution.sln
$
frente do caminho relativo. Além disso, a resposta para sua pergunta sobre os arquivos NuGet.Config está aqui . Ele primeiro procura no .nuget, depois em todos os diretórios pai, depois no arquivo 'global' no seu AppData: depois os aplica na ordem REVERSE (o que isso significa).