lib/xcjobs/xcodebuild.rb in xcjobs-0.2.1 vs lib/xcjobs/xcodebuild.rb in xcjobs-0.2.2

- old
+ new

@@ -144,10 +144,104 @@ def sdk @sdk || 'iphonesimulator' end private + + def show_coverage(profdata_path, target_path) + cmd = ['xcrun', 'llvm-cov', 'report'] + opts = ['-instr-profile', profdata_path, target_path, '-use-color=0'] + puts (cmd + opts).join(" ") + out, status = Open3.capture2(*(cmd + opts)) + out.lines.each do |line| + puts line + end + end + + def generate_gcov_file(profdata_path, target_path) + puts 'Generage gcov file...' + gcov_file = {} + source_path = '' + + cmd = ['xcrun', 'llvm-cov', 'show'] + opts = ['-instr-profile', profdata_path, target_path, '-use-color=0'] + + out, status = Open3.capture2(*(cmd + opts)) + out.lines.each do |line| + match = /^(['"]?(?:\/[^\/]+)*['"]?):$/.match(line) + if match.to_a.count > 0 + source_path = match.to_a[1] + gcov_file[source_path] = [] + next + end + + match = /^[ ]*([0-9]+|[ ]+)\|[ ]*([0-9]+)\|(.*)$/.match(line) + next unless match.to_a.count == 4 + count, number, text = match.to_a[1..3] + + execution_count = case count.strip + when '' + '-'.rjust(5) + when '0' + '#####' + else count + end + gcov_file[source_path] << "#{execution_count.rjust(5)}:#{number.rjust(5)}:#{text}" + end + + gcov_file.each do |key, value| + gcon_path = File.join(File.dirname(profdata_path), "#{File.basename(target_path)}.gcov") + file = File::open(gcon_path, "w") + file.puts("#{'-'.rjust(5)}:#{'0'.rjust(5)}:Source:#{key}") + file.puts(value) + file.flush + end + end + + def coverage_report(options) + settings = build_settings(options) + + targetSettings = settings.select { |key, _| settings[key]['PRODUCT_TYPE'] != 'com.apple.product-type.bundle.unit-test' } + targetSettings.each do |target, settings| + if settings['PRODUCT_TYPE'] == 'com.apple.product-type.framework' + if sdk.start_with? 'iphone' + target_dir = settings['OBJECT_FILE_DIR_normal'].gsub('Build/Intermediates', "Build/Intermediates/CodeCoverage/#{target}/Intermediates") + executable_name = settings['EXECUTABLE_NAME'] + target_path = File.join(File.join(target_dir, settings['CURRENT_ARCH']), executable_name) + else + target_dir = settings['CODESIGNING_FOLDER_PATH'].gsub('Build/Products', "Build/Intermediates/CodeCoverage/#{target}/Products") + executable_name = settings['EXECUTABLE_NAME'] + target_path = File.join(target_dir, executable_name) + end + else + + end + + code_coverage_dir = settings['BUILD_DIR'].gsub('Build/Products', "Build/Intermediates/CodeCoverage/#{target}/") + profdata_path = File.join(code_coverage_dir, 'Coverage.profdata') + + show_coverage(profdata_path, target_path) + generate_gcov_file(profdata_path, target_path) + end + end + + def build_settings(options) + out, status = Open3.capture2(*(['xcodebuild', 'test'] + options + ['-showBuildSettings'])) + + settings, target = {}, nil + out.lines.each do |line| + case line + when /Build settings for action test and target (.+):/ + target = $1 + settings[target] = {} + else + key, value = line.split(/\=/).collect(&:strip) + settings[target][key] = value if target + end + end + return settings + end def define raise 'test action requires specifying a scheme' unless scheme raise 'cannot specify both a scheme and targets' if scheme && target @@ -155,80 +249,16 @@ task @name do if sdk == 'iphonesimulator' add_build_setting('CODE_SIGN_IDENTITY', '""') add_build_setting('CODE_SIGNING_REQUIRED', 'NO') end - if sdk == 'macosx' - add_build_setting('CONFIGURATION_BUILD_DIR', File.expand_path(build_dir)) if build_dir - end - add_build_setting('CONFIGURATION_TEMP_DIR', File.join(build_dir, 'temp')) if build_dir + add_build_setting('GCC_SYMBOLS_PRIVATE_EXTERN', 'NO') run(['xcodebuild', 'test'] + options) if coverage_enabled - out, status = Open3.capture2(*(['xcodebuild', 'test'] + options + ['-showBuildSettings'])) - - configuration_build_dir = out.lines.grep(/\bCONFIGURATION_BUILD_DIR\b/).first.split('=').last.strip - project_temp_root = out.lines.grep(/\bPROJECT_TEMP_ROOT\b/).first.split('=').last.strip - object_file_dir_normal = out.lines.grep(/\bOBJECT_FILE_DIR_normal\b/).first.split('=').last.strip - current_arch = out.lines.grep(/\bCURRENT_ARCH\b/).first.split('=').last.strip - executable_name = out.lines.grep(/\bEXECUTABLE_NAME\b/).first.split('=').last.strip - executable_path = out.lines.grep(/\bEXECUTABLE_PATH\b/).first.split('=').last.strip - - if sdk.start_with? 'iphone' - target_path = File.join(File.join(object_file_dir_normal, current_arch), executable_name) - elsif sdk == 'macosx' - target_path = File.join(configuration_build_dir, executable_path) - end - - code_coverage_dir = File.join(project_temp_root, 'CodeCoverage') - profdata_dir = File.join(code_coverage_dir, scheme) - profdata_path = File.join(profdata_dir, 'Coverage.profdata') - - gcov_file = {} - source_path = '' - - cmd = ['xcrun', 'llvm-cov', 'report'] - opts = ['-instr-profile', profdata_path, target_path, '-use-color=0'] - puts (cmd + opts).join(" ") - out, status = Open3.capture2(*(cmd + opts)) - out.lines.each do |line| - puts line - end - - cmd = ['xcrun', 'llvm-cov', 'show'] - puts (cmd + opts).join(" ") - out, status = Open3.capture2(*(cmd + opts)) - out.lines.each do |line| - match = /^(['"]?(?:\/[^\/]+)*['"]?):$/.match(line) - if match.to_a.count > 0 - source_path = match.to_a[1] - gcov_file[source_path] = [] - next - end - - match = /^[ ]*([0-9]+|[ ]+)\|[ ]*([0-9]+)\|(.*)$/.match(line) - next unless match.to_a.count == 4 - count, number, text = match.to_a[1..3] - - execution_count = case count.strip - when '' - '-'.rjust(5) - when '0' - '#####' - else count - end - gcov_file[source_path] << "#{execution_count.rjust(5)}:#{number.rjust(5)}:#{text}" - end - - gcov_file.each do |key, value| - gcon_path = File.join(File.dirname(target_path), "#{File.basename(target_path)}.gcov") - file = File::open(gcon_path, "w") - file.puts("#{'-'.rjust(5)}:#{'0'.rjust(5)}:Source:#{key}") - file.puts(value) - file.flush - end + coverage_report(options) end end end end