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


Плагины NuGet для кроссплатформенной работы

В NuGet 4.8+ добавлена поддержка кроссплатформенных подключаемых модулей. Это было достигнуто путем создания новой модели расширяемости подключаемого модуля, которая должна соответствовать строгому набору правил операции. Подключаемые модули являются автономными исполняемыми файлами (запускаемыми в мире .NET Core), которые клиенты NuGet запускают в отдельном процессе. Это действительно плагин "один раз написать, запускать везде". Он будет работать со всеми клиентскими средствами NuGet. Плагины могут быть либо .NET Framework (NuGet.exe, MSBuild.exe и Visual Studio), либо .NET Core (dotnet.exe). Определяется протокол обмена версиями между клиентом NuGet и подключаемым модулем. Во время рукопожатия при запуске два процесса согласовывают версию протокола.

Для покрытия всех сценариев клиентских средств NuGet потребуется как подключаемый модуль для .NET Framework, так и для .NET Core. Опишите комбинации клиента и фреймворка для плагинов ниже.

Клиентское средство Каркас
Visual Studio Платформа .NET Framework
dotnet.exe .NET Core
NuGet.exe Платформа .NET Framework
MSBuild.exe Платформа .NET Framework
NuGet.exe на Mono Платформа .NET Framework

Как это работает

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

  1. NuGet обнаруживает доступные плагины.
  2. При необходимости NuGet будет выполнять итерацию по подключаемым модулям в порядке приоритета и запускает их по одному.
  3. NuGet будет использовать первый плагин, который может обслуживать запрос.
  4. Подключаемые модули будут отключены, когда в них больше не будет необходимости.

Общие требования к подключаемым модулям

Текущая версия протокола 2.0.0.0. В этой версии требования приведены ниже.

  • Иметь сборки с действительной, надежной подписью Authenticode, которые будут выполняться на Windows и Mono. Пока нет особых требований доверия для сборок, выполняемых в Linux и Mac. Релевантная проблема
  • Поддержка запуска без отслеживания состояния в текущем контексте безопасности клиентских средств NuGet. Например, клиентские средства NuGet не будут выполнять повышение или дополнительную инициализацию за пределами протокола подключаемого модуля, описанного далее.
  • Не взаимодействуйте, если не указано явно.
  • Соблюдайте согласованную версию протокола подключаемого модуля.
  • Отвечайте на все запросы в течение разумного периода времени.
  • Удовлетворяйте запросы на отмену для любой операции, находящейся в процессе выполнения.
  • Начиная с NuGet 6.13, исполняемые подключаемые модули (включая глобальные инструменты .NET) должны соответствовать этим требованиям:
    • Правила именования: должны соответствовать шаблону nuget-plugin-*.
    • Виндоус:
      • Должны быть файлы .exe или .bat.
    • Линукс:
      • Должны быть включены их исполняемые разрешения.

Техническая спецификация подробно описана в следующих спецификациях:

Клиент — взаимодействие плагина

Клиентские средства NuGet и подключаемые модули взаимодействуют с JSON через стандартные потоки (stdin, stdout, stderr). Все данные должны быть закодированы в кодировке UTF-8. Подключаемые модули запускаются с аргументом "-Plugin". Если пользователь непосредственно запускает плагин как исполняемый файл без этого аргумента, плагин может выдать информативное сообщение, а не ожидать согласования протокола. Время ожидания подтверждения протокола составляет 5 секунд. Плагин должен завершить настройку за минимально короткое время. Клиентские средства NuGet запрашивают поддерживаемые операции подключаемого модуля, передав индекс службы для источника NuGet. Подключаемый модуль может использовать индекс службы для проверки наличия поддерживаемых типов служб.

Обмен данными между клиентскими средствами NuGet и подключаемым модулем является двунаправленным. Каждый запрос имеет время ожидания в 5 секунд. Если операции должны занять больше времени, соответствующий процесс должен отправить сообщение о ходе выполнения, чтобы предотвратить истечение времени ожидания запроса. Через 1 минуту бездействия подключаемый модуль считается неактивным и отключается.

Установка и обнаружение подключаемого модуля

Плагины будут найдены с помощью структуры директории, основанной на соглашении. Сценарии CI/CD и опытные пользователи могут использовать переменные среды для переопределения поведения. При использовании переменных среды разрешены только абсолютные пути. Обратите внимание, что NUGET_NETFX_PLUGIN_PATHS и NUGET_NETCORE_PLUGIN_PATHS доступны только с 5.3+ версией инструментов NuGet и более поздних версий.

  • NUGET_NETFX_PLUGIN_PATHS — определяет используемые плагины средствами, основанными на .NET Framework (NuGet.exe/MSBuild.exe/Visual Studio). Имеет приоритет над NUGET_PLUGIN_PATHS. (Только версии NuGet 5.3+ )
  • NUGET_NETCORE_PLUGIN_PATHS — определяет плагины, которые будут использоваться средствами на основе .NET Core (dotnet.exe). Имеет приоритет над NUGET_PLUGIN_PATHS. (Только начиная с версии NuGet 5.3+)
  • NUGET_PLUGIN_PATHS
    • определяет используемые для этого процесса NuGet подключаемые модули с сохранением приоритета. Если эта переменная среды установлена, она переопределяет обнаружение, основанное на соглашении. Игнорируется, если указана любая из определенных переменных платформы.

    • начиная с NuGet 6.13:

      • Может указать пути к исполняемым файлам подключаемых модулей, включая подключаемые модули инструментария .NET.
      • Поддерживает пути к файлам и папкам, содержащим файлы подключаемого модуля.
      • Windows: поддерживает файлы .exe и .bat.
      • Linux: необходимы исполняемые права (chmod +x).
  • Расположение пользователя, домашнее расположение NuGet в %UserProfile%/.nuget/plugins. Это расположение не может быть переопределено. Для подключаемых модулей .NET Core и .NET Framework будет использоваться другой корневой каталог.
Каркас Расположение обнаружения корней
.NET Core %UserProfile%/.nuget/plugins/netcore
Платформа .NET Framework %UserProfile%/.nuget/plugins/netfx

Каждый подключаемый модуль должен быть установлен в своей папке. Точка входа подключаемого модуля будет именем установленной папки с расширениями .dll для .NET Core и расширением .exe для .NET Framework.

.nuget
    plugins
        netfx
            myPlugin
                myPlugin.exe
                nuget.protocol.dll
                ...
        netcore
            myPlugin
                myPlugin.dll
                nuget.protocol.dll
                ...

Заметка

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

Поддерживаемые операции

В новом протоколе подключаемого модуля поддерживаются две операции.

Имя операции Минимальная версия протокола Минимальная версия клиента NuGet
Скачивание пакета 1.0.0 4.3.0
проверки подлинности 2.0.0 4.8.0

Запуск подключаемых модулей в правильной среде выполнения

Для NuGet в dotnet.exe сценариях подключаемые модули должны быть в состоянии выполняться в этой конкретной среде выполнения dotnet.exe. На стороне поставщика плагина и потребителя лежит ответственность за то, чтобы использовать совместимое сочетание dotnet.exe/плагин. Потенциальная проблема может возникнуть с плагинами местоположения пользователя, например, когда dotnet.exe в среде выполнения 2.0 пытается использовать плагин, написанный для среды выполнения 2.1.

Кэширование возможностей

Процесс проверки безопасности и создания экземпляров подключаемых модулей обходится дорого. Операция скачивания происходит чаще, чем операция проверки подлинности, однако средний пользователь NuGet, скорее всего, имеет подключаемый модуль проверки подлинности. Чтобы улучшить работу, NuGet кэширует утверждения операции для данного запроса. Кэш выделяется для каждого подключаемого модуля, где ключом модуля является путь модуля, а срок действия кэша возможностей составляет 30 дней.

Кэш находится в %LocalAppData%/NuGet/plugins-cache и переопределяется с помощью переменной среды NUGET_PLUGINS_CACHE_PATH. Чтобы очистить этот кэш, можно выполнить команду locals с параметром plugins-cache. Функция «Локальные параметры all» теперь также удаляет кэш плагинов.

Индекс сообщений протокола

Сообщения версии протокола 1.0.0:

  1. Закрывать

    • Направление запроса: NuGet — плагин>
    • Запрос не будет содержать полезную нагрузку
    • Ответ не ожидается. Правильное действие заключается в том, чтобы процесс плагина немедленно завершился.
  2. Копирование файлов в пакете

    • Направление запроса: NuGet — плагин>
    • Запрос будет содержать следующее:
      • Идентификатор пакета и версия
      • Расположение исходного репозитория пакета
      • Путь к каталогу назначения
      • Перечисляемые файлы в пакете, которые необходимо скопировать в целевую директорию.
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • Перечисление полных путей для скопированных файлов в целевом каталоге, если операция выполнена успешно.
  3. Копировать файл пакета (NUPKG)

    • Запрос направления: NuGet - плагин>
    • Запрос будет содержать следующее:
      • Идентификатор пакета и версия
      • Расположение исходного репозитория пакета
      • Путь к целевому файлу
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
  4. Получение учетных данных

    • Запрос направления: плагин —> NuGet
    • Запрос будет содержать следующее:
      • Расположение исходного репозитория пакета
      • Код состояния HTTP, полученный из исходного репозитория пакета с использованием текущих учетных данных
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • имя пользователя, если доступно
      • пароль, если он доступен
  5. Получить файлы в пакете

    • Направление запроса: NuGet — плагин>
    • Запрос будет содержать следующее:
      • Идентификатор пакета и версия
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • Перечисление путей к файлам в пакете при успешном выполнении операции
  6. Получение утверждений операции

    • Запрос направления: NuGet — плагин>
    • Запрос будет содержать следующее:
      • служба index.json для источника пакета
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • Перечисление поддерживаемых операций (например, скачивание пакета), если операция выполнена успешно. Если подключаемый модуль не поддерживает источник пакета, то он должен вернуть пустой набор поддерживаемых операций.

Заметка

Это сообщение было обновлено в версии 2.0.0.0. Задача клиента — обеспечить обратную совместимость.

  1. Получение хэша пакета

    • Направление запроса: подключаемый модуль> для NuGet
    • Запрос будет содержать следующее:
      • Идентификатор пакета и версия
      • Расположение исходного репозитория пакета
      • хэш-алгоритм
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • Хэш файла пакета, полученный с использованием запрошенного алгоритма хэша, если операция выполнена успешно.
  2. Получить версии пакетов

    • Направление запроса: NuGet — плагин>
    • Запрос будет содержать следующее:
      • идентификатор пакета
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • список доступных версий пакетов, если операция завершилась успешно
  3. Получение индекса службы

    • Направление запроса: плагин —> NuGet
    • Запрос будет содержать следующее:
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • Индекс службы, если операция выполнена успешно
  4. Рукопожатие

    • Запрос направления для плагина NuGet <—>
    • Запрос будет содержать следующее:
      • текущая версия протокола подключаемого модуля
      • минимальная поддерживаемая версия протокола подключаемого модуля
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • согласованная версия протокола, если операция выполнена успешно. Сбой приведет к прекращению работы подключаемого модуля.
  5. Инициализировать

    • Направление запроса: NuGet — подключаемый модуль>
    • Запрос будет содержать следующее:
      • Версия клиентского средства NuGet
      • Эффективный язык клиентского средства NuGet. Следует учитывать параметр ForceEnglishOutput, если он используется.
      • Время ожидания запроса по умолчанию, которое заменяет стандартное значение протокола.
    • Ответ будет содержать следующее:
      • код ответа, указывающий на результат операции. Сбой приведет к отключению подключаемого модуля.
  6. Лог

    • Запрос направления: плагин —> NuGet
    • Запрос будет содержать следующее:
      • Уровень логов для запроса
      • сообщение для входа
    • Ответ будет содержать следующее:
      • код ответа, указывающий на результат операции.
  7. Отслеживание завершения процесса NuGet

    • Направление запроса: NuGet — плагин>
    • Запрос будет содержать следующее:
      • Идентификатор процесса NuGet
    • Ответ будет содержать следующее:
      • код ответа, указывающий на результат операции.
  8. Пакет предварительной выборки

    • Запрос направления: NuGet — плагин>
    • Запрос будет содержать следующее:
      • Идентификатор пакета и версия
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
  9. Настройка учетных данных

    • Направление запроса: NuGet — подключаемый модуль>
    • Запрос будет содержать следующее:
      • Расположение исходного репозитория пакета
      • последнее известное имя пользователя источника пакета, если доступно
      • Последний известный пароль источника пакета, если он доступен
      • последнее известное имя пользователя прокси-сервера, если оно доступно
      • последний известный пароль прокси-сервера, если он доступен
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
  10. Настройка уровня журнала

    • Направление запроса: NuGet — плагин>
    • Запрос будет содержать следующее:
      • Уровень журнала по умолчанию
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции

Версия протокола 2.0.0 сообщения

  1. Получение утверждений операции
  • Направление запроса: NuGet — плагин>

    • Запрос будет содержать следующее:
      • служба index.json для источника пакета
      • Расположение исходного репозитория пакета
    • Ответ будет содержать следующее:
      • код ответа, указывающий результат операции
      • перечисление поддерживаемых операций, если операция выполнена успешно. Если плагин не поддерживает источник пакета, он должен вернуть пустой набор поддерживаемых операций.

    Если индекс службы и источник пакета имеют значение NULL, тогда подключаемый модуль может ответить с аутентификацией.

  1. Получение учетных данных аутентификации
  • Направление запроса: плагин NuGet ->
  • Запрос будет содержать следующее:
    • Ури
    • isRetry
    • неинтерактивный
    • МожетПоказатьДиалог
  • Ответ будет содержать
    • Имя пользователя
    • Пароль
    • Сообщение
    • Список типов проверки подлинности
    • КодОткликаСообщения