C0 code coverage information

Generated on Wed Oct 07 08:33:59 -0700 2009 with rcov 0.8.2.1


Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
Name Total lines Lines of code Total coverage Code coverage
lib/buildr/core/util.rb 449 288
55.0%  
41.3%  
  1 # Licensed to the Apache Software Foundation (ASF) under one or more
  2 # contributor license agreements.  See the NOTICE file distributed with this
  3 # work for additional information regarding copyright ownership.  The ASF
  4 # licenses this file to you under the Apache License, Version 2.0 (the
  5 # "License"); you may not use this file except in compliance with the License.
  6 # You may obtain a copy of the License at
  7 #
  8 #    http://www.apache.org/licenses/LICENSE-2.0
  9 #
 10 # Unless required by applicable law or agreed to in writing, software
 11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 13 # License for the specific language governing permissions and limitations under
 14 # the License.
 15 
 16 
 17 require 'rbconfig'
 18 require 'pathname'
 19 autoload :Tempfile, 'tempfile'
 20 autoload :YAML, 'yaml'
 21 autoload :REXML, 'rexml/document'
 22 gem 'xml-simple' ; autoload :XmlSimple, 'xmlsimple'
 23 gem 'builder' ; autoload :Builder, 'builder' # A different kind of buildr, one we use to create XML.
 24 require 'highline/import'
 25 
 26 
 27 module Buildr
 28   
 29   module Util
 30     extend self
 31 
 32     def java_platform?
 33       RUBY_PLATFORM =~ /java/
 34     end
 35 
 36     # In order to determine if we are running on a windows OS,
 37     # prefer this function instead of using Gem.win_platform?.
 38     #
 39     # Gem.win_platform? only checks these RUBY_PLATFORM global,
 40     # that in some cases like when running on JRuby is not 
 41     # succifient for our purpose:
 42     #
 43     # For JRuby, the value for RUBY_PLATFORM will always be 'java'
 44     # That's why this function checks on Config::CONFIG['host_os']
 45     def win_os?
 46       Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
 47     end
 48 
 49     # Runs Ruby with these command line arguments.  The last argument may be a hash,
 50     # supporting the following keys:
 51     #   :command  -- Runs the specified script (e.g., :command=>'gem')
 52     #   :sudo     -- Run as sudo on operating systems that require it.
 53     #   :verbose  -- Override Rake's verbose flag.
 54     def ruby(*args)
 55       options = Hash === args.last ? args.pop : {}
 56       cmd = []
 57       ruby_bin = File.expand_path(Config::CONFIG['ruby_install_name'], Config::CONFIG['bindir'])
 58       if options.delete(:sudo) && !(win_os? || Process.uid == File.stat(ruby_bin).uid)
 59         cmd << 'sudo' << '-u' << "##{File.stat(ruby_bin).uid}"
 60       end
 61       cmd << ruby_bin
 62       cmd << '-S' << options.delete(:command) if options[:command]
 63       cmd.concat args.flatten
 64       cmd.push options
 65       sh *cmd do |ok, status|
 66         ok or fail "Command ruby failed with status (#{status ? status.exitstatus : 'unknown'}): [#{cmd.join(" ")}]"
 67       end
 68     end
 69 
 70     # Just like File.expand_path, but for windows systems it
 71     # capitalizes the drive name and ensures backslashes are used
 72     def normalize_path(path, *dirs)
 73       path = File.expand_path(path, *dirs)
 74       if win_os?
 75         path.gsub!('/', '\\').gsub!(/^[a-zA-Z]+:/) { |s| s.upcase }
 76       else
 77         path
 78       end
 79     end
 80     
 81     # Return the timestamp of file, without having to create a file task
 82     def timestamp(file)
 83       if File.exist?(file)
 84         File.mtime(file)
 85       else
 86         Rake::EARLY
 87       end
 88     end
 89 
 90     # Return the path to the first argument, starting from the path provided by the
 91     # second argument.
 92     #
 93     # For example:
 94     #   relative_path('foo/bar', 'foo')
 95     #   => 'bar'
 96     #   relative_path('foo/bar', 'baz')
 97     #   => '../foo/bar'
 98     #   relative_path('foo/bar')
 99     #   => 'foo/bar'
100     #   relative_path('/foo/bar', 'baz')
101     #   => '/foo/bar'
102     def relative_path(to, from = '.')
103       to = Pathname.new(to).cleanpath
104       return to.to_s if from.nil?
105       to_path = Pathname.new(File.expand_path(to.to_s, "/"))
106       from_path = Pathname.new(File.expand_path(from.to_s, "/"))
107       to_path.relative_path_from(from_path).to_s
108     end
109 
110     # Generally speaking, it's not a good idea to operate on dot files (files starting with dot).
111     # These are considered invisible files (.svn, .hg, .irbrc, etc).  Dir.glob/FileList ignore them
112     # on purpose.  There are few cases where we do have to work with them (filter, zip), a better
113     # solution is welcome, maybe being more explicit with include.  For now, this will do.
114     def recursive_with_dot_files(*dirs)
115       FileList[dirs.map { |dir| File.join(dir, '/**/{*,.*}') }].reject { |file| File.basename(file) =~ /^[.]{1,2}$/ }
116     end
117 
118     # Utility methods for running gem commands
119     module Gems #:nodoc:
120       extend self
121 
122       # Install gems specified by each Gem::Dependency if they are missing. This method prompts the user
123       # for permission before installing anything.
124       # 
125       # Returns the installed Gem::Dependency objects or fails if permission not granted or when buildr
126       # is not running interactively (on a tty)
127       def install(*dependencies)
128         raise ArgumentError, "Expected at least one argument" if dependencies.empty?
129         remote = dependencies.map { |dep| Gem::SourceInfoCache.search(dep).last || dep }
130         not_found_deps, to_install = remote.partition { |gem| gem.is_a?(Gem::Dependency) }
131         fail Gem::LoadError, "Build requires the gems #{not_found_deps.join(', ')}, which cannot be found in local or remote repository." unless not_found_deps.empty?
132         uses = "This build requires the gems #{to_install.map(&:full_name).join(', ')}:"
133         fail Gem::LoadError, "#{uses} to install, run Buildr interactively." unless $stdout.isatty
134         unless agree("#{uses} do you want me to install them? [Y/n]", true)
135           fail Gem::LoadError, 'Cannot build without these gems.'
136         end
137         to_install.each do |spec|
138           say "Installing #{spec.full_name} ... " if verbose
139           command 'install', spec.name, '-v', spec.version.to_s, :verbose => false
140           Gem.source_index.load_gems_in Gem::SourceIndex.installed_spec_directories
141         end
142         to_install
143       end
144 
145       # Execute a GemRunner command
146       def command(cmd, *args)
147         options = Hash === args.last ? args.pop : {}
148         gem_home = ENV['GEM_HOME'] || Gem.path.find { |f| File.writable?(f) }
149         options[:sudo] = :root unless Util.win_os? || gem_home
150         options[:command] = 'gem'
151         args << options
152         args.unshift '-i', gem_home if cmd == 'install' && gem_home && !args.any?{ |a| a[/-i|--install-dir/] }
153         Util.ruby cmd, *args
154       end
155 
156     end # Gems
157 
158   end # Util
159 end
160 
161 
162 class Object #:nodoc:
163   unless defined? instance_exec # 1.9
164     module InstanceExecMethods #:nodoc:
165     end
166     include InstanceExecMethods
167 
168     # Evaluate the block with the given arguments within the context of
169     # this object, so self is set to the method receiver.
170     #
171     # From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
172     def instance_exec(*args, &block)
173       begin
174         old_critical, Thread.critical = Thread.critical, true
175         n = 0
176         n += 1 while respond_to?(method_name = "__instance_exec#{n}")
177         InstanceExecMethods.module_eval { define_method(method_name, &block) }
178       ensure
179         Thread.critical = old_critical
180       end
181 
182       begin
183         send(method_name, *args)
184       ensure
185         InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
186       end
187     end
188   end
189 end
190 
191 module Kernel #:nodoc:
192   unless defined? tap # 1.9
193     def tap
194       yield self if block_given?
195       self
196     end
197   end
198 end
199 
200 class Symbol #:nodoc:
201   unless defined? to_proc # 1.9
202     # Borrowed from Ruby 1.9.
203     def to_proc
204       Proc.new{|*args| args.shift.__send__(self, *args)}
205     end
206   end
207 end
208 
209 unless defined? BasicObject # 1.9
210   class BasicObject #:nodoc:
211     (instance_methods - ['__send__', '__id__', '==', 'send', 'send!', 'respond_to?', 'equal?', 'object_id']).
212       each do |method|
213         undef_method method
214       end
215 
216     def self.ancestors
217       [Kernel]
218     end
219   end
220 end
221 
222 
223 class OpenObject < Hash
224 
225   def initialize(source=nil, &block)
226     super &block
227     update source if source
228   end
229 
230   def method_missing(symbol, *args)
231     if symbol.to_s =~ /=$/
232       self[symbol.to_s[0..-2].to_sym] = args.first
233     else
234       self[symbol]
235     end
236   end
237 end
238 
239 
240 class Hash
241 
242   class << self
243 
244     # :call-seq:
245     #   Hash.from_java_properties(string)
246     #
247     # Returns a hash from a string in the Java properties file format. For example:
248     #   str = 'foo=bar\nbaz=fab'
249     #   Hash.from_properties(str)
250     #   => { 'foo'=>'bar', 'baz'=>'fab' }.to_properties
251     def from_java_properties(string)
252       hash = {}
253       input_stream = Java.java.io.StringBufferInputStream.new(string)
254       java_properties = Java.java.util.Properties.new
255       java_properties.load input_stream
256       keys = java_properties.keySet.iterator
257       while keys.hasNext
258         # Calling key.next in JRuby returns a java.lang.String, behaving as a Ruby string and life is good.
259         # MRI, unfortunately, treats next() like the interface says returning an object that's not a String,
260         # and the Hash doesn't work the way we need it to.  Unfortunately, we can call toString on MRI's object,
261         # but not on the JRuby one; calling to_s on the JRuby object returns what we need, but ... you guessed it.
262         #  So this seems like the one hack to unite them both.
263         #key = Java.java.lang.String.valueOf(keys.next.to_s)
264         key = keys.next
265         key = key.toString unless String === key
266         hash[key] = java_properties.getProperty(key)
267       end
268       hash
269     end
270 
271   end
272 
273   # :call-seq:
274   #   only(keys*) => hash
275   #
276   # Returns a new hash with only the specified keys.
277   #
278   # For example:
279   #   { :a=>1, :b=>2, :c=>3, :d=>4 }.only(:a, :c)
280   #   => { :a=>1, :c=>3 }
281   def only(*keys)
282     keys.inject({}) { |hash, key| has_key?(key) ? hash.merge(key=>self[key]) : hash }
283   end
284 
285 
286   # :call-seq:
287   #   except(keys*) => hash
288   #
289   # Returns a new hash without the specified keys.
290   #
291   # For example:
292   #   { :a=>1, :b=>2, :c=>3, :d=>4 }.except(:a, :c)
293   #   => { :b=>2, :d=>4 }
294   def except(*keys)
295     (self.keys - keys).inject({}) { |hash, key| hash.merge(key=>self[key]) }
296   end
297 
298   # :call-seq:
299   #   to_java_properties => string
300   #
301   # Convert hash to string format used for Java properties file. For example:
302   #   { 'foo'=>'bar', 'baz'=>'fab' }.to_properties
303   #   => foo=bar
304   #      baz=fab
305   def to_java_properties
306     keys.sort.map { |key|
307       value = self[key].gsub(/[\t\r\n\f\\]/) { |escape| "\\" + {"\t"=>"t", "\r"=>"r", "\n"=>"n", "\f"=>"f", "\\"=>"\\"}[escape] }
308       "#{key}=#{value}"
309     }.join("\n")
310   end
311 
312 end
313 
314 if Buildr::Util.java_platform?
315   require 'ffi'
316 
317   # Fix for BUILDR-292.
318   # JRuby fails to rename a file on different devices
319   # this monkey-patch wont be needed when JRUBY-3381 gets resolved.
320   module FileUtils #:nodoc:
321     alias_method :__mv_native, :mv
322 
323     def mv(from, to, options = nil)
324       dir_to = File.directory?(to) ? to : File.dirname(to)
325       Array(from).each do |from|
326         dir_from = File.dirname(from)
327         if File.stat(dir_from).dev != File.stat(dir_to).dev
328           cp from, to, options
329           rm from, options
330         else
331           __mv_native from, to, options
332         end
333       end
334     end
335     private :mv
336   end
337   
338   module RakeFileUtils #:nodoc:
339     def rake_merge_option(args, defaults)
340       defaults[:verbose] = false if defaults[:verbose] == :default
341       
342       if Hash === args.last
343         defaults.update(args.last)
344         args.pop
345       end
346       args.push defaults
347       args
348     end
349     private :rake_merge_option
350   end
351   
352   module Buildr
353     class ProcessStatus
354       attr_reader :pid, :termsig, :stopsig, :exitstatus
355       
356       def initialize(pid, success, exitstatus)
357         @pid = pid
358         @success = success
359         @exitstatus = exitstatus
360         
361         @termsig = nil
362         @stopsig = nil
363       end
364       
365       def &(num)
366         pid & num
367       end
368       
369       def ==(other)
370         pid == other.pid
371       end
372       
373       def >>(num)
374         pid >> num
375       end
376       
377       def coredump?
378         false
379       end
380       
381       def exited?
382         true
383       end
384       
385       def stopped?
386         false
387       end
388       
389       def success?
390         @success
391       end
392       
393       def to_i
394         pid
395       end
396       
397       def to_int
398         pid
399       end
400       
401       def to_s
402         pid.to_s
403       end
404     end
405   end
406 
407   module FileUtils
408     extend FFI::Library
409     alias_method :__jruby_system__, :system
410     attach_function :system, [:string], :int
411     alias_method :__native_system__, :system
412     alias_method :system, :__jruby_system__
413     
414     # code "borrowed" directly from Rake
415     def sh(*cmd, &block)
416       options = (Hash === cmd.last) ? cmd.pop : {}
417       unless block_given?
418         show_command = cmd.join(" ")
419         show_command = show_command[0,42] + "..."
420         
421         block = lambda { |ok, status|
422           ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]"
423         }
424       end
425       if RakeFileUtils.verbose_flag == :default
426         options[:verbose] = false
427       else
428         options[:verbose] ||= RakeFileUtils.verbose_flag
429       end
430       options[:noop]    ||= RakeFileUtils.nowrite_flag
431       rake_check_options options, :noop, :verbose
432       rake_output_message cmd.join(" ") if options[:verbose]
433       unless options[:noop]
434         cd = "cd '#{Dir.pwd}' && "
435         args = if cmd.size > 1 then cmd[1..cmd.size] else [] end
436         
437         res = if Buildr::Util.win_os? && cmd.size == 1
438           __native_system__("#{cd} call #{cmd.first}")
439         else
440           arg_str = args.map { |a| "'#{a}'" }
441           __native_system__(cd + cmd.first + ' ' + arg_str.join(' '))
442         end
443         $? = Buildr::ProcessStatus.new(0, res == 0, res)    # KLUDGE
444         block.call(res == 0, $?)
445       end
446     end
447 
448   end
449 end

Generated using the rcov code coverage analysis tool for Ruby version 0.8.2.1.

Valid XHTML 1.0! Valid CSS!