rule がうまく機能しない
Rakeで、 rule の依存先が複数の場合、うまく動かないことがあるようです。
以下のような Rakefile の場合、
rule '.foobar' => ['.foo', '.bar'] do |t| sh "cat #{t.prerequisites} > #{t.name}" end rule '.foo' do |t| sh "echo #{t.name} > #{t.name}" end rule '.bar' do |t| sh "echo #{t.name} > #{t.name}" end
この場合、"hoge.foobar" の依存先は ["hoge.foo", "hoge.bar"] になると思うのですが、
% rake hoge.foobar (in /tmp) echo hoge.foo > hoge.foo echo hoge.foo > hoge.foo cat hoge.foo > hoge.foobar
rule の1つ目しか実行されていないようです(しかもなぜか2回)。
ただし例外として、2つ目以降のルールがタスクとして登録されている場合には問題ないようです。
% rake hoge.bar hoge.foobar (in /tmp) echo HOGE.BAR > hoge.bar echo hoge.foo > hoge.foo cat hoge.foo hoge.bar > hoge.foobar
rake.rb のソースを見ると、 attempt_rule 内で
def attempt_rule(task_name, extensions, block, level) sources = make_sources(task_name, extensions) prereqs = sources.collect { |source| if File.exist?(source) || Rake::Task.task_defined?(source) source elsif parent = enhance_with_matching_rule(sources.first, level+1) parent.name else return nil end } task = FileTask.define_task({task_name => prereqs}, &block) task.sources = prereqs task end
enhance_with_matching_rule を呼び出すときに sources.first を渡してますが、ここは source じゃないかと思います。
elsif parent = enhance_with_matching_rule(source, level+1)
とすることで、今回のケースは解決しました。
一応svnのtrunkとのdiffです。
Index: rake.rb =================================================================== --- rake.rb (revision 639) +++ rake.rb (working copy) @@ -1756,7 +1756,7 @@ prereqs = sources.collect { |source| if File.exist?(source) || Rake::Task.task_defined?(source) source - elsif parent = enhance_with_matching_rule(sources.first, level+1) + elsif parent = enhance_with_matching_rule(source, level+1) parent.name else return nil