ぱろっと・すたじお

技術メモなどをまったりと / my site : http://parrot-studio.com/

Rakefileをrspec1.3仕様から2.x仕様に書き直す

Rails以外使ってない・使う気がないって方は、
そもそもRSpecのためにRakefileなんて書かないと思うので、
さくっとスルーしてもらう方向で


Rails3のRakefileは元々RSpec2.x用に作られているのでいいのですが、
別の古いプロジェクトでRakefileを使っていた場合、RSpecを2.x系にして1.3系を消してしまうと、
"rake spec"が実行できなくなります(´・ω・`) *1


もちろん、1.3系と2.x系は共存可能なのですが、
できれば新しい仕組みである2.x系に統一しておいた方が、混在リスクを回避できます


というわけで今回は、先日rdgc-dm0.2.2をリリースしたRDGCの例を元に、
RSpecの移行でどこを書き換えたのかをメモしておきます...φ(・ω・`)


なお、RDGCのソースはこちらで http://sourceforge.jp/projects/rdgc/

元のRakefile

require 'rake'
require 'spec/rake/spectask'

RDGC_TARGET = [:util, :map, :maker, :timer, :article, :device, :character, :monster]

namespace :rdgc do

  RDGC_TARGET.each do |target|
    Spec::Rake::SpecTask.new(target) do |spec|
      spec.libs << 'lib' << 'spec'
      spec.spec_files = FileList["spec/rdgc/#{target}/*_spec.rb"]
      spec.spec_opts = ["-c -fs"]
    end

    task target
  end

  Spec::Rake::SpecTask.new(:all) do |spec|
    spec.libs << 'lib' << 'spec'
    spec.spec_files = FileList['spec/rdgc/**/*_spec.rb']
    spec.spec_opts = ["-c"]
  end

  task :all
end

RDGC_TARGET.each do |target|
  task target=> "rdgc:#{target}"
end

Spec::Rake::SpecTask.new(:rcov) do |spec|
  spec.libs << 'lib' << 'spec'
  spec.spec_files = FileList['spec/rdgc/**/*_spec.rb']
  spec.rcov = true
end

task :all => "rdgc:all"
task :default => :all 

書き換えるポイント

  • require 'spec/rake/spectask' => require 'rspec/core/rake_task'
  • Spec::Rake::SpecTask => RSpec::Core::RakeTask
  • libsを削除
  • spec_files = FileList[hoge] => pattern = hoge
  • spec_opts => rspec_opts
  • (余計な)taskを削除


まず、名前空間が変わったので、requireとクラス名を変更します
spec_optsもrspec_optsに変わっています
(ちなみに実行コマンドも「spec」から「rspec」に変わってます)


次に、libsの設定を削除します
たぶん、他のメソッドで設定はできると思いますが、
適切な配置をしていた場合、自動でlib/やspec/が追加されます


そして対象となるspecの設定ですが、
FileList[patten]を使うのが標準的だったからか、
patternというメソッドで直接パターンを定義できるようになりました


最後に、taskの定義を除去しました
もしかすると、元々いらなかったかもしれませんが、
少なくとも2.xの場合は不要です

新しく書き直したRakefile

require 'rake'
require 'rspec/core/rake_task'

RDGC_TARGET = [:util, :map, :maker, :timer, :article, :device, :character, :monster]

namespace :spec do

  namespace :rdgc do

    RDGC_TARGET.each do |target|
      RSpec::Core::RakeTask.new(target) do |t|
        t.rspec_opts = ["-c", "-fs"]
        t.pattern = "spec/rdgc/#{target}/*_spec.rb"
      end
    end

    RSpec::Core::RakeTask.new(:all) do |t|
      t.rspec_opts = ["-c", "-f progress"]
      t.pattern = "spec/rdgc/**/*_spec.rb"
    end

  end

  task :all => "rdgc:all"
end

task :default => "spec:rdgc:all"


先ほど挙げたポイントの他に、RGDC固有の修正として、
「namespaceの変更」(rakeの用途はrspecの実行に限らない)と、
rcov定義の除去」を行っています


rcovについてはRSpecのサイトにもやり方が書いてあったものの、
どうしてもlib/以下のモジュールをrequireできませんでした
そもそも、rcov自体が(現時点では)1.9系で動かないので、バッサリと




・・・と、書いてはみたものの、特にRakefileが肥大化している場合、
全てのポイントを書き換えるのはそれなりのコストがかかります


先日書いたRVMのgemsetsを使って、
「(Rails3世代の)RSpec2.x系gem環境」と、「古いシステム向けのRSpec1.3系gem環境」を、
システムに応じて切り替えながら実行するってのが妥当かもしれません


まあ、最後まで書いてみてから気づいたんですけどね・・・Σ(・ω・ノ)ノ
あくまで自分用のメモいうことで、一つ*2

*1:蛇足かもしれませんが、実行できなくなるのは「rake spec」であって、個々のspecそのものを書き換える必要はありません

*2:今仕事でやっているシステムのフロントはRails3なのですが、バックのAPIは自分でRakefileを定義していて、RDGCに引き続きこっちもか・・・と思い、こうしてメモしてみたものの、たぶんもう書き換える機会はない気がするな・・・Σ(゚Д゚)ガーン