From f81b515294327143c9e94818c0363fc19b2c41be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joakim=20L=C3=B6fgren?= <joakim.lofgren@gmail.com>
Date: Mon, 6 Oct 2014 16:19:11 +0200
Subject: [PATCH] Refactor checkstyle publisher

Change-Id: If829720c026ecffc6a5e1cede9aafa51d1ec86e6
---
 jenkins_jobs/modules/publishers.py           | 139 ++++++++++---------
 tests/publishers/fixtures/checkstyle004.xml  |  29 ++++
 tests/publishers/fixtures/checkstyle004.yaml |  11 ++
 tests/publishers/fixtures/checkstyle005.xml  |  29 ++++
 tests/publishers/fixtures/checkstyle005.yaml |  20 +++
 tests/publishers/fixtures/checkstyle006.xml  |  37 +++++
 tests/publishers/fixtures/checkstyle006.yaml |  32 +++++
 7 files changed, 228 insertions(+), 69 deletions(-)
 create mode 100644 tests/publishers/fixtures/checkstyle004.xml
 create mode 100644 tests/publishers/fixtures/checkstyle004.yaml
 create mode 100644 tests/publishers/fixtures/checkstyle005.xml
 create mode 100644 tests/publishers/fixtures/checkstyle005.yaml
 create mode 100644 tests/publishers/fixtures/checkstyle006.xml
 create mode 100644 tests/publishers/fixtures/checkstyle006.yaml

diff --git a/jenkins_jobs/modules/publishers.py b/jenkins_jobs/modules/publishers.py
index 77bd03bca..03d3e3664 100644
--- a/jenkins_jobs/modules/publishers.py
+++ b/jenkins_jobs/modules/publishers.py
@@ -1062,92 +1062,93 @@ def checkstyle(parser, xml_parent, data):
     The checkstyle component accepts a dictionary with the
     following values:
 
-    :arg str pattern: report filename pattern
-    :arg bool canRunOnFailed: also runs for failed builds
-     (instead of just stable or unstable builds)
-    :arg bool shouldDetectModules:
-    :arg int healthy: sunny threshold
-    :arg int unHealthy: stormy threshold
-    :arg str healthThreshold: threshold priority for health status
-     (high: only high, normal: high and normal, low: all)
-    :arg dict thresholds:
+    :arg str pattern: Report filename pattern (optional)
+    :arg bool can-run-on-failed: Also runs for failed builds, instead of just
+      stable or unstable builds (default false)
+    :arg bool should-detect-modules: Determines if Ant or Maven modules should
+      be detected for all files that contain warnings (default false)
+    :arg int healthy: Sunny threshold (optional)
+    :arg int unhealthy: Stormy threshold (optional)
+    :arg str health-threshold: Threshold priority for health status
+      ('low', 'normal' or 'high', defaulted to 'low')
+    :arg dict thresholds: Mark build as failed or unstable if the number of
+      errors exceeds a threshold. (optional)
+
         :thresholds:
             * **unstable** (`dict`)
-                :unstable: * **totalAll** (`int`)
-                           * **totalHigh** (`int`)
-                           * **totalNormal** (`int`)
-                           * **totalLow** (`int`)
+                :unstable: * **total-all** (`int`)
+                           * **total-high** (`int`)
+                           * **total-normal** (`int`)
+                           * **total-low** (`int`)
+                           * **new-all** (`int`)
+                           * **new-high** (`int`)
+                           * **new-normal** (`int`)
+                           * **new-low** (`int`)
+
             * **failed** (`dict`)
-                :failed: * **totalAll** (`int`)
-                         * **totalHigh** (`int`)
-                         * **totalNormal** (`int`)
-                         * **totalLow** (`int`)
-    :arg str defaultEncoding: encoding for parsing or showing files
-     (empty will use platform default)
+                :failed: * **total-all** (`int`)
+                         * **total-high** (`int`)
+                         * **total-normal** (`int`)
+                         * **total-low** (`int`)
+                         * **new-all** (`int`)
+                         * **new-high** (`int`)
+                         * **new-normal** (`int`)
+                         * **new-low** (`int`)
+    :arg str default-encoding: Encoding for parsing or showing files (optional)
+    :arg bool do-not-resolve-relative-paths: (default false)
+    :arg bool dont-compute-new: If set to false, computes new warnings based on
+      the reference build (default true)
+    :arg bool use-stable-build-as-reference: The number of new warnings will be
+      calculated based on the last stable build, allowing reverts of unstable
+      builds where the number of warnings was decreased. (default false)
+    :arg bool use-delta-values: If set then the number of new warnings is
+      calculated by subtracting the total number of warnings of the current
+      build from the reference build.
+      (default false)
 
     Example:
 
-    .. literalinclude::  /../../tests/publishers/fixtures/checkstyle001.yaml
+    .. literalinclude::  /../../tests/publishers/fixtures/checkstyle004.yaml
 
     Full example:
 
-    .. literalinclude::  /../../tests/publishers/fixtures/checkstyle002.yaml
+    .. literalinclude::  /../../tests/publishers/fixtures/checkstyle006.yaml
 
     """
-    checkstyle = XML.SubElement(xml_parent,
-                                'hudson.plugins.checkstyle.'
-                                'CheckStylePublisher')
+    def convert_settings(lookup, data):
+        """Helper to convert settings from one key to another
+        """
 
-    XML.SubElement(checkstyle, 'healthy').text = str(
-        data.get('healthy', ''))
-    XML.SubElement(checkstyle, 'unHealthy').text = str(
-        data.get('unHealthy', ''))
-    XML.SubElement(checkstyle, 'thresholdLimit').text = \
-        data.get('healthThreshold', 'low')
+        for old_key, value in data.items():
+            if old_key in lookup:
+                # Insert value if key does not already exists
+                data.setdefault(lookup[old_key], value)
 
-    XML.SubElement(checkstyle, 'pluginName').text = '[CHECKSTYLE] '
+                del data[old_key]
 
-    XML.SubElement(checkstyle, 'defaultEncoding').text = \
-        data.get('defaultEncoding', '')
+    xml_element = XML.SubElement(xml_parent,
+                                 'hudson.plugins.checkstyle.'
+                                 'CheckStylePublisher')
 
-    XML.SubElement(checkstyle, 'canRunOnFailed').text = str(
-        data.get('canRunOnFailed', False)).lower()
+    # Convert old style yaml to new style
+    convert_settings({
+        'unHealthy': 'unhealthy',
+        'healthThreshold': 'health-threshold',
+        'defaultEncoding': 'default-encoding',
+        'canRunOnFailed': 'can-run-on-failed',
+        'shouldDetectModules': 'should-detect-modules'
+    }, data)
 
-    XML.SubElement(checkstyle, 'useStableBuildAsReference').text = 'false'
+    threshold_data = data.get('thresholds', {})
+    for threshold in ['unstable', 'failed']:
+        convert_settings({
+            'totalAll': 'total-all',
+            'totalHigh': 'total-high',
+            'totalNormal': 'total-normal',
+            'totalLow': 'total-low'
+        }, threshold_data.get(threshold, {}))
 
-    XML.SubElement(checkstyle, 'useDeltaValues').text = 'false'
-
-    dthresholds = data.get('thresholds', {})
-    dunstable = dthresholds.get('unstable', {})
-    dfailed = dthresholds.get('failed', {})
-    thresholds = XML.SubElement(checkstyle, 'thresholds')
-
-    XML.SubElement(thresholds, 'unstableTotalAll').text = str(
-        dunstable.get('totalAll', ''))
-    XML.SubElement(thresholds, 'unstableTotalHigh').text = str(
-        dunstable.get('totalHigh', ''))
-    XML.SubElement(thresholds, 'unstableTotalNormal').text = str(
-        dunstable.get('totalNormal', ''))
-    XML.SubElement(thresholds, 'unstableTotalLow').text = str(
-        dunstable.get('totalLow', ''))
-
-    XML.SubElement(thresholds, 'failedTotalAll').text = str(
-        dfailed.get('totalAll', ''))
-    XML.SubElement(thresholds, 'failedTotalHigh').text = str(
-        dfailed.get('totalHigh', ''))
-    XML.SubElement(thresholds, 'failedTotalNormal').text = str(
-        dfailed.get('totalNormal', ''))
-    XML.SubElement(thresholds, 'failedTotalLow').text = str(
-        dfailed.get('totalLow', ''))
-
-    XML.SubElement(checkstyle, 'shouldDetectModules').text = \
-        str(data.get('shouldDetectModules', False)).lower()
-
-    XML.SubElement(checkstyle, 'dontComputeNew').text = 'true'
-
-    XML.SubElement(checkstyle, 'doNotResolveRelativePaths').text = 'false'
-
-    XML.SubElement(checkstyle, 'pattern').text = data.get('pattern', '')
+    build_trends_publisher('[CHECKSTYLE] ', xml_element, data)
 
 
 def scp(parser, xml_parent, data):
diff --git a/tests/publishers/fixtures/checkstyle004.xml b/tests/publishers/fixtures/checkstyle004.xml
new file mode 100644
index 000000000..06b52cf1a
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle004.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project>
+  <publishers>
+    <hudson.plugins.checkstyle.CheckStylePublisher>
+      <healthy>0</healthy>
+      <unHealthy>100</unHealthy>
+      <thresholdLimit>high</thresholdLimit>
+      <pluginName>[CHECKSTYLE] </pluginName>
+      <defaultEncoding/>
+      <canRunOnFailed>false</canRunOnFailed>
+      <useStableBuildAsReference>false</useStableBuildAsReference>
+      <useDeltaValues>false</useDeltaValues>
+      <thresholds>
+        <unstableTotalAll/>
+        <unstableTotalHigh>10</unstableTotalHigh>
+        <unstableTotalNormal/>
+        <unstableTotalLow/>
+        <failedTotalAll/>
+        <failedTotalHigh>1</failedTotalHigh>
+        <failedTotalNormal/>
+        <failedTotalLow/>
+      </thresholds>
+      <shouldDetectModules>false</shouldDetectModules>
+      <dontComputeNew>true</dontComputeNew>
+      <doNotResolveRelativePaths>false</doNotResolveRelativePaths>
+      <pattern>**/checkstyle-result.xml</pattern>
+    </hudson.plugins.checkstyle.CheckStylePublisher>
+  </publishers>
+</project>
diff --git a/tests/publishers/fixtures/checkstyle004.yaml b/tests/publishers/fixtures/checkstyle004.yaml
new file mode 100644
index 000000000..8e9519f94
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle004.yaml
@@ -0,0 +1,11 @@
+publishers:
+ - checkstyle:
+    pattern: '**/checkstyle-result.xml'
+    healthy: 0
+    unhealthy: 100
+    health-threshold: 'high'
+    thresholds:
+        unstable:
+            total-high: 10
+        failed:
+            total-high: 1
diff --git a/tests/publishers/fixtures/checkstyle005.xml b/tests/publishers/fixtures/checkstyle005.xml
new file mode 100644
index 000000000..190a0a115
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle005.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project>
+  <publishers>
+    <hudson.plugins.checkstyle.CheckStylePublisher>
+      <healthy>0</healthy>
+      <unHealthy>100</unHealthy>
+      <thresholdLimit>high</thresholdLimit>
+      <pluginName>[CHECKSTYLE] </pluginName>
+      <defaultEncoding>utf-8</defaultEncoding>
+      <canRunOnFailed>true</canRunOnFailed>
+      <useStableBuildAsReference>false</useStableBuildAsReference>
+      <useDeltaValues>false</useDeltaValues>
+      <thresholds>
+        <unstableTotalAll>90</unstableTotalAll>
+        <unstableTotalHigh>80</unstableTotalHigh>
+        <unstableTotalNormal>70</unstableTotalNormal>
+        <unstableTotalLow>60</unstableTotalLow>
+        <failedTotalAll>90</failedTotalAll>
+        <failedTotalHigh>80</failedTotalHigh>
+        <failedTotalNormal>70</failedTotalNormal>
+        <failedTotalLow>60</failedTotalLow>
+      </thresholds>
+      <shouldDetectModules>true</shouldDetectModules>
+      <dontComputeNew>true</dontComputeNew>
+      <doNotResolveRelativePaths>false</doNotResolveRelativePaths>
+      <pattern>**/checkstyle-result.xml</pattern>
+    </hudson.plugins.checkstyle.CheckStylePublisher>
+  </publishers>
+</project>
diff --git a/tests/publishers/fixtures/checkstyle005.yaml b/tests/publishers/fixtures/checkstyle005.yaml
new file mode 100644
index 000000000..a0fcc7573
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle005.yaml
@@ -0,0 +1,20 @@
+publishers:
+ - checkstyle:
+    pattern: '**/checkstyle-result.xml'
+    can-run-on-failed: true
+    should-detect-modules: true
+    healthy: 0
+    unhealthy: 100
+    health-threshold: 'high'
+    thresholds:
+        unstable:
+            total-all: 90
+            total-high: 80
+            total-normal: 70
+            total-low: 60
+        failed:
+            total-all: 90
+            total-high: 80
+            total-normal: 70
+            total-low: 60
+    default-encoding: 'utf-8'
diff --git a/tests/publishers/fixtures/checkstyle006.xml b/tests/publishers/fixtures/checkstyle006.xml
new file mode 100644
index 000000000..4cbd96390
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle006.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project>
+  <publishers>
+    <hudson.plugins.checkstyle.CheckStylePublisher>
+      <healthy>0</healthy>
+      <unHealthy>100</unHealthy>
+      <thresholdLimit>high</thresholdLimit>
+      <pluginName>[CHECKSTYLE] </pluginName>
+      <defaultEncoding>utf-8</defaultEncoding>
+      <canRunOnFailed>true</canRunOnFailed>
+      <useStableBuildAsReference>true</useStableBuildAsReference>
+      <useDeltaValues>true</useDeltaValues>
+      <thresholds>
+        <unstableTotalAll>90</unstableTotalAll>
+        <unstableTotalHigh>80</unstableTotalHigh>
+        <unstableTotalNormal>70</unstableTotalNormal>
+        <unstableTotalLow>60</unstableTotalLow>
+        <unstableNewAll>50</unstableNewAll>
+        <unstableNewHigh>40</unstableNewHigh>
+        <unstableNewNormal>30</unstableNewNormal>
+        <unstableNewLow>20</unstableNewLow>
+        <failedTotalAll>91</failedTotalAll>
+        <failedTotalHigh>81</failedTotalHigh>
+        <failedTotalNormal>71</failedTotalNormal>
+        <failedTotalLow>61</failedTotalLow>
+        <failedNewAll>51</failedNewAll>
+        <failedNewHigh>41</failedNewHigh>
+        <failedNewNormal>31</failedNewNormal>
+        <failedNewLow>21</failedNewLow>
+      </thresholds>
+      <shouldDetectModules>true</shouldDetectModules>
+      <dontComputeNew>false</dontComputeNew>
+      <doNotResolveRelativePaths>true</doNotResolveRelativePaths>
+      <pattern>**/checkstyle-result.xml</pattern>
+    </hudson.plugins.checkstyle.CheckStylePublisher>
+  </publishers>
+</project>
diff --git a/tests/publishers/fixtures/checkstyle006.yaml b/tests/publishers/fixtures/checkstyle006.yaml
new file mode 100644
index 000000000..a3c6164a5
--- /dev/null
+++ b/tests/publishers/fixtures/checkstyle006.yaml
@@ -0,0 +1,32 @@
+publishers:
+ - checkstyle:
+    pattern: '**/checkstyle-result.xml'
+    can-run-on-failed: true
+    should-detect-modules: true
+    healthy: 0
+    unhealthy: 100
+    health-threshold: 'high'
+    thresholds:
+        unstable:
+            total-all: 90
+            total-high: 80
+            total-normal: 70
+            total-low: 60
+            new-all: 50
+            new-high: 40
+            new-normal: 30
+            new-low: 20
+        failed:
+            total-all: 91
+            total-high: 81
+            total-normal: 71
+            total-low: 61
+            new-all: 51
+            new-high: 41
+            new-normal: 31
+            new-low: 21
+    default-encoding: 'utf-8'
+    do-not-resolve-relative-paths: true
+    dont-compute-new: false
+    use-stable-build-as-reference: true
+    use-delta-values: true