PageRenderTime 100ms CodeModel.GetById 75ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/Rake/ncover.rb

http://github.com/agross/netopenspace
Ruby | 120 lines | 97 code | 23 blank | 0 comment | 12 complexity | dfd623dcac809e676be58c9b47d7118e MD5 | raw file
  1require 'rexml/document'
  2require 'win32/registry'
  3include REXML
  4include Win32
  5
  6class NCover
  7	def self.run_coverage(attributes)
  8		tool = attributes.fetch(:tool)
  9		program = attributes.fetch(:program).to_absolute
 10		assembly = attributes.fetch(:assembly)
 11		args = attributes.fetch(:args, [])
 12		reportDirectory = attributes.fetch(:report_dir, '.')
 13		workingDirectory = attributes.fetch(:working_dir, '.').to_absolute
 14		applicationAssemblies = attributes.fetch(:application_assemblies)
 15		registerProfiler = attributes.fetch(:register_profiler, true)
 16
 17		xmlReport = assembly.name.ext('Coverage.xml').in(reportDirectory).to_absolute
 18		logFile = assembly.name.ext('Coverage.log').in(reportDirectory).to_absolute
 19		FileUtils.mkdir_p xmlReport.dirname
 20		FileUtils.mkdir_p logFile.dirname 
 21		
 22		ncover = tool.to_absolute
 23
 24		register registerProfiler, tool do
 25			sh "#{ncover.escape} #{program.escape} #{assembly} #{args.join(' ')} //a #{applicationAssemblies} //w #{workingDirectory.escape} //x #{xmlReport.escape} //l #{logFile.escape} //reg //v"
 26		end
 27	end
 28	
 29	def self.register(registerProfiler, tool)
 30		begin
 31			if registerProfiler
 32				Registry::HKEY_CURRENT_USER.create('Software\KiwiNova\NCoverExplorer', Registry::KEY_WRITE | Registry::KEY_READ) do |reg|
 33					begin
 34						refCount = reg.read_i 'NCoverRefCount'
 35					rescue
 36						refCount = 0
 37					end 
 38					
 39					reg.write_i 'NCoverRefCount', refCount + 1
 40				end
 41				
 42				Registry::HKEY_CURRENT_USER.create('Software\Classes\CLSID\{6287B5F9-08A1-45e7-9498-B5B2E7B02995}', Registry::KEY_WRITE) do |reg|
 43					reg.write_s nil, 'NCover Profiler Object'
 44					
 45					reg.create('InprocServer32', Registry::KEY_WRITE) do |subkey|
 46						subkey.write_s nil, 'CoverLib.dll'.in(tool.dirname).to_absolute
 47						subkey.write_s 'ThreadingModel', 'Both'
 48					end
 49				end
 50			end
 51			
 52			yield if block_given?
 53		ensure
 54			if registerProfiler
 55				Registry::HKEY_CURRENT_USER.create('Software\KiwiNova\NCoverExplorer', Registry::KEY_WRITE | Registry::KEY_READ) do |reg|
 56					begin
 57						refCount = reg.read_i 'NCoverRefCount'
 58					rescue
 59						refCount = 1
 60					end 
 61					
 62					refCount -= 1
 63					
 64					if refCount == 0
 65						begin
 66							Registry::HKEY_CURRENT_USER.delete_key 'Software\KiwiNova\NCoverExplorer', true
 67							Registry::HKEY_CURRENT_USER.delete_key 'Software\Classes\CLSID\{6287B5F9-08A1-45e7-9498-B5B2E7B02995}', true
 68						rescue
 69						end
 70					else
 71						reg.write_i 'NCoverRefCount', refCount if refCount >= 1
 72					end
 73				end
 74			end
 75		end
 76	end
 77
 78	def self.explore(attributes)
 79		tool = attributes.fetch(:tool)
 80		project = attributes.fetch(:project)
 81		reportDirectory = attributes.fetch(:report_dir, '.')
 82		minCoverage = attributes.fetch(:min_coverage, 90)
 83		fail = attributes.fetch(:fail_if_under_min_coverage, false)
 84		htmlReport = attributes.fetch(:html_report, 'Coverage.html').in(reportDirectory).to_absolute
 85		xmlReport = attributes.fetch(:xml_report, 'Coverage.xml').in(reportDirectory).to_absolute
 86		statistics = attributes.fetch(:statistics, {})
 87		
 88		files = FileList.new("#{reportDirectory}/*.Coverage.xml").map! do |file|
 89			file.to_absolute.escape
 90		end
 91		
 92		return if files.empty?
 93		
 94		FileUtils.mkdir_p htmlReport.dirname
 95		FileUtils.mkdir_p xmlReport.dirname 
 96		
 97		ncoverExplorer = tool.to_absolute
 98			
 99		sh "#{ncoverExplorer.escape} #{files} /report:ModuleClassFunctionSummary /sort:Name #{'/failCombinedMinimum' if fail} /minCoverage:#{minCoverage} /project:#{project.escape} /html:#{htmlReport.escape} /xml:#{xmlReport.escape}" \
100		do |ok, status| 
101			if ok or status.exitstatus == 3
102				doc = Document.new(File.read(xmlReport))
103				
104				statistics.each do |key, query|
105					value = XPath.first(doc, query)
106					
107					yield key, value if block_given?
108					
109					statistics[key] = value
110				end
111			end
112
113			TeamCity.append_build_status_text "Code coverage is below accepted level of #{minCoverage}%" if status.exitstatus == 3
114			
115			raise "NCoverExplorer failed" if not ok or (fail and status.exitstatus == 3)
116		end
117		
118		return statistics
119	end
120end