Dashboard > CruiseControl > Home > CruiseControlWithPMD
CruiseControlWithPMD Log In | Sign Up   View a printable version of the current page.

Added by Robert J. Smith , last edited by Mike Robinet on Apr 18, 2008  (view change) show comment
Labels: 
(None)

Note: since CC 2.4 pmd (and checkstyle) support has shipped already integrated into the reporting application. The sections on this page about adding PMD to your build and merging result files still apply. To enable the detail report you'll need to uncomment the relevant part of main.jsp.

Introduction

From the PMD website:

PMD scans Java source code and looks for potential problems like:

  • Empty try/catch/finally/switch blocks
  • Unused local variables, parameters and private methods
  • Empty if/while statements
  • Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
  • Classes with high Cyclomatic Complexity measurements

Step 1 - Add PMD to your build

For information on adding PMD to your Ant or Maven build, please refer to the PMD website.

In either case, be certain to use an output directory which can later be merged into the CruiseControl log. If you will run PMD against multiple targets within the same build script, be certain to use a unique name for each run. I like to use "<project-name>.pmd.xml".

Step 2 - Merge the results into your CC log

Add a merge child element to your project(s)' log element. If you wish, you can filter based on the extension you used above.

<log dir="${logdir}">
    <merge dir="${builddir}/pmd" pattern="*.pmd.xml"/>
</log>

Step 3 - Add a new tab in main.jsp

main.jsp
.
.
.
    <cruisecontrol:tabsheet>
      <tr>
        <td bgcolor="white" >
          <cruisecontrol:tab name="buildResults" label="Build Results" >
            <%@ include file="buildresults.jsp" %>
          </cruisecontrol:tab>

          <cruisecontrol:tab name="pmdResults" label="PMD Results" >
            <%@ include file="pmd.jsp" %>
          </cruisecontrol:tab>
.
.
.

Step 4 - Create pmd.jsp

pmd.jsp
<%@ taglib uri="/WEB-INF/cruisecontrol-jsp11.tld" prefix="cruisecontrol"%>
<cruisecontrol:xsl xslFile="/xsl/pmd.xsl"/>

Step 5 - Add formating info to cruisecontrol.css

These formats were posted to the mail list by Christopher G. Stach II. Many thanks Chris!

cruisecontrol.css
.pmd-evenrow { font-family:arial,helvetica,sans-serif; font-size:8pt; color:#000000; background-color:#FFFFCC; }
.pmd-oddrow { font-family:arial,helvetica,sans-serif; font-size:8pt; color:#000000; background-color:#CCCCCC; }
.pmd-fileheader { background-color:#FFFFFF; font-family:arial,helvetica,sans-serif; font-size:9pt; color:#000000; }
.pmd-sectionheader { background-color:#000066; font-family:arial,helvetica,sans-serif; font-size:9pt; color:#FFFFFF; }
.pmd-priority-1 { background-color:#FF0000; }
.pmd-priority-2 { background-color:#FF3300; }
.pmd-priority-3 { background-color:#FF9900; }
.pmd-priority-4 { background-color:#FFFF00; }
.pmd-priority-5 { background-color:#0033FF; }

Step 6 - Create pmd.xsl in the xsl directory

There are an infinite number of possibilities here. I use the following:

pmd.xsl
<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" />

  <xsl:template match="/">
    <xsl:apply-templates select="." mode="pmd" />
  </xsl:template>

  <xsl:template match="/" mode="pmd">

    <xsl:variable name="file.count" select="count(cruisecontrol/pmd/file)"/>
    <xsl:variable name="violation.count" select="count(cruisecontrol/pmd/file/violation)"/>
    <xsl:variable name="p1.count" select="count(cruisecontrol/pmd/file/violation[@priority='1'])"/>
    <xsl:variable name="p2.count" select="count(cruisecontrol/pmd/file/violation[@priority='2'])"/>
    <xsl:variable name="p3.count" select="count(cruisecontrol/pmd/file/violation[@priority='3'])"/>
    <xsl:variable name="p4.count" select="count(cruisecontrol/pmd/file/violation[@priority='4'])"/>
    <xsl:variable name="p5.count" select="count(cruisecontrol/pmd/file/violation[@priority='5'])"/>

    <xsl:if test="count(cruisecontrol/pmd) = 0" >
        PMD was not run against this project
    </xsl:if>
    <xsl:if test="count(cruisecontrol/pmd) &gt; 0">
      <h1 align="center">PMD Violation Report</h1>
      <table align="center" cellpadding="8" cellspacing="0" border="0" width="98%">
      <tr>
        <td class="pmd-sectionheader">
          Summary: <xsl:value-of select="$violation.count"/> violation(s) found in
          <xsl:value-of select="$file.count"/> file(s)
        </td>
      </tr>
      <tr>
        <td>
        <table align="right" cellpadding="1" cellspacing="1" border="0" width="95%">
          <tr>
            <td class="changelists-file-header" colspan="3">
              &#160;Violations by Priority&#160;
            </td>
          </tr>
          <tr>
            <td class="changelists-file-header" width="10">Priority</td>
            <td class="changelists-file-header" width="20">Violations</td>
            <td class="changelists-file-header">Percentage</td>
          </tr>
          <tr>
            <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
            <td><xsl:attribute name="class">pmd-priority-1</xsl:attribute>1</td>
            <td><xsl:value-of select="$p1.count"/></td>
            <td><xsl:value-of select="format-number($p1.count div $violation.count, '##%')"/></td>
          </tr>
          <tr>
            <xsl:attribute name="class">pmd-oddrow</xsl:attribute>
            <td><xsl:attribute name="class">pmd-priority-2</xsl:attribute>2</td>
            <td><xsl:value-of select="$p2.count"/></td>
            <td><xsl:value-of select="format-number($p2.count div $violation.count, '##%')"/></td>
          </tr>
          <tr>
            <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
            <td><xsl:attribute name="class">pmd-priority-3</xsl:attribute>3</td>
            <td><xsl:value-of select="$p3.count"/></td>
            <td><xsl:value-of select="format-number($p3.count div $violation.count, '##%')"/></td>
          </tr>
          <tr>
            <xsl:attribute name="class">pmd-oddrow</xsl:attribute>
            <td><xsl:attribute name="class">pmd-priority-4</xsl:attribute>4</td>
            <td><xsl:value-of select="$p4.count"/></td>
            <td><xsl:value-of select="format-number($p4.count div $violation.count, '##%')"/></td>
          </tr>
          <tr>
            <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
            <td><xsl:attribute name="class">pmd-priority-5</xsl:attribute>5</td>
            <td><xsl:value-of select="$p5.count"/></td>
            <td><xsl:value-of select="format-number($p5.count div $violation.count, '##%')"/></td>
          </tr>
        </table>
        </td>
      </tr>
      <tr>
        <td class="pmd-sectionheader">Files: (<xsl:value-of select="$file.count"/>)</td>
      </tr>
      <xsl:apply-templates select="cruisecontrol/pmd/file" mode="pmd" />
      </table>
    </xsl:if>
  </xsl:template>

  <xsl:template match="file" mode="pmd">
    <tr valign="top">
      <xsl:if test="position() mod 2=0">
        <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
      </xsl:if>
      <xsl:if test="position() mod 2!=0">
        <xsl:attribute name="class">pmd-oddrow</xsl:attribute>
      </xsl:if>
      <td class="modifications-data">
        <b><xsl:value-of select="@name"/></b>
      </td>
    </tr>
    <tr valign="top">
      <xsl:if test="position() mod 2=0">
        <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
      </xsl:if>
      <xsl:if test="position() mod 2!=0">
        <xsl:attribute name="class">pmd-oddrow</xsl:attribute>
      </xsl:if>
      <td class="modifications-data" colspan="5">
        <table align="right" cellpadding="1" cellspacing="1" border="0" width="95%">
          <tr>
            <td class="changelists-file-header" colspan="6">
              &#160;Violations associated with this file:&#160;
              (<xsl:value-of select="count(violation)"/>)
            </td>
          </tr>
          <tr>
            <td class="changelists-file-header">Priority</td>
            <td class="changelists-file-header">Line</td>
            <td class="changelists-file-header">Rule</td>
            <td class="changelists-file-header">Ruleset</td>
            <td class="changelists-file-header">Hint</td>
          </tr>
          <xsl:apply-templates select="violation" mode="pmd"/>
        </table>
      </td>
    </tr>
  </xsl:template>

  <xsl:template match="violation" mode="pmd">
    <tr valign="top" >
      <xsl:if test="position() mod 2=0">
        <xsl:attribute name="class">pmd-evenrow</xsl:attribute>
      </xsl:if>
      <xsl:if test="position() mod 2!=0">
        <xsl:attribute name="class">pmd-oddrow</xsl:attribute>
      </xsl:if>
      <td width="10">
        <xsl:attribute name="class">pmd-priority-<xsl:value-of select="@priority" /></xsl:attribute>
        <xsl:value-of select="@priority"/>
      </td>
      <td class="modifications-data"><xsl:value-of select="@line"/></td>
      <td class="modifications-data"><xsl:value-of select="@rule"/></td>
      <td class="modifications-data"><xsl:value-of select="@ruleset"/></td>
      <td class="modifications-data"><xsl:value-of select="."/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

which provides an output like so:

Powered by a free Atlassian Confluence Open Source Project / Non-profit License granted to ThoughtWorks, Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators