PathScanner.native_callに絶対パス形式の除外ディレクトリサポートを追加

rails/bootsnap

bootsnap 1.22.0では、PathScanner.native_callが絶対パス形式での除外ディレクトリ指定に対応しました。これにより、BOOTSNAP_IGNORE_DIRECTORIESに絶対パスを設定した場合も正しく動作するようになり、シンボリックリンクの無限ループなどの問題を確実に回避できます。

背景

#457PathScanner.walkメソッド(PathScanner.ruby_callが使用)に絶対パス対応が追加されましたが、PathScanner.native_callの対応するコードには同様の実装がされていませんでした。この不整合が、#523でエラーハンドリングのrescueブロックが削除された際に顕在化しました。

PR作成者のプロジェクトでは、特定のディレクトリに無限シンボリックリンクループが存在し、BOOTSNAP_IGNORE_DIRECTORIESに絶対パスで除外設定していました。bootsnap 1.22.0へのアップデート後、rescueブロックの削除によりErrno::ELOOP: Too many levels of symbolic linksエラーが発生し、アプリケーションが起動できなくなりました。

技術的な変更

lib/bootsnap/load_path_cache/path_scanner.rbnative_callメソッドが、除外ディレクトリの絶対パス・相対パスを区別して処理するように変更されました。

変更前:

queue.reject! do |dir|
  ignored_directories.include?(dir) ||
    (contains_bundle_path && dir.start_with?(BUNDLE_PATH))
end

変更後:

ignored_abs_paths, ignored_dir_names = ignored_directories.partition { |p| File.absolute_path?(p) }
ignored_abs_paths = nil if ignored_abs_paths.empty?
ignored_dir_names = nil if ignored_dir_names.empty?

queue.reject! do |dir|
  if ignored_dir_names&.include?(dir)
    true
  elsif ignored_abs_paths || contains_bundle_path
    absolute_dir = File.join(root_path, dir)
    ignored_abs_paths&.include?(absolute_dir) ||
      (contains_bundle_path && absolute_dir.start_with?(BUNDLE_PATH))
  end
end

除外ディレクトリリストをFile.absolute_path?絶対パスディレクトリ名に分割し、それぞれ別のロジックで判定するようになりました。ディレクトリ名での判定は従来通り文字列比較で行い、絶対パスでの判定ではFile.join(root_path, dir)で完全なパスを構築してから比較します。

テストケースも3つ追加され、ディレクトリ名による除外、絶対パスによる除外、ネストされたディレクトリの絶対パスによる除外がそれぞれ検証されています。

設計判断

partitionによる事前分類と条件分岐の階層化により、不要な絶対パス構築を避ける設計が採用されました。

除外ディレクトリリストを絶対パスとディレクトリ名に事前分割することで、ディレクトリ名のみでの除外判定時にはFile.joinの呼び出しを完全にスキップできます。elsif ignored_abs_paths || contains_bundle_pathの条件により、絶対パスが1つも指定されておらず、バンドルパスチェックも不要な場合は、内部ブロック全体が実行されません。

また、空の配列をnilに変換する処理(ignored_abs_paths = nil if ignored_abs_paths.empty?)により、安全ナビゲーション演算子(&.)との組み合わせで条件判定を簡潔に記述しています。これはruby_callで使用されるwalkメソッドの実装パターン(ignored_directories.include?(name) || ignored_directories.include?(absolute_path))とは異なるアプローチですが、native_callでは大量のディレクトリを処理するため、パフォーマンスを重視した判断といえます。

まとめ

本PRは、PathScanner.native_callPathScanner.ruby_callの除外ディレクトリ処理の整合性を保つ変更です。絶対パス判定ロジックを追加することで、シンボリックリンクループのような問題を確実に回避できるようになり、bootsnap 1.22.0で顕在化したリグレッションが解消されました。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)、背景・技術的変更・設計判断(各論)、まとめ(結論)の3部構成が明確に適用されており、非常に分かりやすい構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```ruby:path/to/file)およびGitHubのPR番号へのリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

bootsnapの内部実装に関する内容であり、専門知識を持つエンジニアを対象とした適切な技術レベルと表現で書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が遵守されています。可読性が非常に高いです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されている変更前後のコードは、提供されたDiff情報と正確に一致しています。ファイルパスも正しく記載されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`PathScanner.native_call`、`partition`、`Errno::ELOOP`など、使用されている技術用語は文脈に適しており、正確です。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

コード変更に関する技術的な説明は正確かつ論理的です。`partition`メソッドによる処理の分割や、`File.join`による絶対パス構築の説明は、実際のコードの動作と一致しています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張(過去のPRとの関連性、問題が顕在化した経緯など)は、すべてPRのDescriptionで裏付けられています。「設計判断」セクションの推測もコードから導かれる妥当なものであり、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#526, #457, #523)やバージョン番号(1.22.0)などの数値・固有名詞は、PR情報と照合した結果、すべて正確でした。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「PathScanner.native_callに絶対パス形式の除外ディレクトリサポートを追加」は、PRのタイトルと内容を的確に要約しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

PR情報に記載のない、バージョンサポート状況やリリース日程などの外部知識は含まれておらず、事実に即した内容となっています。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「〜でしたが」「〜されていませんでした」「〜アップデート後」といった時間表現は、PR Descriptionに記載された時系列と一致しており、正確です。