wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

Spotless code with a git hook


When developing software in a team, a source of constant annoyment is code formatting. Each IDE has slightly different ideas about it, not even getting into the tabs vs. spaces debate. Especially annoying in Java land is the import sort order

Automation to the rescue

I switch between editors (if you need to know: Eclipse, Visual Studio Code, OxygenXML, IntelliJ, Sublime, Geany, nano or vi (ESC :!wq)) frequently, so an editor specific solution isn't an option.

Spotless to the rescue. It's a neat project using Maven or Gradle to format pretty (pun inteded) much all code types I use. The documentation states:

Spotless can format <antlr | c | c# | c++ | css | flow | graphql | groovy | html | java | javascript | json | jsx | kotlin | less | license headers | markdown | objective-c | protobuf | python | scala | scss | sql | typeScript | vue | yaml | anything> using <gradle | maven | anything>.

Setup

I opted for the eclipse defined Java formatting, using almost the Google formatting rules with the notable exception not merging line breaks back.

There are 3 steps involved for the Maven setup:

  • Obtaining the formatting files, outlined here. Just make sure you are happy with the format first
  • Add the maven plugin (see below)
  • Add a git hook (see below)

pom.xml

This is what I added to my pom.xml. By default spotless would run check only, so I added apply to enforce the formatting

<properties>
   <spotless.version>2.4.1</spotless.version>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>com.diffplug.spotless</groupId>
            <artifactId>spotless-maven-plugin</artifactId>
            <version>${spotless.version}</version>
            <executions>
               <execution>
                 <goals>
                   <goal>apply</goal>
                 </goals>
               </execution>
            </executions>
            <configuration>
                <formats>
                    <format>
                        <!-- Markdown, JSON and gitignore -->
                        <includes>
                            <include>*.md</include>
                            <include>*.json</include>
                            <include>.gitignore</include>
                        </includes>
                        <trimTrailingWhitespace />
                        <endWithNewline />
                        <indent>
                            <spaces>true</spaces>
                            <spacesPerTab>2</spacesPerTab>
                        </indent>
                    </format>
                </formats>
                <!-- ECLIPSE Java format -->
                <java>
                    <toggleOffOn />
                    <importOrder>
                        <file>${maven.multiModuleProjectDirectory}/spotless.importorder</file>
                    </importOrder>
                    <removeUnusedImports />
                    <eclipse>
                        <file>${maven.multiModuleProjectDirectory}/eclipse-java-keep-style.xml</file>
                    </eclipse>
                </java>
            </configuration>
        </plugin>
    </plugins>
</build>

A few remarks:

  • I run apply rather than check
  • the directory variable ${maven.multiModuleProjectDirectory} is needed, so sub projects work
  • you want to extend the configuration to include JS/TS eventually

.git/hooks/pre-commit

Create or edit your [projectroot]/.git/hooks/pre-commit file:

#!/bin/bash
# Run formatting on pre-commit
files=`git status --porcelain | cut -c 4-`
fulllist=''
for f in $files; do
    fulllist+=(.*)$(basename $f)$'\n'
done;
list=`echo "${fulllist}" | paste -s -d, /dev/stdin`
echo Working on $list
# Activate Java 11
export JAVA_HOME=`/usr/libexec/java_home -v 11.0`
/usr/local/bin/mvn spotless:apply -Dspotless.check.skip=false -DspotlessFiles=$list
  • You might not need the line with Java
  • swap apply for check when you just want to check

As usual YMMV


Posted by on 10 December 2021 | Comments (0) | categories: GitHub Java Software

Comments

  1. No comments yet, be the first to comment