Skip to content

Redmineのプラグインやテーマを、rubyの gem として導入できるようにしたい #81

@tohosaku

Description

@tohosaku

概要

現在、Redmineのプラグインやテーマは、public/themes や plugins にファイルを展開することで導入している。
しかし、導入方法はアーカイブの展開や git clone などバラバラであり、アップグレードの際にも個別に対応しなければいけない。

プラグインやテーマを gem として配布する方法が確立すれば、Redmine管理者は必要なプラグインをGemfileに記載し、bundle update を行うだけでアップグレードできる上、バージョンの指定も可能となる。

これを実現するためには、プラグインやテーマをロードする際に、gem の中にプラグインやテーマが含まれているかどうかをチェックし、初期化する機能が必要となる。

redmine.org の既存のチケットの中では、以下のものが該当している。

ただし、Redmine5.0 以降では、Rails6.1 へのアップグレードによってプラグインのロード方法が大幅に変わっていることから新しい対応が必要となる。また上記のチケットでは基本的にプラグインのみを対象としているが、テーマも統一した方法で導入したい。

ロード順序の問題

Redmine は(というか Railsアプリは)、アプリケーションの起動前に、Gemfileに記載された gemのクラス等をBundler.requireメソッドで一括ロードし、その後のアプリケーションの起動プロセスの中でRedmine本体のクラスをロードしている。
このため、Gemfileに記載したgemのコードの中に、Redmine本体のクラス等に依存するコードを記述したとすると、依存するクラスが発見できず起動できない(NameError)。

このため、gem化されたプラグインは、Bundler.requireの際にはロードされないような工夫が必要となる。

対処方法

Gemfile では、gem を groupメソッドでグループ化できる。development や、production、test といった、Rails 特有のグループ意外のグループを作成すると、そのグループのgemは、Railsの起動時にはロードされない。このため、プラグインやテーマは、extensionグループの中に入れる。
起動時には、gem をロードせず、Redmine起動時にプラグインをロードするタイミングで gem をロードする。

既存のディレクトリに重複したテーマ、プラグインがあった場合

プラグインの場合は、pluginsディレクトリに同名のプラグインがあった場合は、そちらを優先させる(二重に存在していることを検知して、ログに警告を出すのが望ましい)。
gemとして導入されたテーマは、起動時に、css や js をコピーする必要がある。ここで、public/themes 以下を優先してしまうと、gem のアップグレード時にファイルが更新されない、という問題が発生する。このためテーマについては、gemのインストール時に、public/themes をチェックし、同名のテーマが存在する場合は全部削除して新しいファイルをコピーする、といった対応が必要。

ただしRailsのアセットパイプラインを使用すればこのあたりの問題は解決するかもしれない。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions