ビルド結果に影響を与えるファイルを突き止めろ!

ソースコードリポジトリからチェックアウトしてビルドする際に
「このビルドを実行する時、どのファイルが参照され成果物に影響するだろうか?」
と考えたことはありますか?

「このディレクトリの変更だけ監視してCIを走らせればオッケーです」
「このコミットは本番の成果物に影響を与えないのでテスト不要です」

本当でしょうか?
私たちはビルド結果に影響を与えうるファイル群を真に把握できているでしょうか?
ソフトウェア開発は人間の認知の限界を軽々と突破します。知らない間に想像していなかった依存がどんどん入り込んできます。
なので、私はツールなどの補助なしに人力では把握しきれないと考えています。

きっと GitHub Actions の paths-filter を漏れなく書くのは大変な仕事に違いありません。

Summary

という事でこの記事の三行まとめです。

  • ビルド時に使われるファイルは少なくともビルド時に参照が行われるだろう(仮説)
  • ビルド実行時に inotify などを用いれば参照されたファイルをリストアップすることができる(linux only)
  • sver というコマンドにリストアップのためのコマンド sver inspect を実験的に実装したよ

使い方など

Summary を書いたらこれ以上説明することも無くなってしまったので sver inspect というサブコマンドの使い方を書きます。
sver そのものの説明は 同じビルドやテストを何度も実行しない方法 というブログ記事を以前書きましたのでそちらを参照ください。

sver inspect はあるコマンドを実行する際にカレントディレクトリが所属する git リポジトリに inotify の watcher を仕掛け、コマンドの実行が終わった後にアクセスされたファイルをリストアップします。

コマンドの凡例は以下のような形式です。

sver inspect [OPTIONS] <COMMAND> [ARGS]...

例として cargo fmt --all を実行するときに参照されたファイルをリストアップする場合は以下のようになります。

sver inspect -- cargo fmt --all

-- はオプション形式の引数が sver コマンドに解釈されないための区切りです。-- 以降の引数はすべて COMMAND (この例では cargo )に渡されます。 実際に実行してみると以下のような出力になります。src だけでなく tests も参照されていることがわかります。

$ sver inspect -- cargo fmt --all
Cargo.toml
src/cli/args.rs
src/cli/mod.rs
src/cli/outputs.rs
src/filemode.rs
src/inspect.rs
src/lib.rs
src/main.rs
src/sver_config.rs
src/sver_repository.rs
tests/integration_test.rs
tests/test_tool.rs

このように、あるコマンドを実行したときにどのファイルが参照されるかをツールでリストアップすることで、想定していなかったビルドコマンドの依存も確実に検出することができるかと思います。

以上、今回実装したサブコマンドが皆さんの快適な依存関係把握ライフにつながれば幸いです。