ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

bundler にサブコマンドを追加する

TL;DR

bundle-#{sub_command_name} というコマンドを作り PATH が通っている箇所に配置をすると bundle sub_command_name で呼ぶことができる。

本文

先日、X 回目の Rails Update 業を行いました。 今回の Rails Update 業は、久しぶりに再開したプロジェクトのため Rails 以外の gem から出されている deprecate warning を消すのに苦労しました。

その際、何のメソッドが呼ばれたことによって deprecate warning が出るのはわかっているので、bundler に入れている gem 群を grep できたらと思いました。

これを実現するには、以下のようなコマンドの組み合わせで実現できます。

$ bundle show --paths | xargs grep keyword

これを bundle grep keyword のように書けたらべんりだなーって思い、bundler のコードを読み実現できないかを調べてみました。

そこで見つけたのが、Bundler::CLI にある以下のコードです。

def self.handle_no_command_error(command, has_namespace = $thor_runner)
  if Bundler.settings[:plugins] && Bundler::Plugin.command?(command)
    return Bundler::Plugin.exec_command(command, ARGV[1..-1])
  end

  return super unless command_path = Bundler.which("bundler-#{command}")

  Kernel.exec(command_path, *ARGV[1..-1])
end

これを見ると、bundler 自体がサブコマンドとして用意していないサブコマンドは、bundler-#{command} というコマンドを探し、存在していたら実行してくれるように読めます。

そこで、bundler-grep という、gem を作ってみました。gem i bundler-grep して、環境変数などをセットすれば、お好きな grep コマンドで bundle show --paths 内を grep できるようになります。

余談

これを作っている最中に、それワンライナーでできるよと bundler に pull request 出してた人 から言われたため、このワンライナーだけではできない機能も入れたりしました。