POSTED ON 21 OCT 2021
READING TIME: 5 MINUTES
On a well-run project, over time, novelty tends to zero, and all good software, if it’s being used at all, will eventually go into maintenance.
At the beginning of a project, when designs are still coming together, commits are likely to be in many different components of the application. As the application moves into maintenance, then - if the SOLID principles have been applied - one would expect commits to impact on smaller and smaller sections of the codebase. This would indicate that the changes for issue fixes and the like don’t require lots of small changes all over the codebase.
Shotgun (and its related gradle plugin) is a new tool that can identify overly complex and interdependent elements of your code base that other tools can’t.
We already have tools for calculating the complexity of code (e.g Cyclomatic Complexity) but they rely on finding the elements of code that talk directly to each other. Shotgun, however, reports on what elements of code are updated at the same time, measuring how coherent your commits are within a code hierarchy.
For example, if you had an event-based architecture, where services interact through a queue, then you may find that changing one service might require changes in the events being sent, and so on down to the receiving services. A cyclomatic complexity rating wouldn’t take account of this, since the services don’t directly interact with each other. Shotgun, however, will report that when these elements are updated at the same time over and over again.
The idea is that - if we’ve been doing our job right - then over time the complexity of commits is getting smaller. If it’s not, then it’s likely that “small” commits are touching too many files because the code is overly interdependent.
The report looks like this:
With:
You can also click on any given day and view the details of the commits for that day.
Shotgun tells you if every change you’re making is a big change in lots of different components.
At the beginning of a project this is normal - you’re just figuring things out. If, after a while, most commits are touching elements all over the codebase, then you need to start thinking about refactoring.
The aim is to derive a score for each commit, that is lower if:
The actual score is calculated as follows.
Imagine a commit like this:
The process is a simple:
src/main/java
srs/main/resources
src/test/java
srs/test/resources
com.sonalake
”This is the shotgun coherency score.
Some examples:
Description | Score |
---|---|
A single file commit | |
1 | |
Two files in the same directory |
| 2 | | Two files in the same hierarchy
| 3 | | Two files in parallel directories
| 4 |
There is a basic library that comes with a command line: shotgun; where you can find full details of the configuration parameters; but in short you can define things like:
The easiest way to use the tool in a project is to use the shotgun-gradle-plugin
Just drop this in as a plugin in your gradle configuration (full details here):
plugins {
id 'com.sonalake.shotgun-gradle-plugin' version "1.0.0"
}
And configure it appropriately for your project:
shotgun {
inputDirectory = "$projectDir"
outputFile = ".shotgun/report.htm"
sourceSets = \["src/main/java",
"src/main/resources",
"src/main/webapp",
"src/test/java",
"src/test/resources"\]
minimumCommitInterest = 3
topCommitValueForFileSets = 10
topCommitValueForFiles = 40
legendLevels = \[10, 20, 30, 50, 80, 120\]
}
The purpose of this app is to spot when changes are consistently being applied in a scattergun approach over the entire codebase.
Also because of this.
We hope this tool is useful to everyone, so we made it public, along with some other tools, libraries and examples, in our Sonalake github project.
If you think there are improvements to make, please fork the project and submit them, and we’d be delighted to review and merge them.