Christian Oestreich

   two guys in design - software.development.professional

Gmetrics & Codenarc Script for Grails

| Comments

I really wanted to get our project working with sonar and grails.  After some searching I found very few people that had this working.  Actually I only found one here.  I tried doing this by adding the pom.xml and invoking the mvn sonar:sonar target.  Maven got to the end and threw an exception.  I spent the better part of a day working on this and poking around at the pom file and finally gave up.

Setting Up The Environment

All the source code for this can be found at GitHub.  You can pull it down via the command:

git clone git@github.com:ctoestreich/jenkins-sandbox.git

I decided to go with using cobertura, gmetrics and codenarc for reporting on the code.  You need to first add the plugins to your project using the following commands

grails install-plugin coverage
grails install-plugin gmetrics
grails install-plugin codenarc

I ran the default targets for gmetrics and codenarc and they both produced html… ugly html.  I was hoping the default output would be a little more like the sonar dashboard; perhaps a little more web 2.0-ish.  Luckily I ran across a couple blog posts by Herbert Ikkink (mrhaki).  The posts had some nice xslt to html transformation and style sheets attached to them. I took the work mrhaki had done and went one step further and created a grails build target to generate the output for both gmetrics and codenarc and publish the results through Jenkins.

Creating The Script

I had first tried to consume the codenarc xml using the violations plugin for Jenkins, but that was puking all over itself, so I opted for making both reports simple HTML reports.

First I needed to create a script in grails by running

grails create-script CodeReports

Then I added the following code to the grails-app\scripts\CodeReports.groovy file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
includeTargets << grailsScript('Init')
includeTargets << new File("${codenarcPluginDir}/scripts/Codenarc.groovy")
includeTargets << new File("${gmetricsPluginDir}/scripts/Gmetrics.groovy")
configClassname = 'Config'
target(main: "Add some style to the gmetrics report") {
  depends(compile, codenarc, gmetrics)
  stylizeGmetrics()
  stylizeCodenarc()
   }

   private void stylizeGmetrics() {
  println "add some style to the gmetrics report"
  ant.mkdir(dir: 'target/gmetrics')
  ant.xslt style: "reports/gmetrics.xslt", out: "target/gmetrics/gmetrics.html", in: 'target/gmetrics.xml'
  ant.copy(todir: 'target/gmetrics') {
    fileset(dir: 'reports') {
      include name: 'default.css'
      include name: '*.png'
      include name: '*.gif'
    }
  }
}

private void stylizeCodenarc() {
  println "Add some style to the codenarc report"
  ant.mkdir(dir: 'target/codenarc')
  ant.xslt style: "reports/codenarc.xslt", out: "target/codenarc/codenarc.html", in: 'target/codenarc.xml'
  ant.copy(todir: 'target/codenarc') {
    fileset(dir: 'reports') {
      include name: 'default.css'
      include name: '*.png'
      include name: '*.gif'
    }
  }
}
setDefaultTarget(main)

This new script can be called at the command line by running

grails code-reports

Some interesting caveats to note.  The paths to the plugins won’t resolve until you run compile at least one time.  So make sure you invoke the compile target directly or through another script like test-app to get the paths all set up in grails before calling code-reports.  I also had some issues with out-of-date plugins and had to blow away the grails 1.3.6 working directory to get this to work on local machine and ubuntu (build server) for my demo project.  It worked no problem on another project… go figure.  Just go to C:\Documents and Settings[your user].grails[grails version]\projects[project name] and remove the [project name] dir (where [project name] if the name of your project, etc).  On my build box the dir is /usr/share/tomcat6/.grails/1.3.6/projects/[project name].

Additional Required Settings

Add the code below at the end of _grails-app\conf\Config.groovy. _ This will set up gmetrics and codenarc to produce xml instead of HTML and set the output for the xml files.  Also I didn’t want to scan my test code.  You might want scan your integration and unit test code to so you can remove those lines or set them to true.  I am also using a custom codenarc.properties file to exclude certain patterns.

1
2
3
4
5
6
7
8
9
gmetrics.reportType = 'org.gmetrics.report.XmlReportWriter'
gmetrics.outputFile = 'target/gmetrics.xml'
gmetrics.processTestUnit = false
gmetrics.processTestIntegration = false
codenarc.reportType='xml'
codenarc.reportName='target/codenarc.xml'
codenarc.processTestUnit = false
codenarc.processTestIntegration = false
codenarc.propertiesFile = 'codenarc.properties'

I added the codenarc.properties at the root of the project folder (same dir as application.properties).  It has one line.

1
GrailsStatelessService.ignoreFieldNames=dataSource,scope,sessionFactory,transactional,*Service,messageSource,s3Credential,applicationContext,expose,profiled

Add the code below to the end of grails-app\conf\BuildConfig.groovy. This sets the coverage report to xml for Jenkins to process and excludes the tests.

1
2
3
4
coverage {
    xml = true
    exclusions = ["**/*Tests*"]
}

I created a directory at the root of the application called reports to hold my report artifacts and xslt files.  These are the files that were provided by mrhaki.  You can change the logo to whatever you want or muddle with the css as it suits you.  There are few image files that you can grab from my github in addition to the following.

reports\codenarc.xslt reports\gmetrics.xslt reports\default.css

So with the script created I ran the following scripts locally to test the output

grails test-app -coverage
grails code-reports

You should get some output in your target dir like the following

Once all that is working we can get to setting up Jenkins.

Setting Up Jenkins

I am assuming you are at least a bit familiar with Jenkins and are already building your grails application with it.  You will need to add the following two plugins

Cobertura Plugin

HTML Publisher plugin

You will then need to go to the project admin screen and add code-reports to your target for your grails build.  Here is mine:

clean "test-app -coverage --non-interactive" code-reports

You will then need to add the following to the html report output section and coverage configuration to get the reports to show up on the home page of the build.

You should see the areas marked in the red boxes show up on your build

I really like the output format that mrhaki produced.  Until there is a better integrated solution with sonar, this is golden.

Here are the report samples

The actual source code that I wrote I neither claim to be useful or entertaining, use at your own enjoyment.

All the source code for this can be found at GitHub.  You can pull it down via the command:

git clone git@github.com:ctoestreich/jenkins-sandbox.git

Comments