CI for Flex Mobile Applications – Part 5: Static Code Analysis
- Step 1: Getting the tools
- Step 2: Defining the Ant-Tasks
- Step 3: Adding to our build script
- Step 4: Testing everything out
- What we did so far
I n this part of the tutorial I’m going to show you how to integrate steps for Static Code Analysis (SCA). The quality of your code can easily be checked by using the following tools:
- FlexPMD checks your code for violations of common conventions, such as unused variables, empty catch-blocks and so on.
- FlexCPD checks your code for violations of the DRY– (Don’t Repeat Yourself’) Paradigma by detecting code duplications
- FlexMetrics checks the ratio of LOC (lines of code) versus the lines used for comments, which can be useful to detect under- (or over-) documentation of your code.
- CLOC reports languages used in your project and counts the single lines of code (LOC) used for each language (omitting comments of course)
Unfortunately, there is no tool to check test coverage. There used to be a tool called FlexCover, but it has not been maintained in a long time and I haven’t brought it to work. Cobertura, a popular tool to measure test coverage, does not support ActionScript (afaik), which leaves us with nothing to check the amount and location of untested code, which in my opinion is a pity.
Nevertheless, let’s get started with the setup of the four tools mentioned above!
Step 1: Getting the tools
First of all, you need to have the tools installed on your CI server. I recommend installing them at the same location on your local machine, which makes testing your build script a lot easier.
FlexPMD, FlexCPD, FlexMetrics
Get the latest version from Adobe’s repository by downloading the ZIP-file called flex-pmd-all-in-one-bundle-X.Y.zip, whereas X and Y stand for the major resp. minor version number. This File contains FlexPMD, FlexCPD and FlexMetrics as well as a default ruleset to check your code. It also contains a tool called violations-viewer which lets you look into the report generated by the three tools in a more readable format.
This tutorial assumes you have the contents of this ZIP-File at the following location:
C:\tools\flexpmd
If you want to create your own custom ruleset, there’s a neat tool from Adobe called Ruleset-Creator, which lets you create your own set of rules by enabling/disabling specific items. Check it out here.
CLOC
We’re going to use CLOC as a tool for counting the lines of code in each language. You can dowload it here.
Saxon
Unfortunately, the output created by CLOC cannot be parsed by a Jenkins plugin. However, there is a plugin for a tool called SLOCCount. However, this tool does not support AS3 as a language.
Since there is no plugin in Jenkins to visualize the output created with CLOC directly, we’re going to translate the XML created by CLOC to a format that can be parsed by the Jenkins SLOCCount-plugin. For this we use an XSL-Transformation file together with a tool called Saxon which does the translation for us based on the Information contained in the XSL-File.
You can downlad Saxon Home Edition here
XML translation
As stated above, the XML translation is made with the help of a file called cloc2sloccount.xml, which holds the information on how to translate to a format which is equivalent to an output created with SLOCCount.
<xsl:stylesheet version="1.0" xmlns:de="." xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="4.0" encoding="iso-8859-1"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="file">
<xsl:variable name="file_path" select="translate(@name,'\\','/')"/>
<xsl:variable name="file_path_part1" select="substring-after($file_path,'/')"/>
<xsl:variable name="module" select="substring-before($file_path_part1,'/')"/>
<xsl:value-of select="@code"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="@language"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="$module"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="files">
<xsl:apply-templates select="file"/>
</xsl:template>
<xsl:template match="cloc_url">For more details see: <xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="cloc_version">This report has been generated by cloc <xsl:value-of select="."/>.<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="header">
<xsl:apply-templates select="cloc_version"/>
<xsl:apply-templates select="cloc_url"/>
</xsl:template>
<xsl:template match="results">
<xsl:apply-templates select="header"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="files"/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="results"/>
</xsl:template>
</xsl:stylesheet>
Step 2: Defining the Ant-Tasks
As several times before, we need to define the tasks we’re going to use or Ant won’t recognize them and throw an error.
<!-- FlexPMD Ant-Taskdef -->
<taskdef name="flexPmd" classname="com.adobe.ac.pmd.ant.FlexPmdAntTask" classpath="path/to/flexPMD/flex-pmd-ant-task-[FlexPMD-Version].jar">
<classpath>
<fileset dir="${FLEXPMD.dir}">
<include name="*.jar" />
</fileset>
</classpath>
</taskdef>
<!-- FlexCPD Ant-Taskdef -->
<taskdef name="flexCPD" classname="com.adobe.ac.cpd.ant.FlexCpdAntTask" classpath="path/to/flexPMD/flex-pmd-cpd-ant-task-[FlexPMD-Version].jar" >
<classpath>
<fileset dir="${FLEXPMD.dir}">
<include name="*.jar" />
</fileset>
</classpath>
</taskdef>
<!-- FlexMetrics Ant-Taskdef -->
<taskdef name="FlexMetrics" classname="com.adobe.ac.pmd.metrics.ant.FlexMetricsAntTask" classpath="path/to/flexPMD/flex-pmd-metrics-ant-task-[FlexPMD-Version].jar" >
<classpath>
<fileset dir="${FLEXPMD.dir}">
<include name="*.jar" />
</fileset>
</classpath>
</taskdef>
The observant reader might have noticed that there’s no Ant-task for CLOC. This is true and a bit sad, but not to worry about: The tool has a simple command line syntax and we’re going to execute it via Ant’s built-in <exec>
-functionality.
Expanding the build properties
To make our life a bit easier, we’re going to add some more variables to our build.properties
file:
TOOLS.cloc = ${env.tools_dir}\\cloc\\cloc.exe
TOOLS.saxon = ${env.tools_dir}\\saxon\\saxon9he.jar
TOOLS.cloc2sloccount = ${env.tools_dir}\\cloc\\cloc2sloccount.xsl
Step 3: Adding to our build script
After downloading the tools and defining the ant tasks, executing the single steps is simple:
FlexPMD Ant-task
The output created by FlexPMD is an XML file (here: pmd.xml
), which can be parsed by the Jenkins PMD plugin. You can specify an (optional) ruleset-parameter which holds the path to your custom ruleset. If you omit it, a default ruleset is applied.
FlexCPD Ant-task
The output created by FlexPMD is an XML file (here: cpd.xml
), which can be parsed by the Jenkins DRY plugin.
<!-- Run FlexCPD (Copy Paste Detector) -->
<flexCPD minimumtokencount="50" outputfile="${OUTPUT.flexpmd}/cpd.xml">
<fileset dir="${PROJECT.src}">
<include name="**/*.as" />
<include name="**/*.mxml" />
</fileset>
</flexCPD>
FlexMetrics Ant-task
The output created by FlexMetrics is an XML file (here: metrics.xml
), which can be parsed by the Jenkins JavaNCSS plugin. Don’t let the name fool you: the plugin can perfectly handle the output produced by FlexMetrics ;-).
<!-- run FlexMetrics -->
<FlexMetrics sourcedirectory="${PROJECT.src}"
outputfile="${OUTPUT.flexpmd}/metrics.xml"/>
CLOC/SLOCCount Ant-task
The first step runs CLOC on our source directory, generating a file called cloc.xml which holds the information of the report. The second steps transforms the cloc.xml to a format consistent with the SLOCCount output format and saves it in a file called sloccount.sc. The output created by the transformation can be parsed by the Jenkins SLOCCount plugin.
<!-- Generate CLOC report -->
<exec command="${TOOLS.cloc}">
<arg value="--by-file"/>
<arg value="--xml"/>
<arg value="-out=${OUTPUT.flexpmd}/cloc.xml"/>
<arg value="${PROJECT.src.main}"/>
</exec>
<!-- transform CLOC-Report to SLOCCount -->
<java jar="${TOOLS.saxon}" fork="true">
<arg value="-xsl:${TOOLS.cloc2sloccount}"/>
<arg value="-o:${OUTPUT.flexpmd}/sloccount.sc"/>
<arg value="${OUTPUT.flexpmd}/cloc.xml"/>
</java>
Step 4: Testing everything out
To make sure everything works as expected install the plugins mentioned above, add some post-build steps to run the plugins on the newly created files and then run your job. You should get some nice charts and tables holding the information about the results.
What we did so far
In this step we extended our build script by performing some common SCA tasks. By doing this we got information about the quality of our code in terms of violations of common coding-conventions, code duplication and code documentation. We also got an overview of the languages used in our app and the lines of code in each language.
Part 6 will tackle the problem of measuring how well your code is covered by tests.