Brian Candler
4/24/2007 12:19:00 PM
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.