Partilhar via


Criar um pacote usando a nuget.exe CLI

Não importa o que seu pacote faz ou qual código ele contém, você usa uma das ferramentas da CLI, ou nuget.exedotnet.exe, para empacotar essa funcionalidade em um componente que pode ser compartilhado e usado por qualquer número de outros desenvolvedores. Para instalar as ferramentas da CLI do NuGet, consulte Instalar ferramentas de cliente NuGet. Observe que o Visual Studio não inclui automaticamente uma ferramenta CLI.

Tecnicamente falando, um pacote NuGet é apenas um ficheiro ZIP que foi renomeado com a extensão .nupkg e cujo conteúdo corresponde a certos padrões. Este tópico descreve o processo detalhado de criação de um pacote que atenda a essas convenções.

O empacotamento começa com o código compilado (assemblies), símbolos e/ou outros arquivos que você deseja entregar como um pacote (consulte Visão geral e fluxo de trabalho). Esse processo é independente de compilar ou gerar de outra maneira os arquivos que entram no pacote, embora se possa extrair informações de um arquivo de projeto para manter os conjuntos e pacotes compilados em sincronia.

Importante

Este tópico se aplica a projetos que não sejam no estilo SDK, geralmente projetos diferentes de projetos .NET Core e .NET Standard usando o Visual Studio 2017 e versões superiores e o NuGet 4.0+.

Decidir quais componentes empacotar

A maioria dos pacotes de uso geral contém um ou mais assemblies que outros desenvolvedores podem usar em seus próprios projetos.

  • Em geral, é preferível ter um assembly por pacote NuGet, desde que cada assembly seja útil de forma independente. Por exemplo, se você tiver um Utilities.dll que depende do Parser.dll, e Parser.dll é útil por conta própria, crie um pacote para cada um. Isso permite que os desenvolvedores usem Parser.dll independentemente do Utilities.dll.

  • Se a sua biblioteca é composta por vários conjuntos que não são úteis de forma independente, é aceitável combiná-los num só pacote. Usando o exemplo anterior, se Parser.dll contiver código usado apenas pelo Utilities.dll, não há problema em manter Parser.dll o mesmo pacote.

  • Da mesma forma, se Utilities.dll depende de Utilities.resources.dll, onde novamente o último não é útil por si só, então coloque ambos no mesmo pacote.

Os recursos são, de facto, um caso especial. Quando um pacote é instalado em um projeto, o NuGet adiciona automaticamente referências de assembly às DLLs do pacote, excluindo aquelas que são nomeadas .resources.dll porque se supõe que sejam assemblies satélite localizados (consulte Criando pacotes localizados). Por esse motivo, evite usar .resources.dll para arquivos que, de outra forma, contenham código de pacote essencial.

Se sua biblioteca contiver assemblies de interoperabilidade COM, siga as diretrizes adicionais em Criar pacotes com assemblies de interoperabilidade COM.

A função e a estrutura do arquivo .nuspec

Depois de saber quais arquivos deseja empacotar, a próxima etapa é criar um manifesto de pacote em um .nuspec arquivo XML.

O manifesto:

  1. Descreve o conteúdo e está incluído no próprio pacote.
  2. Conduz a criação do pacote e instrui o NuGet sobre como instalar o pacote em um projeto. Por exemplo, o manifesto identifica outras dependências de pacote, de modo que o NuGet também pode instalar essas dependências quando o pacote principal é instalado.
  3. Contém propriedades obrigatórias e opcionais, conforme descrito abaixo. Para obter detalhes exatos, incluindo outras propriedades não mencionadas aqui, consulte a referência .nuspec.

Propriedades necessárias:

  • O identificador do pacote, que deve ser exclusivo na galeria que hospeda o pacote.
  • Um número de versão específico no formato Major.Minor.Patch[-Suffix] onde -Suffix identifica versões de pré-lançamento
  • O título do pacote como deve aparecer no host (como nuget.org)
  • Informações do autor e proprietário.
  • Uma longa descrição do pacote.

Propriedades opcionais comuns:

A seguir está um arquivo típico (mas fictício), .nuspec com comentários descrevendo as propriedades:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <!-- Identifier that must be unique within the hosting gallery -->
        <id>Contoso.Utility.UsefulStuff</id>

        <!-- Package version number that is used when resolving dependencies -->
        <version>1.8.3</version>

        <!-- Authors contain text that appears directly on the gallery -->
        <authors>Dejana Tesic, Rajeev Dey</authors>

        <!-- 
            Owners are typically nuget.org identities that allow gallery
            users to easily find other packages by the same owners.  
        -->
        <owners>dejanatc, rjdey</owners>
        
         <!-- Project URL provides a link for the gallery -->
        <projectUrl>http://github.com/contoso/UsefulStuff</projectUrl>

         <!-- License information is displayed on the gallery -->
        <license type="expression">Apache-2.0</license>
        

        <!-- Icon is used in Visual Studio's package manager UI -->
        <icon>icon.png</icon>

        <!-- 
            If true, this value prompts the user to accept the license when
            installing the package. 
        -->
        <requireLicenseAcceptance>false</requireLicenseAcceptance>

        <!-- Any details about this particular release -->
        <releaseNotes>Bug fixes and performance improvements</releaseNotes>

        <!-- 
            The description can be used in package manager UI. Note that the
            nuget.org gallery uses information you add in the portal. 
        -->
        <description>Core utility functions for web applications</description>

        <!-- Copyright information -->
        <copyright>Copyright ©2016 Contoso Corporation</copyright>

        <!-- Tags appear in the gallery and can be used for tag searches -->
        <tags>web utility http json url parsing</tags>

        <!-- Dependencies are automatically installed when the package is installed -->
        <dependencies>
            <dependency id="Newtonsoft.Json" version="9.0" />
        </dependencies>
    </metadata>

    <!-- A readme.txt to display when the package is installed -->
    <files>
        <file src="readme.txt" target="" />
        <file src="icon.png" target="" />
    </files>
</package>

Para obter detalhes sobre como declarar dependências e especificar números de versão, consulte packages.config e controle de versão de pacotes. Também é possível exibir diretamente no pacote os ativos de dependências usando os atributos include e exclude no elemento dependency. Consulte Referência .nuspec - Dependências.

Como o manifesto está incluído no pacote criado a partir dele, você pode encontrar qualquer número de exemplos adicionais examinando os pacotes existentes. Uma boa fonte é a pasta global-packages no seu computador, cujo local é retornado pelo seguinte comando:

nuget locals -list global-packages

Vá para qualquer pasta package\version , copie o .nupkg arquivo para um .zip arquivo, abra esse .zip arquivo e examine o .nuspec dentro dele.

Observação

Ao criar um .nuspec a partir de um projeto do Visual Studio, o manifesto contém tokens que são substituídos por informações do projeto quando o pacote é criado. Consulte Criando o .nuspec a partir de um projeto do Visual Studio.

Criar o arquivo .nuspec

A criação de um manifesto completo normalmente começa com um arquivo básico .nuspec gerado por meio de um dos seguintes métodos:

Em seguida, edite o arquivo manualmente para que ele descreva o conteúdo exato desejado no pacote final.

Importante

Os arquivos gerados pelos .nuspec contêm marcadores que devem ser modificados antes de se criar o pacote com o comando nuget pack. Esse comando falhará se o .nuspec contiver espaços reservados.

A partir de um diretório de trabalho estruturado por convenção

Como um pacote NuGet é apenas um arquivo ZIP que foi renomeado com a .nupkg extensão, geralmente é mais fácil criar a estrutura de pastas desejada no sistema de arquivos local e, em seguida, criar o .nuspec arquivo diretamente a partir dessa estrutura. O comando nuget pack adiciona automaticamente todos os ficheiros nessa estrutura de pastas (excluindo quaisquer pastas que comecem com ., permitindo que mantenha ficheiros privados na mesma estrutura).

A vantagem dessa abordagem é que você não precisa especificar no manifesto quais arquivos deseja incluir no pacote (conforme explicado mais adiante neste tópico). Você pode simplesmente fazer com que seu processo de compilação produza a estrutura de pastas exata que entra no pacote, e você pode facilmente incluir outros arquivos que podem não fazer parte de um projeto de outra forma:

  • Conteúdo e código-fonte que devem ser injetados no projeto de destino.
  • Scripts do PowerShell
  • Transformações em arquivos de configuração e código-fonte existentes em um projeto.

As convenções de pasta são as seguintes:

Folder Description Ação após a instalação do pacote
(root) Localização para readme.txt O Visual Studio exibe um arquivo readme.txt na raiz do pacote quando o pacote é instalado.
lib/{tfm} Arquivos de montagem (.dll), documentação (.xml) e símbolo (.pdb) para o Target Framework Moniker (TFM) Assemblies são adicionados como referências para compilação e durante o tempo de execução; .xml e .pdb copiados para pastas de projeto. Consulte Suporte a várias estruturas de destino para criar subpastas específicas de destino da estrutura.
ref/{tfm} Arquivos de assembly (.dll) e símbolo (.pdb) para o Target Framework Moniker (TFM) Os assemblies são adicionados como referências apenas para o tempo de compilação; Portanto, nada será copiado para a pasta bin do projeto.
Tempos de execução Arquivos de assembly (.dll), símbolos (.pdb) e recursos nativos (.pri) específicos da arquitetura As assemblagens são adicionadas como referências apenas durante a execução; outros arquivos são copiados para pastas do projeto. Sempre deve haver um assembly específico correspondente (TFM) AnyCPU no diretório /ref/{tfm} para fornecer um assembly correspondente para tempo de compilação. Consulte Suportar múltiplos frameworks de destino.
conteúdo Arquivos arbitrários O conteúdo é copiado para a raiz do projeto. Pense na pasta de conteúdo como a raiz do aplicativo de destino que, em última análise, consome o pacote. Para que o pacote adicione uma imagem na pasta /images do aplicativo, coloque-a na pasta content/images do pacote.
compilação (3.x+) MSBuild .targets e .props ficheiros Inserido automaticamente no projeto.
buildMultiTargeting (4,0+) MSBuild .targets e .props arquivos para direcionamento entre estruturas Inserido automaticamente no projeto.
buildTransitive (5,0+) MSBuild .targets e .props ficheiros que são transmitidos transitivamente para qualquer projeto que os consome. Consulte a página do recurso . Inserido automaticamente no projeto.
Ferramentas Scripts e programas Powershell acessíveis a partir do Console do Gerenciador de Pacotes A pasta tools é adicionada à variável de ambiente do Console do Gestor de Pacotes apenas (especificamente, não ao PATH como definido para o MSBuild ao criar o projeto).

Como sua estrutura de pastas pode conter qualquer número de assemblies para qualquer número de estruturas de destino, esse método é necessário ao criar pacotes que suportam várias estruturas.

Em qualquer caso, uma vez que você tenha a estrutura de pastas desejada no lugar, execute o seguinte comando nessa pasta para criar o .nuspec arquivo:

nuget spec

Novamente, o gerado .nuspec não contém referências explícitas a arquivos na estrutura de pastas. O NuGet inclui automaticamente todos os arquivos quando o pacote é criado. No entanto, você ainda precisa editar variáveis de espaço reservado em outras partes do manifesto.

De uma DLL de montagem

No caso simples de criar um pacote a partir de um assembly, você pode gerar um .nuspec arquivo a partir dos metadados no assembly usando o seguinte comando:

nuget spec <assembly-name>.dll

O uso desse formulário substitui alguns espaços reservados no manifesto por valores específicos do assembly. Por exemplo, a <id> propriedade é definida como o nome do assembly e <version> é definida como a versão do assembly. No entanto, outras propriedades presentes no manifesto não possuem valores correspondentes no assembly, e, assim, ainda contêm placeholders.

De um projeto do Visual Studio

Criar um .nuspec a partir de um .csproj arquivo ou .vbproj é conveniente porque outros pacotes que foram instalados nesses projetos são automaticamente referenciados como dependências. Basta usar o seguinte comando na mesma pasta que o arquivo de projeto:

# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget spec

O arquivo resultante <project-name>.nuspec contém tokens que são substituídos no momento do empacotamento por valores do projeto, incluindo referências a quaisquer outros pacotes que já foram instalados.

Se você tiver dependências de pacote para incluir no .nuspec, use nuget packe obtenha o arquivo .nuspec de dentro do arquivo .nupkg gerado. Por exemplo, use o seguinte comando.

# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget pack myproject.csproj

Um token é delimitado por símbolos $ em ambos os lados da propriedade de projeto. Por exemplo, o valor em um manifesto <id> gerado dessa maneira normalmente aparece da seguinte maneira:

<id>$id$</id>

Esse token é substituído pelo valor AssemblyName do arquivo de projeto no momento de empacotamento. Para visualizar o mapeamento exato dos valores do projeto para .nuspec tokens, consulte a referência de Tokens de Substituição.

Os tokens aliviam você da necessidade de atualizar valores cruciais, como o número da versão no .nuspec à medida que você atualiza o projeto. (Você sempre pode substituir os tokens por valores literais, se desejar).

Observe que há várias opções de empacotamento adicionais disponíveis ao trabalhar a partir de um projeto do Visual Studio, conforme descrito em Executando o pacote nuget para gerar o arquivo .nupkg mais tarde.

Pacotes de nível de solução

Apenas NuGet 2.x. Não disponível no NuGet 3.0+.

O NuGet 2.x deu suporte à noção de um pacote de nível de solução que instala ferramentas ou comandos adicionais para o Console do Gerenciador de Pacotes (o conteúdo da tools pasta), mas não adiciona referências, conteúdo ou personalizações de compilação a nenhum projeto na solução. Tais pacotes não contêm arquivos em suas pastas diretaslib, contentou build , e nenhuma de suas dependências tem arquivos em suas respetivas libcontent, ou build pastas.

O NuGet rastreia os pacotes instalados ao nível da solução num arquivo packages.config na pasta .nuget, em vez do arquivo do projeto packages.config.

Novo arquivo com valores padrão

O comando a seguir cria um manifesto padrão com espaços reservados, o que garante que você comece com a estrutura de arquivo adequada:

nuget spec [<package-name>]

Se você omitir <o nome> do pacote, o arquivo resultante será Package.nuspec. Se você fornecer um nome como Contoso.Utility.UsefulStuff, o arquivo será Contoso.Utility.UsefulStuff.nuspec.

O resultado .nuspec contém espaços reservados para valores como o projectUrl. Certifique-se de editar o arquivo antes de usá-lo para criar o arquivo final .nupkg .

Escolha um identificador de pacote exclusivo e defina o número da versão

O identificador do pacote (<id> elemento ) e o número da versão (<version> elemento ) são os dois valores mais importantes no manifesto porque identificam exclusivamente o código exato contido no pacote.

Práticas recomendadas para o identificador de pacote:

  • Exclusividade: o identificador deve ser exclusivo em toda nuget.org ou em qualquer galeria que hospede o pacote. Antes de decidir sobre um identificador, pesquise na galeria aplicável para verificar se o nome já está em uso. Para evitar conflitos, um bom padrão é usar o nome da sua empresa como a primeira parte do identificador, como Contoso..
  • Nomes semelhantes a namespaces: siga um padrão semelhante aos namespaces no .NET, usando notação de ponto em vez de hífenes. Por exemplo, use Contoso.Utility.UsefulStuff em vez de Contoso-Utility-UsefulStuff ou Contoso_Utility_UsefulStuff. Os consumidores também acham útil quando o identificador do pacote corresponde aos namespaces usados no código.
  • Pacotes de exemplo: Se você produzir um pacote de código de exemplo que demonstre como usar outro pacote, anexe como um sufixo ao .Sample, como em Contoso.Utility.UsefulStuff.Sample. (O pacote de amostra teria, naturalmente, uma dependência do outro pacote.) Ao criar um pacote de exemplo, use o método de diretório de trabalho baseado em convenção descrito anteriormente. Na pasta content, organize o código de exemplo numa pasta chamada \Samples\<identifier> como em \Samples\Contoso.Utility.UsefulStuff.Sample.

Práticas recomendadas para a versão do pacote:

  • Em geral, defina a versão do pacote para corresponder à biblioteca, embora isso não seja estritamente necessário. Essa é uma questão simples quando você limita um pacote a um único assembly, conforme descrito anteriormente em Decidindo quais assemblies empacotar. No geral, lembre-se de que o próprio NuGet lida com versões de pacotes ao resolver dependências, não com versões de assembly.
  • Ao usar um esquema de versão não padrão, considere as regras de controle de versão do NuGet, conforme explicado em Controle de versão de pacote.

A seguinte série de breves postagens no blog também é útil para entender o controle de versão:

Adicionar um Leiame e outros ficheiros

Para especificar diretamente os ficheiros a serem incluídos no pacote, utilize o nó <files> no ficheiro .nuspec, que está após a etiqueta <metadata>.

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
    <!-- ... -->
    </metadata>
    <files>
        <!-- Add a readme -->
        <file src="readme.txt" target="" />

        <!-- Add files from an arbitrary folder that's not necessarily in the project -->
        <file src="..\..\SomeRoot\**\*.*" target="" />
    </files>
</package>

Sugestão

Ao usar a abordagem de diretório de trabalho baseada em convenção, você pode colocar o readme.txt na raiz do pacote e em outros conteúdos na content pasta. Nenhum elemento <file> é necessário no manifesto.

Quando você inclui um arquivo nomeado readme.txt na raiz do pacote, o Visual Studio exibe o conteúdo desse arquivo como texto sem formatação imediatamente após a instalação direta do pacote. (Os ficheiros 'Readme' não aparecem para pacotes instalados como dependências). Por exemplo, aqui está como o readme para o pacote HtmlAgilityPack aparece:

A exibição de um ficheiro README para um pacote NuGet após a instalação

Observação

Se incluir um nó vazio <files> no arquivo .nuspec, o NuGet não incluirá qualquer outro conteúdo no pacote além do que está na pasta lib.

Incluir suportes e alvos do MSBuild em um pacote

Em alguns casos, talvez você queira adicionar destinos ou propriedades de compilação personalizados em projetos que consomem seu pacote, como a execução de uma ferramenta ou processo personalizado durante a compilação. Você pode saber mais sobre os props e destinos do MSBuild em pacotes NuGet

Crie <package_id>.targets ou <package_id>.props (como Contoso.Utility.UsefulStuff.targets) dentro das pastas de compilação do projeto.

Em seguida, no .nuspec arquivo, certifique-se de consultar esses arquivos no <files> nó:

<?xml version="1.0"?>
<package >
    <metadata minClientVersion="2.5">
    <!-- ... -->
    </metadata>
    <files>
        <!-- Include everything in \build -->
        <file src="build\**" target="build" />

        <!-- Other files -->
        <!-- ... -->
    </files>
</package>

Quando pacotes são adicionados a um projeto, o NuGet inclui automaticamente esses adereços e destinos.

Execute nuget pack para gerar o arquivo .nupkg

Ao usar um assembly ou o diretório de trabalho baseado em convenção, crie um pacote executando nuget pack com o arquivo .nuspec, substituindo <project-name> pelo seu nome de arquivo específico.

nuget pack <project-name>.nuspec

Ao usar um projeto do Visual Studio, execute nuget pack com seu arquivo de projeto, que carrega automaticamente o arquivo do projeto e substitui todos os .nuspec tokens dentro dele usando valores no arquivo de projeto:

nuget pack <project-name>.csproj

Observação

Usar o arquivo de projeto diretamente é necessário para a substituição do token porque o projeto é a fonte dos valores do token. A substituição de token não acontece se você usar nuget pack com um .nuspec arquivo.

Em todos os casos, nuget pack exclui pastas que começam com um ponto, como .git ou .hg.

O NuGet indica se há erros no arquivo .nuspec que precisam ser corrigidos, como esquecer de alterar valores de marcadores de posição no manifesto.

Quando nuget pack for bem-sucedido, você terá um .nupkg arquivo que poderá publicar em uma galeria adequada, conforme descrito em Publicando um pacote.

Sugestão

Uma maneira útil de examinar um pacote depois de criá-lo é abri-lo na ferramenta Explorador de Pacotes . Isso lhe dá uma visão gráfica do conteúdo do pacote e seu manifesto. Você também pode renomear o arquivo resultante .nupkg para um .zip arquivo e explorar seu conteúdo diretamente.

Opções adicionais

Você pode usar várias opções de linha de comando com o nuget pack para excluir arquivos, alterar o número da versão no manifesto e mudar a pasta de saída, entre outros recursos. Para obter uma lista completa, consulte a referência do comando pack.

As opções a seguir são algumas que são comuns com projetos do Visual Studio:

  • Projetos referenciados: Se o projeto fizer referência a outros projetos, você poderá adicionar os projetos referenciados como parte do pacote ou como dependências, usando a -IncludeReferencedProjects opção:

    nuget pack MyProject.csproj -IncludeReferencedProjects
    

    Esse processo de inclusão é recursivo, portanto, se MyProject.csproj fizer referência aos projetos B e C, e esses projetos fizerem referência a D, E e F, os arquivos de B, C, D, E e F serão incluídos no pacote.

    Se um projeto referenciado incluir um .nuspec arquivo próprio, o NuGet adicionará esse projeto referenciado como uma dependência. Você precisa empacotar e publicar esse projeto separadamente.

  • Configuração de compilação: por padrão, o NuGet usa o conjunto de configurações de compilação padrão no arquivo de projeto, normalmente Depurar. Para pacotar ficheiros de uma configuração de compilação diferente, como Release, use a opção -properties com a configuração:

    nuget pack MyProject.csproj -properties Configuration=Release
    
  • Símbolos: para incluir símbolos que permitem que os consumidores percorram o código do pacote no depurador, use a opção -Symbols.

    nuget pack MyProject.csproj -symbols
    

Instalação do pacote de teste

Antes de publicar um pacote, você normalmente deseja testar o processo de instalação de um pacote em um projeto. Os testes asseguram que todos os ficheiros necessários acabam nos seus lugares corretos no projeto.

Você pode testar instalações manualmente no Visual Studio ou na linha de comando usando as etapas normais de instalação do pacote.

Para testes automatizados, o processo básico é o seguinte:

  1. Copie o .nupkg arquivo para uma pasta local.
  2. Adicione a pasta às fontes do pacote usando o nuget sources add -name <name> -source <path> comando (consulte nuget sources). Observe que você só precisa definir essa fonte local uma vez em qualquer computador.
  3. Instale o pacote a partir dessa fonte usando nuget install <packageID> -source <name> onde <name> corresponde ao nome da sua fonte como dado a nuget sources. Especificar a fonte garante que o pacote seja instalado apenas a partir dessa fonte.
  4. Examine seu sistema de arquivos para verificar se os arquivos estão instalados corretamente.

Próximas Etapas

Depois de criar um pacote, que é um .nupkg arquivo, você pode publicá-lo na galeria de sua escolha, conforme descrito em Publicando um pacote.

Você também pode querer estender os recursos do seu pacote ou oferecer suporte a outros cenários, conforme descrito nos tópicos a seguir:

Finalmente, existem tipos de pacotes adicionais aos quais deve estar atento: