💻

asdf のバージョン アップがうまくいかなかった

2022/05/29に公開

最近、転職により業務環境が Windows から Mac に変わったことで、ツール類のバージョン管理として asdf を使用しはじめました。
asdf 自体のバージョンアップがうまくいかない事象に直面したため、解決方法をメモしておきます。

サマリ

Homebrew により asdf をバージョンアップしたら、asdf でインストールしたツールが使用できなくなりました。
shim ディレクトリ内のスクリプトに記述された asdf のパスが古いバージョンとなっていたことが原因でした。
shim ディレクトリを別のディレクトリに移動後、asdf reshim を実行することで shim ディレクトリ内のスクリプトを再生成することで解決しました。

asdf とは

まずは asdf とは何かを簡単に記載します。
asdf の公式ページ (英語)

asdf とは、Python や Terraform といったプログラミング言語/ツールのバージョンを管理するツールです。

プログラミング言語/ツールによってはそれぞれバージョン管理システムがあります。
Python なら pyenv、Terraform なら tfenv などです。

asdf は言語/ツールによらず、単一のツールで複数の言語/ツールを管理することができます。

また、asdf を使用すると、.tool-versions というファイルによりディレクトリごとに言語/ツールのバージョンを定義できます。
Git リポジトリで .tool-versions を管理することでプロジェクトで言語/ツールのバージョンを管理することができます。

バージョン アップの時に何が起こったか

asdf 自体のバージョンアップは、asdf のインストール方法によって異なります。
私の場合、Homebrew でインストールしていたため、下記のコマンドで 0.10.0 から 0.10.1 にバージョンアップを行いました。

brew update && brew upgrade asdf

他のインストール方法ごとのバージョンアップ方法は、asdf の公式ページをご覧ください。

バージョンアップ後、asdf でインストールした kubectl を実行した際、下記のエラーが発生しました。

/Users/hoge/.asdf/shims/kubectl: line 6: /opt/homebrew/Cellar/asdf/0.10.0/libexec/bin/asdf: No such file or directory
/Users/hoge/.asdf/shims/kubectl: line 6: exec: /opt/homebrew/Cellar/asdf/0.10.0/libexec/bin/asdf: cannot execute: No such file or directory

エラーメッセージから、古い asdf を実行しているようです。

エラーの原因

エラーの原因の前に、asdf がどのようにツールを実行しているかを簡単に説明します。

asdf では下記の流れでツールを実行しています。

  1. shell でツールを実行
    例: kubectl version --client
  2. shim ディレクトリ内の、ツールごとのシェル スクリプトを実行
    例: $HOME/.asdf/shims/kubectl
  3. ツールごとのシェルスクリプトにより asdf exec (ツール) (ツールの引数) を実行
    例: asdf exec kubectl version --client

エラーメッセージおよび上記の流れから、shim ディレクトリ内のシェル スクリプトで古い asdf を呼び出しているようです。
エラー発生時のシェル スクリプトの内容は下記の通りでした。

#!/usr/bin/env bash
# asdf-plugin: kubectl 1.23.6
# asdf-plugin: kubectl 1.22.9
# asdf-plugin: kubectl 1.21.12
# asdf-plugin: kubectl 1.24.0
exec /opt/homebrew/Cellar/asdf/0.10.0/libexec/bin/asdf exec "kubectl" "$@"

解決策

shim ディレクトリ内のシェル スクリプトに記載されている asdf のバージョンを直していけば修正されそうですが、全てのツールのシェル スクリプトを修正していくのは手間です。

調べていると、同様の事象が確認されているようです。
上記 Issue を参考に下記を実行したところ、解決しました。
なお $HOME/.asdf/shims が存在している状態で asdf reshim を実行しても修正されないため、ディレクトリの名前を書き換える必要があります。

mv $HOME/.asdf/shims $HOME/.asdf/shims_bk_0.10.0
asdf reshim

asdf reshim 後の shim ディレクトリ内のシェル スクリプトは下記の通りに修正されました。

#!/usr/bin/env bash
# asdf-plugin: kubectl 1.21.12
# asdf-plugin: kubectl 1.22.9
# asdf-plugin: kubectl 1.23.6
# asdf-plugin: kubectl 1.24.0
exec /opt/homebrew/opt/asdf/libexec/bin/asdf exec "kubectl" "$@" # asdf_allow: ' asdf '

修正後はバージョンに依存しない形となっています。
(元々この形であれば問題になっていなかったのでは...)

まとめ

shim ディレクトリ内のスクリプトが asdf のバージョンに依存していることがあります。
asdf のバージョンアップでスクリプトを修正してくれないので asdf reshim により修正する必要があります。

Discussion