asdf
Нет, это не просто кто-то уронил четыре пальца на клавиатуру!
В предыдущей статье я писал про
pyenv
—
отличный инструмент для установки различных версий интерпретатора.
Для питонистов pyenv
вполне достаточно, но люди,
пишущие на нескольких языках, могут обнаружить себя в ситуации,
когда им приходится держать установленными
pyenv
,
rvm
/ rbenv
,
nvm
,
rustup
,
gvm
или ещё какие-нибудь менеджеры версий для разных языков программирования.
При этом, конечно же, у каждого инструмента свой синтаксис команд,
свои тонкости по работе с ним, свои зависимости. Если установить это всё
сразу в свой шелл, то боюсь представить, что будет с переменной $PATH
(она будет очень толстой). Потенциально это может замедлить работу шелла вообще.
Но все эти проблемы остались в прошлом
— встречайте asdf
, универсальный менеджер версий!
asdf
, так же как и pyenv
, написан на чистом bash
.
Это означает, что инструмент отлично работает под Linux и MacOS, но,
к сожалению, никак не работает на Windows (ну, разве что в
WSL).
asdf
сам по себе не требует никаких внешних зависимостей, кроме
некоторых базовых утилит, типа git
и curl
, которые и так наверняка
у вас есть. Эти утилиты нужны для установки плагинов.
Вокруг asdf
выстроилась огромная экосистема плагинов.
Именно благодаря плагинам asdf
и именует себя универсальным менеджером версий.
Преимущества:
- не нужно учить диалекты команд для каждой отдельной утилиты, чтобы делать типовые действия;
- умеет управлять версиями всех мыслимых и немыслимых инструментов и языков программирования через плагины;
- можно настроить версии локально для определённой директории и
asdf
автоматически переключит версии инструментов при входе в неё; - классное название — удобно печатать.
Недостатки:
- у каждого плагина могут быть свои тонкости в плане настройки и свои зависимости, так что придётся читать инструкции, но, как правило, это единоразовые действия.
Установка
Установка во всех подробностях
описана на официальном сайте.
Глупо было бы пытаться описать установку лучше, чем на оф.сайте
— лучше и не напишешь. Документация у asdf
просто бомбическая.
Есть варианты установки на Linux или MacOS (через brew
),
описана настройка для всех популярных шеллов — bash
, zsh
и fish
.
Всё просто — выбираете вашу систему и шелл,
и получаете команды по установке и настройке.
Обратите внимание, что для корректной работы asdf
требует
наличия git
и curl
. Если вдруг у вас в системе нет таких утилит,
то инструкции по установке опять-таки можно
найти на сайте asdf
.
После установки перезапустите ваш шелл и проверьте установку:
$ asdf
...
"Late but latest"
-- Rajinikanth
Если вы видите этот девиз asdf
после справки по командам,
то установка удалась, можно продолжать.
Девиз в моём вольном переводе означает что-то типа
"да, поздновато, но после нас подобных утилит уже не будет".
Амбициозно, но я думаю, что asdf
и правда в силах вытеснить с рынка все
другие подобные утилиты, которые специфичны для одного языка.
Плагины
По умолчанию asdf
поставляется без плагинов и содержит только базовую
функциональность, такую как управление плагинами. asdf
без плагинов по сути
не делает ничего полезного. Чтобы управлять версиями чего-либо,
нужно установить соответствующий плагин.
Давайте запросим список доступных к установке плагинов:
$ asdf plugin list all
У меня вывелось аж 194 штуки. Список плагинов можно посмотреть и на сайте, вот здесь.
Есть плагины для всех популярных языков программирования:
python
;nodejs
;rust
;java
;kotlin
;golang
;php
;ruby
;- и, конечно же, для вашего любимого языка плагин тоже наверняка есть.
Кроме того, через asdf
можно управлять версиями различных утилит, например:
github-cli
;jq
;kubectl
;poetry
.
И сервисов, например:
postgres
;mysql
;mongodb
;redis
.
Установка интересующего плагина выполняется следующим образом:
$ asdf plugin add <имя плагина>
Рассмотрим работу с теми плагинами, с которыми мне доводилось работать.
Плагин для Python
Установим плагин для Python:
$ asdf plugin add python
asdf
имеет очень логично организованный интерфейс командной строки.
Запомните одно правило: если хотите просмотреть только установленные
плагины или версии плагина, то делайте list
,
а если вообще все, то list all
.
плагин | версия | |
---|---|---|
все | asdf plugin list all |
asdf list all python |
установленные | asdf plugin list |
asdf list python |
Выше мы уже смотрели список всех плагинов (через list all
), а теперь
давайте просмотрим список установленных плагинов. Там должен быть python
,
мы ведь его только что установили:
$ asdf plugin list
python
Отлично, плагин установлен! Давайте попросим asdf
показать
список доступных версий (хотим вообще все, поэтому list all
)
для плагина python
:
$ asdf list all python
…
3.6-dev
3.6.1
3.6.2
3.6.3
3.6.4
3.6.5
3.6.6
3.6.7
3.6.8
3.6.9
3.6.10
3.7.0
3.7-dev
3.7.1
3.7.2
3.7.3
3.7.4
3.7.5
3.7.6
3.7.7
3.8.0
3.8-dev
3.8.1
3.8.2
3.9.0a6
3.9-dev
…
Список я подсократил, но поверьте — он длинный.
Там есть как все версии эталонного интерпретатора CPython,
начиная с 2.1.3, так и альтернативные реализации Python
— PyPy, IronPython, Jython, MicroPython и другие.
Этот список очень напоминает подобный список из pyenv
, и это не просто
совпадение. Плагин asdf-python
действительно под капотом использует pyenv
.
В процессе установки asdf
скачивает исходники Python и
собирает интерпретатор из них. Это значит, что на машине придётся иметь
установленные инструменты для сборки кода на C/C++ и все нужные
библиотеки-зависимости. Список зависимостей для всех ОС и дистрибутивов можно
посмотреть здесь.
Обязательно установите эти зависимости прежде чем пытаться устанавливать
какой-либо интерпретатор.
Установка конкретной версии интерпретатора происходит вот так:
$ asdf install python 3.7.7
$ asdf install python 3.8.2
Давайте запросим список установленных версий (list
):
$ asdf list python
3.7.7
3.8.2
Давайте назначим глобальной ту версию Python, которую собираемся
использовать чаще всего. Она будет использоваться по умолчанию, когда
не найдена никакая локальная версия. Здесь всё работает так же, как и в
pyenv
, но даже если вы никогда им не пользовались, то я надеюсь, что дальше
по примеру станет понятно как работают глобальные и локальные версии:
$ asdf global python 3.8.2
$ python -V
Python 3.8.2
Если вам интересно, как работает asdf
, то:
$ which python
/home/br0ke/.asdf/shims/python
Опять же, он использует тот же принцип, что и pyenv
— создает небольшие исполняемые файлы (shims) для всех команд,
которыми собирается управлять.
Эти шимы вызывают asdf
и он принимает решение о том,
какую версию программы нужно вызвать.
Давайте для демонстрации работы локальных версий создадим директорию, и представим, что в ней мы собираемся разрабатывать проект под определенной версией Python, отличной от глобальной:
$ mkdir my_project
$ cd my_project
Установим локальную версию:
$ asdf local python 3.7.7
$ python -V
Python 3.7.7
В этой директории asdf
создал специальный файл .tool-versions
(аналог .python-version
из pyenv
):
$ cat .tool-versions
python 3.7.7
Этот файл содержит версии всех утилит, которые мы настроили для директории,
т.е. потенциально тут может быть не только Python.
Как правило, этот файл не нужно добавлять в систему контроля версий (git),
особенно если asdf
в рамках проекта пользуетесь только вы.
asdf
также вместо универсального .tool-versions
умеет использовать
файлы, специфичные для отдельных языков или инструментов, такие как
.python-version
(pyenv
), .ruby-version
(rbenv
),
.nvmrc
и .node-version
(nodejs
) и другие. Это сделано для того, чтобы
облегчить миграцию на asdf
с других менеджеров версий. По умолчанию эта
функциональность выключена, а включатся созданием файла ~/.asdfrc
со следующим
содержимым:
legacy_version_file = yes
При выходе из директории локально настроенная версия перестанет действовать и версия вернётся на глобальную:
$ cd ..
$ python -V
Python 3.8.2
По-моему, это очень удобно.
В целом asdf
работает так же как pyenv
и многие другие менеджеры версий
— в конце концов, они вдохновлены одной идеей.
Только asdf
вдохновился сильнее.
Допустим, что нужда прижала вас установить IPython:
$ pip install ipython
Чтобы IPython можно было запускать, нужно попросить asdf
пересоздать шимы:
$ asdf reshim
$ ipython
Python 3.8.2 (default, May 10 2020, 22:17:35)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.14.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: print("asdf is awesome!")
Плагин для Node.js
Установим плагин для Node.js:
$ asdf plugin add nodejs
Запросим список доступных версий:
$ asdf list all nodejs
…
12.16.3
13.0.0
13.0.1
13.1.0
13.2.0
13.3.0
13.4.0
13.5.0
13.6.0
13.7.0
13.8.0
13.9.0
13.10.0
13.10.1
13.11.0
13.12.0
13.13.0
13.14.0
14.0.0
14.1.0
14.2.0
Все инструменты устанавливаются по-разному, и плагины это учитывают. Например, Python собирался из исходников, а Node.js устанавливается простым скачиванием бинарника, так что никакие зависимости для сборки не нужны.
Но у плагина Node.js тоже есть свои тонкости. Чтобы установить версию
интерпретатора Node.js, нужно добавить ключи мейнтейнеров проекта Node.js
в систему. Это нужно, чтобы при установке плагин asdf-nodejs
проверил
цифровую подпись бинарника (в системе должна быть установлена
утилита установлена gpg
):
$ bash ~/.asdf/plugins/nodejs/bin/import-release-team-keyring
Теперь установим последнюю на данный момент версию Node.js:
$ asdf install nodejs 14.2.0
Назначим её глобальной и проверим работу:
$ asdf global nodejs 14.2.0
$ node
Welcome to Node.js v14.2.0.
Type ".help" for more information.
> console.log("asdf is super awesome!")
asdf is super awesome!
undefined
Давайте вернемся в директорию из предыдущего примера и добавим там ещё и локальную версию Node.js:
$ cd my_project
$ asdf local nodejs 14.2.0
Теперь в .tool-versions
лежит следующее содержимое:
$ cat .tool-versions
python 3.7.7
nodejs 14.2.0
Заключение
asdf
незаменим, если вы программируете более чем на одном языке.
Крайне рекомендую присмотреться к нему, даже если сейчас вы
программируете только на одном языке. Лучше выбирать инструменты на вырост.
Не бойтесь пробовать устанавливать разные плагины, только обязательно читайте инструкции к ним.
Обязательно подпишитесь на уведомления о новых постах в блоге, чтобы ничего не пропустить!