hidakatsuya.dev hidakatsuya

Redmine のプラグインとテーマを管理するコマンドラインツール Rexer を作った

Redmine のプラグインとテーマをまとめてインストールしたり、定義したまとまりに切り替えたりできるコマンドラインツール Rexer を作った。

https://github.com/hidakatsuya/rexer

使い方

asciicast

どんなツールなのかを理解するには、実際の使い方を見るのが早い。

まず、Redmine のルートディレクトリに次の内容で .extensions.rb を作る。

theme :bleuclair, github: { repo: "farend/redmine_theme_farend_bleuclair" }

plugin :redmine_issues_panel, git: { url: "https://github.com/redmica/redmine_issues_panel" }

ルートディレクトリで次のコマンドを実行すると、これらのテーマとプラグインがインストールされる。

rex install

成功すると、次のような内容が出力される。

Rexer: 0.3.0
Env: default

Themes:
 * bleuclair (master)

Plugins:
 * redmine_issues_panel (master)

rex install の中では次のことが行われる。

  1. 設定されたソース(GitHub や Git)からプラグイン・テーマを取得して、それぞれ plugins/ themes/ に配置
  2. プラグインが db/migrate を持っていれば bin/rails redmine:plugins:migrate NAME=plugin_name を実行
  3. installed フックが定義されていれば実行
  4. .extensions.lock ファイルを生成
  5. インストール結果を出力(rex state と同じ内容)

なお、v0.3.0 時点では bundle install には対応していないが #6 で対応中である。完全に忘れていた...。

インストールしたものを全て削除する場合は次のコマンドを実行する。

rex uninstall

これは次のこと行う。

  1. プラグインが db/migrate を持っていれば bin/rails redmine:plugins:migrate NAME=plugin_name VERSION=0 を実行
  2. uninstalled フックが定義されていれば実行
  3. プラグイン・テーマのディレクトリを削除
  4. .extensions.lock を削除

環境を定義する

開発版と安定版でプラグイン・テーマの状態(バージョンなど)を切り替えたいことがある。そんなときは次のように定義できる。

theme :bleuclair, github: { repo: "farend/redmine_theme_farend_bleuclair" }

plugin :redmine_issues_panel, git: { url: "https://github.com/redmica/redmine_issues_panel" }

env :stable do
  theme :bleuclair, github: { repo: "farend/redmine_theme_farend_bleuclair", branch: "support-propshaft" }

  plugin :redmine_issues_panel, git: { url: "https://github.com/redmica/redmine_issues_panel", tag: "v1.0.2" }
end

env ... do-end 以外の定義は暗黙的に env :default do-end として定義される。よって、上記は以下のように理解される。

default env をインストールする場合は

rex install or rex install default

stable env をインストールする場合は

rex install stable

現在 default env をインストールしていて、stable に切り替える場合は

rex switch stable

とできる。

なお、現在の状態を確認する場合は rex state を実行する。

$ rex state
Rexer: 0.3.0
Env: default

Themes:
 * bleuclair (support-propshaft)

Plugins:
 * redmine_issues_panel (v1.0.2)

rex install と rex update

これらのコマンドの名前と役割は非常に悩んだ。Rexer においてはそれぞれ次の用途で使う。

rex install [ENV]

ENV環境をインストールして利用できる状態にする。具体的には次のことを行う。

rex update

.extensions.lock を読み込み、現在インストールされているプラグイン・テーマを最新の状態にする。.extensions.rb参照しない

これらの説明はとても大事なので、別途 GitHub の README にも記載する。

installed / uninstall フックを定義する

プラグインの中には、追加のインストール手順が必要なことがある。例えば設定ファイルを作成したり。そういう場合は、次のようにする。

theme :bleuclair, github: { repo: "farend/redmine_theme_farend_bleuclair" } do
  installed do
    puts "installed"
  end

  uninstalled do
    puts "uninstalled"
  end
end

plugin :redmine_issues_panel, git: { url: "https://github.com/redmica/redmine_issues_panel" } do
  installed do
    puts "installed"
  end

  uninstalled do
    puts "uninstalled"
  end
end

なぜ作ったのか

今年の3月から Redmine を扱う会社にジョインしたこともあり、複数のプラグインやテーマ、Redmine 本体の開発を日々行っている。 Redmine やプラグイン・テーマの開発でも、当然 development と stable な状態があり、それぞれに含まれるプラグインやテーマの状態は異なる。

しかし、現在の Redmine にはプラグインやテーマを管理するような公式のツールは(私が観測する範囲では)存在しないため、 development と stable 環境の切り替えは手動で行ったり、スクリプトを書いて自動化したり、環境ごとの Redmine の開発環境を用意するなどの対応が必要となる。

Rexer はこれを解決するために作っている。

なお、Rexer という名前は非常に安易なもので、[Re]dmine E[x]tension Manag[er] である。コマンドラインツールなので、 とにかく短く打ちやすい名前にすることだけ考えて命名した。元々 Rex という名前で適当に作っていたので、gem もその名前にしたかったがすでに使われていたため、無理やり er をつけた。 名前を考えるのはとても難しい...。

Redmine Extension とは

Rexer では、Redmine プラグインとテーマのことを Redmine Extension と呼んでいる。 Redmine 界隈や公式には Redmine Extension という名前は一般的ではないが、プラグインとテーマを指す名前があった方が設計も実装もやりやすかったため、 Rexer においては Extension という名前で扱うことにした。GitHub の README でも冒頭の説明で説明している。

足りないこと

優先して対応している/しようと思っているタスクは https://github.com/hidakatsuya/rexer/issues を参照して欲しい。すでに述べたが bundle install の実行は完全に忘れていた...。

その他、細かいタスクとしては次のようなものを考えている。

上記のタスク + v0.3.0 で自分が必要な機能は一通り揃う。

最後に

今回使っている thorgit gem がとても便利だった。感謝。 また、設計や実装の面では kamal のコードを読み込んで参考にさせてもらった。とても勉強になった。