Noraworld Developers Blog
まだ anyenv (**env) 使ってるの? asdf を使おう!

はじめに

メジャーなプログラミング言語には、たいていバージョン管理システムがある。これを利用することで、プロジェクトごとに異なるバージョンの言語を使用することができる。

代表的なバージョン管理システムを以下に挙げる。

Language Version manager
Node.js ndenv
Ruby rbenv
Python pyenv
PHP phpenv

しかし、言語ごとにバージョン管理システムをインストールするのはめんどうだ。そこで、これらをまとめた anyenv というものがある。

このツールはとても便利で、筆者も利用していたのだが、一点、致命的な弱点がある。それは、ロードが遅い ことだ。

筆者は ndenv, rbenv, pyenv, phpenv の 4 種類を anyenv で管理していた。そして、シェル起動時にそれらをロードするようにしていた。

ロードするための設定を以下に示す。

# anyenv
if [[ -s ~/.anyenv ]]; then
  PATH="$HOME/.anyenv/bin:$PATH"
  eval "$(anyenv init -)"
fi

# ndenv
if [[ -s ~/.ndenv ]]; then
  PATH="$HOME/.ndenv/bin:$PATH"
  eval "$(ndenv init -)"
fi

# rbenv
if [[ -s ~/.rbenv ]]; then
  PATH="$HOME/.rbenv/bin:$PATH"
  eval "$(rbenv init -)"
fi

# pyenv
if [[ -s ~/.pyenv ]]; then
  PYENV_ROOT="$HOME/.pyenv"
  PATH="$PYENV_ROOT/bin:$PATH"
  eval "$(pyenv init -)"
fi

# phpenv
if [[ -s ~/.phpenv ]]; then
  PATH="$HOME/.phpenv/bin:$PATH"
  eval "$(phpenv init -)"
fi

ベンチマークを利用して正確に時間を計測したわけではないが、ここの部分の実行時間が、約 2.6786839962 秒だった。とても遅い……。

何かもっと良いツールはないかなと探していたら、asdf というものを発見した。これも複数の言語に対応したバージョン管理システムだ。

anyenv から asdf に置き換えたことにより、シェルの起動が驚くほど速くなった。

そこで今回はこの asdf のインストール方法と簡単な使い方について紹介する。

インストール

依存関係パッケージのインストール

curl と git が必要なので、インストールされていない場合はインストールする。例として Ubuntu の場合は以下のコマンドを実行する。

sudo apt install -y curl git

ただし、Homebrew 経由でインストールする場合は自動的にインストールされるので、対応不要。

asdf のインストール

3 種類の方法を紹介するが、おすすめは Zinit だ。

Homebrew

brew install asdf

続いて、以下のコマンドを実行する。

echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh"

実行後に表示されるスクリプトをそのまま ~/.bashrc や ~/.zshrc などに追記する。

Git

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

上記の場合、master ブランチの最新版がインストールされる。

master の最新版にはバグが含まれている可能性があるので、特定のバージョンをインストールする場合は --branch オプションを使用する。

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

続いて、以下を ~/.bashrc や ~/.zshrc などに追記する。

. $HOME/.asdf/asdf.sh

Zinit (おすすめ)

以下を ~/.bashrc や ~/.zshrc などに追記する。

zinit light asdf-vm/asdf

注: Zinit 自体をロードする部分は割愛。

補完機能

補完を有効にする場合は、~/.bashrc や ~/.zshrc などに以下も追記する。

Bash

以下のコマンドを実行した結果を ~/.bashrc にそのまま追記する。

echo -e "\n. $(brew --prefix asdf)/etc/bash_completion.d/asdf.bash"

Zsh

以下を ~/.zshrc に追記する。

fpath=(${ASDF_DIR}/completions $fpath)
autoload -Uz compinit && compinit

プラグインのインストール

使用する言語用のプラグインをインストールする。

以下で紹介されていない言語については、検索するとすぐに出てくるはずだ。

Node.js

asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git

Ruby

asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git

Ruby をインストールする場合は事前に openssl や readline をインストールしておく必要がある。

参考: Suggested build environment

Homebrew

brew install openssl readline

Ubuntu

sudo apt install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev

Python

asdf plugin-add python

言語のインストール

使用する言語とそのバージョンを指定してインストールする。

例として、Node.js 15.2.1 をインストールする場合は以下のコマンドを実行する。

asdf install nodejs 15.2.1

nodejs の部分を、それぞれ ruby や python にすることで他の言語もインストールできる。

また、15.2.1 の部分を latest とすると、最新版をインストールすることができる。

グローバルで使用する

インストールしたバージョンをグローバルで使用したい場合は以下のようにコマンドを実行する。

asdf global nodejs 15.2.1

ローカルで使用する

逆に、カレントディレクトリ以下でのみそのバージョンを使用したい場合は以下のようにコマンドを実行する。

asdf local nodejs 15.2.1

ちなみにこのとき、.tool-versions というファイルが生成されるが、.node-version や .ruby-version のような従来のファイルでバージョンを管理したい場合は、~/.asdfrc に以下を追加する。

legacy_version_file = yes

一時的に別のバージョンを使用する

カレントディレクトリ以下では 15.2.1 が使用されているが、このコマンドの実行時だけ一時的に 12.16.1 を使用したい、みたいな場合には環境変数 ASDF_NODEJS_VERSION が利用できる。

ASDF_NODEJS_VERSION=12.16.1 node -v
v12.16.1

グローバルにインストールしたコマンドを使用する

npm install -g <PACKAGE_NAME> や gem install <PACKAGE_NAME> などでインストールしたパッケージに、コマンドが提供されているものがある。

それらのコマンドを使用するためには、再読み込みをする必要がある。

asdf reshim nodejs

参考