lib/slather/project.rb in slather-2.4.6 vs lib/slather/project.rb in slather-2.4.7
- old
+ new
@@ -116,37 +116,71 @@
end
private :gcov_coverage_files
def profdata_coverage_files
coverage_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|
- coverage_json_string = llvm_cov_export_output(binary_path)
- coverage_json = JSON.parse(coverage_json_string)
- pathnames_per_binary = coverage_json["data"].reduce([]) do |result, chunk|
- result.concat(chunk["files"].map do |file|
- Pathname(file["filename"]).realpath
- end)
- end
+ pathnames_per_binary = pathnames_per_binary(binary_path)
+ coverage_files.concat(create_coverage_files_for_binary(binary_path, pathnames_per_binary))
+ end
+ end
- files = profdata_llvm_cov_output(binary_path, pathnames_per_binary).split("\n\n")
+ coverage_files
+ end
+ private :profdata_coverage_files
- coverage_files.concat(files.map do |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 = pathnames_per_binary.first if pathnames_per_binary.count == 1
- !coverage_file.ignored? ? coverage_file : nil
- end.compact)
+ def pathnames_per_binary(binary_path)
+ coverage_json_string = llvm_cov_export_output(binary_path)
+ coverage_json = JSON.parse(coverage_json_string)
+ coverage_json["data"].reduce([]) do |result, chunk|
+ result.concat(chunk["files"].map do |file|
+ Pathname(file["filename"]).realpath
+ end)
+ end
+ end
+ private :pathnames_per_binary
+
+ def create_coverage_files_for_binary(binary_path, pathnames_per_binary)
+ coverage_files = []
+
+ begin
+ coverage_files.concat(create_coverage_files(binary_path, pathnames_per_binary))
+ rescue Errno::E2BIG => e
+ # pathnames_per_binary is too big for the OS to handle so it's split in two halfs which are processed independently
+ if pathnames_per_binary.count > 1
+ left, right = pathnames_per_binary.each_slice( (pathnames_per_binary.size/2.0).round ).to_a
+ coverage_files.concat(create_coverage_files_for_binary(binary_path, left))
+ coverage_files.concat(create_coverage_files_for_binary(binary_path, right))
+ else
+ # pathnames_per_binary contains one element which is too big for the OS to handle.
+ raise e, "#{e}. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414", e.backtrace
end
end
coverage_files
end
- private :profdata_coverage_files
+ private :create_coverage_files_for_binary
+ def create_coverage_files(binary_path, pathnames)
+ line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
+ files = create_profdata(binary_path, pathnames)
+ files.map do |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 = pathnames.first if pathnames.count == 1
+ !coverage_file.ignored? ? coverage_file : nil
+ end.compact
+ end
+ private :create_coverage_files
+
+ def create_profdata(binary_path, pathnames)
+ profdata_llvm_cov_output(binary_path, pathnames).split("\n\n")
+ end
+ private :create_profdata
+
def remove_extension(path)
path.split(".")[0..-2].join(".")
end
def first_product_name
@@ -178,10 +212,10 @@
# Look up one directory
# The ProfileData directory is next to Intermediates.noindex (in previous versions of Xcode the coverage was inside Intermediates)
coverage_files = Dir[File.join(build_directory, "../**/ProfileData/*/Coverage.profdata")]
end
- if coverage_files != nil
+ if coverage_files != nil && coverage_files.count != 0
dir = Pathname.new(coverage_files.first).parent()
end
end
raise StandardError, "No coverage directory found." unless dir != nil