Redmineのプラグインをgem化するためのパッチの話
この記事は、Redmine Advent Calendar 2023 の8日目の記事です。前日の記事は、門屋さんの「RedmineにGoogleスプレッド+GoogleAppsScriptでチケット作成」でした。
はじめに
Redmine には、様々な用途に向けた大量のプラグインが提供されています。プラグインは、 plugins というディレクトリに手動でダウンロード、展開する、というインストール方式を取ってきました。
これに対しては、通常のrubyのライブラリと同じように、gem形式でインストールしたい、という要望が以前からあがっていました。(https://redmine.org/issues/27705)
やってみようと取りかかったのは、記録によると2022年4月らしいのですが、中断・迷走したあげく今年の8月に本家にパッチを投稿した(https://www.redmine.org/issues/27705#note-7)ので、そのことを書きたいと思います(本家に投げたパッチでは、gem化のサンプルとして、view customizeプラグインを使わせてもらいました。onozaty さんにはこの場を借りてお礼申し上げます)
本記事中では、上記の投稿にあわせて gem化したプラグインを”gemプラグイン”、従来のプラグインを”ファイルシステムプラグイン”と呼ぶことにします。
さっそく試してみる
redmine.org に投げたパッチはやや古くなっており、現在のRedmine trunk には、そのままでは適用できません。
github にブランチを作成しましたので、試してみたい、という奇特な方はこちらから clone してみてください。
上にも書きましたが、試行のため view customize プラグインをgem化しました。
Redmine をインストールしたディレクトリに Gemfile.extension というファイルを作り以下のように書き込み、bundle install
することでプラグインがインストールできます。
gem 'redmine-view-customize', git: 'https://github.com/tohosaku/redmine-view-customize'
, branch: 'rubygems'
今は、github からのインストールなので長々と URL を書き込む必要がありますが、このパッチが本格採用され、プラグインが rubygems.org にアップロードされた暁には Gemfile.extension に
gem 'redmine-view-cusomize'
と書き込んで bundle install
するだけでプラグインがインストールできてしまうわけです。
gemプラグインのメリット
- 上記の通りインストール方法が統一され簡単になる。
- Gemfile.extension というファイルに行を追加するだけ。
- プラグイン作者からすると、導入方法を細かく説明する手間が省ける。
- Redmine以外のRubyの開発に慣れている人にも理解しやすい。他の言語にも同じような仕組みはあるので説明もしやすい。
- Docker で運用する場合も、インストールのためにDockerfile にシェルスクリプトを記述するのではなく、Gemfile.extension をコピーするだけですむ。
- プラグインのバージョン指定も、Gemfile.extension に記入するだけになる。
- bundle update でプラグインのバージョンアップが可能になる。
- プラグインの脆弱性確認もcliで可能になる(当初のチケットの要望では、bundler-audit という仕組みで脆弱性チェックをしたいというコメントがありました)。
- プラグインに依存するプラグインなどの記述が簡単になる。
- 従来のプラグインの設定ファイル(init.rb)の中には依存を記述する機能がありますが、依存プラグインがインストールされているかどうかを判別できるだけでした。gemの設定ファイル(gemspecファイル)の中に依存関係を記述することで依存プラグインを自動的にインストールしてくれるようになります。
- 複数のプラグインで使用する共通機能をもったプラグインなどの、インストールが簡単になります。
gemプラグインのデメリット
- ユーザーの立場からは、しばらくはファイルシステムプラグインとgemプラグインが混在するようになる。
- プラグイン開発者の立場からは、過去のRedmineで利用されることも想定したコーディングが必要となります。ひとつのブランチでgem形式とファイルシステム形式の両方に対応できる仕組みとはなっていますが、依存gemの記述がやや煩雑になります。
- ささっと導入してささっと移行しよう!!
想定される問題と現在の対応
- 同じプラグインをファイルシステムプラグイン、gemプラグイン、双方の方式でインストールできてしまうのではないか?
- ファイルシステムプラグインを優先する仕様です(ログで警告が出ます)。
- 異なるgemプラグインのプラグインIDが重複した場合は?
- 例外を投げます。従来はプラグインのディレクトリ名とプラグインIDが合致している必要があったため、起こりえない事態だった。
- gem プラグインでは、gem名とプラグインIDの相違は許容している(rubygems.org にアップロードするときは、redmine-hoge-plugin といった名前でアップロードされることを想定。一方で、Redmine 内部では、hoge-plugin という名前で動くことを想定)
- プラグインの設定ファイル、init.rb と rubygems の設定ファイル gemspec の両方を管理する必要がある。情報の二重管理は面倒では?
- ここは実際に面倒。特に gemプラグイン専用とした場合、init.rb の属性の一部は gemspec と共用できるようになっているが、gemプラグインとファイルシステムプラグインの両方の方式に対応させようとるると、両方のファイルに同じような属性情報を記入しなければいけなくなる。
今後について
- この記事を読んで「良さそう」と思った方は、本家のチケットに「+1」の投稿をしてもらえると助かります。
- Redmine 本体がアセットパイプラインを利用するようになれば、テーマもgem化できるようになります。アセットパイプラインの説明は昨年のアドベントカレンダーに書いていますが、こちらも導入のパッチを投げてありますので、興味のある方は見てみてください。
Discussion