トップ «前の日記(2024/09/11 (水) ) 最新 次の日記(2024/09/13 (金) )» 編集 RSS feed

HsbtDiary


2024/09/12 (木) [長年日記]

Gemfile に関係なく gem を読み込む force_activate というものを作った

irb を Ruby 3.5 で bundled gems にするにあたって、Bundler の環境下で Gemfile に irb がないときに binding.irb を実行したときに起動できないのは不便、という意見があり、それはそうだ、ともい最初に PoC として gemspec を読み込んで実現するというのを入れていた。

https://github.com/ruby/ruby/pull/11560

この方法はだいぶ強引というか最終手段になっていて、再帰的に gemspec の activate と require する必要があるというのと適当にバージョンを選ぶということができないので強引に見つかった最新バージョンを activate してうまく行ったらラッキー、失敗したら残念でした。というものだった。

で、さすがにねえ、ということと bundler/inline の不具合を直す過程で Bundler の内部の理解を深めたこともあって、以下の方針で Bundler の機能を使って書き換えた。

  • Gemfile か bundler/inline で読み込んだ gem の情報はそのまま使う(Bundler::Dsl)
  • その Bundler::Dsl に対して、今回なら irb の情報を差し込む
  • Bundler::Dsl から Bundler::Definition, Bundler::Runtime を作成して resolution を実行

できたものが以下

https://github.com/ruby/ruby/pull/11601

実際に実行してみると、Gemfile に irb が含まれてなくてもちゃんと irb を呼び出すことができるので、これはすごいと思う。他にも細かいところだと resolution の実行に際して lockfile の更新はしないとか、余計な表示はしないとかしている。

この機能を応用すると、rubocop をシュッと実行したいのに Gemfile に入れないとダメでだるいみたいな linter, formatter とか、あるいは stackprof, debug みたいな開発ツールについても oneshot でシュシュっと使えるようになるのでだいぶ体験が良くなると思うけどどうですかね。