Терминология OneGet, NuGet, Chocolatey, PowerShellGet — разложим по полочкам

    В этой статье я хочу помочь разобраться в структуре пакетных менеджеров под Windows. Статья нацелена больше на тех, кто, как и я, пришли из мира Linux, где принято заходить в понимание процессов ниже уровня абстракций.

    Уверен, что абстракции вы уже прочитали и без меня:
    chocolatey для установки приложений, nuget — для установки зависимостей разработчиком.

    Но это мало того грубо, так еще и неправда.

    Итак, какие типы пакетов мы знаем из мира Linux? Внимание: не пакетные менеджеры, а именно сами пакеты. Самые распространенные условно делятся на две группы: ОС-зависимые (deb, rpm) или языко-зависимые (как правило, tar-болы). В принципе можно сказать, что первая группа — это приложения (утилиты), а вторые — зависимости (библиотеки). Но иногда это не так: среди пакетов ОС есть библиотеки, а среди языковых пакетов есть пакеты, устанавливающие еще и утилиты (например stdeb в pip или elastalert в npm) — если их устанавливать глобально, то получится как пакет ОС.

    Возвращаемся к Windows.

    Изначально здесь придумали тоже формат пакета. Сделан он был на замену старому формату msi/msu потому, что старый формат имел достаточно высокий входной порог для понимания, как его автоматизировать [вполне вероятно, что я сейчас брежу]. В общем и целом новый формат очень похож на rpm. У него даже есть spec-файл. Имя ему — NuGet, но расширение .nupkg. Внутри этого пакета есть директории, файлы и инсталляционные скрипты — все нам, линуксойдам, привычно и знакомо.

    Теперь давайте вспомним, какие пакетные менеджеры мы знаем. Для ОС это apt, yum,… Для языковых: pip, gem, npm, cpan, cpm,…
    Что для Windows? Тут мы знакомимся с новым NuGet. Есть NuGet-пакет, а есть одноименный nuget.exe — утилита, которая умеет эти пакеты скачивать и разархивировать. Вообще, она умеет много другое, но это за пределами обсуждаемого вопроса.

    Какой расклад мы получаем:

    Debian: apt(deb) + pip + npm + gem +…
    RHEL: yum(rpm) + pip + npm + gem +…
    Windows: nuget(nupkg) + pip + npm + gem +…

    Обратите внимание, для msi пакетного менеджера так и не создали (это не совсем так, но пока для простоты).

    И вот здесь начинается отличие от Linux. В мире Windows появился какой-то талантливый парень, который решил, что он хочет устанавливать все одной командой. И начал писать open-source'ный проект OneGet (его проприетарное название: PackageManager, который является одним из модулей PowerShell версии >=5.0).

    OneGet — это абстрактный интерфейс, который умеет разговаривать с каждым пакетным менеджером на его языке. OneGet публикует для нас набор унифицированных команд. Например, команду Install-Package, которая является wrapper'ом каждый раз для разных команд.

    Что получается: мы подключаем к OneGet несколько пакетных менеджеров. Например: NuGet, PIP, NPM.

    Далее, если мы хотим поставить какой-то питоний пакет, то мы пишем:

    Install-Package <имя pip-пакета>

    OneGet преобразует это в:

    pip install <имя pip-пакета>

    А теперь мы хотим поставить пакет NuGet и запускаем:

    Install-Package <имя nupkg-пакета>

    В этот раз команда вызвала:

    nuget install <имя nupkg-пакета>

    Я соврал. На самом деле Install-Package не вызывает эти команды в бэкграунде — пакетные менеджеры более не используются. Выпали из пищевой цепочки. Вместо них установлены специализированные пакетные провайдеры (считайте плагины PowerShell) для управления инородными пакетами. И эти провайдеры занимаются задачей установки вместо привычных нам пакетных менеджеров. А OneGet над ними начальник. За зависимостями следят сами провайдеры.

    И тут мы знакомимся с третьим NuGet — NuGet-пакетный провайдер. Я с самого начала статьи мечтал взорвать ваш мозг: NuGet — это пакетный провайдер, который пришел на смену пакетному менеджеру NuGet(nuget.exe), чтобы управлять пакетами NuGet(.nupkg).

    Здесь очень важный момент. Старые пакетные менеджеры имели каждый свой список репозиториев (Source в терминологии Windows):

    PS C:\> nuget source list
    Registered Sources:
    
      1.  nuget.org [Enabled]
          https://api.nuget.org/v3/index.json
      2.  ABC [Enabled]
          http://<тут_я_спрятал_IP>/artifactory/api/nuget/<имя_репо>

    Или:

    PS C:\> gem sources
    *** CURRENT SOURCES ***
    
    https://rubygems.org

    OneGet опирается не на них, а на заменивших их провайдеров. А список репозиториев один для всех, но с указанием, кому какой репозиторий принадлежит — по аналогии с внешними ключами БД.

    Смотрим сначала список пакетных провайдеров:

    PS C:\> Get-PackageProvider
    
    Name                     Version          DynamicOptions
    ----                     -------          --------------
    Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVers
    ChocolateyGet            1.0.0.1          AdditionalArguments
    msi                      3.0.0.0          AdditionalArguments
    msu                      3.0.0.0
    NuGet                    2.8.5.208        Destination, ExcludeVersion, Scope, SkipDependen
    PowerShellGet            1.0.0.1          PackageManagementProvider, Type, Scope, AllowClo
    Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent
    

    А теперь смотрим кому какой репозиторий принадлежит:

    PS C:\> Get-PackageSource
    
    Name                             ProviderName     IsTrusted  Location
    ----                             ------------     ---------  --------
    nuget.org                        NuGet            False      https://api.nuget.org/v3/index.json
    PSGallery                        PowerShellGet    False      https://www.powershellgallery....
    chocolatey                       Chocolatey       False      http://chocolatey.org/api/v2/
    

    Теперь я сделаю паузу и отвлекусь на один из странных пакетных провайдеров — PowerShellGet. Этот провайдер призван устанавливать модули самого PowerShell. Появился он в PowerShell 2 — еще до прихода PackageManager(aka OneGet). Но они друг другу не ровня. PowerShellGet — это один из рядовых пакетных провайдеров, умеющих делать только свой тип пакетов, а не управленец пакетными провайдерами, как OneGet.

    Его тип пакетов — .nupkg, содержимое которых — модули PowerShell. Поэтому не удивляйтесь, что его репозиторий PSGallery имеет формат NuGet:

    PS C:\> Get-PSRepository -Name "PSGallery" | Format-List * -Force
    
    Name                      : PSGallery
    SourceLocation            : https://www.powershellgallery.com/api/v2/
    Trusted                   : False
    Registered                : True
    InstallationPolicy        : Untrusted
    PackageManagementProvider : NuGet
    PublishLocation           : https://www.powershellgallery.com/api/v2/package/
    ScriptSourceLocation      : https://www.powershellgallery.com/api/v2/items/psscript/
    ScriptPublishLocation     : https://www.powershellgallery.com/api/v2/package/
    ProviderOptions           : {}

    И сейчас вы могли заметить следующую тонкость: список репозиториев в PackageManager выполняется командой Get-PackageSource, а не Get-PSRepository.

    Дело в том, что работа этого модуля, как я сказал выше, устанавливать модули PowerShell. В комплект установки входит и регистрация новых командлетов, что он и сделал. Этот командлет дает дополнительные поля при регистрации репозитория (например PublishLocation). Этого не видно, если использовать стандартный командлет:

    PS C:\> Get-PackageSource -Name "PSGallery" | Format-List * -Force
    
    Name         : PSGallery
    Location     : https://www.powershellgallery.com/api/v2/
    Source       : PSGallery
    ProviderName : PowerShellGet
    Provider     : Microsoft.PackageManagement.Implementation.PackageProvider
    IsTrusted    : False
    IsRegistered : True
    IsValidated  : False
    Details      : {[ScriptPublishLocation, https://www.powershellgallery.com/api/v2/package/], [InstallationPolicy, Untrusted], [PackageManagementProvider, NuGet],
                   [ScriptSourceLocation, https://www.powershellgallery.com/api/v2/items/psscript/]...}
    

    Последнее: Chocolatey.

    Вот все говорят, что Chocolatey — надстройка над NuGet. Оно как бы так, но не совсем. Chocolatey использует те же spec'и, но не полностью. Вместо полноценного пакета он зачастую использует скачивание .msi или чего угодно другого и последующую silent-установку. То есть в то время, как пакетный провайдер NuGet или пакетный менеджер nuget.exe устанавливает только нативные NuGet-пакеты, Chocolatey устанавливает их же + все то, что что другие устанавливать не умеют. Поэтому база пакетов Chocolatey такая внушительная по сравнению с базой NuGet. И поэтому в пакетах Chocolatey столько скриптов много.

    Возможно вы заметили, что есть два провайдера Chocolatey и ChocolateyGet. Первый — самодельная времянка. Второй — официальный провайдер, который недавно только вышел. Ну вы видите по версиям.

    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 23

      0
      Намного хуже в винде отсутствие не пакетного менеджера, а приницпа «наследил — убери». До сих пор не понимаю как можно было додуматься сохранять настройки в реестр, вместо того, чтобы писать в конфигурационные файлы в папках системы\приложения\драйверов. И в целом бОльшая часть приложений написано таким образом, что не удаляют за собой полностью, в том числе и от мелкософта(ваша любимая VS например очень мусорит). Заодно это источник многих ошибок, которые очень тяжко потом ловить и фиксить. Это кстати одна из причин почему винду проще переставить, чем очистить.
        +1
        Не уверен, что реестр — плохо. Представьте, что вы на Debian. У вас установлен пакет, у которого в конфиге что-то изменено. И вот вышел апдейт, вы хотите обновить. И apt предоставит вам экран, где спросит оставить ли версию мейнтейнеров, оставить ли адаптированную или сравнить версии.
        А теперь представьте, что вы обновляете 100500 машин и участие в подобных диалогах вам недоступно.
        А вот если вы что-то меняете в реестре, то изменение всегда атомарное. И дельта «конфигов» между версиями ляжет нормально.

        Но вот то, что реестр сложнее чистится — это согласен конечно.
          +1

          В реестре пишется в отдельную папку приложения, в чем проблема? Кстати сейчас реестр использовать не рекомендуют.

          0
          А OpenGet над ними начальник.

          Это что за зверь?

            0
            Ой, OneGet. Исправил. Спасибо.
            0
            А я-то думал: куда делся удобный command-line'овый nuget.exe. Жаль, что унификация через powershell слелана так, что без мануала нужную команду не угадаешь.
            Спасибо за статью, отличный формат для вводного курса «как это в целом вообще устроено». То самое, чего больше всего не хватает в мануалах, особенно MSDN.
              0
              Спасибо!

              По поводу пропавшего nuget.exe — не спешите расстраиваться, он еще жив.
              Ведь без него не собрать пакет и не отправить в репозиторий. Поэтому вы можете его поставить:
              Install-Package NuGet.CommandLine
              


              Там вообще много чего еще есть:
              WARNING: 'nuget' matched package 'NuGet.CommandLine/4.1.0' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'NugetPackageExplorer/3.23' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'NugetPackageManager/2.8.60318.667' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'NuGet.vs/2.8.60318.667' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'NugetPackageManagerForVisualStudio2013/2.8.50313.4600' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'NuGet.ContextMenu/1.0.0.20141024' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'SymbolSource.Integration.NuGet.CommandLine/1.3.4' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'nugetupload/1.0.2' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'nuget-credentialprovider-vss/0.23.0' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'nuget' matched package 'visualstudio2015-nugetpackagemanager/3.5.0' from provider: 'Chocolatey', source 'chocolatey'.
              WARNING: 'NuGet' matched package 'NuGet/1.3.3' from provider: 'PowerShellGet', source 'PSGallery'.
                0
                  0

                  Конечно, просто раньше он ставился вместе со студией (или ее nuget-расширением, не помню) и попадал в PATH в Visual Studio Command Line.
                  Т.е. стало выглядеть как магия — студия пакеты качает, но каким образом — не сразу понятно;)

                0
                По-моему в nuget только библиотеки для .NET, разве нет?
                  0
                  Не, там полно всего: nuget.org
                  Есть куча утилит всяких, например. Но всех их объединяет одно — чистый формат NuGet. Чего не скажешь про пакеты репозиториев провайдера Chocolatey, где можно встретить как чистый NuGET, так и MSI, завернутый в NuGet и даже ZIP, завернутый в NuGet.
                    0
                    По ссылке как раз и есть библиотеки.
                      0
                      промазал ответом :-)
                      см.ниже: 19 июня 2017 в 01:40
                  0
                  Подавляющее большинство — да. Но если пролистать дальше, то можно найти и что-то другое.
                  Например:
                  пакет конфигов: NLog.Config
                  пакет приложения: Selenium.Chrome.WebDriver
                  пакет библиотека, но не .Net: knockoutjs
                  пакет для .Net, но не библиотека, а тулза: FAKE
                    0
                    И как же тогда добавить провайдеры npm и pip в OneGet? А что если будет конфликт имён? А как мне пользоваться всякими npm install без флага -g через OneGet?
                      0

                      Не стоит этим пользоваться в таких целях. Вопреки написанному, это не замена pip и yarn/npm/gem. Это ближе к apt/yum/whatever/chocolate.

                        0
                        А в чем особо разница между первой группой и второй? И почему вы считаете, что не стоит пользоваться?
                          0

                          apt/yum/chocolate — для приложений, которые устанавливаются в систему. pip/npm — для пакетов, специфичных для языков/проектов. Я вообще pip вне virtual environment стараюсь не пользоваться. Да и npm в пределах проекта в основном. Я не знаю как буду реализованы провайдеры в OneGet, но точно знаю, что у меня не будет OneGet в системе отличной от Windows. А вот аналог apt в Windows это да, хорошо.

                            0
                            Неубедительно.
                            Устанавливаются в систему

                            Все устанавливается в систему.
                            Только apt раскидывает по FHS (опять же не всегда), а pip ставит в dist-packages. В начале статьи я привел случаи, когда их вообще не отличишь.

                            pip/npm — для пакетов, специфичных для языков/проектов

                            Пока абстрактно — правильно звучит. Начнете копать, сделаете более точные утверждения и ситуация развернется.

                            Все они просто раскладывают код, который либо сам запускается и выполняет функционал, либо является библиотекой для кого-то. И все они могут быть где угодно на файловой системе. Деление на языки и место установки очень условно и является вопросом традиций и привычек.
                              0
                              Первоначальное предназначение нугета — быть пакетным менеджером для .net языков. Т.е. это аналог npm в мире .net. Всякие вангеты и шоколати его абьюзят как хотят. Родной нугет клиент ничего в «систему» не ставит.
                                0

                                Обязательно это учту, когда мы заговорим про нугет. А, стоп. Уже учёл.

                                  0
                                  Всякие вангеты и шоколати его абьюзят как хотят

                                  Глубоко сказано. Проникновенно. Нам всем будет о чем поразмыслить на выходных.
                            0
                            И как же тогда добавить провайдеры npm и pip в OneGet?

                            Я так понимаю, его еще не сделали. В процессе.
                            Вот wish-list провайдеров от народа.
                            А что если будет конфликт имён?

                            Запросит указать точного провайдера. Есть такая опция у Install-Package.

                          Only users with full accounts can post comments. Log in, please.