André Carlucci

Skeptic .net development

Lidando com pacotes do Nuget em seu sistema de controle de versão

NuGet é com certeza uma excelente ferramenta de gerenciamento de dependências de seu projeto no mundo .net.

Antigamente eu acabava criando uma pasta chamada “libs” em meus projetos e lá colocava todas as dlls que ele iria utilizar. Esta pasta acabava indo junto pro controle de versão para deixar um clean checkout mais prático e ter tudo pronto para rodar o projeto no mesmo lugar.

Ao começar a utilizar o Nuget, minha pasta “libs” deixou de ser necessária porque o NuGet cria automaticamente uma outra chamada “packages” onde ele deposita todas as dependências que baixamos.

O problema é que esta pasta acaba ficando muito grande visto que lá são colocadas todas as versões e artefatos de cada projeto que queremos referenciar e não somente o que usamos realmente. Dar commit destes arquivos se tornou inviável.

Usando o “NuGet Package Restore”

O legal de não colocar diretório “packages” no controle de versão é que não precisamos fazer isso. O NuGet nos fornece uma funcionalidade chamada “NuGet Package Restore” que faz com que quando damos build no projeto ele verifique se algum pacote está faltando. Caso esteja, ele o baixa automaticamente.

Isso facilita muito nossa vida ao mesmo tempo que deixa nosso projeto bem pequeno no controle de versão. O único “side effect” é que seu projeto agora vai ter o executável do NuGet adicionado para fazer o serviço, mas os benefícios dessa funcionalidade com certeza ofuscam esse detalhe.

Para habilitar NuGet Package Restore, clique em sua solução com botão direito e em seguida va em: “Enable NuGet Package Restore“. O NuGet vai adicionar um diretório chamado .nuget com os arquivos que ele precisa. Sim, é realmente simples assim.

O problema de muitas soluções e múltiplos repositórios de dependências

Quando você tem muitas soluções em seu computador, a quantidade e o tamanho dos diretórios com dependências pode começar a incomodar. Por exemplo, suponha que sua estrutura de diretórios seja assim:

Caso você use por exemplo o Log4net nas 3 soluções, você terá um diretório de “packages” em cada uma delas com todas as versões disponíveis do Log4net sendo repetidas 3 vezes.

Isso é porque os pacotes são compartilhados por padrão pelos projetos de uma mesma solução, mas não entre soluções (há não ser soluções no mesmo diretório).

Compartilhando diretório de pacotes entre soluções

Uma maneira de compartilhar esses pacotes de forma mais eficiente é tirar proveito do fato de que depois da versão 2.1 do NuGet, o arquivo de configuração nuget.config é lido de forma hierárquica de uma forma muito parecida com que o web.config é lido.

Veja no exemplo:

Primeiramente, o nuget.exe vai procurar seu arquivo de configuração no local padrão, que é definido como %APPDATA%\NuGet\NuGet.Config (DOS) ou $ENV:APPDATA\NuGet\NuGet.Config (PowerShell).

Depois disso, ele vai procurar qualquer arquivo chamado nuget.config começando pela raiz do drive que o projeto se encontra e subindo até chegar no diretório onde o nuget.exe.

Então na estrutura abaixo, se compilarmos a SoluçãoA:

  1. lê o nuget.config no local padrão
  2. lê o nuget.config (se existir) e c:
  3. lê o nuget.config (se existir) e c:\Projetos
  4. lê o nuget.config (se existir) e c:\Projetos\SolucaoA
  5. lê o nuget.config (se existir) e c:\Projetos\SolucaoA\.nuget\ (local do nuget.exe)

As configurações de diretórios acima sobrescrevem configurações anteriores.

Ok, mas como compartilho os pacotes sem ter que alterar cada solução?

Basta criar um arquivo chamado nuget.config no diretório base de seus projetos. No caso acima, em:

com a seguinte configuração:

[xml]
<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>
<config>
<add key=”repositoryPath” value=”C:\projetos\packages” />
</config>
<packageRestore>
<add key=”enabled” value=”True” />
</packageRestore>
</configuration>
[/xml]

Repare que o nome do diretório pode ser o que você quiser.

E ponto, os pacotes de todos os projetos em diretórios acima do “c:\projetos” serão jogados ali. Uma boa economia de espaço :)