Pete Freitag Pete Freitag

Using Subversion build hooks to send a findbugs report email


I recently started using FindBugs a java application that runs through your source, and compiled code to find bugs. On our project we use subversion for version control, and send out emails every time someone commits with the build status, if the build fails we send out a reason, if it is successful we show what files have changed. So I thought a great thing to do would be to add a report from findbugs, this way if the developer introduces a new bug we can point them out and laugh at them ;) We also generate a HTML findbugs report, and throw that on our web server.

Our development server runs linux, and houses our subversion repository, and a development web server. We have some developers that run linux, and some that run Windows (and possibly OS X now that we have Java 1.5 for Mac).

I started by installing findbugs in /usr/local/findbugs/.

Next you will need to create a working directory for findbugs, I create it here: /home/projectname-autobuild/findbugs/, and give it the variable name WORK_DIR in my script.

Checkout a copy of your project repository in your working dir, this will be the CHECKOUT_DIR variable, and I use : CHECKOUT_DIR="$WORK_DIR/projectname". Every time the script runs it will call a svn update on the checkout dir.

Next you need to setup a project file for findbugs. You can either use the findbugs GUI to do this, or simply create your own. Here's what the file may look like;

[Jar files]
/home/projectname-autobuild/findbugs/projectname/lib/projectname.jar
[Source dirs]
/home/projectname-autobuild/findbugs/projectname/src/java
[Aux classpath entries]
/home/projectname-autobuild/findbugs/projectname/lib/log4j-1.3alpha-6.jar
/home/projectname-autobuild/findbugs/projectname/lib/xercesImpl.jar
/home/projectname-autobuild/findbugs/projectname/lib/xml-apis.jar
/home/projectname-autobuild/findbugs/projectname/lib/xmlParserAPIs.jar

Name this file proojectname.fb (I put it in my working dir), and set it to the PROJECT_FILE variable in the script.

Now create a script, I call it findbugs.sh, you will need to change some of the variables on top:

#!/bin/sh

export JAVA_HOME="/usr/java/current"
FINDBUGS_HOME="/usr/local/findbugs"
SVN_REPOSITORY="file:///home/svn/projectname"
WORK_DIR="/home/projectname-autobuild/findbugs"
CHECKOUT_DIR="$WORK_DIR/projectname"
PROJECT_FILE="$WORK_DIR/projectname.fb"
DEV_EMAILS="[email protected] [email protected]"
PROJECT_NAME="projectname"
HTML_OUTPUT_DIR="/home/www/projectname/findbugs"
HTML_DOC_URL="https://dev.you.com/projectname/findbugs/"

#update source, and get current version number
CURRENT_REV="`svn update $CHECKOUT_DIR | sed 's/[^0-9]//g' -`"

#build a file with findbugs info in it
$FINDBUGS_HOME/bin/findbugs -textui -project $PROJECT_FILE > $WORK_DIR/findbugs.current.txt

#find the total number of bugs
TOTAL_BUGS=`cat $WORK_DIR/findbugs.current.txt | wc -l`

echo [$TOTAL_BUGS BUGS TOTAL] >> $WORK_DIR/findbugs.email
cat $WORK_DIR/findbugs.current.txt >> $WORK_DIR/findbugs.email
echo $HTML_DOC_URL >> $WORK_DIR/findbugs.email

#send the email
cat $WORK_DIR/findbugs.email | mail -s "[findbugs:$PROJECT_NAME] $TOTAL_BUGS bugs total" $DEV_EMAILS 

#generate HTML docs
$FINDBUGS_HOME/bin/findbugs -textui -html -project $PROJECT_FILE > $HTML_OUTPUT_DIR/index.html

cp $HTML_OUTPUT_DIR/index.html $HTML_OUTPUT_DIR/findbugs.$CURRENT_REV.html

The next step is to setup a subversion hook to run your findbugs.sh script.

Create or modify the file in your subversion repository called hooks/post-commit make an executable shell script that invokes your findbugs script, perhaps something like this:

#!/bin/sh

/home/projectname-autobuild/findbugs/findbugs.sh &

And that's it, ever time you commit you should get an email with a bug summary.

Some things you might want to try

HTML Email

You could send the HTML report in the email, I wanted to keep the emails plain-text so I chose not to do that.

Track new and fixed bugs

I currently have some code that does diff's on the reports to find out if there were new bugs introduced. I do this by keeping a findbugs.current.txt and a findbugs.old.txt run a diff against them. This isn't working 100% yet, so I did not include it in the script above.

Comments

Please post any comments here.

Other Articles