Хабрахабр

[Перевод] .NET Core 2.1 Global Tools

NET Core 2. Пару недель назад вышел . Это первая версия SDK, где есть фича под названием "Глобальные утилиты . 1 RC1. NET Core Global Tools"). NET Core" (". Она дает простой способ создания кросс-платформенных консольных утилит.

NET Core Global Tools и кратко посмотрим, что внутри. Мы познакомимся с основами использования . NET Core 2. А еще вы можете скачать . 1 SDK и попробовать написать собственный пример.

Основы

NET Core global tool — это специальный пакет NuGet, в котором находится консольное приложение. . NET Core CLI скачивает пакет и делает его доступным в виде новой глобальной консольной команды. Когда вы устанавливаете его, .

Пользователи могут устанавливать утилиты с помощью команды dotnet tool install:

dotnet tool install -g <nuget package name>

После установки консольные утилиты, находящиеся в пакете, будут глобально доступны по имени:

<command name>

Например: dotnet tool имеет и другие команды.

dotnet tool list -g
dotnet tool uninstall -g <nuget package name>
dotnet tool update -g <nuget package name>

Под капотом

NuGet пакет с консольной утилитой содержит все файлы, полученные в результате выполнения команды dotnet publish, а также несколько дополнительных файлов с мета-информацией.

Когда вы запускаете dotnet tool install --global, происходит следующее:

  1. Запускается dotnet restore со специальными параметрами, чтобы скачать пакет.
  2. Файлы распаковываются в папку $HOME/.dotnet/.store/<package id>/<version>.
  3. Генерируется запускаемый файл в папке $HOME/.dotnet/tools.

NET Core DLL файл и автоматически запускает его. Сгенерированный запускаемый файл — это небольшое консольное приложение (написанное на C++), которое знает, где находится ваш .

Эта команда делает всё то же самое, но устанавливает консольное приложение в папку $installDir, а не в $HOME/.dotnet/tools. Вы также можете запустить dotnet tool install с аргументом --tool-path $installDir.

Как создать свой пакет

NET Core SDK версии 2. Для создания глобальных консольных утилит вам нужен . В этой версии добавлено несколько дополнительных настроек проектов для управления неймингом и содержимым пакетов с глобальными консольными утилитами. 1.

Минимальные необходимые параметры проекта:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <PackAsTool>true</PackAsTool> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> </Project>

Дополнительные (не обязательные) параметры, управляющие сборкой пакета:

  • AssemblyName — задает название .dll файла вашего консольного приложения.
  • ToolCommandName — название команды, по которому пользователь будет запускать вашу консольную утилиту. По умолчанию оно совпадает с названием .dll файла (которое задано в параметре AssemblyName).
    • Название команды не обязательно должно начинаться с dotnet-. Можно использовать любое название без пробелов.
    • Если название начинается с dotnet-, то утилиту можно будет запускать как команду утилиты dotnet (убедитесь, что команды с таким именем еще нет). Например, утилита dotnet-say-moo может быть вызвана и как dotnet-say-moo, и как dotnet say-moo.
  • PackageId — идентификатор NuGet пакета. По умолчанию совпадает с названием .csproj файла. Этот идентификатор нужно указывать при установке. При этом он может отличаться от названия команды (ToolCommandName) и названия .dll файла (AssemblyName).
  • PackageVersion — версия NuGet пакета (по умолчанию 1.0.0). Также вместо PackageVersion можно использовать VersionPrefix и VersionSuffix.

Пример использования этих параметров:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <PackAsTool>true</PackAsTool> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.1</TargetFramework> <ToolCommandName>pineapple</ToolCommandName> <PackageId>dole-cli</PackageId> <PackageVersion>1.0.0-alpha-$(BuildNumber)</PackageVersion> <AssemblyName>Dole.Cli</AssemblyName> </PropertyGroup>
</Project>

Сборка и установка пакета

SDK увидит, что установлен параметр PackAsTool=true и автоматически сгенерирует нужные дополнительные файлы. Сборка пакета происходит как обычно — при помощи команды dotnet pack.

dotnet pack --output ./packages

Это может быть полезно для проверки, что всё сделано правильно. С помощью параметра --source-feed вы можете установить пакет, который еще не опубликован в репозитории пакетов NuGet. 0. Также, если версия пакета — не релизная (например, 3. 0-alpha — содержит что-то, кроме трех чисел), нужно при установке явно указать её.

Например:

dotnet tool install -g my-package-name --version 3.0.0-alpha --source-feed ./packages/

Что внутри пакета

Как я писал выше, команда dotnet pack собирает пакет особым образом, если в файле проекта указан параметр PackAsTool=true.

Зависимости

Все файлы, необходимые для работы вашей консольной утилиты, должны быть включены в NuGet пакет. В пакет попадают не только файлы, полученные через dotnet build, но и все другие зависимости вашего проекта (подключенные сторонние пакеты NuGet). Команда dotnet-tool-install не устанавливает зависимости, указанные в резделе <dependencies> вашего .nuspec файла.

DotnetToolSettings.xml

Если этого файла по какой-то причине не окажется в пакете (например, пытаетесь установить произвольный пакет как консольную утилиту), то при установке вы получите ошибку: Генерируется специальный файл DotnetToolSettings.xml, который содержит информацию о вашем консольном приложении.

The settings file in the tool’s NuGet package is invalid: Settings file ‘DotnetToolSettings.xml’ was not found in the package.

Пример содержимого файла:

<DotNetCliTool Version="1"> <Commands> <Command Name="my-command-name" EntryPoint="my-file.dll" Runner="dotnet" /> </Commands>
</DotNetCliTool>

Сейчас есть следующие требования к файлу DotnetToolSettings.xml:

  • Файл DotnetToolSettings.xml должен находиться в папке tools/$targetframework/any/. Например: tools/netcoreapp2.1/any/DotnetToolSettings.xml.
  • Пакет должен содержать только один файл DotnetToolSettings.xml.
  • В файле DotnetToolSettings.xml должна быть описана только одна секция <Command>.
  • Значение атрибута Runner должно быть "dotnet".
  • В качестве значения атрибута EntryPoint должно быть указано название .dll файла, который лежит в одной папке с файлом DotnetToolSettings.xml.

<packageType name="DotnetTool" />

Например: В .nuspec файл автоматически добавляется параметр <packageType name="DotnetTool" />.

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"> <metadata> <!-- Следующий фрагмент обязательно должен быть! --> <packageTypes> <packageType name="DotnetTool" /> </packageTypes> <!-- ... --> </metadata>
</package>

Если параметр packageType[name] не указан как DotnetTool, то при установке получите ошибку:

0. error NU1212: Invalid project-package combination for awesome-tool 1. DotnetToolReference project style can only contain references of the DotnetTool type 0.

На Github есть issue, чтобы это улучшить. Конечно, это не очень понятное сообщение об ошибке.

Что может пойти не так

Глобальные утилиты — глобальные для пользователя, а не для компьютера

NET Core CLI по умолчанию устанавливает глобальные утилиты в папку $HOME/.dotnet/tools (на Linux/macOS) или в папку %USERPROFILE%\.dotnet\tools (на Windows). . Установленные утилиты доступны только для пользователя, который их установил. Это значит, что вы не можете установить пакет глобально для всех пользователей компьютера с помощью dotnet tool install --global.

Не хватает пути в переменной PATH

NET Core автоматически добавляет путь к папке с установленными утилитами в переменную окружения PATH, чтобы они были доступны по имени, без указания полного пути. Обычно . Например: Но иногда это может не сработать.

  • если вы добавили переменную окружения DOTNET_SKIP_FIRST_TIME_EXPERIENCE (например, чтобы ускорить первый запуск .NET Core), то значение переменной PATH может быть не установлено при первом использовании
  • macOS: если вы установили CLI из .tar.gz файла (а не из .pkg файла), то у вас может не быть файла /etc/paths.d/dotnet-cli-tool который настраивает переменную PATH.
  • Linux: вам нужно вручную отредактировать свой shell environment file, т.е ~/.bash_profile или ~/.zshrc

Например: В этом случае при запуске своей консолььной утилиты вы получите ошибку.

bash: my-command-name: command not found

Например так (после добавления нужно перезапустить терминал): Чтобы всё заработало, нужно добавить в переменную PATH путь к папке с утилитами.

cat << \EOF >> ~/.bash_profile
# Add .NET Core SDK tools
export PATH="$PATH:/Users/<user-name>/.dotnet/tools"
EOF

Или вот так можно добавить для текущей сессии:

export PATH="$PATH:/Users/<user-name>/.dotnet/tools"

Для других систем всё аналогично. Примеры выше — для MacOS. Кроме того, при установке вашей глобальной консольной утилиты команда dotnet tool install проверит, что переменная PATH правильно настроена и предложит варианты решения, если это не так.

.NET Core CLI установлен не в папку по умолчанию

NET Core CLI как .zip/.tar.gz архив и распаковали его в папку, которая отличается от папки по умолчанию, то при запуске своей консольной утилиты вы можете получить ошибку: Если вы скачали .

  • Windows: A fatal error occurred, the required library hostfxr.dll could not be found
  • Linux: A fatal error occurred, the required library libhostfxr.so could not be found
  • macOS: A fatal error occurred, the required library libhostfxr.dylib could not be found

В сообщении об ошибке будет также дополнительная информация:

If this is a self-contained application, that library should exist in [some path here].
If this is a framework-dependent application, install the runtime in the default location [default location] or use the DOTNET_ROOT environment variable to specify the runtime location.

NET Core в папке по умолчанию. Причина в том, что запускаемы файл, который генерируется командой dotnet tool install при установке пакета, ищет . Например: Вы можете переопределить пути по умолчанию, установив переменную окружения DOTNET_ROOT.

# Windows
set DOTNET_ROOT=C:\Users\username\dotnet # MacOS/Linux
export DOTNET_ROOT=/Users/username/Downloads/dotnet

Подробности в issue на GitHub.

Заключение

NET Core. Мы познакомились с глобальными консольными утилитами в . Я крайне счастлив, что команда . На мой взгляд, это очень крутая штука. Не могу дождаться, когда все начнут её использовать 🙂 NET Core её запилила.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть