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 出してた人 から言われたため、このワンライナーだけではできない機能も入れたりしました。