Docs header transparent bg

Bundlerプラグインの書き方

プラグインとは?

Bundlerプラグインは、Bundlerの機能を統合・拡張することを目的とした特殊なgemです。このガイドでは、独自のBundlerプラグインの作成を始めるのに役立ちます。

なぜプラグインを使うのか?

プラグインは、Bundlerと統合し、拡張することができます。
現在、プラグインは以下のことが可能です

  • Bundlerにコマンドを追加する(例:bundle my_command
  • gemをインストールするための特別なハンドラーを追加する(例:MercurialやSVN)
  • 特定のフックポイントに機能を追加する
    • 利用可能なすべてのフック、その説明、およびブロック引数のリストは、plugin/events.rbファイルにあります。
    • 注意:使用しているBundlerのバージョンでevents.rbファイルを確認してください。

プラグインの使用

コマンドからプラグインをインストールする

プラグインは、RubyGems(デフォルト)またはGitサーバーからインストールできます。マシン上のgemを使用するには、bundler plugin install gem_nameを実行します。プラグインがインストールされると、コマンドが使用可能になり、フックが自動的にBundlerに登録されます。

Gitからのインストールに関する詳細なヘルプと手順については、bundler plugin help installを実行してください。

Bundler 2.2.0では、bundler plugin uninstall gem_nameでアンインストールできます。

Gemfileからプラグインをインストールする

Gemfileでプラグインを指定することもできます

plugin 'my_plugin' # Installs from Rubygems
plugin 'my_plugin', path: '/path/to/plugin' # Installs from a path
plugin 'my_plugin', git: 'https://github.com:repo/my_plugin.git' # Installs from Git

開発を始める

1. gemを作成する

Bundlerプラグインを作成する前に、まず特殊なgemを作成する必要があります。

このガイドを使用してgemを作成します。 完了したら、このガイドに戻ってステップ2に進みます。

2. plugins.rbファイルを作成する

plugins.rbファイルは、gemのフォルダーの最上位にあり、Bundlerがプラグインを呼び出すためのエントリポイントです。これは、コマンド、フック、その他のコードを定義するRubyファイルです。多くの場合、gemの最上位のlibファイルをrequireするだけで済みます。

たとえば、gemの名前が「my_plugin」の場合、lib/my_plugin.rbにgemの最上位の名前空間を含むファイルがあるかもしれません。plugins.rbファイルは次のようになります。

require 'my_plugin'

lib/my_plugin.rbファイルには、通常のgemと同様に、他のrequireステートメント、フック、およびコマンドが含まれます。

3. Bundlerコマンドの作成

Bundlerコマンドを使用すると、Bundlerインターフェースを拡張して機能を追加できます。

Bundlerコマンドを追加するには、自身(または別のクラス)をコマンドとして登録するクラスを作成する必要があります。たとえば、bundler my_commandコマンドのサポートを追加するには、次のようなクラスを作成します。

class MyCommand < Bundler::Plugin::API
  # Register this class as a handler for the `my_command` command
  command "my_command"

  # The exec method will be called with the `command` and the `args`.
  # This is where you should handle all logic and functionality
  def exec(command, args)
    if args.empty?
      # Using BundlerError in plugins is recommended. See below.
      raise BundlerError, 'My plugin requires arguments'
    end
    puts "You called " + command + " with args: " + args.inspect
  end
end

または

module MyCommand
  # Register this class as a handler for the `my_command` command
  Bundler::Plugin::API.command('my_command', self)

  # The exec method will be called with the `command_name` and the `args`.
  # This is where you should handle all logic and functionality
  def exec(command_name, args)
    puts "You called " + command_name + " with args: " + args.inspect
  end
end

コマンドをBundlerに登録するには、次の2つの要素が重要です。

  1. Bundler::Plugin::API.command(COMMAND_NAME, CLASS)またはcommand 'COMMAND_NAME'が、使用する方法に応じて呼び出されます(上記の例を参照)。
  2. クラスは、インスタンスメソッドexec(command_name, args)を定義します。

エラーの発生

何か問題が発生した場合、プラグインはBundlerErrorを発生させる必要があります。プラグインでExceptionなどを発生させることは推奨されません。これは、Bundlerが独自のバグレポートテンプレートを出力し、ユーザーにBundler自体にバグを報告するように求めるためです。

bundlerがどのようにエラーをrescueするかを詳しく見るには、bundler/friendly_errors.rbを確認してください。

4. Bundlerフックの使用

Bundlerのさまざまな部分とインターフェースするには、フックを使用できます。フックを使用すると、特定のアクションが発生するのをリッスンするように登録することで、特定のイベントで一部の機能を注入できます。イベントをリッスンするには、イベントのフックを追加し、ブロックを提供する必要があります。

たとえば、Bundler::Plugin::Events::GEM_BEFORE_INSTALL_ALLフックの場合、Bundler::Dependencyオブジェクトの配列の引数を持つブロックを提供する必要があります。

Bundler::Plugin.add_hook('before-install-all') do |dependencies|
  # Do something with the dependencies
end

5. ソースプラグインの開発

ソースプラグインを使用すると、Bundler内で使用できるインストールソースをさらに指定できます。たとえば、Amazon S3からgemをインストールしたいとします。これはプラグインを構築することで実現できます。

rubydoc.infoまたはソースコードで利用可能なBundler::Plugin::API::SourceのAPIに慣れることをお勧めします。

ソースプラグインの基本的な概要は、Bundler::Plugin::API::Sourceをサブクラス化し、多くのメソッドをオーバーライドする必要があるということです。これらのメソッドは、上記のリンクされたドキュメント/ソースコードに示されています。

Bundlerは、ソースプラグインAPIを使用して、RubyGems、Git、およびパスベースのgemのインターフェースを提供します。これらの部分のソースコードは、APIを理解する上で役立つ可能性があります。

6. ローカルでプラグインを実行する

ローカルでプラグインをインストールして実行するには、bundler plugin install --git '/PATH/TO/GEM' copycatを実行できます。

7. プラグインのデプロイ

他の人がインストールできるように、プラグインをRubyGemsにデプロイします。RubyGemsへのデプロイの手順については、このガイドをご覧ください。

プラグインはGitブランチからインストールすることもできますが、RubyGemsから直接インストールすることをお勧めします。

プラグインの例

以下は、例やインスピレーションとして使用できるプラグインのいくつかです

bundlerプラグインの完全なリストも確認できます。

エラーを見つけたり、何か不足していることに気づいたら、GitHubでこのドキュメントを編集してください。