rubygems の plugin を実装する【Red Data Tools開発者に聞け!】

Red Data Tools

前回の動画ではローカル環境にて Gem の開発を行う準備を整えました。

今回の動画からは実際に rubygems の plugin の実装をおこなっていきます!

Red Data Tools開発者に聞け!第24回 「RubyGemsとRDocの密結合を解消する」Part5

rubygems の plugin を追加する手順

rubygems の plugin を実装する手順については以下の公式ドキュメントにまとまっています。

Plugins - RubyGems Guides

要点だけをまとめていくと、plugin として読み込ませるためには rubygems_plugin という名前のファイルを作成する必要があること、require_path でロードされるルートディレクトリにそれを配置する必要があるという点です。

このルールに基づいたプラグインを持つ Gem がインストールされた環境においては、rubygems が実行されるたびにこのプラグインをロードして実行してくれます。

実際に rdocrubygems_plugin.rb を作成して試してみましょう。ファイルは以下の構成のように作成します。

❯ tree -L 1 ./rdoc/lib
./rdoc/lib
├── rdoc
├── rdoc.rb
└── rubygems_plugin.rb

確認のために rubygems_plugin.rb の中身は以下のようにしてみましょう。

# frozen_string_literal: true

pp "called!!!!"

適当な rubygems のコマンドを実行してみると called!!!! が表示されました。この通りプラグインがロードされて実行されていることがわかります。

❯ ruby -I rdoc/lib -I rubygems/lib rubygems/exe/gem list
"called!!!!"

*** LOCAL GEMS ***

abbrev (default: 0.1.0)
base64 (default: 0.1.1)
// ...

rubygems の中の rdoc に依存しているコードを移植する

いよいよ今回の本題である、rubygems の中にある rdoc に依存しているコードの移植をしていきます。

問題のコードは rubygems/lib/rubygems/rdoc.rb にある以下のコードです。

# frozen_string_literal: true

require_relative "../rubygems"

begin
  require "rdoc/rubygems_hook"
  module Gem
    RDoc = ::RDoc::RubygemsHook
  end

  Gem.done_installing(&Gem::RDoc.method(:generation_hook))
rescue LoadError
end

このコードは rdoc/rubygems_hook という rdoc にあるコードをロードして実行する必要がありました。この部分が密結合になってしまっているわけです。ですのでこの処理を rdoc 側に移してしまいましょう。

# frozen_string_literal: true

require "rdoc/rubygems_hook"

Gem.done_installing(&::RDoc::RubygemsHook.method(:generation_hook))

ただ移行するだけではなく少しリファクタリングも加えています。

begin-rescue 節は rdoc がインストールされていない環境では require に失敗するためエラーハンドリングをおこなっていたものです。今回は rdoc 側に実装するのでこのようなケースを想定する必要はありません。

module Gem を拡張する形で実装している部分も移行後はもはや不要です。こちらも修正を加えました。

実際に適当な Gem をインストールしてみましょう。

❯ ruby -I rdoc/lib -I rubygems/lib rubygems/exe/gem install settingslogic
Fetching settingslogic-2.0.9.gem
Successfully installed settingslogic-2.0.9
Parsing documentation for settingslogic-2.0.9
Installing ri documentation for settingslogic-2.0.9
Done installing documentation for settingslogic after 0 seconds
1 gem installed

Parsing documentation for settingslogic-2.0.9 という行が表示されていると思いますが、これは実際に rdoc/rubygems_hook が呼び出されて実行されたことを表しています。

これで問題のあるコードを移植することに成功しました!

しかし、これをそのままリリースするわけにはいきません。

なぜなら rubygems からは rdoc のドキュメントを生成する処理は削除してしまったので、rubygems のバージョンを上げて rdoc のバージョンが古いまま、という環境の人はドキュメントの生成がされない不具合が発生してしまうからです。

次回の動画ではこのような問題に対して、後方互換性を担保するためにはどうするか?というテーマで進めていく予定ですので、楽しみにして頂ければと思います!

コメント

タイトルとURLをコピーしました