rake

作業環境をrailsへ移行しよう、の1st stepとして、rakeで戯れてみる。rubyをはじめる前にrakeを検討したときは、イマイチ、ピンとこなかった(あたりまえか)のだけれど、rubyをはじめてからだと、かなりしっくりくる。これまで、

% cat my.rb
def task(file)
 # ...
end
% cat Makefile
target: source
    ruby -r my.rb -e 'task("$<")' > $@

とか記述していたのが

% cat Rakefile
def task(file1, file2)
  #...
end

file 'target' => ['source'] do
  task(t.name, t.prerequisites[0])
end

と、一ファイル(Rakefie)のみにまとまっていい感じ。でも結局、ファイルが一つにまとまる程度のメリットかな...と思っていたら、Martin Fowler氏が目から鱗の利用方法を披露していた

http://martinfowler.com/articles/rake.html#DefiningDependenciesBackwards

まず、依存関係を個別に宣言できるらしい。

task :second do
  #second's body
end

task :first do
  #first's body
end
task :second => :first

へーぇ。なるほど。また、rakeはrubyで記述しているがゆえに、こんな感じでTaskクラスにメソッドを追加できる。

class Task 
  def investigation
    result = "------------------------------\n"
    result << "Investigating #{name}\n" 
    result << "class: #{self.class}\n"
    result <<  "task needed: #{needed?}\n"
    result <<  "timestamp: #{timestamp}\n"
    result << "pre-requisites: \n"
    prereqs = @prerequisites.collect {|name| Task[name]}
    prereqs.sort! {|a,b| a.timestamp <=> b.timestamp}
    prereqs.each do |p|
      result << "--#{p.name} (#{p.timestamp})\n"
    end
    latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max
    result <<  "latest-prerequisite time: #{latest_prereq}\n"
    result << "................................\n\n"
    return result
  end
end

すると、

file target => src do |t|
  puts t.investigation
end

とかいう感じで、investigationメソッドが追加される。なんというか、渋い。