Skip to content

Instantly share code, notes, and snippets.

@xpepper
Forked from aslakknutsen/blog.md
Last active September 10, 2021 23:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xpepper/2269d0b0a5fb439c688be78c60a4bf2a to your computer and use it in GitHub Desktop.
Save xpepper/2269d0b0a5fb439c688be78c60a4bf2a to your computer and use it in GitHub Desktop.
Import your project's history in Sonar

When you do your first Sonar run on your project, you get a lot of new quality numbers to play with, but no trends. You only have one data set for comparison, the now picture.

Wouldn't it be nice if you could see the current trend of the project without waiting a couple of month for the 'daily/weekly' Sonar runs to fill up the data? Well, you're in luck! And if you're using git as a version system as well, this is your day. :)

In the Sonar Advanced Parameter documentation you will find a System Property called sonar.projectDate. The property let you tell Sonar when in time the running analysis was ran.

By combining this property and what your version system does best, track changes to source, we can now play back the history of the project as far as Sonar is concerned.

This little Bash script illustrates the concept. To spell out what it does in human readable form:

for each tag in the given git repository, checkout the source and run sonar, using the tag date as projectDate

GIT_REPO=$1
START_TAG=$2

MVN_COMMAND="mvn clean install"
SONAR_COMMAND="mvn org.codehaus.sonar:sonar-maven3-plugin:3.0:sonar"

if [ -z "$GIT_REPO" ]; then
    echo "Missing program argument: repository"
    echo "Usage: ./sonar_history.sh git_repository_path [start-tag]"
    exit
fi

pushd $GIT_REPO
for tag in `git tag`
do
    if [[ -n "$START_TAG" && "$START_TAG" > "$tag" ]] ; then
        echo "Skipping $tag (start tag $START_TAG)"
        continue
    fi

    TAG_DATE=`git show $tag --date=iso | grep Date: -m1 | cut -d' ' -f 4`
    echo "Checking out source from $TAG_DATE tagged as $tag"
    git checkout $tag  > /dev/null 2>&1
    git clean -df > /dev/null 2>&1

    SONAR_PROJECT_COMMAND="$SONAR_COMMAND -Dsonar.projectDate=$TAG_DATE"

    echo "Executing Maven: $MVN_COMMAND"
    $MVN_COMMAND > /dev/null 2>&1
    echo "Executing Sonar: $SONAR_PROJECT_COMMAND"
    $SONAR_PROJECT_COMMAND > /dev/null 2>&1
done
popd

You can of course modify this script to fit your own need. Maybe you want to checkout the history pr week or pr month instead of using tags. It's up to you.

Have fun! :)

@xpepper
Copy link
Author

xpepper commented Apr 7, 2017

I use an alternative implementation in Ruby, with the "rugged" gem (https://github.com/libgit2/rugged).

This is an example of processing a git repo from the first commit onwards, skipping a "broken" commit down the line.
For each commit, the script performs a git checkout of that commit and than execute the maven command to build, run and compute the coverage before sending all these data to a local Sonarqube instance (with docker it's pretty easy, see https://hub.docker.com/_/sonarqube/)

More info also here: https://blog.sonarsource.com/sonar-time-machine-replaying-the-past/

require 'rugged'

repo = Rugged::Repository.new('.')

walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_REVERSE)  # Rugged::SORT_TOPO instead would go from the last commit backwards
walker.push(repo.head.target_id)

commits = []
walker.each { |c| commits << c }
commits.reject! {|c| c.oid == "ffb7f4f1970f44f024fe5c757021910de05a0621"} # skipping a problematic commit :-(

commits.each do |c|
  puts "#{c.time} - #{c.oid}"
  %x[ git checkout #{c.oid} ]
  puts %x[ mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install -Dmaven.test.failure.ignore=true -Dsonar.projectName=PCE-core -Dsonar.projectDate=#{c.time.strftime("%Y-%m-%d")} sonar:sonar ]
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment