module Danger # This plugin will show the coverage of the project. You can add warnings or failures # depending on the coverage percentage. It uses Xcode xccov to generate the coverage report. # # @example Require a minimum file coverage of 30%, a project coverage of 60% and show all modified files coverage # xccov_summary.configure("Path/to/my/build_directory") # xccov_summary.notify_if_coverage_is_less_than(minimum_coverage: 60) # xccov_summary.show_coverage # @see /danger-xccov_summary # @tags codecoverage class DangerXccovSummary < Plugin # Required method to configure xccov. It's required to provide the path to the build directory. # @param [String] build_directory path where the derivied data folder lives # @return [void] def configure(project_build_directory) @build_directory = project_build_directory calculate_total_coverage end # Method to check if the coverage of the project is at least a minumum # @param options [Hash] a hash with the options # @option options [Float] :minimum_coverage the minimum code coverage required # @option options [Symbol] :notify_level the level of notification # @return [Array] def notify_if_coverage_is_less_than(options) minimum_coverage = options[:minimum_coverage] notify_level = options[:notify_level] || :fail current_coverage = @current_coverage if current_coverage < minimum_coverage notify_message = "Total coverage is #{current_coverage} and is less than minimum: #{minimum_coverage}%" if notify_level == :fail fail notify_message else warn notify_message end end end # Show a header with the total coverage and coverage table # @return [Array] def show_coverage line = "## Code coverage\n" line << total_coverage_markdown markdown line end private # String header with the total coverage of the project # @return [String] def total_coverage_markdown "### Total coverage: **`#{@current_coverage}%`**\n" end # Total coverage of the project def calculate_total_coverage file = `find "#{@build_directory}" -name "action.xccovreport"`.strip result = `xcrun xccov view #{file} --json` coverage_report = JSON.parse(result) @current_coverage = (coverage_report['lineCoverage'] * 100).round(2) end end end