mise を使って Erlang と Elixir をインストールする

## はじめに

今まで Erlang や Elixir 、 Node.js 、 Python などの言語、 Terraform 、 AWS CLI 、　jq などのツール類などは asdf で macOS にインストールしてました

https://asdf-vm.com/

しかし、知人から「最近は mise が良いよ」という話を聞いたので、 mise （ミーズ）に切り替えてみました

https://mise.jdx.dev/

## asdf の無効化

asdf で各種言語、ツールのバージョンを管理している状態を無効化します

最終的には asdf をアンインストールすれば良いのですが、全て消してから戻るのは面倒なので、とりあえず無効化だけしておきます

asdf を Homebrew でインストールしている場合、シェルの設定ファイル（bash の場合は `~/.bashrc` 、 zsh の場合は `~/.zshrc` ）から以下の行をコメントアウトします

```bash
. /opt/homebrew/opt/asdf/libexec/asdf.sh
```

:::note info
`asdf.sh` のバスは環境によって違うことがあります

asdf.sh の書いてある行をコメントアウトしてください
:::

## mise のインストール

mise の Getting Started に従ってインストールします

https://mise.jdx.dev/getting-started.html

macOS の場合は Homebrew でインストールします

https://brew.sh/ja/

:::note info
Homebrew は以下のコマンドでインストールします

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
:::

Homebrew で mise をインストールします

```bash
brew install mise
```

実行すると、最後に以下のようなメッセージが表示されます

```
If you are using fish shell, mise will be activated for you automatically.

zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions
```

メッセージに書かれてある通り、 fish を使っている場合は自動的に mise が有効化されます

bash の場合は以下のコマンドを実行し、 mise を有効化します

```bash
echo 'eval "$(/opt/homebrew/bin/mise activate bash)"' >> ~/.bashrc
```

zsh の場合は以下のコマンドを実行し、 mise を有効化します

```bash
echo 'eval "$(/opt/homebrew/bin/mise activate zsh)"' >> ~/.zshrc
```

## Erlang のインストール

まずは Erlang をインストールしてみましょう

mise には Erlang と Elixir のプラグインが最初から含まれているため、プラグインのインストールは不要です

https://github.com/jdx/mise/tree/main/src/plugins/core

新しいターミナルを開き、以下のコマンドを実行します

```bash
mise use -g erlang@latest
```

:::note info
`use -g` によって、デフォルトで使用するバージョンを指定しています

`@latest` で最新版をインストールします
:::

以下のような結果が表示されます

```
mise erlang@27.2 ✓ installed
mise ~/.config/mise/config.toml tools: erlang@27.2
````

Erlang のバージョンを確認してみます

```bash
erl -noshell -eval 'erlang:display(erlang:system_info(system_version))' -eval 'init:stop()'
```

実行結果

```
"Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n"
```

## Elixir のインストール

```bash
mise use -g elixir@latest
```

以下のような結果が表示されます

```
mise elixir@1.18.0-otp-27 ✓ installed
mise ~/.config/mise/config.toml tools: elixir@1.18.0-otp-27
````

Elixir のバージョンを確認してみます

```bash
elixir --version
```

実行結果

```
Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.18.0 (compiled with Erlang/OTP 25)
```

## バージョン指定のインストール

一時ディレクトリー配下で別のバージョンをインストールしてみます

```bash
mkdir mise_test
cd mise_test
```

まず Erlang

```bash
mise use erlang@26.2.5.6
```

実行結果

```
mise erlang@26.2.5.6 ✓ installed
mise ~/mise_test/mise.toml tools: erlang@26.2.5.6
```

続いて Elixir

```bash
mise use elixir@1.16.3
```

実行結果

```
mise elixir@1.16.3 ✓ installed
mise ~/mise_test/mise.toml tools: elixir@1.16.3
```

`mise_test/mise.toml` が以下の内容で作成されます

```toml
[tools]
elixir = "1.16.3"
erlang = "26.2.5.6"
```

これにより、 `mise_test` ディレクトリー配下では `mise.toml` に書かれたバージョンが使用されるようになりました

バージョンを確認します

```elixir
elixir --version
```

実行結果

```
Erlang/OTP 26 [erts-14.2.5.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.16.3 (compiled with Erlang/OTP 24)
```

asdf と同じ `.tool-versions` でバージョンを指定することもできます

`.tool-versions` の場合は以下のように記述します

```
elixir 1.16.3
erlang 26.2.5.6
```

`.tool-versions` と `mise.toml` の両方が存在する場合、 `mise.toml` が優先されます

`.tool-versions` があり、 `mise.toml` がない状態で `mise use` を実行すると、 `.tool-versions` が更新されます

つまり、 asdf を使っていた場合、何も変えずにそのまま mise を使うことができます

## インストール済バージョンの確認

以下のコマンドでインストール済バージョンを確認することができます

現在有効になっているバージョンは `~/mise_test/.tool-versions` のように、バージョン指定している設定ファイルのパスが表示されます

```bash
mise ls
```

実行結果

```
elixir     1.16.3         ~/mise_test/.tool-versions  1.16.3
elixir     1.18.0
erlang     26.2.5.6       ~/mise_test/.tool-versions  26.2.5.6
erlang     27.2
```

`-c` を付けることで、現在有効になっているバージョンだけを表示することができます

```bash
mise ls -c
```

実行結果

```
elixir     1.16.3         ~/mise_test/.tool-versions  1.16.3
erlang     26.2.5.6       ~/mise_test/.tool-versions  26.2.5.6
```

## インストール可能なバージョンの確認

以下のコマンドで Elixir のインストール可能なバージョンを確認することができます

```bash
mise ls-remote elixir
```

実行結果

```
0.12.4
0.12.5
0.13.0
...
1.18.0
1.18.0-otp-25
1.18.0-otp-26
1.18.0-otp-27
```

## 一括インストール

`mise_test/.tool-versions` を作っていた場合は削除し、　`mise_test/mise.toml` を以下の内容で作成します

```toml
[tools]
elixir = "1.17.3"
erlang = "27.2"
node = "22.12.0"
python = "3.13.1"
yarn = "4.5.3"
```

Node.js や Python も mise 自体にプラグインが含まれていますが、 yarn は外部のプラグインを使用します

しかし、外部のプラグインを使用する場合も、個別にプラグインのインストールをする必要はありません

`mise.toml` や `.tool-versions` があるディレクトリー内で以下のコマンドを実行すれば、プラグインも含めて一括インストールしてくれます

```bash
mise install
```

## 環境変数の設定

環境変数は `mise.toml` 内で以下のように指定できます

```toml
[env]
MIX_ENV = "dev"
_.file = ".env"
_.source = "./env.sh"
```

`.env` は [dotenv](https://www.npmjs.com/package/dotenv) による環境変数指定です

```
HELLO="dotenv"
HI="Elixir"
```

`./env.sh` はシェルスクリプトによる環境変数指定です

```
export MY_ENV_VAR="my value"
```

これらのファイルがある状態で環境変数を表示すると、正しく読み込まれています

```bash
printenv
```

実行結果

```
...
HELLO=dotenv
HI=Elixir
MIX_ENV=dev
MY_ENV_VAR=my value
```

これにより、特定ディレクトリー配下での環境変数設定が可能になっています

asdf でよく使っていた [direnv](https://github.com/direnv/direnv) も使用できますが、非推奨になっています

https://mise.jdx.dev/direnv.html

## Windows での mise について

mise は Windows にもインストールできます

:::note warn
後述しますが、 Python や Node.js では使えるものの、 Erlang や Elixir では使い物になりません

今後に期待です
:::

以下のように winget を使用して mise をインストールします

```powershell
winget install jdx.mise
```

https://learn.microsoft.com/ja-jp/windows/package-manager/winget/

scoop でのインストール方法も書かれていますが、まだプルリクエストがマージされていないため、エラーになります

```powershell
scoop install mise
```

https://scoop.sh/

https://github.com/ScoopInstaller/Main/pull/6374

PowerShell で以下のコマンドを実行することで、 mise でインストールした言語、ツールが有効化されます

```powershell
$shimPath = "$env:USERPROFILE\AppData\Local\mise\shims"
$currentPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$newPath = $currentPath + ";" + $shimPath
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
```

Python の最新版は以下のコマンドでインストールできます

```powershell
mise use -g python@latest
```

ただし、 Erlang は未対応のため、 mise ではインストールできません

Elixir は対応しているものの、バージョン番号の指定方法が macOS の場合と違っていたり、ダウンロード元が違っていたり（macOS は hex.pm 、 Windows は GitHub）するので、同じようには使えません

例えば 1.17.3 を使いたい場合、以下のようにバージョンを指定します

```bash
mise use -g elixir@1.17.3-elixir-otp-27
```

macOS の場合は `elixir@1.17.3` もしくは `elixir@1.17.3-otp-27` なので、 macOS と Windows でバージョン指定ファイルが共有できません

mise の Windows 版は vfox のプラグインを利用しています

https://github.com/version-fox/vfox

しかし、 vfox の Elixir プラグインの仕様が前述のようになっているため、このままだと macOS との統合が厳しい状況です

https://github.com/version-fox/vfox-elixir

Issue は上がっているものの対応されていないので、現状では期待できなさそうです

## asdf のアンインストール

使っているツールが一通り mise でインストール、使用できた場合、 asdf でインストールした各種言語、ツールプラグイン、 asdf 自体をアンインストールしましょう

## まとめ

mise を使って Erlang と Elixir をインストールできました（macOS では）

インストールも高速だし、プラグインも含めて一括インストールできるなど便利なので、 asdf から mise に移行したいと思います

Windows でも出来れば完璧だったのですが