Clean Code with Spotless
“The ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …making it easy to read makes it easier to write.”
- Robert C. Martin (a.k.a Uncle Bob)
Uncle Bob, author of Clean Code and many other influential books, also a co-author of the Agile Manifesto, I think it’s safe we trust him on this. I completely agree with him too. Writing new code is the easy part. Trying to work out where to write the code, and how to not break the existing codebase is what takes the most time and brainpower. Having a clean codebase makes finding the right spot to add the new change much easier.
The Broken Window Theory
“…is a criminological theory that states that visible signs of crime, anti-social behaviour, and civil disorder create an urban environment that encourages further crime and disorder, including serious crimes.”
- Wikipedia, the source of all knowledge.
If the code format is a mess, it’s often easier to justify to yourself that it’s okay to add to that mess. I’m sure we can all admit to at least once in our careers we’ve opened a project with zero tests and then we’ve snuck more code into that project without adding tests. In contrast how many times have we opened a beautifully written and loved codebase and felt we must maintain this work of art?
…But yawn…
- Code style is boring
- Following the style is boring
- Writing the style for others to follow is also boring
- Reading the style document is boring
- Reviewing code for style mistakes is boring
So far we’ve talked about how important all these things are and how we must do them. There must be a way we can automate the boring part.
Tools Don’t Replace Engineering Principals
It doesn’t matter how good the tools we use are, it’s always better to work with the ability to write quality code without them.
Just to keep in the back of your mind, we should constantly be trying to better ourselves as engineers by striving to write cleaner code without the need for tools. Tools just help keep us in check.
Spotless
“…is a general-purpose formatting plugin. It is completely à la carte, but also includes powerful “batteries-included” if you opt-in.”
- Spotless Readme
Solve the low hanging fruit of Code Quality
It does the pretty stuff like formatting the line indents and makes the line spacing consistent. Order imports the same way, remove extra return carriages a developer might have put in.
It doesn’t solve bigger picture problems, like variable names we spoke about earlier, or the “and, and, and” problem.
Because it won’t fix these things, it’s a benefit of Spotless as you’re pretty much guaranteed you can run this over your entire project and have zero functionality break as no logic or code is changed.
Spotless Setup
If you’re working with Java, just a few lines in the plugin section of your pom.xml file:
In the execution phase, we’ve told Spotless to “apply” the changes to our codebase every time we compile the project. Another option we could use instead is “check” which will report back to the developer the issues without actually making changes. This would be a great fit as part of the Jenkins pipeline since we don’t want our build pipeline modifying code.
As we look at the block below, sure I can read this and understand it, but it’s harder than it needs to be, and I’d need to double-check if I caught all the OR statements.
If we run mvn spotless:apply
it will format the code. It’s not a huge change, but enough that I can easily see 4 conditions happening here.
Spotless pre-commit Hook
Running on compile is nice, but what to do when someone commits a sacrilege and doesn’t compile the code before committing it?
To make sure we always run Spotless before we commit code, we use a commit hook…
The hook is very simple, we just ratchet from origin/master meaning only check code which is different to master and run Spotless check each time we commit. If any code is found that doesn’t compile the commit will fail.
Ratcheting from a point in time is a massive win because if we tried to implement this in an existing codebase with lots of open PRs you’re going to have a nightmare with merge conflicts.
Bonus — Automate installing git hooks
I’m not a huge fan of client-side hooks, as it becomes a nightmare trying to sync them to all developer machines, and what if we make a change to what the hook does? Have you ever tried to get a bunch of engineers to all update something at the same time?
There is another quick Maven/Gradle plugin we can take advantage of here.
If we put the code from the hook above into a file in our ${project}/hooks/
directory, this plugin will automatically install it every time someone executes the ‘install’ phase in maven.
Spotless in summary
- It’s plug-and-play with sensible defaults (Google Style Guide)
- No extra configuration files if you don’t wish
- Safe to run over the entire codebase knowing it won’t break anything
- If I don’t have to comment about line spacing in a review, you don’t have to fix it saving time
- Keeps the codebase formatted consistently across every developer’s machine
- Open-source