1902 文字
5 分
日本語

設定は簡単だった。大変なのは維持することだ

一度きれいにした開発環境も、だいたい半年ほど経つと崩れてくる。この前きちんと調べたときは、1つだと思っていたPythonが3バージョンあり、Brewfileと実際のマシンが一致せず、mise listには何の実験で入れたのか思い出せないruntimeが並んでいた。何かが壊れたわけではない。毎日使う間に、元の状態から静かにずれていただけだった。

この記事でシリーズは最後になる。これまでの6本で扱ったのはレイヤー、設定、dotfilesだったが、そこまでは午後のうちに終えられる。1年後も同じ環境を保てるかどうかは、その後もずれを見つけ、不要になったものを取り除けるかにかかっている。

ずれ方はだいたい3種類#

実際に見つかるのは、主に次の3つだった。

ツールによる無言の自動インストール。 Pythonの記事では、uvが独自のPythonをダウンロードしていた。確認を求められないまま、自分で選んでいない状態がマシンに増えるため、最も見落としやすいずれ方だ。python-preference = only-systemのような宣言的な設定を使えば、無言のダウンロードを明示的なエラーに変えられる。ただし、あらゆるツールを設定だけで防げるわけではないので、結果を調べる手段は別に必要になる。

インストール後の同期忘れ。 自分でアプリを入れても、宣言ファイルへの追記を忘れることがある。するとアプリ管理の記事で作ったBrewfileが、実際のマシンから少しずつ遅れていく。普段は困らなくても、移行時には「これも入れていたのか」が一度に出てくる。復旧に使う段階まで放置せず、先に両方の状態を突き合わせておく必要がある。

使い終わったものの蓄積。 runtimeやグローバルツール、パッケージを必要があって入れ、一度だけ使い、そのまま残す。これは特に片づけにくい。個々の項目には問題がないため、エラーは出ず、リスト全体を見たときに初めて、積み重なったこと自体が問題だと分かる。

ヘルスチェックは、ずれを見せるだけでいい#

確認用に、いくつかのshell関数を残している。前の記事で紹介したbrewdiffはインストール済みアプリとBrewfileを比較し、zhealthはホームディレクトリに散らばったzshファイルを探す。Pythonは複数のツールが別々のインタプリタを持っても気づきにくいので、専用の確認も用意した。

Terminal window
# 30-functions.zsh — surface Python version drift across tools
pyversions() {
echo "shell PATH : $(command -v python)"
echo " reports : $(python --version 2>&1)"
echo "mise current : $(mise current python 2>/dev/null || echo '—')"
echo "uv would use : $(uv run python --version 2>&1)"
echo "mise list :"
mise list python 2>/dev/null | sed 's/^/ /'
}

pyversionsを実行すると、shellのpythonmise currentuv run python、そしてmiseにインストール済みのバージョンを一度に確認できる。最初の3つが一致していれば、このレイヤーは正常だ。一致しなければ、想定外のPythonをどこかのツールが持っている。Pythonの記事で行った調査を、確認コマンドを一から思い出すことなく繰り返せる。

ほかのレイヤーでも考え方は同じだ。

  • mise listと、実際に使っているmise.tomlを比較する
  • brew bundle checkで、マシンとBrewfileを比較する
  • $HOMEの中身が「zshファイルは1つだけ」という想定に合っているか確認する

どのチェックも自動修復はしない。これは意図的にそうしている。報告だけを行う小さなコマンドなら、挙動を把握しやすく、実行もしやすい。偶然見つけて驚くしかなかったずれが、自分で対処を選べる差分になる。

30日使わなかったものを見直す#

自分にとって成熟した環境とは、使っていないツールがほとんど残っていない環境だ。そのため、メンテナンスで行うことの多くは追加ではなく削除になる。

残すか迷うものについては、過去30日に実際に使ったかを考える。1か月触っていないruntime、グローバルツール、アプリは削除候補にする。自動的に消すわけではないが、残すのが当然のものから、残す理由が必要なものへ扱いを変える。

miseのruntimeなら、確認と整理は具体的だ。

Terminal window
$ mise list # what's installed
$ mise uninstall python@3.11 # remove a version no project uses
$ mise prune # drop versions nothing references

前回のRubyについての判断は、同じ基準をインストール前に適用した例でもある。システムRubyが古いというだけで、Rubyプロジェクトのないマシンにmise管理のRubyを追加する理由にはならない。必要なプロジェクトができるまで待てば、あとで確認して削除するruntimeも増えない。

この作業は、整理したい気分になるのを待たず、定期的に行う。新しいツールの導入は進歩のように感じやすい一方、削除には損失や、最初の選択が間違いだったと認めるような感覚がある。サンクコストも、放置するほうへ気持ちを傾ける。決まった作業にしてしまえば、チェックを実行し、30日使っていないものを見て、残す理由を説明できないものを消すだけで済む。

mise listの行が減ること、短いBrewfile、ホームディレクトリにdotfileが1つしかないことは、設定不足とは限らない。それが整理後の正しい状態である場合もある。

メンテナンスのためのシステムを増やさない#

掃除の仕組み自体も、簡単に作り込みすぎてしまう。ダッシュボード、定期ジョブ、大量のヘルスチェックを揃えた結果、それらを維持する仕事が新しく増えることもある。

2秒で終わるbrewdiffなら実際に使う。世話が必要な監視システムは使わなくなる。状態の突き合わせは、それによって避けられる混乱より低コストな間だけ役に立つ。だから確認ツールは小さく保ち、報告だけを任せ、削除の判断までは自動化しない。

シリーズ最初の記事では、環境をSystem、Runtime version、Package manager、Project dependenciesの4レイヤーに分けた。それらの設定だけでは用意できない5つ目の要素がある。たまにマシンを見直し、実際の状態と宣言した状態を比較して、壊れる前に両者を揃える習慣だ。

しばらく確認していないマシンなら、まずwhich pythonuv run python --versionを実行し、次にmise listから1か月触っていないものを探す。それだけでも、自分が覚えている環境と、手元にある環境がまだ同じかどうかは見えてくる。


この記事はSovereign Toolsシリーズの最終回です。全記事の順番はシリーズ一覧にまとめています。

設定は簡単だった。大変なのは維持することだ
https://www.shiinayane.com/ja/posts/maintenance/
著者
YANKAI WANG
公開日
2026-05-30
ライセンス
CC BY-NC-SA 4.0