Class: Danger::DangerShroud
- Inherits:
-
Plugin
- Object
- Plugin
- Danger::DangerShroud
- Defined in:
- lib/shroud/plugin.rb
Overview
Parse a Jacoco report to enforce code coverage on CI. Results are passed out as a table in markdown.
Shroud depends on having a Jacoco coverage report generated for your project. For Android projects, [jacoco-android-gradle-plugin](github.com/arturdm/jacoco-android-gradle-plugin) works well.
Instance Method Summary collapse
-
#report(file, totalProjectThreshold = 90, modifiedFileThreshold = 90, failIfUnderThreshold = true) ⇒ void
Report coverage on diffed files, as well as overall coverage.
Instance Method Details
#report(file, totalProjectThreshold = 90, modifiedFileThreshold = 90, failIfUnderThreshold = true) ⇒ void
This method returns an undefined value.
Report coverage on diffed files, as well as overall coverage.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/shroud/plugin.rb', line 50 def report(file, totalProjectThreshold = 90, modifiedFileThreshold = 90, failIfUnderThreshold = true) raise "Please specify file name." if file.empty? raise "No jacoco xml report found at #{file}" unless File.exist? file rawXml = File.read(file) parsedXml = Nokogiri::XML.parse(rawXml) totalInstructionCoverage = parsedXml.xpath("/report/counter[@type='INSTRUCTION']") missed = totalInstructionCoverage.attr("missed").value.to_i covered = totalInstructionCoverage.attr("covered").value.to_i total = missed + covered coveragePercent = (covered / total.to_f) * 100 # get array of files names touched by this PR (modified + added) touchedFileNames = @dangerfile.git.modified_files.map { |file| File.basename(file) } touchedFileNames += @dangerfile.git.added_files.map { |file| File.basename(file) } # used to later report files that were modified but not included in the jacoco report fileNamesNotInJacocoReport = [] # hash for keeping track of coverage per filename: {filename => coverage percent} touchedFilesHash = {} touchedFileNames.each do |touchedFileName| xmlForFileName = parsedXml.xpath("//class[@sourcefilename='#{touchedFileName}']/counter[@type='INSTRUCTION']") if (xmlForFileName.length > 0) missed = 0 covered = 0 xmlForFileName.each do |classCountXml| missed += classCountXml.attr("missed").to_i covered += classCountXml.attr("covered").to_i end touchedFilesHash[touchedFileName] = (covered.to_f / (missed + covered)) * 100 else fileNamesNotInJacocoReport << touchedFileName end end puts "Here are unreported files" puts fileNamesNotInJacocoReport.to_s puts "Here is the touched files coverage hash" puts touchedFilesHash output = "## 🧛 Project Code Coverage: **`#{'%.2f' % coveragePercent}%`**\n" output << "### Coverage of Modified Files:\n" output << "File | Coverage\n" output << ":-----|:-----:\n" # go through each file: touchedFilesHash.sort.each do |fileName, coveragePercent| output << "`#{fileName}` | **`#{'%.2f' % coveragePercent}%`**\n" # warn or fail if under specified file threshold: if (coveragePercent < modifiedFileThreshold) warningMessage = "Uh oh! #{fileName} is under #{modifiedFileThreshold}% coverage!" if (failIfUnderThreshold) fail warningMessage else warn warningMessage end end end output << "### Modified Files Not Found In Coverage Report:\n" fileNamesNotInJacocoReport.sort.each do |unreportedFileName| output << "#{unreportedFileName}\n" end output << '> Codebase cunningly covered by count [Shroud 🧛](https://github.com/livefront/livefront-shroud-android/)' markdown output # warn or fail if total coverage is under specified threshold if (coveragePercent < totalProjectThreshold) totalCoverageWarning = "Uh oh! Your project is under #{totalProjectThreshold}% coverage!" if (failIfUnderThreshold) fail totalCoverageWarning else warn totalCoverageWarning end end end |