class Danger::DangerXcodeSummary
Shows all build errors, warnings and unit tests results generated from `xcodebuild`. You need to use the `xcresult` produced by Xcode 11. It's located in the Derived Data folder. @example Showing summary
xcode_summary.report 'build.xcresult'
@example Filtering warnings in Pods
xcode_summary.ignored_files = '**/Pods/**' xcode_summary.report 'build.xcresult'
@see diogot/danger-xcode_summary @tags xcode, xcodebuild, format
Constants
- Location
- Result
Attributes
A globbed string or array of strings which should match the files that you want to ignore warnings on. Defaults to nil. An example would be `'/Pods/'` to ignore warnings in Pods that your project uses.
@param [String or [String]] value @return [[String]]
A block that filters specific results. An example would be `lambda { |result| result.message.start_with?('ld') }` to ignore results for ld_warnings.
@param [Block value @return [Block]
Defines if warnings should be included or not Defaults to `false`. @param [Boolean] value @return [Boolean]
Defines if using inline comment or not. Defaults to `false`. @param [Boolean] value @return [Boolean]
The project root, which will be used to make the paths relative. Defaults to `pwd`. @param [String] value @return [String]
Public Instance Methods
Pick a Dangerfile plugin for a chosen request_source and cache it based on github.com/danger/danger/blob/master/lib/danger/plugin_support/plugin.rb#L31
# File lib/xcode_summary/plugin.rb, line 83 def plugin plugins = Plugin.all_plugins.select { |plugin| Dangerfile.essential_plugin_classes.include? plugin } @plugin ||= plugins.select { |p| p.method_defined? :html_link }.map { |p| p.new(@dangerfile) }.compact.first end
Reads a `.xcresult` and reports it.
@param [String] file_path Path for xcresult bundle. @return [void]
# File lib/xcode_summary/plugin.rb, line 93 def report(file_path) if File.exist?(file_path) xcode_summary = XCResult::Parser.new(path: file_path) format_summary(xcode_summary) else fail 'summary file not found' end end
Reads a `.xcresult` and reports its warning and error count.
@param [String] file_path Path for xcresult bundle. @return [String] JSON string with warningCount and errorCount
# File lib/xcode_summary/plugin.rb, line 106 def warning_error_count(file_path) if File.exist?(file_path) xcode_summary = XCResult::Parser.new(path: file_path) warning_count = 0 error_count = 0 xcode_summary.actions_invocation_record.actions.each do |action| warning_count += warnings(action).count error_count += errors(action).count end result = { warnings: warning_count, errors: error_count } result.to_json else fail 'summary file not found' end end
Private Instance Methods
# File lib/xcode_summary/plugin.rb, line 159 def errors(action) errors = [ action.action_result.issues.error_summaries, action.build_result.issues.error_summaries ].flatten.compact.map do |summary| result = Result.new(summary.message, parse_location(summary.document_location_in_creating_workspace)) Result.new(format_warning(result), result.location) end test_failures = [ action.action_result.issues.test_failure_summaries, action.build_result.issues.test_failure_summaries ].flatten.compact.map do |summary| result = Result.new(summary.message, parse_location(summary.document_location_in_creating_workspace)) Result.new(format_test_failure(result, summary.producing_target, summary.test_case_name), result.location) end results = (errors + test_failures).uniq.reject { |result| result.message.nil? } results.delete_if(&ignored_results) end
# File lib/xcode_summary/plugin.rb, line 212 def escape_reason(reason) reason.gsub('>', '\>').gsub('<', '\<') end
# File lib/xcode_summary/plugin.rb, line 192 def format_path(file_path, line) if plugin path = file_path path += "#L#{line}" if line plugin.html_link(path) else file_path end end
# File lib/xcode_summary/plugin.rb, line 124 def format_summary(xcode_summary) xcode_summary.actions_invocation_record.actions.each do |action| warnings(action).each do |result| if inline_mode && result.location warn(result.message, sticky: false, file: result.location.file_path, line: result.location.line) else warn(result.message, sticky: false) end end # rubocop:disable Lint/UnreachableLoop errors(action).each do |result| if inline_mode && result.location fail(result.message, sticky: false, file: result.location.file_path, line: result.location.line) else fail(result.message, sticky: false) end end # rubocop:enable Lint/UnreachableLoop end end
# File lib/xcode_summary/plugin.rb, line 227 def format_test_failure(result, producing_target, test_case_name) path = result.location.file_path path_link = format_path(path, result.location.line) suite_name = "#{producing_target}.#{test_case_name}" "**#{suite_name}**: #{escape_reason(result.message)} <br /> #{path_link}" end
# File lib/xcode_summary/plugin.rb, line 216 def format_warning(result) return escape_reason(result.message) if result.location.nil? path = result.location.file_path return nil if should_ignore_warning?(path) path_link = format_path(path, result.location.line) "**#{path_link}**: #{escape_reason(result.message)}" end
# File lib/xcode_summary/plugin.rb, line 181 def parse_location(document_location) return nil if document_location.nil? file_path = document_location.url.gsub('file://', '').split('#').first file_name = file_path.split('/').last fragment = document_location.url.split('#').last params = CGI.parse(fragment).transform_values(&:first) line = params['StartingLineNumber'].to_i + 1 # StartingLineNumber is 0-based, but we need a 1-based value Location.new(file_name, relative_path(file_path), line) end
# File lib/xcode_summary/plugin.rb, line 202 def relative_path(path) return nil if project_root.nil? path.gsub(project_root, '') end
# File lib/xcode_summary/plugin.rb, line 208 def should_ignore_warning?(path) ignored_files.any? { |pattern| File.fnmatch(pattern, path) } end
# File lib/xcode_summary/plugin.rb, line 145 def warnings(action) return [] if ignores_warnings warnings = [ action.action_result.issues.warning_summaries, action.build_result.issues.warning_summaries ].flatten.compact.map do |summary| result = Result.new(summary.message, parse_location(summary.document_location_in_creating_workspace)) Result.new(format_warning(result), result.location) end warnings = warnings.uniq.reject { |result| result.message.nil? } warnings.delete_if(&ignored_results) end