mise pruneはどうやって使用中のバージョンを判定しているか

【mise】mise pruneで使われていないバージョンをまとめて削除する は、どの設定ファイルからも参照されなくなったバージョンを自動で検出する。この判定の元になっているのが~/.local/state/mise/tracked-configsというディレクトリで、これまでにmise installmise useを実行したプロジェクトの設定ファイルが記録されている。

tracked-configsの中身

jq = "1"と書かれたmise.tomlを持つ2つのプロジェクトでmise installを実行してから、tracked-configsディレクトリの中身を確認する。

$ ls -la ~/.local/state/mise/tracked-configs/
lrwxrwxrwx 1 root root 25 Sep  5 13:04 e3386870cea34a6e -> /work/project-a/mise.toml
lrwxrwxrwx 1 root root 25 Sep  5 13:04 f5111cca7a1b5843 -> /work/project-b/mise.toml

ハッシュ化されたファイル名のシンボリックリンクが並んでおり、リンク先はそれぞれの設定ファイルの絶対パスそのものである。設定内容のスナップショットではなく、パスへの参照だけを保持する軽量な仕組みになっている。

mise config ls –tracked-configsで一覧を確認する

シンボリックリンクを直接lsする代わりに、mise configのオプションで同じ情報を確認できる。

$ mise config ls --tracked-configs
/work/project-a/mise.toml
/work/project-b/mise.toml

この一覧が「どのプロジェクトがmise管理下のツールを要求しているか」の逆引きになる。あるバージョンがなぜprune対象にならないのか調べたい場合、この一覧の各設定ファイルをcatすれば、参照元を特定できる。

削除済みプロジェクトのリンクは自動では消えない

プロジェクトのディレクトリ自体を削除しても、tracked-configsのシンボリックリンクはすぐには消えない。project-bのディレクトリを丸ごと削除してから確認する。

$ rm -rf /work/project-b
$ ls -la ~/.local/state/mise/tracked-configs/
lrwxrwxrwx 1 root root 25 Sep  5 13:04 e3386870cea34a6e -> /work/project-a/mise.toml
lrwxrwxrwx 1 root root 25 Sep  5 13:04 f5111cca7a1b5843 -> /work/project-b/mise.toml

f5111cca7a1b5843はリンク先が存在しないdangling symlinkとして残り続ける。一方mise config ls --tracked-configsはリンク先が実在するものだけをフィルタして表示するため、削除済みのプロジェクトは一覧に出てこない。

$ mise config ls --tracked-configs
/work/project-a/mise.toml

mise pruneのバージョン判定も同様にリンク先の実在を確認して行われるため、プロジェクトを削除しただけであれば、そのプロジェクトだけが必要としていたバージョンは正しくprune対象になる。ただしディスク上のtracked-configsディレクトリ自体には、削除済みプロジェクトを指す空のシンボリックリンクがゴミとして溜まり続ける。

環境変数では隔離できない点に注意する

【mise】MISE_DATA_DIRでツールのインストール先ディレクトリを変更する で紹介したMISE_DATA_DIRは、ツールのインストール先を切り替えられる環境変数である。

【mise】MISE_GLOBAL_CONFIG_FILEでグローバル設定ファイルの場所を変更する で紹介したMISE_GLOBAL_CONFIG_FILEは、グローバル設定ファイルの場所を切り替えられる環境変数である。

しかしtracked-configsの保存先はこれらの環境変数の影響を受けない。常に実際のホームディレクトリ配下の~/.local/state/mise/tracked-configsに書き込まれる。動作確認用に使い捨てのプロジェクトディレクトリでmise installmise useを試す場合は注意する。その環境変数を隔離していても、実マシンのtracked-configsにパスが記録されてしまう。