Aprenda a criar seu primeiro pacote NuGet

Pacote NuGetO assunto NuGet está longe de ser novidade – aliás, hoje em dia é quase impossível criar um projeto .NET no Visual Studio que não tenha algum pacote NuGet em uso.

Entretanto, por mais convenientes que esses pacotes possam ser, a verdade é que poucos times têm criado pacotes para compartilhar suas bibliotecas de uso interno por achar que dá muito trabalho.

Sabia que criar um pacote NuGet para uns biblioteca de uso interno é mais simples do que parece? Veja neste post como criar seu primeiro pacote NuGet.

A ideia deste post é te ajudar na criação do seu primeiro pacote NuGet. Isso significa que não iremos a fundo em nenhum dos aspectos da criação de pacotes. Por outro lado, o site oficial do NuGet tem uma documentação detalhada sobre a criação de pacotes, para quando você estiver pronto para se aprofundar. Enquanto isso, vamos começar com o básico.

Todos os exemplos daqui por diante usarão uma hipotética biblioteca de validação de CPF feita em C#, criada por um time em uma empresa fictícia chamada Fabrikam, que deseja compartilhar essa biblioteca com outros times internos dentro da mesma empresa.

Conceitos básicos

Pacotes NuGet são um mecanismo conveniente para o compartilhamento de artefatos de software. Apesar de otimizados para compartilhar bibliotecas (assemblies) .NET, eles podem ser usados para muito mais que apenas.net, sendo usados para empacotar virtualmente qualquer coisa que precise ser versionada e distribuída de maneira conveniente. Quer um exemplo? Sabia que há vários casos de pacotes NuGet que contêm apenas scripts PowerShell? É uma maneira prática de empacotar e redistribuir scripts que são usados, por exemplo, durante o processo de build e deployment de uma aplicação.

Tecnicamente falando, um pacote NuGet é apenas um arquivo ZIP que segue um padrão de nomenclatura e contém um arquivo de metadados descrevendo o conteúdo do dito arquivo. Significa que, desde que seguindo as convenções apropriadas, poderíamos criar um pacote NuGet usando apenas uma ferramenta de compactação como o 7-Zip!

Vamos ver agora cada um desses três aspectos: nomenclatura, metadados e conteúdo.

Nome de um pacote NuGet

Pacotes NuGet devem seguir uma convenção ao serem nomeados. Você deve, obrigatoriamente, seguir a mesma convenção para que seu pacote seja reconhecido pelo NuGet:

<Nome do pacote>.<Versão SemVer>.nupkg

No nome do pacote, você pode usar letras, números e pontos. Uma estratégia comum parte evitar colisões de nome é usar o nome da empresa como prefixo no nome da biblioteca, tal como fazemos com assemblies .NET. No nosso exemplo, nosso pacote irá se chamar Fabrikam.ValidadorCPF. A extensão do arquivo, por sua vez, sempre deverá ser nupkg. Vamos falar agora sobre versionamento.

Versionamento de pacotes

O versionamento de pacotes é um aspecto central no NuGet. Afinal, um dos grandes benefícios de se usar o NuGet é poder gerenciar as diferentes dependências de um projeto, atualizando-as sempre que desejado ou necessário. Para isso, faz-se preciso usar um esquema para descrição da versão dos pacotes.

O problema é um número de versão, por mais que seja algo corriqueiro em nossos dias, está longe de ser consistente. Afinal, se você chegar numa roda de amigos programadores e apresentar um número de versão como 1.0.3.257 e perguntar qual o significado de cada um dos segmentos (e em que circunstâncias eles devem ser incrementados) vai provavelmente ouvir explicações bem diferentes.

Na tentativa de criar um algoritmo consistente para a definição de números de versão, nasceu a iniciativa de Versionamento Semântico ( Semantic Versioning), que descreve como criar um identificador de versão, qual o significado de cada segmento e em que circunstâncias incrementa-los. O NuGet, felizmente, segue o padrão definido no site semver.org, que é a fonte oficial de documentação para o Versionamento Semântico. É importante que você se familiarize com esse conceito; dê uma pausa na leitura deste post, vá até o semver.org e depois volte aqui. Eu espero ;-).

Voltando ao nosso exemplo, escolhi decidi que meu primeiro pacote vai nascer com a versão 1.0. Dessa forma, o nome completo do meu pacote (agora com o número da versão) fica sendo:

Fabrikam.ValidadorCPF.1.0.0.nupkg

Simples, né? Agora vamos falar dos metadados necessários para descrever nosso pacote.

Metadados – o arquivo de manifesto

Quando você acessa a caixa de diálogo de Gestão de Pacotes do Visual Studio (ou quando navega pelo site NuGet.org) pode perceber que um pacote NuGet contém vários metadados que ajudam a descreve-lo. Informações como nome amigável, autor, descrição, dependências… Sem isso, outros programadores teriam dificuldade em entender para que seu pacote serve. Esses metadados fazem parte de um arquivo de especificação NuGet – um arquivo XML de manifesto, com um formato predeterminado e de extensão nuspec. Precisamos criar esse arquivo e incorpora-lo em nosso pacote (ou seja, coloca-lo dentro do arquivo zip).

Caixa de diálogo do NuGet no Visual Studio, mostrando os diversos metadados de um pacote NuGet: O ID (1), a descrição (2) e outras informações como versão, autores, licença e site do projeto (3)
484

A definição completa do formato de arquivo nuspec está disponível no site oficial do NuGet, caso você queira se aprofundar depois. Vamos ver agora os elementos básicos para a criação de um manifesto para descrever o nosso pacote de validação de CPF:

<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>Fabrikam.ValidadorCPF</id>
    <version>1.0.0</version>
    <authors>Time de Serviços Compartilhados da Fabrikam</authors>
    <description>Este pacote oferece rotinas de validação de CPF para aplicações .NET</description>
    <language>pt-BR</language>
    <projectUrl>http://intranet.fabrikam.com/componentes/Fabrikam.ValidadorCPF</projectUrl>
    <licenseUrl>http://intranet.fabrikam.com/componentes/Fabrikam.ValidadorCPF/license.htm</licenseUrl>
  </metadata>
</package>

Exemplo do arquivo Fabrikam.ValidadorCPF.nuspec

Este é o manifesto típico de um pacote NuGet. Nele você vê os elementos que, minimamente, precisam estar presentes num arquivo nuspec para descrever seu pacote. Os elementos são auto-explicativos, com exceção talvez dos dois URLs. O primeiro, <projectURL>, indica onde um desenvolvedor que queira mais informações sobre sua biblioteca pode encontrar um site com documentação. Pode ser um wiki, um team project do TFS, um repositório do GitHub… Já o < licenseUrl> aponta para um documento com a licença de uso do componente. Essa informação é mais importante para componentes compartilhados publicamente, mas às vezes mesmo componentes internos podem ter modelos de licença diferentes – em especial quando temos times terceirizados de diferentes empresas consumindo nossos componentes.

Onde coloco o arquivo nuspec? O melhor lugar para coloca-lo é na pasta de projeto, junto ao arquivo csproj da biblioteca. O nuspec deve ser colocado sob controle de versão, junto com o resto do código da biblioteca.

Conteúdo – definindo os arquivos a empacotar

Ainda no nosso arquivo nuspec, precisamos agora listar quais arquivos devem ser incluídos em nosso pacote. Para manter nosso exemplo simples, incluirei apenas um arquivo: o assembly da nossa biblioteca de validação de CPF.

O conteúdo do pacote NuGet é definido a partir do elemento <files>. Dê uma olhada em como fica nosso arquivo, agora alterado para incluir nossa biblioteca e seu arquivo XML de documentação (gerado a partir dos comentários XML):

<?xml version="1.0" encoding="utf-8"?>
<package>
  <metadata>
    <id>Fabrikam.ValidadorCPF</id>
    <version>1.0.0</version>
    <authors>Time de Serviços Compartilhados da Fabrikam</authors>
    <description>Este pacote oferece rotinas de validação de CPF para aplicações .NET</description>
    <language>pt-BR</language>
    <projectUrl>http://intranet.fabrikam.com/componentes/Fabrikam.ValidadorCPF</projectUrl>
    <licenseUrl>http://intranet.fabrikam.com/componentes/Fabrikam.ValidadorCPF/license.htm</licenseUrl>
  </metadata>
  <files>
    <file src="bin\Release\Fabrikam.ValidadorCPF.dll" target="lib" />
    <file src="bin\Release\Fabrikam.ValidadorCPF.xml" target="lib"/>
  </files>
</package>

Nas linhas em destaque podemos que nossos dois arquivos são obtidos a partir da pasta Bin\Release do projeto e copiados para uma pasta chamada lib, através do atributo target do elemento <file>. Aliás, lembra que colocamos o nuspec na mesma pasta do csproj? Este é um dos motivos: permitir referências relativas.

Essa pasta lib tem um significado especial para o NuGet: Quaisquer assemblies encontrados nessa pasta durante a instalação do pacote serão referenciadas no projeto de destino. Ou seja, se alguém da nossa empresa adicionar nosso pacote NuGet a um projeto .NET qualquer, nossa biblioteca (que foi copiada para a pasta lib) será automaticamente adicionada às referências do tal projeto. Exatamente o comportamento que queremos!

Agora é hora de ver tudo isso funcionar. Apesar de “teoricamente” podermos usar o 7-Zip, na prática tem um jeito muito mais fácil de criar nosso pacote!

Gerando o arquivo .nupkg

Com o arquivo .nuspec criado, tudo fica bem fácil. Vamos usar a ferramenta de linha de comando do NuGet (nuget.exe; instruções para download aqui).

A primeira coisa a fazer é compilar seu projeto em modo Release (pois é a configuração que estamos referenciando no arquivo nuspec de exemplo). Depois, abra o prompt de comando e, a partir da pasta onde estão os arquivos de projeto, execute:

nuget pack Fabrikam.ValidadorCPF.nuspec

O resultado é seu arquivo .nupkg, pronto para uso! Alegre

Pronto para testar? Então abra seu Visual Studio e siga os passos abaixo.

Caixa de diálogo com as opções do NuGet
437

Em Tools | Options, pesquise por “nuget” (1). Aí, selecione a opção Package Sources (2) e clique no botão para adicionar uma nova origem de pacotes NuGet (3). Dê um nome qualquer a essa nova origem (4), informe o diretório onde acabamos de gerar o arquivo .nupkg (5) e então clique em Update (6) e OK.

Finalmente, crie um novo projeto .NET qualquer e selecione a opção “Manage NuGet Packages…”.

Novo pacote sendo listado no Visual Studio
434

Na janela do NuGet, selecione a origem de pacotes (1) que acabamos de criar e veja o que acontece!

Distribuindo os pacotes

Obviamente nada disso faz sentido se você não puder compartilhar seus pacotes com os outros desenvolvedores da empresa. Logo, vem a pergunta: onde hospedo meus pacotes para que outros desenvolvedores tenham acesso? Bem, isso depende se seu pacote é público ou privado.

Pacotes públicos

Para pacotes públicos (que podem ser livremente usados por desenvolvedores dentro e fora da sua empresa), a escolha óbvia é o nuget.org. Entretanto, por ser um repositório acessível ao público em geral, não é o melhor lugar para publicar pacotes de teste. Enquanto você estiver testando seus pacotes, utilize o serviço do site myget.org. O plano gratuito é suficiente para fins de testes.

Pacotes privados

Se seus pacotes são apenas para uso interno de sua empresa, um repositório público obviamente não é uma boa opção. Há um sem-número de opções para hospedar repositórios NuGet privados, seja na nuvem ou dentro de sua empresa:

Na maioria dos casos (com exceção das pastas de rede e do AppVeyor), você precisa criar uma conta. Uma vez criada, sua conta conterá uma informação fundamental para o processo de publicação: sua chave de API (API Key). Essa chave será usada pelo comando push do NuGet, responsável por publicar seu pacote para seu repositório. O comando é:

nuget push -Source <URL do servidor de destino> -ApiKey <sua chave de API>

Os desenvolvedores que forem usar seus pacotes precisam adicionar seu repositório ao Visual Studio. O processo é idêntico àquele que usamos logo acima para adicionar a pasta de testes; a diferença é que ao invés de apontar para um diretório local no computador, eles adicionariam o URL do seu feed NuGet. Cada repositório NuGet representa seus URLs de feed de uma maneira diferente. Verifique a documentação do seu repositório escolhido para saber qual URL deve ser adicionada ao Visual Studio.

Conclusão

Ufa! Sei que é bastante coisa para um post só, mas acho que com isso você já consegue iniciar a construção de seus primeiros pacotes. Ainda há muito mais para ser explorado neste assunto. Fique ligado nos próximos posts sobre NuGet!

Ah, deixo um exercício para você, caro leitor: Se você reparar bem, verá que muitos dos metadados incluídos em nosso arquivo .nuspec tipicamente estão presentes também em nosso assembly .NET, através dos vários atributos de metadados de assembly. Informações como nome, descrição, autor, versão e outros provavelmente estarão duplicados. Não seria muito mais legal se, ao invés de digitar essas informações no arquivo .nuspec, pudéssemos instruir o NuGet a buscar isso dentro de nosso projeto em tempo de empacotamento? Assim poderíamos manter esses dados em um lugar só: no projeto .NET!

O exercício, portanto, é: como fazer o NuGet reaproveitar os metadados de assembly que temos em nosso projeto, para que não precisemos redigitar esses mesmos dados no arquivo .nuspec?

Bom exercício! Ah, e não deixe de compartilhar sua opinião nos comentários!

 

Um abraço,
Igor

Autor: Igor Abade

Igor Abade V. Leite ([email protected]) é Microsoft MVP (Most Valuable Professional) de Visual Studio ALM desde 2006. Palestrante em diversos eventos da comunidade de desenvolvimento de software (TechEd Brasil, The Developers’ Conference, DevOps Summit Brasil, Agile Brazil, Visual Studio Summit, QCON e outros), é também autor de artigos em revistas e sites como o MSDN Brasil. Desde março de 2011 é um dos sócios da Lambda3, uma consultoria especializada em ALM, desenvolvimento de software e treinamentos. Visite seu blog sobre VS ALM em http://www.tshooter.com.br/ e siga-o no Twitter @igorabade.

4 pensamentos em “Aprenda a criar seu primeiro pacote NuGet”

    1. Rodrigo, no começo do uso do NuGet a Microsoft achou que daria para usar o NuGet no lugar de tecnologias como Gulp e Grunt. O que percebeu-se, com o passar do tempo, é que essa não era uma boa ideia. Um dos problemas era, por exemplo, a necessidade do NuGet de incluir os assets dos pacotes (Javascript, CSS e afins) no projeto. Com isso, você acabava colocando sob controle de versão coisas que não deveriam nem precisariam ser versionadas.

      Tudo isso serve para dizer que NuGet e Gulp/Grunt acabam resolvendo problemas diferentes de formas diferentes. Minha sugestão? Use NuGet para bibliotecas .NET e Gulp/Grunt/NPM etc. para assets não-.NET.

Deixe seu comentário!