prontoとは
githubのプルリクエストにrubocopなどのlintツールの結果をコメントしてくれるgemです。
https://github.com/prontolabs/pronto
prontoにはプラグイン機構がある
prontoはプラグインという機構を使って様々なlinterに対応できるようになっています。
たとえば、pronto-rubocopもプラグインとして提供されています。
https://github.com/prontolabs/pronto-rubocop
prontoがプラグインを読み込むまで
(1) thorで呼ばれるメソッド
CLIから入力を変換する部分です。
thorを使っており、thorのコマンドラインを呼び出すと下記がrunメソッドがコールされます。
https://github.com/prontolabs/pronto/blob/65dd2623750324bdff277b7a43529c228ed9d3cc/lib/pronto/cli.rb#L48
この中で次の ::Pronto.run
が呼ばれます。
(2) Pronto.run
ここでは、git diff
相当のオブジェクトを生成し、各プラグインにdiffオブジェクトを渡して、結果を受け取る、という処理です。
プラグインが読み込むまでを知りたいので、次は Runners.new.run(patches)
に潜ります。
(3) Pronto::Runners.new.run
Pronto::Runners
という名前からわかるように、Runner
のコレクションクラスです。Runner
とは何かというとプラグインのことを指しています。わかりにくいですね。
飛躍しますが、Runner.runners
が読み込んだプラグインを返しています。
module Pronto
class Runners
def initialize(runners = Runner.runners, config = Config.new)
@runners = runners
@config = config
end
Runner.runners
に値をセットする流れを見てみましょう。
(4) Pronto::Runner.runnersに値をセットするまで
Pronto::Runner
はPlugin
というmodelu
をinclude
しています。
Pronto::Plugin
moduleを見ると、 ingerited
というフックメソッドが書かれており、継承を行うと@repository
というインスタンス変数に値をセットしていることがわかります。
https://github.com/prontolabs/pronto/blob/65dd2623750324bdff277b7a43529c228ed9d3cc/lib/pronto/plugin.rb
pronto-rubocopを見てみましょう。
module Pronto
class Rubocop < Runner
[...]
pronto-rubocop は Pronto::Runner
を継承していました。継承することでプラグインとしてprontoが読み込んでくれるようになっていたんですね。
継承したクラスでは、linter毎に出力の違いがあるので、メソッドを適宜オーバーライドする必要がありそうです。
まとめ
Pronto::Runner
を継承するだけでプラグインとして読み込むことができる。