Поделиться через


Создание пакета с помощью интерфейса командной строки nuget.exe

Независимо от того, что делает ваш пакет или какой код он содержит, используйте один из средств CLI, либо nuget.exe либо dotnet.exe, чтобы упаковать эту функциональность в компонент, который может быть использован и предоставлен любому количеству других разработчиков. Сведения об установке средств интерфейса командной строки NuGet см. в разделе "Установка клиентских средств NuGet". Обратите внимание, что Visual Studio не включает средство CLI автоматически.

Технически говоря, пакет NuGet — это просто ZIP-файл, который был переименован с .nupkg расширением и содержимое которого соответствует определенным соглашениям. В этом разделе описывается подробный процесс создания пакета, соответствующего этим соглашениям.

Упаковка начинается с скомпилированного кода (сборок), символов и/или других файлов, которые вы хотите доставить в виде пакета (см. обзор и рабочий процесс). Этот процесс не зависит от компиляции или создания файлов, которые отправляются в пакет, хотя вы можете извлечь данные из файла проекта, чтобы сохранить скомпилированные сборки и пакеты в синхронизации.

Это важно

В этом разделе рассматриваются проекты, не относящиеся к SDK-стилю, которые отличаются от проектов .NET Core и .NET Standard и используют Visual Studio 2017 и более поздние версии, а также NuGet 4.0 и более поздние версии.

Определите, какие сборки следует упаковать

Большинство пакетов общего назначения содержат одну или несколько сборок, которые другие разработчики могут использовать в своих проектах.

  • Как правило, лучше всего иметь одну сборку на пакет NuGet, если каждая сборка является независимо полезной. Например, если у вас есть Utilities.dll, который зависит от Parser.dll, и Parser.dll полезен сам по себе, создайте отдельный пакет для каждого из них. Это позволяет разработчикам использовать Parser.dll независимо от Utilities.dll.

  • Если ваша библиотека состоит из нескольких сборок, которые не представляют самостоятельной ценности, то допустимо объединить их в один пакет. Используя предыдущий пример, если Parser.dll содержит код, который используется только Utilities.dll, то Parser.dll можно оставить в том же пакете.

  • Также, если Utilities.dll зависит от Utilities.resources.dll, при этом последний снова не имеет самостоятельной пользы, поместите оба в один пакет.

Ресурсы, на самом деле, являются особым случаем. При установке пакета в проект, NuGet автоматически добавляет ссылки на DLL сборки пакета, исключая те, которые совпадают с именами .resources.dll, так как предполагается, что это локализованные спутниковые сборки (см. статью Создание локализованных пакетов). По этой причине не следует использовать .resources.dll для файлов, которые содержат важный код пакета.

Если библиотека содержит сборки COM-взаимодействия, следуйте дополнительным рекомендациям в разделе "Создание пакетов с сборками COM-взаимодействия".

Роль и структура nuspec-файла

Когда вы знаете, какие файлы нужно упаковать, следующий шаг — создание манифеста пакета в .nuspec XML-файле.

Манифест:

  1. Описывает содержимое пакета и включается в пакет.
  2. Управляет как созданием пакета, так и указывает NuGet, как установить пакет в проект. Например, манифест определяет другие зависимости пакета, поэтому NuGet также может установить эти зависимости при установке основного пакета.
  3. Содержит обязательные и необязательные свойства, как описано ниже. Подробные сведения, включая другие свойства, не упомянутые здесь, см. в справочнике nuspec.

Обязательные свойства:

  • Идентификатор пакета, который должен быть уникальным в коллекции, в которой размещается пакет.
  • Определенный номер версии в форме Major.Minor.Patch[-Suffix], где -Suffix определяет предварительные версии
  • Название пакета должно отображаться на сайте (например, nuget.org)
  • Сведения о авторе и владельце.
  • Длинное описание пакета.

Общие необязательные свойства:

  • Примечания к релизу
  • Сведения об авторских правах
  • Краткое описание пользовательского интерфейса диспетчера пакетов в Visual Studio
  • Идентификатор языкового стандарта
  • URL-адрес проекта
  • Лицензия в виде выражения или файла (licenseUrl устарел, используйте вместо этого элемент метаданных licensenuspec )
  • Файл значка (iconUrl устарел, используйте вместо этого элемент метаданных nuspec icon)
  • Списки зависимостей и ссылок
  • Теги, помогающие в поиске коллекции

Ниже приведен типичный (но вымышленный) .nuspec файл с комментариями, описывающими свойства:

<?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>

Дополнительные сведения об объявлении зависимостей и указании номеров версий см. в разделе packages.config и управление версиями пакетов. Также можно предоставить доступ к ресурсам из зависимостей непосредственно в пакете, используя атрибуты include и exclude на элементе dependency. См. справочник по nuspec — зависимости.

Так как манифест включен в пакет, созданный из него, можно найти любое количество дополнительных примеров, проверив существующие пакеты. Хороший источник — это папка глобальных пакетов на компьютере, расположение которой возвращается следующей командой:

nuget locals -list global-packages

Перейдите в любую папку package\version, скопируйте файл .nupkg в файл .zip, затем откройте этот файл .zip и изучите .nuspec его.

Замечание

При создании .nuspec проекта Visual Studio манифест содержит маркеры, которые заменяются сведениями из проекта при создании пакета. См. Создание файла .nuspec из проекта Visual Studio.

Создание nuspec-файла

Создание полного манифеста обычно начинается с базового .nuspec файла, созданного с помощью одного из следующих методов:

Затем вы редактируете файл вручную, чтобы он описывал точное содержимое, которое требуется в окончательном пакете.

Это важно

Созданные .nuspec файлы содержат заполнители, которые необходимо изменить перед созданием пакета с помощью команды nuget pack. Эта команда завершается ошибкой, если .nuspec содержит заполнители.

Из рабочего каталога на основе общепринятых стандартов

Поскольку пакет NuGet — это просто ZIP-файл, который был переименован с расширением .nupkg, чаще всего проще сначала создать нужную структуру папок в вашей локальной файловой системе, а затем непосредственно из этой структуры создать файл .nuspec. Затем nuget pack команда автоматически добавляет все файлы в эту структуру папок (исключая все папки, которые начинаются с ., что позволяет хранить частные файлы в одной структуре).

Преимуществом этого подхода является то, что вам не нужно указывать в манифесте, какие файлы необходимо включить в пакет (как описано далее в этом разделе). Процесс сборки может просто создать точную структуру папок, которая входит в пакет, и вы можете легко включить другие файлы, которые могут не быть частью проекта в противном случае:

  • Содержимое и исходный код, которые следует внедрить в целевой проект.
  • Скрипты PowerShell
  • Изменения существующих конфигурации и исходного кода файла проекта.

Соглашения о папках приведены следующим образом:

Folder Description Действие при установке пакета
(root) Расположение для readme.txt Visual Studio отображает readme.txt файл в корневом каталоге пакета при установке пакета.
lib/{tfm} Сборка (.dll), документация (.xml) и файлы символов (.pdb) для заданного Target Framework Moniker (TFM) Сборки добавляются в качестве ссылок для компиляции, а также для времени выполнения; .xml и .pdb скопированы в папки проекта. См. Поддержка нескольких целевых фреймворков для создания папок, специфичных для конкретных платформ.
ref/{tfm} Файлы сборки (.dll) и файлы символов (.pdb) для заданного Целевой платформы Moniker (TFM) Сборки добавляются только в качестве ссылок на время компиляции. Ничего не копируется в папку bin проекта.
среды выполнения Сборка для конкретной архитектуры (.dll), символ (.pdb) и нативные файлы ресурсов (.pri) Сборки добавляются только в качестве ссылок для среды выполнения; другие файлы копируются в папки проекта. В папке всегда должна быть соответствующая сборка AnyCPU (TFM), /ref/{tfm} чтобы предоставить соответствующую сборку времени компиляции. См. раздел "Поддержка нескольких целевых платформ".
содержимое Произвольные файлы Содержимое копируется в корневой каталог проекта. Подумайте о папке содержимого в качестве корневого каталога целевого приложения, которое в конечном итоге использует пакет. Чтобы пакет добавил изображение в папку /images приложения, поместите его в папку содержимого и изображений пакета.
строить (3.x+) файлы MSBuild .targets и .props Автоматически вставляется в проект.
buildMultiTargeting (4.0+) MSBuild .targets и .props файлы для кросс-фреймворк таргетинга Автоматически вставляется в проект.
buildTransitive (5.0+) MSBuild .targets и .props файлы, которые транзитивно перетекают в любой потребляемый проект. См. об этой функции. Автоматически вставляется в проект.
инструменты Скрипты и программы PowerShell, доступные в консоли диспетчера пакетов Папка tools добавляется в переменную среды PATH только для консоли диспетчера пакетов (в частности, не в PATH, как это задано для MSBuild при сборке проекта).

Так как структура папок может содержать любое количество сборок для любого количества целевых платформ, этот метод необходим при создании пакетов, поддерживающих несколько платформ.

В любом случае, когда у вас есть требуемая структура папок, выполните следующую команду в этой папке, чтобы создать .nuspec файл:

nuget spec

Опять же, созданный .nuspec объект не содержит явных ссылок на файлы в структуре папок. NuGet автоматически включает все файлы при создании пакета. Однако все равно необходимо изменить значения заполнителей в других частях манифеста.

из DLL сборки

В простом случае создания пакета из сборки можно создать .nuspec файл из метаданных в сборке с помощью следующей команды:

nuget spec <assembly-name>.dll

Использование этой формы заменяет несколько заполнителей в манифесте определенными значениями из сборки. Например, <id> для свойства задано имя сборки и <version> задана версия сборки. Однако в манифесте другие свойства не имеют совпадающих значений в сборке и, таким образом, содержат заполнители.

Из проекта Visual Studio

.nuspec Создание из .csproj или .vbproj файла удобно, так как другие пакеты, установленные в этом проекте, автоматически упоминаются в качестве зависимостей. Просто используйте следующую команду в той же папке, что и файл проекта:

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

Полученный <project-name>.nuspec файл содержит маркеры , которые заменяются во время упаковки значениями из проекта, включая ссылки на все уже установленные пакеты.

Если у вас есть зависимости пакетов для включения в .nuspec, вместо этого используйте nuget pack, а .nuspec файл получите из созданного .nupkg файла. Например, используйте следующую команду.

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

Токен разграничивается символами $ на обеих сторонах свойства проекта. Например, значение в манифесте, <id> созданном таким образом, обычно отображается следующим образом:

<id>$id$</id>

Этот маркер заменяется AssemblyName значением из файла проекта во время упаковки. Точное сопоставление значений проекта с .nuspecтокенами см. в справочнике по маркерам замены.

Использование маркеров освобождает вас от необходимости обновлять важные значения, такие как номер версии в .nuspec, по мере обновления проекта. (При желании маркеры всегда можно заменить литеральными значениями.

Обратите внимание, что при работе с проектом Visual Studio есть несколько дополнительных вариантов упаковки, как описано в статье "Запуск пакета nuget" для создания Nupkg-файла позже.

Пакеты уровня решения

Только NuGet 2.x. Недоступно в NuGet 3.0+.

NuGet 2.x поддерживает понятие пакета на уровне решения, который устанавливает средства или дополнительные команды для консоли диспетчера пакетов (содержимое tools папки), но не добавляет ссылки, содержимое или настройки сборки для любых проектов в решении. Такие пакеты не содержат файлов в своих прямых lib, content, или build папках, и ни одна из зависимостей не содержит файлов в соответствующих папках или lib, content, или build папках.

NuGet отслеживает установленные пакеты уровня решения в packages.config файле в папке .nuget, а не в файле проекта packages.config.

Новый файл со значениями по умолчанию

Следующая команда создает манифест по умолчанию с заполнителями, что обеспечивает правильную структуру файлов:

nuget spec [<package-name>]

Если не указать имя< пакета, результирующий >файл имеет значение Package.nuspec. Если указать имя, например Contoso.Utility.UsefulStuff, файл будет Contoso.Utility.UsefulStuff.nuspec.

Результирующий .nuspec элемент содержит заполнители для значений, таких как projectUrl. Перед созданием окончательного .nupkg файла обязательно измените файл.

Выбор уникального идентификатора пакета и настройка номера версии

Идентификатор пакета (<id> элемент) и номер версии (<version> элемент) — это два наиболее важных значения в манифесте, так как они однозначно определяют точный код, содержащийся в пакете.

Рекомендации по идентификатору пакета:

  • Уникальность. Идентификатор должен быть уникальным в nuget.org или в любой коллекции, где размещается пакет. Прежде чем принимать решение об идентификаторе, выполните поиск в применимой коллекции, чтобы проверить, уже ли используется имя. Чтобы избежать конфликтов, рекомендуется использовать имя вашей компании в качестве первой части идентификатора, например Contoso..
  • Имена, подобные пространствам имен: следуйте шаблону, аналогичному пространствам имен в .NET, используя точечную нотацию вместо дефисов. Например, используйте Contoso.Utility.UsefulStuff, а не Contoso-Utility-UsefulStuff или Contoso_Utility_UsefulStuff. Потребители также считают полезным, когда идентификатор пакета соответствует пространствам имен, используемым в коде.
  • Примеры пакетов: Если вы создаете пакет примера кода, демонстрирующий использование другого пакета, присоедините .Sample в качестве суффикса к идентификатору, как и в Contoso.Utility.UsefulStuff.Sample. (Пример пакета, конечно, имеет зависимость от другого пакета.) При создании примера пакета используйте ранее описанный выше метод рабочего каталога на основе соглашения. В папке content расположите пример кода в папке, называемой \Samples\<identifier>, как в \Samples\Contoso.Utility.UsefulStuff.Sample.

Рекомендации по версии пакета:

  • Как правило, задайте версию пакета для сопоставления библиотеки, хотя это не обязательно. Это простой вопрос при ограничении пакета на одну сборку, как описано ранее в разделе "Выбор сборки для упаковки". В целом помните, что NuGet сам занимается версиями пакетов при разрешении зависимостей, а не версий сборок.
  • При использовании схемы нестандартной версии следует учитывать правила управления версиями NuGet, как описано в разделе "Управление версиями пакетов".

Следующие серии кратких записей блога также полезны для понимания управления версиями:

Добавьте readme и другие файлы

Чтобы напрямую указать файлы для включения в пакет, используйте узел <files> в файле .nuspec, который следует за тегом <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>

Подсказка

При использовании подхода к рабочему каталогу на основе соглашений, вы можете поместить readme.txt в корневой каталог пакета, а другое содержимое в папку content. В манифесте не требуется <file> элементов.

При включении файла с именем readme.txt в корневом каталоге пакета Visual Studio отображает содержимое этого файла в виде обычного текста сразу после непосредственной установки пакета. (Файлы readme не отображаются для пакетов, установленных в качестве зависимостей. Например, вот как выглядит файл readme для пакета HtmlAgilityPack:

Отображение файла readme для пакета NuGet при установке

Замечание

Если файл содержит пустой узел <files> в .nuspec, NuGet не включает ничего другое в пакет, кроме того, что находится в папке lib.

Включение свойств и таргетов MSBuild в пакет

В некоторых случаях может потребоваться добавить пользовательские целевые объекты сборки или свойства в проектах, использующих пакет, например запуск пользовательского средства или процесса во время сборки. Дополнительные сведения о возможностях и целевых объектах MSBuild см. в пакетах NuGet

Создайте <package_id>.targets или <package_id>.props (например Contoso.Utility.UsefulStuff.targets) в папках сборки проекта.

Затем в файле .nuspec обязательно укажите эти файлы в узле <files>.

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

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

При добавлении пакетов в проект NuGet автоматически будет включать эти реквизиты и целевые объекты.

Запустите пакет nuget, чтобы создать NUPKG-файл

При использовании сборки или рабочего каталога на основе соглашений создайте пакет, выполнив команду nuget pack с файлом .nuspec, заменив <project-name> на ваше конкретное имя файла.

nuget pack <project-name>.nuspec

При использовании проекта Visual Studio запустите nuget pack с вашим файлом проекта, что автоматически загружает файл .nuspec и заменяет все маркеры в нем с помощью значений в файле проекта.

nuget pack <project-name>.csproj

Замечание

Использование файла проекта напрямую необходимо для замены маркеров, так как проект является источником значений маркера. Замена маркера nuget pack не происходит, если вы используете .nuspec файл.

Во всех случаях nuget pack исключает папки, начинающиеся с периода, например .git или .hg.

NuGet указывает, есть ли ошибки в .nuspec файле, которые нужно исправить, например, если вы забыли изменить значения заполнителей в манифесте.

После nuget pack успешного выполнения у вас есть .nupkg файл, который можно опубликовать в подходящей галерее, как описано в разделе Публикация пакета.

Подсказка

Полезный способ проверить пакет после создания пакета — открыть его в средстве обозревателя пакетов . Это дает графическое представление содержимого пакета и его манифеста. Вы также можете переименовать полученный .nupkg файл в .zip файл и изучить его содержимое напрямую.

Дополнительные параметры

С помощью различных коммутаторов nuget pack командной строки можно исключить файлы, переопределить номер версии манифеста и изменить выходную папку среди других функций. Полный список см. в справочнике по команде пакета.

Ниже приведены некоторые распространенные варианты для проектов Visual Studio.

  • Ссылки на проекты: если проект ссылается на другие проекты, можно добавить ссылки на проекты в составе пакета или в качестве зависимостей, используя -IncludeReferencedProjects этот параметр:

    nuget pack MyProject.csproj -IncludeReferencedProjects
    

    Этот процесс включения рекурсивен, поэтому если MyProject.csproj ссылки на проекты B и C, а эти проекты ссылаются на D, E и F, то файлы из B, C, D, E и F включены в пакет.

    Если проект, являющийся ссылкой, содержит собственный файл .nuspec, тогда NuGet добавляет этот проект как зависимость. Необходимо упаковать и опубликовать этот проект отдельно.

  • Конфигурация сборки. По умолчанию NuGet использует набор конфигураций сборки по умолчанию в файле проекта, как правило, отладка. Чтобы упаковать файлы из другой конфигурации сборки, например release, используйте -properties параметр с конфигурацией:

    nuget pack MyProject.csproj -properties Configuration=Release
    
  • Символы: для включения символов, позволяющих потребителям выполнять шаги по коду пакета в отладчике, используйте этот -Symbols параметр:

    nuget pack MyProject.csproj -symbols
    

Установка тестового пакета

Перед публикацией пакета обычно требуется протестировать процесс установки пакета в проект. Тесты обеспечивают, что все необходимые файлы окажутся в правильных местах в проекте.

Вы можете протестировать установки вручную в Visual Studio или в командной строке, выполнив обычные действия по установке пакета.

Для автоматического тестирования базовый процесс выглядит следующим образом:

  1. Скопируйте .nupkg файл в локальную папку.
  2. Добавьте папку в источники пакетов с помощью nuget sources add -name <name> -source <path> команды (см. источники nuget). Обратите внимание, что необходимо задать только этот локальный источник один раз на любом компьютере.
  3. Установите пакет из этого источника, используя nuget install <packageID> -source <name>, где <name> совпадает с именем вашего источника, как указано в nuget sources. Указание источника гарантирует, что пакет устанавливается только из этого источника.
  4. Проверьте файловую систему, чтобы проверить правильность установки файлов.

Дальнейшие шаги

После создания пакета, который представлен файлом .nupkg, вы можете опубликовать его в галерее по вашему выбору, как описано в разделе «Публикация пакета».

Вы также можете расширить возможности пакета или поддерживать другие сценарии, как описано в следующих разделах:

Наконец, существуют дополнительные типы пакетов, которые следует учитывать: