はじめまして。つい先日、星空博士を目指すべく天文宇宙検定3級を受験した谷村です。
今回は最近触れて便利だったバージョン管理ツール、asdfについてのご紹介です。

伝えたいこと

  • asdfは複数のプログラミング言語のバージョン管理を統合できる。
  • asdfはプログラミング言語以外にもjq, tmuxなど多くのツールの管理にも対応している。
  • asdfすごい

皆さんバージョン管理ツール使われてますか?

例えば、複数のプロジェクトやマイクロサービスの開発に参加している時など、同じプログラミング言語を使用しているアプリでも、メンテナンス状況の関係で異なるバージョンを使わなくてはいけない場合があるかと思います。
そういった時にプロジェクトに応じた言語のバージョン切り替えが気軽に出来ると嬉しいです。

例えば、Pythonのバージョン管理ツールとしてよく知られてるのがpyenv, virtualenv, Anacondaなどです。
初めてPythonをインストールする時の案内にもよく出てくるかと思います。

pyenvのインストール・使い方は以下のようなイメージです。

# インストール
$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv

# PATHとpyenv用の設定をシェル起動時に読むために追加
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc

# 上記設定を読み込みます
$ source ~/.zshrc

# 使い方
$ pyenv install 3.9.6

# ディレクトリごとにバージョン指定したい場合
$ pyenv local 3.9.6
$ python --version
3.9.6

# ディレクトリを限定せずグローバルにバージョン指定したい場合
$ pyenv global 3.9.6
$ python --version
3.9.6

他にも各言語ごとに以下のようなバージョン管理ツールがあります。

言語 バージョン管理ツール
Ruby rbenv
Go goenv
Node.js nodenv

以降はこれらのツールを総称して、 env系ツール と呼ぶことにします。

また、これらのツールを統合して扱うのを補助してくれる anyenv というツールもあります。

env系ツールの少し辛いところ

前述の使用例のようにenv系ツールでも言語のバージョン管理は十分可能です。
しかし、扱うプログラミング言語が複数に渡る場合はどうでしょう。その場合は、扱う数分env系ツールのインストール、シェルの読み込み設定を書かなくてはなりません。
扱うプログラミング言語の数が少ない間は管理に困らないのですが、数が増える毎に少しずつ辛くなってきます。

env系ツールで管理する対象が増えた時に、私が考えられるデメリットをまとめると以下のようになります。

  • env系ツール自体を管理するコストが増える
  • シェル起動時に読み込むファイルの記述が増える
  • env系ツールが増える毎に少しだけシェルの起動が遅くなる
  • env系ツールがごとにホームディレクトリにディレクトリが増える (~/.pyenv, ~/.rbenv, ~/.goenvなど)
  • env系ツール毎に使い方を覚えなくてはいけない

実際、多くの場合許容できるデメリットではあるのですが、昨今は開発に非常に多様なプログラミング言語やツールを用いるようになりました。
検証で一時的に使いたい時にインストール手順を都度調べたり、検証で不要となった場合に後片付けが必要なのも面倒ではあるので、扱いが楽であるに越したことはありません。

そこで、これらの課題を解決する手助けをしてくれるのが、今回ご紹介する asdf です。

asdfとは

asdfは複数のプログラミング言語のバージョン管理に使えるツールです。プログラミング言語以外にも様々なツールの管理に対応しています。(この件は後述します。)

ツール名の由来は、手元のキーボードを見てみて下さい。QWERTY配列のキーボードでしたら「asdf」が横一列に並んでいると思います。
これは英語圏のネットスラングで、迷った時にとりあえず文字を埋めておく時や、感情が昂ぶった時にキーボードを叩くときなどに使われるみたいです。
日本で言う 「くぁwせdrftgyふじこlp」 に近いですね。

インストール方法

インストール方法は公式ドキュメントに記載されています。
Getting Started | asdf

Macの場合はbrewでインストールできます。

$ brew install asdf

使い方

ここではPythonをインストールする手順を紹介します

asdfではまず使いたいツールのpluginを追加する所から始めます。

# プラグインの追加
$ asdf plugin add python
or
# プラグインの管理リポジトリを指定する場合
$ asdf plugin add python https://github.com/asdf-community/asdf-python.git

インストール可能なバージョンを調べます。

$ asdf list-all python

追加したpluginを指定してPythonをインストールします。

# バージョン指定でインストール
$ asdf install python 3.10.8
or
# 最新バージョンをインストールする場合
$ asdf install python latest

インストールしたバージョンを有効化します。

# グローバルに有効化する場合
$ asdf global python  3.10.8
$ python --version
Python 3.10.8
or
# ディレクトリごとにバージョン指定する場合
$ asdf local python  3.10.8
$ python --version
Python 3.10.8

以上でPythonをインストールして使えるようになりました。
使い方はenv系ツールと似たような感じです。
自分の場合は、初めpluginの追加が少々面倒に感じたり、pluginを指定する引数の順番に苦戦していたのですが、慣れてくると特に気にならなくなります。

asdfの魅力

プログラミング言語に限らず様々なツールに対応している

私にとって一番魅力に映ったのはこの点でした。
asdfは先程紹介したようにpluginによってインストール可能なツールをどんどん追加できます。
このインストール対象はプログラミング言語に限らず、有名なもので行くと以下のようなツールに対応しています。

  • jq
  • kubectl
  • tmux
  • terraform
  • vim
  • yq

特にkubectlterraformなどはバージョンにシビアなため、asdf一つでまとめてバージョン管理出来るのはかなり嬉しいです。

pluginを追加する時は基本的に asdf-plugins を見に行くので、対応しているツールはこのリポジトリから探すことが出来ます。

asdfのplugin例

https://github.com/asdf-vm/asdf-plugins/tree/master/plugins

試しにこのディレクトリのファイル数を調べてみた所、 500種類以上のツールインストールに対応していることが分かりました。

❯ cd asdf-plugins/plugins
❯ find . -type f | wc
    547     547    5487

ただし、これらのpluginは一定の規約に則ってはいるものの有志によって作られています。
もし実際のインストール処理が心配であったり気になる場合は以下のような流れで確認できます。

以下はjqについて調べる場合の例です。

  1. pluginのファイルを確認
    https://github.com/asdf-vm/asdf-plugins/blob/master/plugins/jq
  2. ファイルに書かれているリポジトリを確認しにいく
    https://github.com/azmcode/asdf-jq.git
  3. リポジトリ内の bin/install が実際のインストール処理
    https://github.com/AZMCode/asdf-jq/blob/master/bin/install

注意点

pluginに依存ツールがある場合は事前にインストールが必要

pluginの対象に依存ツールがある場合は事前にインストールが必要です。
これらのツールはPATHの関係上、asdfで入れるのではなく直接インストールが必要なことがほとんどなためご注意下さい。

pluginがメンテナンスされる保証はない

asdfのpluginは誰でも作れるため非常に多くのツールに対応している反面、pluginのサポートは各pluginの管理者に委ねられています。

例えば alp というログ解析ツールがあるのですが、こちらもasdfでインストールするためのplugin、asdf-alp が存在します。
自分はこのpluginでalpのインストールを試みたのですが、私の使っているM1 Macではインストール出来ませんでした。

実際にpluginのインストール処理を見に行った所、CPUアーキテクチャに応じたURL生成の条件分岐にarm64が存在していなかったことが原因と判明しました。
そこで、Forkしたリポジトリで改修してみた所上手く行ったので、以下のようなPRを出してみました。
Support arm64 architecture for M1 mac by daylight55 · Pull Request #13 · asdf-community/asdf-alp

しかし、PRを作成した 2022/07/17 から4ヶ月以上経過した今現在(2022/12/09時点)でもこのPRは音沙汰がなく、M1 Macの対応はまだされていません。
→ 追記: 2023/02/23にマージされました!ありがとうございます!

分散管理される以上、plugin作成者がOSSとして積極的にメンテナンスする意志がなくては維持が困難な側面は否めません。
ニッチなツールを利用したい場合などは利用者が必要に応じてForkなどで対応する必要性は出てくると思います。

まとめ

以上がasdfの紹介でした。
ここでは簡単な利用方法のみ紹介しましたが、asdfは工夫するとより便利に扱えます。
例えばasdfのバージョンを記述する .tool-versions をドットファイルで管理すると新規環境構築が楽になったりもします。
もし気になる方がいらしたら是非公式ドキュメントの Getting Started | asdf もご参照ください。

また、 pluginの作り方も案内があります
「何でも良いからOSS開発してみたい!」という方には初めて取り組むのに難易度的にも丁度いいかもしれません。
自分も何かpluginを作れたらまたここで紹介しようと考えています。

それでは、良きバージョン管理ライフを!

プロフィール

谷村昌則
谷村昌則
エンジニア5年目。最近は専らAWS勉強中。作業効率化などが好きです。