watchr - ファイルに変更があったら何かする / もしくはオサーンについて

みなさま、いかがお過ごしでしょうか。以前人のことをオサーンオサーン云いまくっていたけどその当時のオサーン年齢のもうすぐ三十路になります secondlife ですこんばんわ。言葉のしっぺ返しが痛い今日この頃です。

さて、若かりし頃には合わなかったけど今使ってみるとしっくり来る物もありますね。その一つが AutoTest(ZenTest) です。ファイルが更新したらこける / SyntaxError になると解っていてもテストが走りFFF、自分のテストサイクルでテストが実行できないのが我慢できませんでしたが、久しぶりに使ってみるとそんなのは気にならず、いちいちテスト実行しなくてよくなってとても気持ちがよい感じです。

しかしながら ZenTest に含まれる AutoTest はレールが敷かれているテスト環境では利用しやすいけど、ちょっと道を踏み外すと結構テストを実行するのがめんどくさいです。そんなとき、海外では結構使われているのが watchr というライブラリ。最近のライブラリのカレントディレクトリに spec.watchr のようなファイルをちらほら見かけますが日本じゃ全く使われている気配がないので紹介します。

"flexible alternative to Autotest" との通り、AutoTest の代替としてももちろん使えますが、ファイルに変更があったら何かアクションをおこすという設定をさくっと書くことができます。

サンプルを見れば一目瞭然なんですが、

watch( 'test/test_.*\.rb' )  {|md| system("ruby #{md[0]}") }
watch( 'lib/(.*)\.rb' )      {|md| system("ruby test/test_#{md[1]}.rb") }

なかんじで watch() にマッチしたらアクション起こすコード書くだけです。それらを記述したファイルを name.watchr とカレントディレクトリに配置して watchr コマンドを叩くだけで簡単にファイル監視 -> アクションを行う事ができます。

もちろん Ruby のコードで色々できるので、たとえば css に変更があったら MozRepl 経由で Firefox をリロードなんかは

@telnet = nil
def browser_reload
  require 'net/telnet'
  @telnet ||= Net::Telnet.new({
    "Host" => "localhost",
    "Port" => 4242
  })
  # 見ているホスト名が localhost... ならリロード
  @telnet.puts("if (content.location.host.indexOf('localhost') == 0) content.location.reload(true)\n")
end

watch('^.*\.css') { browser_reload }

みたいにサクッと書くことができます。
また RSpec2 には特定の spec だけを実行する filter をよしなに記述することができるんですが、それができない RSpec1 で、特定の spec だけ実行したい場合、実行したい spec コードに # focus! とコメントしておくとそこの spec のみが実行されるようなコードはこんな感じに書けます。

def run(files_to_run)
  system("clear")
  file = Pathname.new(files_to_run)
  options = ''
  if file.exist?
    file.open.read.split("\n").each_with_index {|line, i|
      if line['# focus!']
        options <<  "-l #{i} "
      end
    }
  end
  puts("Running: #{options} #{files_to_run}")
  system("spec #{options} #{files_to_run}")
  no_int_for_you
end

watch('^spec/(.*)_spec\.rb') { |m| run_spec_matching(m[1]) }
...

アイデア次第で色々できそうな感じが良いですね。なお rspec + rails の組み合わせで使うには

とかを参考にすると良さそうです。

というわけで、みなさんも三十路に近づいてきたら、再度 AutoTest 系の自動テストを試してみるのも良いのでは無いでしょうか。なお三十路になる直前は、『まだ20代ですよ』と云うと三十路になった時ショックが大きいので、『もうじき三十路なんですよ』と云っておいた方がよいですよとありがたい忠告を、検索無料ですの会社の @ku さんからいただきました。ありがとうございます…。