[rails/bootsnap] Rakeのcleanタスクでbootsnap cacheを削除可能に
Context
BootsnapはRubyアプリケーションの起動を高速化するライブラリで、load-path-cacheやcompile-cacheといったキャッシュファイルを生成します。これまで、これらのキャッシュを削除する標準的な方法が提供されていませんでした。#519で報告されているように、ユーザーが手動でキャッシュディレクトリを削除する必要がありました。
このPRでは、Rakeの標準的なcleanタスクにbootsnapのキャッシュディレクトリを追加することで、rake cleanコマンドでキャッシュを削除できるようにしました。これはMakefileのmake cleanに相当する、Ruby/Rakeエコシステムにおける慣習的なアプローチです。
Technical Detail
cache_dirのアクセサ追加
Bootsnap本体にcache_dirのreaderを追加し、セットアップ時に設定されたキャッシュディレクトリを外部から参照できるようにしました。
変更後:
class << self
attr_reader :cache_dir, :logger
end
setupメソッド内では、引数で受け取ったcache_dirに/bootsnapを付加したパスをインスタンス変数に保存します。
@cache_dir = "#{cache_dir}/bootsnap"
if load_path_cache
Bootsnap::LoadPathCache.setup(
cache_path: "#{@cache_dir}/load-path-cache",
# ...
)
end
Bootsnap::CompileCache.setup(
cache_dir: "#{@cache_dir}/compile-cache",
# ...
)
これにより、各サブシステムで重複していた"#{cache_dir}/bootsnap"という文字列結合を一箇所にまとめ、DRYな実装になりました。
Rake統合の新エントリーポイント
新しくlib/bootsnap/rake.rbを追加し、Rakefileからrequire "bootsnap/rake"することでcleanタスクとの統合が有効になります。
require "bootsnap"
require "rake/clean"
# デフォルトセットアップが未実行の場合は自動実行
require "bootsnap/setup" if Bootsnap.cache_dir.nil?
if Bootsnap.cache_dir
CLEAN.include Bootsnap.cache_dir
else
abort "Bootsnap must be set-up prior to rake integration"
end
実装のポイント:
-
opt-in方式:
require "bootsnap/rake"しない限り、Rakeの動作に一切影響を与えない -
柔軟な初期化順序: Bootsnap未セットアップの場合は
bootsnap/setupを自動読み込み - 拡張性: 将来的にプリコンパイルタスクなど他のRake機能を追加する際の統一エントリーポイントとして設計
-
先行事例: Bundlerも同様に
pkgディレクトリをCLEANに追加している
使用例
RailsアプリケーションのRakefileに以下を追加するだけで、rake cleanでbootsnapのキャッシュが削除されるようになります。
require_relative "config/application"
require "bootsnap/rake"
Rails.application.load_tasks
実行例:
$ rake clean
# tmp/cache/bootsnap 配下のキャッシュが削除される
テストの改善
PR内では、テストコードのエラーハンドリングも改善されています。cache.closeとcache.unlinkの呼び出しに安全なナビゲーション演算子(&.)を使用することで、cacheオブジェクトがnilの場合のエラーを防いでいます。
ensure
cache&.close
cache&.unlink
end
まとめ
この変更により、bootsnap利用者はrake cleanという標準的なコマンドでキャッシュクリアが可能になります。opt-in設計により既存のアプリケーションに影響を与えず、必要に応じて機能を有効化できる点が優れています。また、将来的な拡張を見据えた設計思想も含まれており、bootsnap/rakeは今後のRake関連機能の統一エントリーポイントとなることが期待されます。