2013/12/29
今開いているファイルの *** をレジスタに
クリップボードと連携しておけば、さらに捗る。

2013/12/08
Redmineのプラグインで既存の文言を上書きする
この情報は Redmine 2.5 で不要になりました。→ tail -f pinzo.log: Redmine 2.5.0 からプラグインでの文言上書きが復活しています
Redmine のプラグインで本体の文言を上書きすることが出来ません。
昔はできたようなのですが、バージョンが違うのか I18n の仕様が変わったのか現在は出来ません。
ja:
project_module_documents: ドキュメント
project_module_calendar: 日程表
プラグインの ja.yml
にこんな記述をしても画面はかわりません。
通常、プラグインをロードすると、I18n.load_path
はこんな状態になります。
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.15/lib/active_support/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activemodel-3.2.15/lib/active_model/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.15/lib/active_record/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/actionpack-3.2.15/lib/action_view/locale/en.yml
$REDMINE_HOME/plugins/<plugin_name>/config/locales/en.yml
$REDMINE_HOME/plugins/<plugin_name>/config/locales/ja.yml
$REDMINE_HOME/config/locales/ar.yml
$REDMINE_HOME/config/locales/az.yml
$REDMINE_HOME/config/locales/bg.yml
--- 延々と Redmine 本体の言語ファイルが列挙
$REDMINE_HOME/config/locales/vi.yml
$REDMINE_HOME/config/locales/zh-TW.yml
$REDMINE_HOME/config/locales/zh.yml
rails/railties/lib/rails/engine.rb at 3-2-stable · rails/rails にあるように、I18n.load_path
の後ろのほうが優先度が高いので、本体の言語ファイルのほうが優先されてしまいプラグイン側で上書きすることができません。
プラグインの登録は config/initializers/30-redmine.rb
で行われていて、その際にプラグインの辞書ファイルが I18n.load_path
に登録されるのですが、この時点ではアプリケーション本来の辞書ファイルが登録されていないからでしょう。
じゃあどうすればいいのかというと、どこかで I18n.load_path
を調整して、プラグインの辞書ファイルを後ろの方にもっていくのがいいのかなと。
確実に行うなら、初期化完了時がよさげですね。
Rails::Engine
には after_initialize
という目的そのままの機能があるのでこれが使えそうです。
こんなコードを lib
あたりに突っ込んでおいて、init.rb
で require
すればOK。
I18n.load_path
はこんな感じになります。
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activesupport-3.2.15/lib/active_support/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activemodel-3.2.15/lib/active_model/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/activerecord-3.2.15/lib/active_record/locale/en.yml
$REDMINE_HOME/vendor/bundle/ruby/2.0.0/gems/actionpack-3.2.15/lib/action_view/locale/en.yml
$REDMINE_HOME/config/locales/ar.yml
$REDMINE_HOME/config/locales/az.yml
$REDMINE_HOME/config/locales/bg.yml
--- 延々と Redmine 本体の言語ファイルが列挙
$REDMINE_HOME/config/locales/vi.yml
$REDMINE_HOME/config/locales/zh-TW.yml
$REDMINE_HOME/config/locales/zh.yml
$REDMINE_HOME/plugins/<plugin_name>/config/locales/en.yml
$REDMINE_HOME/plugins/<plugin_name>/config/locales/ja.yml
2013/12/07
Railsのログに出力されるパラメータとSQLを整形するgemを作った
最初に
この記事は Ruby on Rails Advent Calendar 2013 - Qiita [キータ] の7日目の記事です。
前日は a_suenami さんの Railsでサービスとフォームを導入してみる話 - assertInstanceOf('Engineer', $a_suenami) です。
本題
こういう gem を作りました。
pinzolo/rails-flog - Github
rails-flog - RubyGems.org
Gemfile に下記を追加して bundle install
するだけで、ログに出力されるパラメータとSQLが整形して出力されるようになります。
gem 'rails-flog', :require => 'flog'
Redmine でのスクリーンショットはこんな感じ。
使用前

使用後

Railsアプリケーションに tmp/no-flog.txt
を配置すれば一時的に整形をやめることもできます。
残念なところ
作った経緯
- 先日、西脇.rb & 東灘.rb 合同もくもく会 7th - 西脇.rb & 東灘.rb に参加した時に、@jnchito さんが、色々と awesome_print で出力するWebサービスを作成されてて、その際にログに出力される複雑なパラメータを手作業で整形するのがタルいみたいな事をおっしゃってまして、「あるある」と思っていた。
- んで、複雑なSQLもタルいよなー、整形してログに出力させるぐらいならできんじゃね?
- anbt-sql-formatter てのがあるじゃない。イケそう。
- 誰か作ってんじゃない?と調べてみると Railsのログに出力されるパラメータやSQLを整形する - ( ꒪⌓꒪) ゆるよろ日記 というそのものなものが見つかる。しかも自分でブクマ済み。
- もう少し調べてみるとどうやら同等の機能をもつ gem は存在していないみたい。
- 作ってみるか。
思うところ
我々エンジニアは誰しも素晴らしいプロダクトやサービスを作りたいと思っていると思います。
そして多くの人が時間、技術力、アイデア、ビジョン等々の不足であきらめているのでしょう。
でもエンジニアの本質は「素晴らしい物を生み出す」よりも、「一歩進める」ことだと思っています。
ひとが考えもしない方向へ一歩進められたり、一歩がとっても大きい人が素晴らしいプロダクトやサービスを生み出せるのでしょう。
出来なかったことをできるようにしたり、自動化したり、簡略化したり、みんな一歩進めた結果です。
rails-flog
も、アイデアも実装手段も他の巨人に乗っかったものですが、gemにするという一歩だけ進めることが出来ました。
一歩進めるだけなら誰にでもできるでしょう、さああなたも身近なものを一歩進めてみてください。
Next
明日は znz さんです。
2013/11/28
Coverallsで特定のファイルのみ集計対象にする
なにか作って Github に置く場合、基本的に Travis と Coveralls を利用している。
Coveralls を利用するのは簡単で、基本的には下記の手順で問題ない。
- coveralls の gem をインストールする
- .coveralls.yml を作成
- spec_helper などの最初に
require "coveralls"
してCoveralls.wear!
する - push する
とはいえ、これだとテストでロードされた全てのファイルが対象になってしまう。
全てのファイルが対象になるとスペックファイルの fail
とか、lib に突っ込んだ外部ライブラリとかも対象になってしまい、永久に 100% にならない。
それは困るので調べてみたら、ちゃんと公式に書いてあった。
なるほど、フォーマッタだけ Coveralls のを使用すればいいのね。
ちょっと、個人的に直感的じゃないなと思うのは、add_filter
の引数がパスに含まれているファイルやブロックにて true を返すファイルを除外するというところ。
フィルタなんだから、マッチするものだけを対象にするかと思ったら逆なんだな。

2013/11/23
Redmine のプラグインを Travis で CI してみた
Redmine のプラグインの場合、プラグイン本体のみ Github に登録しているので、そのままでは Travis で CI することができない。
諦めていたんだけど、.travis.yml のオプションとにらめっこしたらなんとなく出来そうな気がしたので試してみた。
10数回の試行を経て、なんとか出来たのでスクリプトを紹介します。
.travis.yml
before_install
があるので、after_install
があるかと思ったらなかった。before_install.sh
gem インストール前に実行させるスクリプト。
Travis ではbundle install
前に直下のGemfile
がBUNDLE_GEMFILE
環境変数に登録されてしまう。
しかし、指定したいのはプラグインのGemfile
ではなく、Redmine のものなのである。
なので、mv
しまくりでなんとかディレクトリ構成を整えた。苦労した。
Redmine のダウンロード URL がバージョンだけに依存してくれないのが少し残念。exec_test.sh
テスト実行用スクリプト。
前述のとおりafter_install
がなかったので、bundle install
後の処理(Redmineの初期化など)とテストの実行を同時にすることにした。
こちらはそんなに苦労しなかった。
これで、プラグインを複数バージョンの Ruby でテストすることができるようになった。
でも、複数バージョンの Redmine でテストすることは当然できない。
複数バージョンの Redmine を対象にテストするなら Jenkins 使うのがいいんだろうな。
2013/11/06
OS X Mavericks にすると gcc-4.2 がなくなるらしい
bundle install
したらエラーになった。
pinzolo@ileach [master] % bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata>from https://rubygems.org/..
Resolving dependencies...
Using rake (10.1.0)
Using i18n (0.6.5)
Using minitest (4.7.5)
Using multi_json (1.8.2)
Installing atomic (1.1.14)
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
/Users/pinzolo/.rbenv/versions/2.0.0-p195/bin/ruby extconf.rb
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/Users/pinzolo/.rbenv/versions/2.0.0-p195/bin/ruby
--with-atomic_reference-dir
--without-atomic_reference-dir
--with-atomic_reference-include
--without-atomic_reference-include=${atomic_reference-dir}/include
--with-atomic_reference-lib
--without-atomic_reference-lib=${atomic_reference-dir}/
/Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:431:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from /Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:516:in `try_link0'
from /Users/pinzolo/.rbenv/versions/2.0.0-p195/lib/ruby/2.0.0/mkmf.rb:814:in `try_run'
from extconf.rb:26:in `'
Gem files will remain installed in /Users/pinzolo/projects/detox/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14 for inspection.
Results logged to /Users/pinzolo/projects/detox/vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14/ext/gem_make.out
An error occurred while installing atomic (1.1.14), and Bundler cannot continue.
Make sure that `gem install atomic -v '1.1.14'` succeeds before bundling.
mkmf.log
見ろって言われたので見てみる。
pinzolo@ileach [master] % cat vendor/bundle/ruby/2.0.0/gems/atomic-1.1.14/ext/mkmf.log
"gcc-4.2 -o conftest -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0/x86_64-darwin12.4.0 -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0/ruby/backward -I/Users/pinzolo/.rbenv/versions/2.0.0-p195/include/ruby-2.0.0 -I. -I'/Users/pinzolo/.rbenv/versions/2.0.0-p195/include' -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -Wno-error=shorten-64-to-32 -fno-common -pipe conftest.c -L. -L/Users/pinzolo/.rbenv/versions/2.0.0-p195/lib -L. -L'/Users/pinzolo/.rbenv/versions/2.0.0-p195/lib' -lruby.2.0.0 -lpthread -ldl -lobjc "
sh: gcc-4.2: command not found
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main(int argc, char **argv)
4: {
5: return 0;
6: }
/* end */
gcc-4.2
がないらしい。
どうやら Mavericks にしたら、gcc-4.2
がgcc
になるらしい。
sudo ln -s /usr/bin/gcc /usr/bin/gcc-4.2
したら、解決した。
2013/09/08
RedmineのプラグインをRSpecでテストする
Redmineは基本的にはxUnitなコードでテストが書かれています。
今のところ例に習いxUnit形式でテスト書いていたんだけど、RSpecで書きたいなという欲求は当然あるわけです。
なので今回RSpecを導入してみた。
まずは、$REDMINE/plugins/<plugin_name>/Gemfile
を作成して、bundle install
# Gemfile
group :development, :test do
gem "rspec-rails", ">= 2.8.1"
end
$REDMINE/plugins/<plugin_name>/spec/spec_helper.rb
を作成し、設定を記述。
require File.expand_path(File.dirname(__FILE__) + '/../../../spec/spec_helper')
RSpec.configure do |config|
config.mock_with :mocha
config.fixture_path = "#{::Rails.root}/test/fixtures"
end
各種specファイルの冒頭で spec_helper
をrequireする。
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
# require 'spec_helper' ではダメだった。
基本的にはこれで設定はいいはずだけど、なぜかspecタスクで実行できない。
実行できないというよりspecファイルが見つけられないらしい。
rspec コマンドを指定しても不可能。
ベースディレクトリを指定してやれば実行できた。
$ bundle exec rake spec # ダメ
$ bundle exec rspec # これもダメ
$ bundle exec rake spec plugins/<plugin_name>/spec # これでもダメ
$ bundle exec rspec plugins/<plugin_name>/spec # これはOK
2013/08/20
[#nshgrb]西脇.rb & 東灘.rb もくもく会 6th と Kobe Rubyist Meetup に参加してきました
8/17に西脇.rb & 東灘.rb もくもく会 6th と Kobe Rubyist Meetup に続けて参加してきました。
いつも Kyoto.rb に参加してくださってる @spring_aki さんから、宣伝があったのと、SonicGarden の人が来るというのと、コードレビューつきもくもく会に興味があったので、新快速で一時間ほど揺られて行ってきました。
作ったもの
redmine_yare という簡単な Redmine のプラグインを作りました。
最近プライベートで Redmine のプラグインを作っているので、勉強がてらということととりあえず今回はもくもく会の中で完結するものを作りたかったので、シンプルなものにした。
画面遷移する度に今日が期限のチケットをダイアログ表示する非常に迷惑なプラグインです。
苦労したところ
フックのロジックとビューを分離するところが苦労した。
コレについてのまとめは後日に別エントリであげます。
もくもく会の感想
意外と3時間というのは短くて思ったより実装が進まなかった。調査に時間がかかったというのもあるけれど。結構時間を無駄に使っていたと思う。その都度しっかり意思決定していればもっと効率的な進め方が出来たと思う。
コードレビューでは、自分のコードはコード量自体が少なくてあまり突っ込まれなかった。(スペルミスしたけど)
気になったのは、レビューイと限られた人がメインでしゃべっている感じだったので、もっと全員でコードレビューしている感じがでるといいなと思う。(一人15分だし、スキルや経験の差があるのでしかたのないこととは思うが)
Meetup
懇親会はやっているけど、規模を拡大して Meetup は初の試みだったそうだ。
やっぱり酒が入って話しやすくなってくると濃い話が自然発生するのが楽しい。
正規表現の話や、Railsのコントリビュータの体験談などの話を酒を聞けるのは貴重な機会だった。
今後
特性上、大人数で行えないタイプの勉強会なので毎回参加というのは難しいとは思うが、また参加したいなと思う。
今回の ProMotion のお話のように、他者に新しい体験を提供できるようなネタがあればいいんだけど、しばらくは難しいかもな。Redmine のプラグインを頑張らねば。
西脇.rb と東灘.rb の皆様お疲れ様でした。

2013/08/01
Redmine plugin にて自動ロード対象のディレクトリを追加するには
どうやら Redmine はプラグインの lib は自動的にロードパスに登録するが、app 以下は controllers, models, helpers のみを autoload の対象にするようだ。
lib/redmine/plugin.rb にこんな記述があった。
2013/07/28
Redmine plugin 開発時の fixture
Redmine のプラグインのユニットテストのために、fixture を追加した。
$REDMINE/plugins/my_plugin/test/fixtures/my_models.yml
という形でテストデータを追加し、bundle exec rake redmine:plugins:test RAILS_ENV=test
を実行したらエラーになった。
Errno::ENOENT: No such file or directory - /Users/pinzolo/projects/my_plugin/redmine-2.3.1/test/fixtures/my_models.yml
つまり、プラグインのtest/fixtures
ディレクトリを見ていないということみたいだ。
プラグインの test/fixtures
を見るように設定するなら、$REDMINE/plugins/my_plugin/test/test_helper.rb
に下記を追加すればいいんだけど、こうすると $REDMINE/test/fixtures
を見てくれなくなる。
fixture_path
が配列でもよしなにやってくれるようにパッチを当てたいところだが、fixture_path
が結構ダイレクトに使われているので大変そうなのと、プラグイン側がやることでもなかろうということで、仕方なく $REDMINE/test/fixtures
にコピーする。
fixture を作ったり更新したりする度にコピーするのはめんどいな。