1require "coverage.so" 2 3Coverage.start 4 5ext = ENV["COVERUBY_EXT"] || ".cov" 6accum = ENV["COVERUBY_ACCUM"] 7accum = !accum || accum == "" || !(%w(f n 0).include?(accum[0])) 8pwd = Dir.pwd 9 10at_exit do 11 exit_exc = $! 12 Dir.chdir(pwd) do 13 Coverage.result.each do |sfile, covs| 14 cfile = sfile + ext 15 16 writable = proc do |f| 17 File.writable?(f) || File.writable?(File.dirname(f)) 18 end 19 unless writable[cfile] 20 cfile = cfile.gsub(File::PATH_SEPARATOR, "#") 21 next unless writable[cfile] 22 end 23 24 readlines = proc do |f| 25 File.read(f).force_encoding("ASCII-8BIT").lines.to_a 26 end 27 28 sources = (readlines[sfile] rescue []) 29 30 pcovs = [] 31 if accum 32 pcovs = (readlines[cfile] rescue []).map.with_index do |line, idx| 33 if line[/^\s*(?:(#####)|(\d+)|-):\s*\d+:(.*)$/n] 34 cov, line = $1 ? 0 : ($2 ? $2.to_i : nil), $3 35 if !sources[idx] || sources[idx].chomp != line.chomp 36 warn("source file changed, ignoring: `#{ cfile }'") 37 break [] 38 end 39 cov 40 else 41 p line 42 warn("coverage file corrupted, ignoring: #{ cfile }") 43 break [] 44 end 45 end 46 unless pcovs.empty? || pcovs.size == covs.size 47 warn("coverage file changed, ignoring: `#{ cfile }'") 48 pcovs = [] 49 end 50 end 51 52 open(cfile, "w") do |out| 53 covs.zip(sources, pcovs).each_with_index do |(cov, line, pcov), idx| 54 cov += pcov || 0 if cov 55 cov = (cov ? (cov == 0 ? "#####" : cov.to_s) : "-").rjust(9) 56 out.puts("%s:% 5d:%s" % [cov, idx + 1, line]) 57 end 58 end 59 end 60 end 61 raise exit_exc if exit_exc 62end 63