redmine_auditプラグインのRedmine 4.1.0に向けた準備

自作のredmine_auditプラグインが4.1.0からは動作しなくなるはずなので修正した。 詳しくは以下のチケットにあるが、プラグインのidとディレクトリ名が一致しない場合は例外が挙がるようになってしまった。

init.rbのディレクトリ名を取れない理由は「難しい」以外なかったが、それはともかく対応するために以下でinit.rbでディレクトリを指定するようにした。こうした場合は(以前から)任意のディレクトリが指定できる。(自作のプラグインは自分の都合でgemで入れたいので入らない状態になる。自分で勝手にやってる事だから本体の修正の影響を強く受けるのはしょうがない

なお、関連して以下のチケットを発行したがプラグインには興味がない人が多いようなので、取り込まれるかはわからない。

こっちは、プラグインをレポジトリのtrunk/masterから入れる習慣がないため、redmine root/plugins/foo-1.2.3みたいなのを許しておいて欲しいと思ったため。レポジトリのタグを取ってきてもいい訳だけども、それはそれとしてできると嬉しいなぁ。全体的にプラグインがgemになるともっといいけど...そういう事考えなくていいし。

ちなみにgem化する方は以下でチケットを作ったりしてるんだけど、これがもし入ったとしても相当先の話になりそうだ。

2018年の山陰ITPro勉強会の年末の総会でGitHubの脆弱性通知について話してきた

昨晩の山陰ITPro勉強会の年末の総会でなんでもかんでも(難しければパッケージ管理用のだけでも)GitHubに置いて更新のタイミングがわかりやすいようにしようという年が忘れにくそうなお話しをしてきた。

自分で管理してるサイトが複数あるのだけど、このようにする前は「Jenkinsで何かするのはしんどいなー」な状況から、やった後は「ファイル一個置くだけとか超楽」という状況にはなった。

自分的にももっといいやり方ができればなと思ってる状態ではあるのだけど、現状何箇所かで試してる方法がこれ。JSまわりでなかなか更新がしにくい状況から、完璧ではないと思いつつも「更新が必要である」という状況はわかるようになって非常にGitHubさんありがとうございます的な感じ。

「何も知らなくても設定ができる」+「バージョンだけ更新すれば継続できる」というのが本当にすごいと思う。

SITWでも割と好評だったので話してみてよかったかも。

Redmine本体のリファレンスをバージョン情報付きで生成する

この記事は Redmine Advent Calendar 2018の12/15分です。今日はRedmineプラグイン開発用にRedmineのドキュメントにバージョン情報(いつから使えるか)を含めるというお話しです。以下の画像右側のような感じです。yardにuntilタグがないので、ちょっと見た目が悪いですね...

f:id:sho-hashimoto:20181216093519p:plain:w300f:id:sho-hashimoto:20181216093941p:plain:w300
バージョン情報追加前→後

これはRedmine本体のIssue#each_notificationが2.4.0から4.0.0の間で使える事を示しています。

それらを機械的Redmineのバージョンごとに見れるようにしたものが以下です。

とりあえずまとめ

リンク先もしくは画像にあるようにSince やDeprecatedのような情報が確認できるようになりましたので、Redmineプラグインのメンテナンスに使ってみようかと思っています。 ところでこれを yardoc.redmine.jp/Redmine/<redmine_ver>/以下かGitHubミラーのgh-pages(まだない)などで公開したいような気もしますね*1機械的に付与してる情報ですし、リリース毎に一回更新するだけだから、メンテナンスも難しくないので。

明日は @onozaty さんの予定です。お楽しみにー。

蛇足(やりかた)

以降はどうやって生成したかです。気になる人向け。

  1. Redmine本体のリファレンスの生成
  2. バージョン情報がないのでねじ込む

1. Redmine本体のリファレンスの生成

Redmineのリファレンスはyardで記述されています(正確にはrdocとyardのドキュメントが混在しているのですが...)。production環境以外ならbundle install後すぐに以下のコマンドでdoc/app以下にリファレンスを生成できます。

$ bundle exec rake yard

この後でdoc/app/index.htmlを開くとリファレンスが参照できます。なお、ありがたい事にここまでの情報は以下で公開されています。

ただし、このままだと現状のメソッドに関する記述はわかりますが、それぞれのメソッドがいつから使えるかわかりません*2。僕自身もredmine_auditという運用中のRedmineで更新が必要な脆弱性の対応がリリースされたら通知してくれるプラグインを作っているのですが、そこではRuby x Redmineの組み合わせ単体テストを実行しています。ですが、そもそもRedmine本体のメソッドを使う前にもう少し情報が欲しい感じです。

2. バージョン情報がないのでねじ込む

という事で生成時に機械的にねじ込みます。大まかには以下のようにするだけです。

  1. yardで各バージョンの.yardocを生成
  2. yard diffで各バージョンの.yardocを比較してバージョン情報の一覧を生成
  3. yardocのテンプレートを修正してリファレンス生成時にバージョン情報をねじ込み

バージョン情報の一覧はここに置きました。この辺は細かい話しは別記事を参照してください。最後にどうバージョン情報をねじ込むかですが、yardocは自分で作ったテンプレートが指定できます。それとバージョン情報の一覧を混ぜてやれば完成です。今回はテンプレート内でYARDの各種オブジェクト(MethodObjectなど)にadd_tagしているだけです。強引すぎる。

具体的には以下でやっています。この修正自体はRedmine本体をforkして入れてますけど、プラグインにしてタスクだけ生やしてしまうのがいいかもしれませんね。

ところで yard diff@sinceタグ を組み合わせるこの手順はRedmineに限らず使えるので便利ですね。(本当におしまい)

2018/12/16: 画像や文言等を少し修正。

*1:後日ここでチケットにしました

*2:本記事の前にパッチは投げたんだけど、手動で付与するのは大変など微妙な感じだったので諦めた

Redmine 3.0.0からのクラス/メソッドの変化を(詳細不明の)一覧にしてみた

yard diffが便利だったので、Redmine 3.0.0からのクラス/メソッドの変化を一覧にしてみた。

具体的な内容がわかるとより良いけど何か変化があった事がわかる程度。とりあえずGitHubのcompareのURLも付けるようにしたので現状は自分で詳細を確認する感じ。いつから使えていつ削除されたかがわかるだけでもRedmine本体のコードに依存するプラグインを作る時には多少は参考になるだろうか?と思って作ってみた。

ちなみにRedmine本体のドキュメントはyardで書かれてて、@sinceタグなんかも使えるので本当は本体にこの情報が付いてるとだいぶうれしい。以下でとりあえずRedmine::Pluginについてチケットにしてみたけど、メンテナンスに不安があるとの事なので、まだ取り込まれていない。そこで自動生成してみた。

やり方は以下。

  1. gitでredmineをcloneしてタグをcheckout
  2. yard doc --no-outputして.yardocだけ生成
  3. バージョンごとに.yardocがほしいので.yardocを.yardoc.<version>にmv
  4. 1〜3を調べたいタグ全部で実行
  5. yard diff .yardoc.<version1> .yardoc.<version2>を調べたいタグ全部で実行
  6. 5.の結果をadded/modified/removedなメソッドごとに分類

でも面倒くさいからとりあえず自動でやるようにした。特にRedmineに依存してないので、他のyardでドキュメントを書いてあるツールでも同じようにできると思う。

 

github.com

 まだちゃんとコマンドの出力を考えてないので、rake buildしてできたgemをインストールしないといけないけど、インストールしたら以下のようにできる。markdownの表を吐くだけだけど...というか、READMEすらない。便利そうならもう少し頑張るかも。

$ yard-method-since --from <version> --github redmine/redmine

 

手製のRedmineプラグインのCIを複数バージョンRedmine経由でまわすようにした

プラグインが動かないからRedmineのバージョンを上げれない」という意見をよく見る。ではどうすべきかと思い、とりあえず自分が作ってるRedmineプラグインredmine_audit の .travis.yml 周辺を更新して複数のバージョンのRedmineRubyでまわすようにした。

以下のようにenvを設定する(= 9パターンテストできる)ようにした。

env:
  - RUBY_VER=2.6.0-preview2 REDMINE_VER=master
  - RUBY_VER=2.6.0-preview2 REDMINE_VER=3.4-stable
  - RUBY_VER=2.5 REDMINE_VER=master
  - RUBY_VER=2.5 REDMINE_VER=3.4-stable
  - RUBY_VER=2.4 REDMINE_VER=master
  - RUBY_VER=2.4 REDMINE_VER=3.4-stable
  - RUBY_VER=2.3 REDMINE_VER=master
  - RUBY_VER=2.3 REDMINE_VER=3.4-stable
  - RUBY_VER=2.3 REDMINE_VER=3.3-stable

Travisから以下のようにdocker build→docker runの流れでコミットしたブランチを上述の組み合わせでテストしている。

before_install:
  - docker build -t ${TRAVIS_REPO_SLUG}:${RUBY_VER} --build-arg RUBY_VER=${RUBY_VER} --file=Dockerfile.travis .
script:
  - docker run -e REDMINE_VER=${REDMINE_VER} -e TRAVIS_BRANCH=${TRAVIS_BRANCH} -e TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG} ${TRAVIS_REPO_SLUG}:${RUBY_VER}

以下はその他の関連するファイル。Travisさんはほんと便利やで...

Dockerを使う事にした理由はRedmineからプラグインのテストを呼びたかったため。Redmine本体のコードに依存するテストはRedmineからrake redmine:plugins:testしてやる必要がある。(自分のプラグイン程度だと依存度が低いのでモックでもやれなくもないけど

実行スクリプトではプラグインマイグレーションは呼んでないので参考にする時はご注意を。(マイグレーション付きのプラグインは更にこれにDBの組み合わせが増える事になるのかな。

なお、本当は12パターンになる予定だった。Redmine 3.3系をRuby 2.4以上で回してないのは以下のチケットがあるため。SystemStackErrorになってしまうようだったが対応はされないようなので外した。新しいRedmine使ってくだされという事でいいと思うので自分でもパッチ投げたりはしない予定。

# 2018/07/22 更新: 少し移動や更新がやりやすくなるように修正。

松江Ruby会議09でRedmineについて発表してきた

松江Ruby会議のスタッフとして準備をしつつRedmineについて発表もしてきた。

Redmineの更新を楽にしたくてredmine_auditというプラグインを作った話をしたんだけど、Redmineどうでもいい人向けの情報も入れようとしたのが無駄だったかもしれない。Redmineの事だけ話せばよかったかも。

ところで自分はスライドたくさん書いてしまう人なんだけど、今回は15分で29枚だった。絵とかが多めだったりしたので多いけど多すぎというほどでもなかった(時間ややたりなかったけど)。そんな事を思ってたら懇親会でも「橋本さん、大人になりましたね」と冗談を言われてちょっとおもしろかった。

今日はMatsue.rb定例会だった

今日はMatsue.rb定例会だったので貯めてた作業を幾つかやっつけた。春が近づいてるのか人がたくさんだった。以下の作業をした(現時点ではまだいずれも取り込まれるかわかってない)。一方で今日はるりまの作業はお休みした。

最後のPRはちょっと気に入ってて、did_you_meanに手を入れて引数を間違えるArgumentError起こすと(わかる範囲で)正しいものを教えてくれるというもの。

require 'did_you_mean/experimental'

Dir.glob('*', 0, 1, 2)
# test.rb:n:in `glob': wrong number of arguments (given 4, expected 1..2) (ArgumentError)
# Did you mean?
#                  Dir.glob( pattern, [flags], [base: path] )
#                  Dir.glob( pattern, [flags], [base: path] ) { |filename| block }

Array.new(3, "foo", "bar")
# test.rb:n:in `initialize': wrong number of arguments (given 3, expected 0..2) (ArgumentError)
# Did you mean?
#                  Array.new(size=0, default=nil)
#                  Array.new(array)
#                  Array.new(size) {|index| block }

a = [1,2,3]
p a.slice(1, 2, 3)
# test.rb:n:in `slice': wrong number of arguments (given 3, expected 1..2) (ArgumentError)
# Did you mean?
#                  ary.slice(index)
#                  ary.slice(start, length)
#                  ary.slice(range)

実は前から欲しかったんだけど、どう実現しようかなと思ってたら @hanachin_さんのQiitaをみてひらめいたのでPRにしてみた。これはもしや沖縄Ruby会議効果でもあるのでは?などと思ったりもした。現時点だと少なくともCIに怒られてるのは直さないといけなさそうだけど...。

次回は4/21(土)の予定ですので松江近辺の人はよかったらどうぞ。