Recently I’ve had to add SonarQube to our Grails application to gain visibility in our metrics and though at the end the change was only a few of config lines I think can be interesting to document it in this post due the lack of updated documentation about it
Grails is a groovy-lang framework where you can develop a CRUD web application in a few seconds with a great plugin ecosystem. It has close to 10 years and it has evolved from initial heavy versions to a more light framework. Currently I’m working in a 3.x application althouht version 4.x is out a few months ago.
We’re using some plugins as Codenarc and Coverage how generate reports about the quality of your code (rule violations, check style, coverture, and so on) and we have some asserts to abort the build if we’re in a low coverture situtation for example
SonarQube is an open-source platform developed by SonarSource for continuous inspection of code quality to perform automatic reviews with static analysis of code to detect bugs, code smells, and security vulnerabilities on 20+ programming languages. SonarQube offers reports on duplicated code, coding standards, unit tests, code coverage, code complexity, comments, bugs, and security vulnerabilities. ( https://en.wikipedia.org/wiki/SonarQube )
With SonarQube you can have a good dashboard your QA team will appreciate, so we’ll try to integrate our gradle build with it.
Docker SonarQube
Firstly you need to have a SonarQube instance running due the build needs to comunicate with it to send the information. The idea is to have an instance for multiple projects and in this way compare between them, align force, styles etc.
For development I’ll used a docker instance at port 9000:
$ docker run -d --name sonarqube -p 9000:9000 sonarqube
Grails
This is part of our build.gradle configuration (nothing special to comment) where, plus standard Grails configuration, we’ve codenarc and clover installed
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
maven { url "https://plugins.gradle.org/m2/" }
jcenter()
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.grails.plugins:hibernate4:${gormVersion - ".RELEASE"}"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.2"
classpath 'com.bmuschko:gradle-clover-plugin:2.2.3'
// others stuff
}
}
// others plugins
apply plugin: "codenarc"
apply plugin: 'com.bmuschko.clover'
dependencies {
clover 'org.openclover:clover:4.4.1'
}
codenarc {
config = file('conf/codenarc-rulsets.groovy')
//... some more configs
}
clover {
excludes = ['/test/**',]
testIncludes = ['**/*Spec.groovy']
compiler {
}
compiler {
encoding = 'UTF-8'
// used to add debug information for Spring applications
debug = true
additionalArgs = '-Dclover.pertest.coverage=off'
additionalGroovycOpts = [configscript: project.file('cloverXtraConfig.groovy').absolutePath]
}
report {
html = true
xml = true
pdf = true
columns{
complexity format: 'raw'
coveredBranches format: '%'
totalBranches format: 'raw'
coveredStatements format: '%'
lineCount format: 'raw'
}
}
}
cloverGenerateReport.doLast {
run(new File("scripts/AbortIfNotCoverage.groovy"))
}
Grails & SonarQube
First thing I did was a quick search with grails sonarqube
terms and I realized more usefull post were a little out of date (2014-2015)
After reading some of these posts I was confused because in some of them I understood the required plugins need to be installed in local project downloading some jars but in others talking to download to a sonarqube directory.
So after some investigation the photo finish is:
you need to install in your Grails (Gradle) project only the sonarqube plugin
you install the
groovy
andcoverage
plugins via sonarqube web applicationat the build time the plugin downloads both of them (and others), perfom the analisys and send the result to the backend
To sumarize, we only need to include the sonarqube
plugin and set some properties:
buildscript {
...
dependencies {
...
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
}
}
...
apply plugin: "org.sonarqube"
...
sonarqube {
properties {
property 'sonar.verbose', 'true'
property "sonar.host.url", "http://localhost:9000/" (1)
property "sonar.sourceEncoding","UTF-8"
property "sonar.projectName", "hello-grails"
property "sonar.projectKey", "hello-grails"
property "sonar.dynamicAnalysis","reuseReports" (2)
property "sonar.clover.reportPath", file("build/reports/clover/clover.xml").absolutePath
property "sonar.projectBaseDir",""
property "sonar.sources","grails-app,src/main/groovy" (3)
property "sonar.exclusions"," **/*.properties,** /*.js,**/*.html"
property "sonar.test.exclusions","**/*.properties"
}
}
| 1 | Only to test, needed to change to your QA instance. You can overwrite via -D or -P |
| 2 | We’ll use the report generated by clover |
| 3 | Sonar will scan all the grails applicaion plus src except js and html |
Sonarqube dashboard
These are some images from official page to show you what kind of information you can obtain
More information
If you want to read more about Sonarqube these links are helpfull
Top comments (2)
hi thx for the article, it was very helpful.
what's in your cloverXtraConfig.groovy & AbortIfNotCoverage.groovy files .
Cheers !
true, I forgotten them
I use cloverXtraConfig.groovy to remove
CompileStatic
andTypeChecked
annotations:and in AbortIfNoCoverage.groovy I parse the final
xml
to calculate the average cobertura and if it's under a limit throw a exception to abort the pipeline