|
| 1 | +#!/usr/bin/env php |
| 2 | +<?php |
| 3 | +// @ref: http://ocramius.github.io/blog/automated-code-coverage-check-for-github-pull-requests-with-travis/ |
| 4 | + |
| 5 | +//---------- |
| 6 | +function usage() |
| 7 | +{ |
| 8 | + $script = basename(__FILE__); |
| 9 | + echo <<<EOT |
| 10 | +
|
| 11 | +${script} [coverage_percent] [clover.xml] |
| 12 | + Uses the provided Clover XML code coverage report value to calculate |
| 13 | + the percentage of code covered by phpunit unit tests. Compares that |
| 14 | + percentage to the provided integer value, and if coverage is lower |
| 15 | + than specified the script returns a non-zero value to indicate failure. |
| 16 | +
|
| 17 | + Intended to be used with automated build systems like Travis to ensure |
| 18 | + code coverage remains above a designated percentage. |
| 19 | +
|
| 20 | +Usage: |
| 21 | + bin/${script} |
| 22 | +
|
| 23 | + coverage_percent - Optional integer value between 0 and 100 represented |
| 24 | + the minimum required percentage of coverage required. |
| 25 | + If not provided, defaults to 100. |
| 26 | +
|
| 27 | + clover.xml - Optional filesystem path to an XML file produced |
| 28 | + by PHPunit's code coverage. If absent, the script |
| 29 | + will attempt to obtain the correct path using the |
| 30 | + project's Config/phpunit.xml file and will exit |
| 31 | + with an error if this fails. |
| 32 | +
|
| 33 | +EOT; |
| 34 | + |
| 35 | + exit(0); |
| 36 | +} |
| 37 | +if (isset($argv[1]) && $argv[1] == '-h') { |
| 38 | + usage(); |
| 39 | +} |
| 40 | + |
| 41 | +// Set up variables. |
| 42 | +$percentage = (isset($argv[1]) ? (int)$argv[1] : 100); |
| 43 | +$percentage = max(0, min(100, $percentage)); |
| 44 | + |
| 45 | +// Try to auto-detect the clover file path. |
| 46 | +if (isset($argv[2])) { |
| 47 | + $inputFile = $argv[2]; |
| 48 | +} else { |
| 49 | + $baseDir = getcwd(); |
| 50 | + $phpunitConfigFile = "{$baseDir}/Config/phpunit.xml"; |
| 51 | + if (!is_readable($phpunitConfigFile)) { |
| 52 | + echo "!! Could not guess path to clover.xml file. Aborting." . PHP_EOL; |
| 53 | + exit(2); |
| 54 | + } |
| 55 | + |
| 56 | + $xml = new SimpleXMLElement(file_get_contents($phpunitConfigFile)); |
| 57 | + $snippet = $xml->xpath('//log[@type="coverage-clover"]'); |
| 58 | + if (!count($snippet)) { |
| 59 | + echo "!! Config/phpunit.xml file does not specify a coverage-clover log. Aborting." . PHP_EOL; |
| 60 | + exit(3); |
| 61 | + } |
| 62 | + |
| 63 | + $snippet = array_pop($snippet); |
| 64 | + if (!isset($snippet['target'])) { |
| 65 | + echo '!! Config/phpunit.xml: <log type="coverage-clover"> does not specify a `target` attribute. Aborting.' . PHP_EOL; |
| 66 | + exit(4); |
| 67 | + } |
| 68 | + |
| 69 | + $snippet = (string)$snippet['target']; |
| 70 | + $inputFile = "{$baseDir}/Config/{$snippet}"; |
| 71 | +} |
| 72 | + |
| 73 | +// Parse the clover report file. |
| 74 | +if (!is_readable(realpath($inputFile))) { |
| 75 | + echo "!! Invalid input file provided: `{$inputFile}`. Aborting." . PHP_EOL; |
| 76 | + exit(5); |
| 77 | +} |
| 78 | +$xml = new SimpleXMLElement(file_get_contents(realpath($inputFile))); |
| 79 | +$metrics = $xml->xpath('//metrics'); |
| 80 | +$totalElements = 0; |
| 81 | +$checkedElements = 0; |
| 82 | + |
| 83 | +foreach ($metrics as $metric) { |
| 84 | + $totalElements += (int) $metric['elements']; |
| 85 | + $checkedElements += (int) $metric['coveredelements']; |
| 86 | +} |
| 87 | + |
| 88 | +$coverage = ($checkedElements / $totalElements) * 100; |
| 89 | + |
| 90 | +// Spit out the results. |
| 91 | +echo 'Code coverage is ' . number_format($coverage, 1) . '% - '; |
| 92 | + |
| 93 | +if ($coverage < $percentage) { |
| 94 | + echo "Minimum accepted is {$percentage}%" . PHP_EOL; |
| 95 | + exit(1); |
| 96 | +} |
| 97 | + |
| 98 | +echo 'OK!' . PHP_EOL; |
0 commit comments