Integrando CruiseControl com FlexPMD

terça-feira, março 9th, 2010 @ 22:02

Após configurarmbanneros o CruiseControl com o SVN aqui na Informant decidimos que era hora de buscar novas ferramentas para tornar o processo de integração contínua mais completo. Para que pudessemos monitorar a qualidade do código a cada build, assumi a tarefa de integrar o CruiseControl com o FlexPMD, famoso detector de más práticas em código fonte Flex.

Antes de tudo, você precisa baixar a última versão do FlexPMD Ant Task. Descompacte todos os arquivos exceto o jar do Ant dentro da pasta lib de sua instalação do Ant.

Depois de feito isso é hora de adicionar a tarefa do FlexPMD ao build do seu projeto:

<property name="src.dir" value="../../checkout/projeto/flex_src" />
<property name="bin.dir" value="../../projects/projeto/pmd/" />

<taskdef name="flexPmd" classname="com.adobe.ac.pmd.ant.FlexPmdAntTask"/>

<target name="flex-pmd" depends="mkdir">
	<flexPmd sourceDirectory="${src.dir}"
		outputDirectory="${bin.dir}"/>
</target>

Agora que o FlexPMD já está sendo executado junto ao build do seu projeto Flex é necessário fazer com que o log de saída do CruiseControl incorpore o log do FlexPMD. No arquivo de configurações do seu projeto adicione a tag <merge> dentro de <log>. Repare que o atributo “dir” corresponde ao mesmo caminho informado em “bin.dir” no seu build:

<log dir="logs/${project.name}">
	<merge dir="projects/projeto/pmd/"/>
</log>

Com o log sendo salvo, chegou a hora de mostrá-lo em tela. Dentro de main.jsp crie uma nova aba chamada “pmdResults”:

.
.
.
    <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>
.
.
.

Como você pode ver, essa nova aba chama o arquivo pmd.jsp que também precisa ser criado:

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

Para que nosso nova aba possa mostrar resultados mais intuitivos vamos adicionar dentro de cruisecontrol.css o seguinte código:

.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; }

Já temos quase tudo configurado, precisamos “apenas” formatar nossa saída e para isso iremos criar o arquivo pmd.xsl, que já informamos em pmd.jsp. No tutorial da ThoughtWorks de como integrar o CC como o PMD (Java) eles sugerem o seguinte:

<?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>

Pronto. Com tudo configurado é hora de dar o build no seu projeto e esperar para ver os resultados:

Capturar2

Fontes:
http://confluence.public.thoughtworks.org/display/CC/CruiseControlWithPMD
http://opensource.adobe.com/wiki/display/flexpmd/FlexPMD

Tags: ,
Posted in cookbook | No Comments »

Leave a Reply