💨

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

2021/10/27に公開

はじめに

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

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

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

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

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

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

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

~/.zshrc
# 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 のインストール方法と簡単な使い方について紹介する。

インストール

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

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

Shell
sudo apt install -y curl git

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

asdf のインストール

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

Homebrew

Shell
brew install asdf

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

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

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

Git

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

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

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

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

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

~/.zshrc
. $HOME/.asdf/asdf.sh

Zinit (おすすめ)

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

~/.zshrc
zinit light asdf-vm/asdf

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

補完機能

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

Bash

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

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

Zsh

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

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

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

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

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

Node.js

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

Ruby

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

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

参考: Suggested build environment

Homebrew

Shell
brew install openssl readline

Ubuntu

Shell
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

Shell
asdf plugin-add python

言語のインストール

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

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

Shell
asdf install nodejs 15.2.1

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

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

グローバルで使用する

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

Shell
asdf global nodejs 15.2.1

ローカルで使用する

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

Shell
asdf local nodejs 15.2.1

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

~/.asdfrc
legacy_version_file = yes

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

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

Shell
ASDF_NODEJS_VERSION=12.16.1 node -v
v12.16.1

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

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

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

Shell
asdf reshim nodejs

参考

GitHubで編集を提案

Discussion