On Tue, Apr 24, 2007 at 05:39:57PM +0900, Brian Candler wrote: > I had rails_rcov working perfectly last week. Now when I try it again on the > current iteration of the same project, it bombs out: This turns out to be an extremely weird problem. Firstly I made the following change to rails-1.2.3/lib/tasks/rails.rb --- rails.rb.orig 2007-04-21 21:24:18.000000000 +0100 +++ rails.rb 2007-04-24 12:23:01.000000000 +0100 @@ -4,5 +4,10 @@ Dir["#{File.dirname(__FILE__)}/*.rake"].each { |ext| load ext } # Load any custom rakefile extensions +begin Dir["#{RAILS_ROOT}/lib/tasks/**/*.rake"].sort.each { |ext| load ext } Dir["#{RAILS_ROOT}/vendor/plugins/**/tasks/**/*.rake"].sort.each { |ext| load ext } +rescue Exception => e +STDERR.puts "XXX #{e.message}\n#{e.backtrace.join("\n")}" +raise +end (ISTM that rake should not be hiding this exception when I give --trace) This gives me the following error: XXX undefined method `exclude' for nil:NilClass /usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/clean.rb:19 /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' /home/candlerb/svn/dev/projects/deploy2/trunk/config/../vendor/plugins/rails_rcov/tasks/rails_rcov.rake:30 /usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/tasks/rails.rb:9 /usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/tasks/rails.rb:9 /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' /home/candlerb/svn/dev/projects/deploy2/trunk/Rakefile:10 /usr/lib/ruby/1.8/rake.rb:1641:in `load_rakefile' /usr/lib/ruby/1.8/rake.rb:1713:in `run' /home/candlerb/svn/dev/projects/deploy2/trunk/vendor/plugins/rails_rcov/tasks/rails_rcov.rake:146 rake aborted! undefined method `exclude' for nil:NilClass /home/candlerb/svn/dev/projects/deploy2/trunk/Rakefile:10 (See full trace by running task with --trace) Line 19 of rake/clean.rb is CLEAN.clear_exclude.exclude { |fn| So it looks like CLEAN.clear_exclude is returning nil. This is where it gets interesting. I had gems for both rake-0.7.1 and rake-0.7.3 installed. The code for clear_exclude in rake-0.7.3 is def clear_exclude @exclude_patterns = [] @exclude_procs = [] calculate_exclude_regexp if ! @pending self end but in rake-0.7.1 it is def clear_exclude @exclude_patterns = [] calculate_exclude_regexp if ! @pending end and the latter clearly could return nil. I checked that nothing was referring to rake version 0.7.1 explicitly, but just to be on the safe side I uninstalled the rake-0.7.1 gem. However the problem remained. Next I made the following changes to rake: --- gems/rake-0.7.3/lib/rake.rb.orig 2007-04-24 12:47:03.000000000 +0100 +++ gems/rake-0.7.3/lib/rake.rb 2007-04-24 12:54:36.000000000 +0100 @@ -1084,10 +1084,12 @@ # Clear all the exclude patterns so that we exclude nothing. def clear_exclude +STDERR.puts "enter clear_exclude" @exclude_patterns = [] @exclude_procs = [] calculate_exclude_regexp if ! @pending - self +STDERR.puts "exit clear_exclude" + return self end # Define equality. --- gems/rake-0.7.3/lib/rake/clean.rb.orig 2007-04-24 12:49:15.000000000 +0100 +++ gems/rake-0.7.3/lib/rake/clean.rb 2007-04-24 12:57:38.000000000 +0100 @@ -16,9 +16,13 @@ require 'rake' CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"] -CLEAN.clear_exclude.exclude { |fn| +STDERR.puts "AAA CLEAN=#{CLEAN.inspect}" +cce = CLEAN.clear_exclude +STDERR.puts "cce = #{cce.inspect}" +cce.exclude { |fn| fn.pathmap("%f") == 'core' && File.directory?(fn) } +STDERR.puts "BBB" desc "Remove any temporary products." task :clean do And here's the result: $ rake test:units:rcov(in /home/candlerb/svn/dev/projects/deploy2/trunk) AAA CLEAN=[] enter clear_exclude exit clear_exclude cce = [] BBB rm -rf ./coverage/units /usr/bin/ruby1.8 "/home/candlerb/svn/dev/projects/deploy2/trunk/vendor/plugins/rails_rcov/tasks/rails_rcov.rake" --run-rake-task=test:units (in /home/candlerb/svn/dev/projects/deploy2/trunk) AAA CLEAN=[] cce = /^$/ XXX undefined method `exclude' for /^$/:Regexp /usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake/clean.rb:22 /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' /home/candlerb/svn/dev/projects/deploy2/trunk/config/../vendor/plugins/rails_rcov/tasks/rails_rcov.rake:30 /usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/tasks/rails.rb:9 /usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/tasks/rails.rb:9 /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require' /home/candlerb/svn/dev/projects/deploy2/trunk/Rakefile:10 /usr/lib/ruby/1.8/rake.rb:1641:in `load_rakefile' /usr/lib/ruby/1.8/rake.rb:1713:in `run' /home/candlerb/svn/dev/projects/deploy2/trunk/vendor/plugins/rails_rcov/tasks/rails_rcov.rake:146 rake aborted! undefined method `exclude' for /^$/:Regexp This proves that the gem installation of rake-0.7.3 is being run, but it is so weird that I cannot understand it at all. CLEAN.clear_exclude now appears to be returning a regexp rather than nil. But look at the code - it can't possibly be doing so! So finally I undid all those changes and made just this one: --- gems/rake-0.7.3/lib/rake/clean.rb.orig 2007-04-24 12:49:15.000000000 +0100 +++ gems/rake-0.7.3/lib/rake/clean.rb 2007-04-24 13:00:38.000000000 +0100 @@ -16,7 +16,8 @@ require 'rake' CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"] -CLEAN.clear_exclude.exclude { |fn| +CLEAN.clear_exclude +CLEAN.exclude { |fn| fn.pathmap("%f") == 'core' && File.directory?(fn) } and now everything works! The only theory I have to work on is that rcov breaks the Ruby interpreter in such a way that "return self" no longer works. However that's a very wild theory, and I've not been able to replicate it in a small test case. Can anyone else think of a mechanism which would cause it to behave this way? Environment is Ubuntu 6.06, $ ruby -v ruby 1.8.4 (2005-12-24) [i486-linux] Regards, Brian.