【バージョンマネージャ】pyenv, nvmから卒業してasdfを使いましょうという話

## はじめに
**asdf**というバージョンマネージャがめちゃくちゃ便利なので紹介します。

https://asdf-vm.com/

**`pyenv`とか`nodenv`とか、言語ごとのバージョンマネージャ入れるの面倒だな〜〜**
って人におすすめです。
asdf単体でさまざまなパッケージのインストール〜バージョン管理が行えます。

<details>
<summary>asdfの使った感じ</summary>

```sh
$ asdf plugin add python
$ asdf install python latest
$ asdf local python latest
$ python -V
Python 3.12.3

$ asdf install python 3.9.9
$ asdf local python 3.9.9
$ python -V
Python 3.9.9

$ asdf list python
3.12.3
*3.9.9
```
</details>

## 目次
[1. インストール](#1-インストール)
[2. pluginの追加](#2-pluginの追加)
[3. バージョンのinstall](#3-バージョンのinstall)
[4.バージョンのセット](#4-バージョンのセット)
[おまけ](#おまけ)

## 1. インストール
macとlinuxしか対応してませんが、windowsの人はwslにubuntuとかlinux系のOS入れてもらうと使えます。

なおasdfのインストールに`git`と`curl`が必要になるので、事前にインストールしておく必要があります。

- mac
  ```sh
  brew install git curl  #インストール済であれば不要
  brew install asdf
  echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ${ZDOTDIR:-~}/.zshrc
  . ~/.zshrc
  ```
- linux
  ```sh
  apt install curl git  #インストール済であれば不要
  git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0
  . "$HOME/.asdf/asdf.sh"
  . "$HOME/.asdf/completions/asdf.bash"
  . ~/.bashrc
  ```

`asdf -v`が動けばOKです。

詳細については以下を参照ください。

https://asdf-vm.com/guide/getting-started.html

## 2. pluginの追加
asdfでは、一般的には`パッケージ`と呼ばれるものを`plugin`と呼びます。
pythonやnodejsもpluginとしてasdfに追加する形となります。
`asdf plugin list all`でpluginのリストを取得できるので見てみてください。`awscli`なんかもありますね。

:::note warn
量が多いので、適当なファイルにリダイレクトさせることを推奨します
`adsf plugin list all > asdf-plugin-list-all`
:::

今回はpythonのバージョン管理を想定します。

```sh
asdf plugin add python
```

でpluginの追加ができます。
追加したpluginは以下のコマンドで確認できます。

```sh
$ asdf plugin list
python
```

pluginを追加しただけではpythonは使えません。
pluginを経由して、特定のバージョンのpythonをinstallする必要があります。

## 3. バージョンのinstall
追加したpluginでinstallできるバージョンのリストは以下で取得できます。

```sh
$ asdf list all python
2.1.3
2.2.3
2.3.7
(中略)
stackless-3.4.7
stackless-3.5.4
stackless-3.7.5
```

今回は最新をinstallしてみます。

```sh
$ asdf install python latest
python-build 3.12.3 /Users/user/.asdf/installs/python/3.12.3
python-build: use openssl@3 from homebrew
python-build: use readline from homebrew
Downloading Python-3.12.3.tar.xz...
-> https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xz
Installing Python-3.12.3...
python-build: use readline from homebrew
python-build: use ncurses from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.12.3 to /Users/user/.asdf/installs/python/3.12.3
asdf: Warn: You have configured asdf to preserve downloaded files (with always_keep_download=yes or --keep-download). But
asdf: Warn: the current plugin (python) does not support that. Downloaded files will not be preserved.
```

:::note info
最下部のwarnが表示される場合は`touch ~/.asdfrc`して、以下を追記してください。
`always_keep_download = yes`

https://github.com/asdf-vm/asdf/issues/1711
:::

installしたバージョンは以下で確認できます。
```sh
$ asdf list python
3.12.3
```

今回は3.12.3が入ったようですね。
ただしバージョンをinstallしてもまだpythonは使えません。バージョンのセットが必要になります。

## 4. バージョンのセット
バージョンのセットには`global`と`local`の2つのモードがあり、これらを使い分けます。
コマンドとしては以下のようになります。

```sh
asdf global python latest
asdf local python latest
```

結果としては、どちらを実行した場合でも`python`コマンドが使えるようになるのですが、`global`と`local`は以下の使い分けをします。(他のバージョン管理ツールを使っている方はピンとくるかと思います)

- global
  指定したバージョンを**全ディレクトリ**で使用する
- local
  指定したバージョンを**カレントディレクトリのみ**で使用する

なおlocalを指定した場合、カレントディレクトリに`.tool-versions`というファイルが出力されます。

```./.tool-versions
python 3.12.3
```

このファイルをたとえばgit管理するなどしてチームで共有する場合、共有された側は`.tool-versions`のあるディレクトリで`asdf install`すると必要なplugin@バージョンをinstallできます。

若干余談でしたが、バージョンのセットを以て、asdfを使ったpythonのinstallは完了です！！！:tada:

## おまけ
よく使うコマンド集です。`asdf -h`でも全コマンド見れるので参照ください。

|コマンド|サブコマンド|引数|用途|
|:--|:--|:--|:--|
|plugin|list|all|追加できるpluginのリスト|
||add|`plugin_name`|pluginの追加|
|list|all|`plugin_name`|installできるバージョンの一覧|
|install||`plugin_name` `version`|バージョンのinstall|
|local||`plugin_name` `version`|バージョンのセット(local)|


## 最後に
個人的に好きなasdfの好きなところです

- `asdf`という名前
  - タイピングを極限までlazyにしたいという開発者の宗教的な思想が垣間見れて好き
- `.tool-versions`
  - このファイル見れば使ってるパッケージわかる+ローカルインストールもすぐ
  - パッケージごと(多くの場面では言語ごと)にファイルが生成されず`.tools-versions`だけで全てのパッケージ情報を管理できる

以上です！バージョン管理をスッキリさせたい方はぜひ！！！