asdfで様々な言語のバージョンを管理する

プログラミング言語のバージョン管理にはasdfを使うと便利かもしれない、という話です。

背景

僕は普段rubyやnode.jsを使っているのですが、各言語の複数のバージョンをインストールして管理するのに、

のように、言語別のバージョン管理ツールを使っていました。

新たにElixirを覚えようかと思って、インストール方法を調べていたところ、asdfというツールを知り、ちょっと試してみたので、使い方などをまとめておこうと思います。

asdfとは

asdfは、READMEに、

Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more

とある通り、様々な言語に対応した拡張可能なバージョン管理ツールで、asdf plugins repositoryにある言語ごとのプラグインによってたくさんの言語の管理を可能にしているようです。

インストール

READMEに従って、インストールしてみました。ターミナルで、

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.5.1

を実行後、

echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.zshrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.zshrc

とするとインストールできます。(zshを使っている場合です。)

使い方

プラグインの管理

asdfで言語を管理するには、言語ごとのプラグインを追加する必要があります。

利用可能なプラグインは、asdf-vm/asdf-plugins: Central plugin repository for asdfで公開されています。

asdfインストール直後は、何のプラグインも入っていません。

一覧

asdf plugin-list

で、追加したプラグインの一覧が確認できます。

追加

プラグインを追加するには、

asdf plugin-add <name>

を実行します。例えば、erlangelixirのプラグインを追加するには、

asdf plugin-add erlang
asdf plugin-add elxir

を実行します。

このあと、plugin-listで確認すると、

asdf plugin-list
elixir
erlang

が出力されます。

削除

プラグインを削除するには、

asdf plugin-remove <name>

を実行します。

言語の管理

一覧

特定の言語について、インストールされているバージョンの一覧を表示するには、

asdf list <name>

とします。 例えば、Elixirの一覧を表示するには、

asdf list elixir

を実行します。すると、

  1.7.3

のように出力されます。

インストール

特定の言語の特定のバージョンをインストーするには、

asdf install <name> <version>

とします。 例えば、Erlang21.1をインストールするには、

asdf install erlang 21.1

を実行します。すると、

Downloading OTP-21.1.tar.gz to /path/to/.asdf/plugins/erlang/kerl-home/archives
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   120    0   120    0     0    133      0 --:--:-- --:--:-- --:--:--   133
100 51.3M    0 51.3M    0     0  3774k      0 --:--:--  0:00:13 --:--:-- 4427k
Extracting source code
Building Erlang/OTP 21.1 (asdf_21.1), please wait...
APPLICATIONS DISABLED (See: /path/to/.asdf/plugins/erlang/kerl-home/builds/asdf_21.1/otp_build_21.1.log)
 * odbc           : ODBC library - header check failed

APPLICATIONS INFORMATION (See: /path/to/.asdf/plugins/erlang/kerl-home/builds/asdf_21.1/otp_build_21.1.log)
 * wx             : wxWidgets not found, wx will NOT be usable

DOCUMENTATION INFORMATION (See: /path/to/.asdf/plugins/erlang/kerl-home/builds/asdf_21.1/otp_build_21.1.log)
 * documentation  :
 *                  fop is missing.
 *                  Using fakefop to generate placeholder PDF files.

Erlang/OTP 21.1 (asdf_21.1) has been successfully built
Installing Erlang/OTP 21.1 (asdf_21.1) in /path/to/.asdf/installs/erlang/21.1...
You can activate this installation running the following command:
. /path/to/.asdf/installs/erlang/21.1/activate
Later on, you can leave the installation typing:
kerl_deactivate
Cleaning up compilation products for
Cleaned up compilation products for  under /path/to/.asdf/plugins/erlang/kerl-home/builds

Erlang 21.1 has been installed. Activate globally with:

    asdf global erlang 21.1

Activate locally in the current folder with:

    asdf local erlang 21.1

のように出力されます。一覧を確認すると、

asdf list erlang
  21.0.7
  21.1

となり、新しいバージョンがインストールされました。

アンインストール

特定の言語の特定のバージョンをアンインストールするには、

asdf uninstall <name> <version>

とします。

globalバージョン

特定の言語について、システムワイドなバージョンを指定する場合は、

asdf global <name> <version>

とします。 例えば、Erlang21.1をシステムのデフォルトとしたい場合は、

asdf global erlang 21.1

を実行します。これによって、asdfは、$HOME/.tool-versionsというファイルを生成し、

erlang 21.1

を書き込みます。

localバージョン

特定の言語について、特定のディレクトリ配下固有のバージョンを指定する場合は、

asdf local <name> <version>

とします。 例えば、/path/to/projectディレクトリで、Erlang21.0.7を使いたい場合は、

cd /path/to/project
asdf local erlang 21.0.7

を実行します。これによって、asdfは、/path/to/project/.tool-versionsというファイルを生成し、

erlang 21.0.7

を書き込みます。

現在のバージョンの確認

特定の言語について、現在使用しているバージョンを確認するには、

asdf current <name>

とします。 例えば、これまでの例を実行したとして、$HOME

asdf current erlang

を実行すると、

21.1    (set by /path/to/home/.tool-versions)

が出力され、/path/to/project

asdf current erlang

を実行すると、

21.0.7  (set by /path/to/project/.tool-versions)

が出力されます。

.tool-version

前述の通り、asdfはバージョンの特定に、.tool-versionsというファイルを使用します。 プロジェクトのディレクリにこのファイルを作成し、適宜バージョンを記述しておくことで、asdfにどのバージョンを使用するのかを伝えることができます。

例えば、あるプロジェクトで、

  • Ruby 2.5.1
  • Node.js 10.10.1

を使用する場合、.tool-versionsに、

ruby 2.5.1
nodejs 10.10.1

と書いておくことで、当該バージョンを有効にすることができます。

また、

To install all the tools defined in a .tool-versions file run the asdf install command with no other arguments in the directory containing the .tool-versions file.

とあるので、.tool-versionsに書かれたバージョンがインストールされていない場合は、

asdf install

を実行すると、足りないバージョンをインストールしてくれるようです。(試していないです…)


rbenvnvmとの共存ができるのかどうかなど、細かいことも調べていきたいですが、 1つのツールで複数の言語のバージョンをまとめて管理できるのは、とても便利そうです。