Enforcing a Coding style with Spotless

Maven has an awesome plugin to enforce coding styles automatically. You can find information about it spotless-maven-plugin.

In order to not forget some of my work, I’ll put some of my conclusions and final configuration of the plugin.

<dependencies>
     <!-- Less boilerplate-->
     <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.18.34</version>
         <scope>provided</scope>
     </dependency>
     <!-- More dependencies here-->
 </dependencies>
 <build>
     <plugins>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-compiler-plugin</artifactId>
             <version>3.13.0</version>
             <configuration>
                 <release>21</release>
                 <annotationProcessorPaths>
                     <path>
                         <groupId>org.projectlombok</groupId>
                         <artifactId>lombok</artifactId>
                         <version>1.18.34</version>
                     </path>
                 </annotationProcessorPaths>
             </configuration>
         </plugin>

         <!-- Enforce Java Google formatting conventions -->
         <plugin>
             <groupId>com.diffplug.spotless</groupId>
             <artifactId>spotless-maven-plugin</artifactId>
             <version>2.44.0.BETA2</version>
             <configuration>
                 <formats>
                     <!-- you can define as many formats as you want, each is
                                 independent -->
                     <format>
                         <!-- define the files to apply to -->
                         <includes>
                             <include>.gitattributes</include>
                             <include>.gitignore</include>
                         </includes>
                         <!-- define the steps to apply to those files -->
                         <trimTrailingWhitespace/>
                         <endWithNewline/>
                         <indent>
                             <tabs>true</tabs>
                             <spacesPerTab>4</spacesPerTab>
                         </indent>
                     </format>
                 </formats>
                 <!-- define a language-specific format -->
                 <java>
                     <encoding>UTF-8</encoding>
                     <eclipse>
                         <version>4.26</version>
                         <file>${project.basedir}/eclipse-java-google-style.xml</file>
                     </eclipse>
                     <importOrder>
                         <wildcardsLast>false</wildcardsLast>
                         <order> <!-- Static imports last-->
                             ,\# 
                         </order>
                         <semanticSort>true</semanticSort>
                     </importOrder>
                     <removeUnusedImports/>
                     <formatAnnotations/>
                 </java>
                 <m2eEnableForIncrementalBuild>true</m2eEnableForIncrementalBuild> <!-- this is false by default -->
             </configuration>
             <executions>
                 <execution>
                     <goals>
                         <goal>check</goal>
                     </goals>
                     <!-- Uncomment the following to make formatting mandatory -->
                     <!-- <phase>compile</phase> -->
                 </execution>
             </executions>
         </plugin>
     </plugins>
 </build>

You can find the eclipse-java-google-style.xml here (referenced here).

This is useful to call the formatter in the current Java buffer while working in Emacs (relies on projectile):

(defun apply-spotless-to-current-buffer ()
  "Apply Spotless formatter to the current buffer."
  (interactive)
  (when (buffer-file-name)
    (save-buffer)
    (let* ((file (buffer-file-name))
           (project-root (projectile-project-root)))
      (if project-root
          (let ((default-directory project-root))
            (shell-command (format "mvn spotless:apply -DspotlessFiles=%s" file))
            (revert-buffer t t t)
            (message "Spotless applied to %s in project %s" file project-root))
        (message "Could not find project root. Is Projectile installed and configured?")))))

(global-set-key (kbd "C-c s") 'apply-spotless-to-current-buffer)

Additionally, to run spotless, you can:

  1. Use maven directly to check all files: mvn spotless:check.

  2. Use maven directly to apply (overwriting the files) to all files: mvn spotless:apply.

  3. Use maven to check only some (or current) files:

    mvn spotless:apply -DspotlessFiles=my/file/pattern.java,more/generic/.*-pattern.java
    
  4. If you use IntelliJ IDEA for Java programming, use spotless applier during your development.


Date
September 6, 2024