torutkのブログ

ソフトウェア・エンジニアのブログ

RedmineのWikiページからカスタムクエリへリンクするマクロをプラグインとして用意

torutk.hatenablog.jp
で、RedmineのWikiページにカスタムクエリへのリンクを設けて、クリックすると所定のカスタムクエリの結果のチケット一覧ページに飛ぶようにする方法を模索し、Wikiマクロを作成することで解決の目途を立てました。

このWikiマクロを、プラグインとして展開できるように、また今後いろいろなマクロを追加していけるように構成を見直して、Githubにリポジトリをつくりました。
https://github.com/torutk/redmine_cozy_wiki_macros

今日の日記は、構成の見直しとGithubへ上げる作業のメモです。

プラグイン名

Redmineのプラグイン名は大半が、redmine_xxx のようにredmine_を付けています。最初、わざわざredmine_を付けるのはプラグイン名が長くなるし、redmineディレクトリ下のplugins下にはどうせRedmineのプラグインしか置かないので、redmine_を付けずにcozy_wiki_macrosとしました。

次に、Githubにリポジトリを作成する段になった際、Githubはユーザー名の下にフラットにリポジトリが並ぶので、cozy_wiki_macrosでは何のリポジトリか一見分からないです。Github上で分かりやすくするにはredmineを付けたくなり、redmine_cozy_wiki_macrosとしました。

プラグインを入れる際に、プラグイン名とGithubのリポジトリ名は別にしておいて、git cloneしたあとディレクトリ名を変更してもらう方法もあります。しかし、それはインストールする人への不要な手間となり、名前を変更し忘れインストール失敗の要因にもなるので、gitリポジトリをそのままcloneして生成されるディレクトリをプラグイン名にしました。

最近のプラグインは、リポジトリからpluginsディレクトリへcloneしてそのまま使うものが多くなっています。以前はよくプラグインの配布用zipファイルを展開し、そのままのディレクトリ名ではエラーになるのでinit.rbの中でregsiterで呼ばれる名前を調べ、その名前にリネームするということがありましたが、最近はgithubやbitbucketからcloneしただけで名前が一致するようになっています。

マクロを定義するファイルをinit.rbから呼ぶ

最初はinit.rbにWikiマクロ定義をべた書きしていましたが、複数のマクロ定義を収容するプラグインとしては1マクロ1ファイルで構成したくなります。

別なファイルを読み込む際に、Ruby on Railsで用意されているrequire_dependency を使うと、developmentモードで実行しているときは指定ファイルを変更すると再ロードが走るので、マクロ定義rubyソースファイルを修正したあとRailsサーバー(WEBrick)を起動し直すことが不要になって便利です。

plugin_name = :redmine_cozy_wiki_macros

Rails.configuration.to_prepare do
  %w{query_link}.each do |file_name|
    require_dependency "#{plugin_name}/#{file_name}"
  end
end

このように記述すると

redmine-3.3.1
  +-- plugins
        +-- redmine_cozy_wiki_macros
              +-- lib
                    +-- redmine_cozy_wiki_macros
                          +-- query_link.rb

のように、プラグインのlibディレクトリ下を基点に、#{plugin_name} がredmine_cozy_wiki_macrosに展開され、そのディレクトリ下にあるマクロ名に対応するソースファイルをロードします。

%w{query_link} のマクロ名は、複数記述する場合は空白で区切って記述します。
例)%w{query_link query_list}.each do |file_name|

この辺のマクロを複数定義するプラグインの作り方は、ほぼWiki Listsプラグインを真似ています。>感謝
http://www.redmine.org/plugins/redmine_wiki_lists

ローカルで作ったディレクトリをGithubに上げる

最初はRedmine開発環境上でpluginディレクトリ下にこのマクロ用のプラグインディレクトリを作成し、ファイルを2つ(init.rbとquery_link.rb)作り軽い動作確認を行いました。その段階でローカルのgitリポジトリを作ります。

まず、ディレクトリとファイルを作成します。ディレクトリ名は正式前の時の名前(先頭にredmine_がない)です。

~$ cd work/redmine-3.3.1/plugins
plugins$ mkdir cozy_wiki_macros
plugins$ cd cozy_wiki_macros
cozy_wiki_macros$ vi init.rb
 :
cozy_wiki_macros$ mkdir lib/cozy_wiki_macros
cozy_wiki_macros$ vi lib/cozy_wiki_macros/query_link.rb
 :

ローカルでgitリポジトリ作成

cozy_wiki_macros$ git init .
cozy_wiki_macros$ git add init.rb lib/cozy_wiki_macros/query_link.rb
cozy_wiki_macros$ git commit

Githubにリポジトリ redmine_cozy_wiki_macros を作成

ローカルのgitリポジトリとGithubのリポジトリを紐づけ

cozy_wiki_macros$ git remote add origin https://github.com/torutk/redmine_cozy_wiki_macros.git

Githubにコミット内容をpush

cozy_wiki_macros$ git push

プラグイン名をredmine_cozy_wiki_macrosに変更する際、ディレクトリ名を変える

cozy_wiki_macros$ cd lib
lib$ git mv cozy_wiki_macros redmine_cozy_wiki_macros

他の修正を加えた後に、git commit して pushします。

module定義

query_link.rbの先頭行

module RedmineCozyWikiMacros::QueryLink

は、Redmineのプラグイン名(redmine_cozy_wiki_macros)をキャメルケース化したものに一致していないとエラーとなりました。

マクロの引数チェック

プラグイン化するので、マクロの引数チェックとエラー表示をそれなりに記述しました。

    macro :query_link do |obj, args|

      begin
        raise 'no parameters' if args.count.zero?
        raise 'too few parameters' if args.count < 2
        raise 'too many parameters' if args.count > 2
          :(中略)
      rescue => err_msg
        raise <<-TEXT.html_safe
Parameter error: #{err_msg}<br>
Usage: {{query_link(text, query_id)}}
TEXT
      end            

begin 〜 rescue 〜 end がrubyのエラー処理(例外処理)構文なようです。

マクロの引数をチェックし、所定の2個以外であれば例外を発生させます(raise)。
例外はrescueで拾います。raise時のエラーメッセージ文字列はrescueのerr_msgに入ります。これをもとに、エラー内容を説明する文字列を作り、さらにraiseします。

こうすると、誤った指定をしたら次のように説明が表示されます。