はじめに
私の dotfiles では、ローカルの dry-run と GitHub Actions で、設定の変更を確認できるようにしています。dotfiles の設定適用にはスクリプトを使っていたのですが、手を入れるうちにスクリプトとテストコードが増えてきました。
そこで、シンボリックリンクの作成・解除や、パッケージ・開発ツールの導入を mise bootstrap に寄せました。
この記事では、もともとスクリプトで行っていた処理と、mise に移したあとの設定やコマンドを紹介します。
1. もともとはスクリプトで導入・解除していた
dotfiles のセットアップは、PC のリプレイスなどを除けば頻繁に実行するものではありません。
そこで、ローカルでは dry-run で適用・解除の内容を確認し、GitHub Actions では自動テスト用に HOME 相当のディレクトリを用意して、一連の操作を試せるようにしていました。
当初は、複雑なことをしていなかったので、mise のようなツールを使うのはオーバーキルだと考えていました。そのため、install / uninstall といった操作に使うスクリプトを書いていました。
その後、適用前に dry-run で内容を確認したい、ローカルと CI でできるだけ同じ操作を使いたい、と要件が増えていきました。導入処理とは別に、それらを支えるスクリプトやテストコードも増え、構成が複雑になってきました。
要件が増えるたびに、実装とテストの両方を変更する必要がありました。dotfiles の設定に加えて、導入・解除の仕組みも自分でメンテすることになっていました。そこで、mise bootstrap を使って、このあたりをまとめて管理することにしました。
2. dotfiles の配置とツールの導入を mise bootstrap にまとめる
mise bootstrap は、[dotfiles]、[bootstrap.packages]、[tools] などの設定をまとめて扱います。dotfiles だけを操作したい場合は mise dotfiles のコマンドを使えます。
dotfiles だけを操作するには、mise dotfiles を使えます。
2-1. シンボリックリンクの配置先を [dotfiles] に書く
mise.toml の [dotfiles] に、どのファイルをどこへ配置するかを記述します。下記は一例です。
[dotfiles]
# "<target>" = { source = "<リポジトリをルートとした相対パス>", mode = "<symlink/シンボリックリンクなど指定したいモード>" }
"~/.dotfiles" = { source = ".", mode = "symlink" }
"~/.bashrc" = { source = ".bashrc", mode = "symlink" }
"~/.bash_profile" = { source = ".bash_profile", mode = "symlink" }
"~/.gitconfig" = { source = ".gitconfig", mode = "symlink" }
"~/.config/mise/config.toml" = { source = "mise.toml", mode = "symlink" }
各エントリに mode = "symlink" を明示して、シンボリックリンクで配置するようにしています。たとえば、~/.bashrc にはリポジトリ内の .bashrc へのリンクを作ります。リンクの作成・解除は mise に任せるので、dotfiles 側では配置先の設定をメンテすることになります。
2-2. パッケージや開発ツールを [bootstrap.packages] と [tools] に書く
Homebrew で導入する Git は、同じ mise.toml の [bootstrap.packages] に書いています。
[bootstrap.packages]
"brew:git" = "latest"
Node.js や Python などの開発ツールは [tools] に記述します。mise bootstrap を実行すると、パッケージの導入、シンボリックリンクの配置、開発ツールの導入をまとめて行えます。私の構成では、Makefile から mise bootstrap を呼び出しています。
3. 一連の操作を Makefile に集約する
Homebrew と mise のセットアップからインストール、状態確認、アンインストールまで、Makefile を共通のエントリポイントにしています。mise 導入後の操作は、Makefile から mise-operations.toml のタスクを経由して mise bootstrap などを呼び出します。
make setup # Homebrew と mise を準備
make install # install 内容を確認(dry-run)
make install-apply # install する
make verify # install できたか確認
make uninstall # シンボリックリンクの解除対象を確認(dry-run)
make uninstall-apply # シンボリックリンクを解除
uninstall は実際にアンインストールするわけではなく、dotfiles のファイル群のシンボリックリンクを解除することに留めました。この点は「### 3-5. アンインストールではシンボリックリンクだけを解除する」で後述します。
3-1. 設定と操作を分ける
構成は次のようにしています。
Makefile
make install / make install-apply / make verify
│ mise run でタスクを呼び出す
▼
mise-operations.toml(操作用のタスク)
dotfiles:install / dotfiles:install:apply / dotfiles:verify
│ MISE_CONFIG_FILE で mise.toml を指定
▼
mise.toml(配置先・導入するものの設定)
[dotfiles] シンボリックリンクの配置先
[bootstrap.packages] パッケージ
[tools] 開発ツール
setup 以外の操作は mise-operations.toml のタスクを経由します。配置先や導入対象は mise.toml に置き、操作用のタスクとは分けています。
3-2. Makefile から操作用のタスクを呼び出す
Makefile では MISE_CONFIG_FILE に操作用の mise-operations.toml を指定し、mise run で対応するタスクを呼び出します。
MISE := mise
MISE_CONFIG := $(CURDIR)/mise-operations.toml
MISE_RUN = MISE_CONFIG_FILE="$(MISE_CONFIG)" MISE_TRUSTED_CONFIG_PATHS="$(CURDIR)" $(MISE)
.PHONY: install install-apply
install:
$(MISE_RUN) run dotfiles:install
install-apply:
$(MISE_RUN) run dotfiles:install:apply
3-3. タスクから mise.toml を読み込む
mise-operations.toml では、タスク内の MISE_CONFIG_FILE に mise.toml を指定します。これにより、操作用のタスクと、dotfiles やパッケージなどの設定を分けています。
[env]
DOTFILES = "{{ config_source | canonicalize | dirname }}"
[task_config]
dir = "{{ env.DOTFILES }}"
[tasks."dotfiles:install"]
run = 'MISE_CONFIG_FILE="$DOTFILES/mise.toml" mise bootstrap --dry-run'
[tasks."dotfiles:install:apply"]
run = 'MISE_CONFIG_FILE="$DOTFILES/mise.toml" mise bootstrap --yes'
mise.toml は ~/.config/mise/config.toml にシンボリックリンクで配置しますが、操作用の mise-operations.toml はグローバル設定にはせず、Makefile から明示的に指定しています。
3-4. dry-run、適用、状態確認を使い分ける
install 時は、適用内容の確認・実際の適用・適用後の状態確認でコマンドを分けています。
make install:mise bootstrap --dry-runで変更内容を確認するmake install-apply:mise bootstrap --yesで適用するmake verify:mise bootstrap status --missingで不足しているものを確認する
3-5. アンインストールではシンボリックリンクだけを解除する
アンインストールでは、環境全体を元に戻すのではなく、mise が管理しているシンボリックリンクだけを解除します。
make uninstall:mise bootstrap dotfiles unapply --dry-runで解除内容を確認するmake uninstall-apply:mise bootstrap dotfiles unapply --yesで管理しているシンボリックリンクを解除する
パッケージや開発ツールは残るため、環境全体を導入前の状態に戻す操作ではありません。
4. GitHub Actions では何を確認する?
GitHub Actions では、自動テスト用に HOME 相当のディレクトリを用意し、Makefile から一連の操作を試しています。mise 自体の挙動をテストするのではなく、mise.toml の設定と Makefile からの呼び出しを組み合わせて、ローカルと同じ操作が成立することを確認しています。
5. 補足:リポジトリに載せたくない設定
最後に、リポジトリに載せたくない設定の扱いにも少し触れておきます。Git の設定では、そうしたものを ~/.gitconfig.local に分け、リポジトリ内の .gitconfig から include で読み込んでいます。
[include]
path = ~/.gitconfig.local
リポジトリには記入例として .gitconfig.local.example を置き、実際の値は手元の ~/.gitconfig.local に記入する形です。
6. まとめ
dotfiles の導入・解除に使っていたスクリプトの処理を mise に寄せました。dry-run と GitHub Actions で変更を確認する流れは残しつつ、シンボリックリンクの作成・解除やパッケージ、開発ツールの導入は mise に任せています。
7. 参考リンク
- dotfiles リポジトリ
- mise の公式ドキュメント