lib/slather/project.rb in slather-2.0.2 vs lib/slather/project.rb in slather-2.1.0
- old
+ new
@@ -49,29 +49,43 @@
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, :binary_file, :binary_basename
+ :output_directory, :xcodeproj, :show_html, :verbose_mode, :input_format, :scheme, :workspace, :binary_file, :binary_basename
alias_method :setup_for_coverage, :slather_setup_for_coverage
def self.open(xcodeproj)
proj = super
proj.xcodeproj = xcodeproj
proj
end
+ def failure_help_string
+ "\n\tAre you sure your project is generating coverage? Make sure you enable code coverage in the Test section of your Xcode scheme.\n\tDid you specify your Xcode scheme? (--scheme or 'scheme' in .slather.yml)\n\tIf you're using a workspace, did you specify it? (--workspace or 'workspace' in .slather.yml)"
+ end
+
def derived_data_path
# Get the derived data path from xcodebuild
# Use OBJROOT when possible, as it provides regardless of whether or not the Derived Data location is customized
+ if self.workspace
+ projectOrWorkspaceArgument = "-workspace \"#{self.workspace}\""
+ else
+ projectOrWorkspaceArgument = "-project \"#{self.path}\""
+ end
+
if self.scheme
- build_settings = `xcodebuild -project "#{self.path}" -scheme "#{self.scheme}" -showBuildSettings`
+ schemeArgument = "-scheme \"#{self.scheme}\""
+ buildAction = "test"
else
- build_settings = `xcodebuild -project "#{self.path}" -showBuildSettings`
+ schemeArgument = nil
+ buildAction = nil
end
+ build_settings = `xcodebuild #{projectOrWorkspaceArgument} #{schemeArgument} -showBuildSettings #{buildAction}`
+
if build_settings
derived_data_path = build_settings.match(/ OBJROOT = (.+)/)[1]
end
if derived_data_path == nil
@@ -97,11 +111,11 @@
# If there's no source file for this gcno, it probably belongs to another project.
coverage_file.source_file_pathname && !coverage_file.ignored? ? coverage_file : nil
end.compact
if coverage_files.empty?
- raise StandardError, "No coverage files found. Are you sure your project is setup for generating coverage files? Try `slather setup your/project.xcodeproj`"
+ raise StandardError, "No coverage files found."
else
dedupe(coverage_files)
end
end
private :gcov_coverage_files
@@ -139,11 +153,11 @@
if dir == nil
# Xcode 7.3 moved the location of Coverage.profdata
dir = Dir[File.join("#{build_directory}","/**/CodeCoverage")].first
end
- raise StandardError, "No coverage directory found. Are you sure your project is setup for generating coverage files? Try `slather setup your/project.xcodeproj`" unless dir != nil
+ raise StandardError, "No coverage directory found." unless dir != nil
dir
end
def profdata_file
profdata_coverage_dir = self.profdata_coverage_dir
@@ -191,20 +205,28 @@
def self.yml
@yml ||= File.exist?(yml_filename) ? YAML.load_file(yml_filename) : {}
end
def configure
- configure_build_directory
- configure_ignore_list
- configure_ci_service
- configure_coverage_access_token
- configure_coverage_service
- configure_source_directory
- configure_output_directory
- configure_input_format
- configure_scheme
- configure_binary_file
+ begin
+ configure_scheme
+ configure_workspace
+ configure_build_directory
+ configure_ignore_list
+ configure_ci_service
+ configure_coverage_access_token
+ configure_coverage_service
+ configure_source_directory
+ configure_output_directory
+ configure_input_format
+ configure_binary_file
+ rescue => e
+ puts e.message
+ puts failure_help_string
+ puts "\n"
+ raise
+ end
if self.verbose_mode
puts "\nProcessing coverage file: #{profdata_file}"
puts "Against binary file: #{self.binary_file}\n\n"
end
@@ -248,10 +270,14 @@
def configure_scheme
self.scheme ||= self.class.yml["scheme"] if self.class.yml["scheme"]
end
+ def configure_workspace
+ self.workspace ||= self.class.yml["workspace"] if self.class.yml["workspace"]
+ end
+
def ci_service=(service)
@ci_service = service && service.to_sym
end
def configure_coverage_service
@@ -299,13 +325,26 @@
# Get scheme info out of the xcodeproj
if self.scheme
schemes_path = Xcodeproj::XCScheme.shared_data_dir(self.path)
xcscheme_path = "#{schemes_path + self.scheme}.xcscheme"
+
+ raise StandardError, "No shared scheme named '#{self.scheme}' found in #{self.path}" unless File.exists? xcscheme_path
+
xcscheme = Xcodeproj::XCScheme.new(xcscheme_path)
- buildable_name = xcscheme.build_action.entries[0].buildable_references[0].buildable_name
+ 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_for = binary_basename || buildable_name
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
@@ -342,12 +381,11 @@
else
found_binary = find_binary_file_in_bundle(xctest_bundle)
end
end
- raise StandardError, "No product binary found in #{profdata_coverage_dir}. Are you sure your project is setup for generating coverage files? Try `slather setup your/project.xcodeproj`" unless found_binary != nil
+ raise StandardError, "No product binary found in #{profdata_coverage_dir}." unless found_binary != nil
found_binary
end
-
end
end