From 28c5c1c93bb0754bb9adf8c44639c7a292a428b4 Mon Sep 17 00:00:00 2001 From: Antoine Musso Date: Mon, 21 Oct 2013 16:36:22 +0200 Subject: [PATCH] cloverphp publisher Capture code coverage reports from PHPUnit, requires the Jenkins Clover PHP Plugin: https://wiki.jenkins-ci.org/display/JENKINS/Clover+PHP+Plugin Note: whenever the healthy targets are left blank, the v0.3.3 plugin will fill in default values which then appears in the configuration. I have ported that in Jenkins Job Builder to ensure clean diff in the Job Configuration History plugin. Change-Id: I9010dee62611094840304cdc2e7317b058d6495a --- jenkins_jobs/modules/publishers.py | 106 ++++++++++++++++++++ setup.py | 1 + tests/publishers/fixtures/cloverphp001.xml | 16 +++ tests/publishers/fixtures/cloverphp001.yaml | 4 + tests/publishers/fixtures/cloverphp002.xml | 23 +++++ tests/publishers/fixtures/cloverphp002.yaml | 17 ++++ tests/publishers/fixtures/cloverphp003.xml | 17 ++++ tests/publishers/fixtures/cloverphp003.yaml | 10 ++ 8 files changed, 194 insertions(+) create mode 100644 tests/publishers/fixtures/cloverphp001.xml create mode 100644 tests/publishers/fixtures/cloverphp001.yaml create mode 100644 tests/publishers/fixtures/cloverphp002.xml create mode 100644 tests/publishers/fixtures/cloverphp002.yaml create mode 100644 tests/publishers/fixtures/cloverphp003.xml create mode 100644 tests/publishers/fixtures/cloverphp003.yaml diff --git a/jenkins_jobs/modules/publishers.py b/jenkins_jobs/modules/publishers.py index 2af6d7e88..e5edfc56c 100644 --- a/jenkins_jobs/modules/publishers.py +++ b/jenkins_jobs/modules/publishers.py @@ -248,6 +248,112 @@ def trigger(parser, xml_parent, data): tcolor.text = thresholds[threshold]['color'] +def cloverphp(parser, xml_parent, data): + """yaml: cloverphp + Capture code coverage reports from PHPUnit + Requires the Jenkins `Clover PHP Plugin. + `_ + + Your job definition should pass to PHPUnit the --coverage-clover option + pointing to a file in the workspace (ex: clover-coverage.xml). The filename + has to be filled in the `xml-location` field. + + :arg str xml-location: Path to the coverage XML file generated by PHPUnit + using --coverage-clover. Relative to workspace. (required) + :arg dict html: When existent, whether the plugin should generate a HTML + report. Note that PHPUnit already provide a HTML report via its + --cover-html option which can be set in your builder (optional): + + * **dir** (str): Directory where HTML report will be generated relative + to workspace. (required in `html` dict). + * **archive** (bool): Whether to archive HTML reports (default True). + + :arg list metric-targets: List of metric targets to reach, must be one of + **healthy**, **unhealthy** and **failing**. Each metric target can takes + two parameters: + + * **method** Target for method coverage + * **statement** Target for statements coverage + + Whenever a metric target is not filled in, the Jenkins plugin can fill in + defaults for you (as of v0.3.3 of the plugin the healthy target will have + method: 70 and statement: 80 if both are left empty). Jenkins Job Builder + will mimic that feature to ensure clean configuration diff. + + Minimal example: + + .. literalinclude:: ../../tests/publishers/fixtures/cloverphp001.yaml + + Full example: + + .. literalinclude:: ../../tests/publishers/fixtures/cloverphp002.yaml + + """ + cloverphp = XML.SubElement( + xml_parent, + 'org.jenkinsci.plugins.cloverphp.CloverPHPPublisher') + + # The plugin requires clover XML file to parse + if 'xml-location' not in data: + raise JenkinsJobsException('xml-location must be set') + + # Whether HTML publishing has been checked + html_publish = False + # By default, disableArchiving = false. Note that we use + # reversed logic. + html_archive = True + + if 'html' in data: + html_publish = True + html_dir = data['html'].get('dir', None) + html_archive = data['html'].get('archive', html_archive) + if html_dir is None: + # No point in going further, the plugin would not work + raise JenkinsJobsException('htmldir is required in a html block') + + XML.SubElement(cloverphp, 'publishHtmlReport').text = \ + str(html_publish).lower() + if html_publish: + XML.SubElement(cloverphp, 'reportDir').text = html_dir + XML.SubElement(cloverphp, 'xmlLocation').text = data.get('xml-location') + XML.SubElement(cloverphp, 'disableArchiving').text = \ + str(not html_archive).lower() + + # Handle targets + + # Plugin v0.3.3 will fill defaults for us whenever healthy targets are both + # blanks. + default_metrics = { + 'healthy': {'method': 70, 'statement': 80} + } + allowed_metrics = ['healthy', 'unhealthy', 'failing'] + + metrics = data.get('metric-targets', []) + # list of dicts to dict + metrics = dict(kv for m in metrics for kv in m.iteritems()) + + # Populate defaults whenever nothing has been filled by user. + for default in default_metrics.keys(): + if metrics.get(default, None) is None: + metrics[default] = default_metrics[default] + + # The plugin would at least define empty targets so make sure + # we output them all in the XML regardless of what the user + # has or has not entered. + for target in allowed_metrics: + cur_target = XML.SubElement(cloverphp, target + 'Target') + + for t_type in ['method', 'statement']: + val = metrics.get(target, {}).get(t_type) + if val is None or type(val) != int: + continue + if val < 0 or val > 100: + raise JenkinsJobsException( + "Publisher cloverphp metric target %s:%s = %s " + "is not in valid range 0-100." % (target, t_type, val)) + XML.SubElement(cur_target, t_type + 'Coverage').text = str(val) + + def coverage(parser, xml_parent, data): """yaml: coverage WARNING: The coverage function is deprecated. Instead, use the diff --git a/setup.py b/setup.py index 5718c97af..926a6b36e 100644 --- a/setup.py +++ b/setup.py @@ -126,6 +126,7 @@ setuptools.setup( 'checkstyle=jenkins_jobs.modules.publishers:checkstyle', 'cifs=jenkins_jobs.modules.publishers:cifs', 'claim-build=jenkins_jobs.modules.publishers:claim_build', + 'cloverphp=jenkins_jobs.modules.publishers:cloverphp', 'cobertura=jenkins_jobs.modules.publishers:cobertura', 'copy-to-master=jenkins_jobs.modules.publishers:copy_to_master', 'coverage=jenkins_jobs.modules.publishers:coverage', diff --git a/tests/publishers/fixtures/cloverphp001.xml b/tests/publishers/fixtures/cloverphp001.xml new file mode 100644 index 000000000..f572450d4 --- /dev/null +++ b/tests/publishers/fixtures/cloverphp001.xml @@ -0,0 +1,16 @@ + + + + + false + build/clover.xml + false + + 70 + 80 + + + + + + diff --git a/tests/publishers/fixtures/cloverphp001.yaml b/tests/publishers/fixtures/cloverphp001.yaml new file mode 100644 index 000000000..3b4e90484 --- /dev/null +++ b/tests/publishers/fixtures/cloverphp001.yaml @@ -0,0 +1,4 @@ +# Test for the defaults, only xml-location is required +publishers: + - cloverphp: + xml-location: 'build/clover.xml' diff --git a/tests/publishers/fixtures/cloverphp002.xml b/tests/publishers/fixtures/cloverphp002.xml new file mode 100644 index 000000000..5f4db9f31 --- /dev/null +++ b/tests/publishers/fixtures/cloverphp002.xml @@ -0,0 +1,23 @@ + + + + + true + html + build/clover.xml + true + + 80 + 90 + + + 40 + 50 + + + 10 + 20 + + + + diff --git a/tests/publishers/fixtures/cloverphp002.yaml b/tests/publishers/fixtures/cloverphp002.yaml new file mode 100644 index 000000000..e48dcf815 --- /dev/null +++ b/tests/publishers/fixtures/cloverphp002.yaml @@ -0,0 +1,17 @@ +# Exercise all options with non defaults values +publishers: + - cloverphp: + xml-location: 'build/clover.xml' + html: + dir: 'html' + archive: false + metric-targets: + - healthy: + method: 80 + statement: 90 + - unhealthy: + method: 40 + statement: 50 + - failing: + method: 10 + statement: 20 diff --git a/tests/publishers/fixtures/cloverphp003.xml b/tests/publishers/fixtures/cloverphp003.xml new file mode 100644 index 000000000..a9255397f --- /dev/null +++ b/tests/publishers/fixtures/cloverphp003.xml @@ -0,0 +1,17 @@ + + + + + false + build/clover.xml + false + + 77 + + + 88 + + + + + diff --git a/tests/publishers/fixtures/cloverphp003.yaml b/tests/publishers/fixtures/cloverphp003.yaml new file mode 100644 index 000000000..07c798bbe --- /dev/null +++ b/tests/publishers/fixtures/cloverphp003.yaml @@ -0,0 +1,10 @@ +# Specify only method or statement +# Does not specify failling +publishers: + - cloverphp: + xml-location: 'build/clover.xml' + metric-targets: + - healthy: + method: 77 + - unhealthy: + statement: 88