lib/slather/project.rb in slather-2.3.0 vs lib/slather/project.rb in slather-2.4.0
- old
+ new
@@ -50,11 +50,11 @@
module Slather
class Project < Xcodeproj::Project
attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :coverage_access_token, :source_directory,
:output_directory, :xcodeproj, :show_html, :verbose_mode, :input_format, :scheme, :workspace, :binary_file, :binary_basename, :source_files,
- :decimals
+ :decimals, :llvm_version
alias_method :setup_for_coverage, :slather_setup_for_coverage
def self.open(xcodeproj)
proj = super
@@ -82,11 +82,11 @@
schemeArgument = nil
buildAction = nil
end
# redirect stderr to avoid xcodebuild errors being printed.
- build_settings = `xcodebuild #{projectOrWorkspaceArgument} #{schemeArgument} -showBuildSettings #{buildAction} 2>&1`
+ build_settings = `xcodebuild #{projectOrWorkspaceArgument} #{schemeArgument} -showBuildSettings #{buildAction} CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO 2>&1`
if build_settings
derived_data_path = build_settings.match(/ OBJROOT = (.+)/)
# when match fails derived_data_path is nil
derived_data_path = derived_data_path[1] if derived_data_path
@@ -124,17 +124,18 @@
private :gcov_coverage_files
def profdata_coverage_files
coverage_files = []
source_files = find_source_files || []
+ line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
if self.binary_file
self.binary_file.each do |binary_path|
files = profdata_llvm_cov_output(binary_path, source_files).split("\n\n")
coverage_files.concat(files.map do |source|
- coverage_file = coverage_file_class.new(self, source)
+ coverage_file = coverage_file_class.new(self, source, line_numbers_first)
# If a single source file is used, the resulting output does not contain the file name.
coverage_file.source_file_pathname = source_files.first if source_files.count == 1
!coverage_file.ignored? ? coverage_file : nil
end.compact)
@@ -206,11 +207,12 @@
`xcrun llvm-cov #{llvm_cov_args.shelljoin} #{source_files.shelljoin}`
end
private :unsafe_profdata_llvm_cov_output
def profdata_llvm_cov_output(binary_path, source_files)
- unsafe_profdata_llvm_cov_output(binary_path, source_files).encode!('UTF-8', 'binary', :invalid => :replace, undef: :replace)
+ output = unsafe_profdata_llvm_cov_output(binary_path, source_files)
+ output.valid_encoding? ? output : output.encode!('UTF-8', 'binary', :invalid => :replace, undef: :replace)
end
private :profdata_llvm_cov_output
def dedupe(coverage_files)
coverage_files.group_by(&:source_file_pathname).values.map { |cf_array| cf_array.max_by(&:percentage_lines_tested) }
@@ -237,10 +239,12 @@
configure_source_directory
configure_output_directory
configure_input_format
configure_binary_file
configure_decimals
+
+ self.llvm_version = `xcrun llvm-cov --version`.match(/Apple LLVM version ([\d\.]+)/).captures[0]
rescue => e
puts e.message
puts failure_help_string
puts "\n"
raise
@@ -389,24 +393,13 @@
raise StandardError, "No scheme named '#{self.scheme}' found in #{self.path}" unless File.exists? xcscheme_path
xcscheme = Xcodeproj::XCScheme.new(xcscheme_path)
- begin
- buildable_name = xcscheme.build_action.entries[0].buildable_references[0].buildable_name
- rescue
- # xcodeproj will raise an exception if there are no entries in the build action
- end
-
- if buildable_name == nil or buildable_name.end_with? ".a"
- # Can't run code coverage on static libraries, look for an associated test bundle
- buildable_name = xcscheme.test_action.testables[0].buildable_references[0].buildable_name
- end
-
configuration = xcscheme.test_action.build_configuration
- search_list = binary_basename || [buildable_name]
+ search_list = binary_basename || find_buildable_names(xcscheme)
search_list.each do |search_for|
found_product = Dir["#{profdata_coverage_dir}/Products/#{configuration}*/#{search_for}*"].sort { |x, y|
# Sort the matches without the file extension to ensure better matches when there are multiple candidates
# For example, if the binary_basename is Test then we want Test.app to be matched before Test Helper.app
@@ -457,9 +450,40 @@
end
raise StandardError, "No product binary found in #{profdata_coverage_dir}." unless found_binaries.count > 0
found_binaries.map { |binary| File.expand_path(binary) }
+ end
+
+ def find_buildable_names(xcscheme)
+ found_buildable_names = []
+
+ # enumerate build action entries
+ begin
+ xcscheme.build_action.entries.each do |entry|
+ buildable_name = entry.buildable_references[0].buildable_name
+
+ if !buildable_name.end_with? ".a"
+ # Can't run code coverage on static libraries
+ found_buildable_names.push(buildable_name)
+ end
+ end
+ rescue
+ # xcodeproj will raise an exception if there are no entries in the build action
+ end
+
+ # enumerate test action entries
+ begin
+ xcscheme.test_action.testables.each do |entry|
+ buildable_name = entry.buildable_references[0].buildable_name
+ found_buildable_names.push(buildable_name)
+ end
+ rescue
+ # just in case if there are no entries in the test action
+ end
+
+ # some items are both buildable and testable, so return only unique ones
+ found_buildable_names.uniq
end
def find_source_files
source_files = load_option_array("source_files")
return if source_files.nil?