Liferay Workspace: Code Formatter

 Liferay Workspace: Code Formatter

How to integrate Spotless Code Formatter to a Liferay Gradle Workspace



1. What is Spotless?


Spotless is a nice tool that can auto-format code for multiple programming languages using different build tools to ensure consistent codestyle across the project. It supports different configuration options to provide developers with the possibility to define project-specific codestyle preferences and restrictions. Using code formatters like Spotless you can prevent different code formatting approaches in a single project, make sure the codebase is consistent, avoid possible merge conflicts, and reduce time spent for code reviews.

2. How to integrate Spotless to a Gradle module?


To integrate Spotless plugin to a Java module in the Liferay Gradle Workspace you need to:


  1. Define Spotless plugin in the module’s build.gradle:

plugins {

   id "com.diffplug.spotless" version "7.2.1"

}


  1. Specify Spotless configuration:

spotless {

   java {

       palantirJavaFormat()

       removeUnusedImports()

       importOrder("java", "javax|jakarta", "com.liferay", "com.mycompany")

   }

}


  1. Register spotlessApply task before compilation:

compileJava.dependsOn "spotlessApply"


The complete module’s build.gradle is the following:


plugins {

   id "com.diffplug.spotless" version "7.2.1"

}

dependencies {

   compileOnly "com.liferay.portal:release.dxp.api"

}

spotless {

   java {

       palantirJavaFormat()

       removeUnusedImports()

       importOrder("java", "javax|jakarta", "com.liferay", "com.mycompany")

   }

}

compileJava.dependsOn "spotlessApply"


In this example the following options are defined for Spotless code formatter:

  • palantirJavaFormat - specifies Palantir Java Format for the code style;

  • removeUnusedImports - removes unused imports in Java files;

  • importOrder - sorts import statements according to specified imports order.


With this configuration once you build the module - the source code is auto-formatted according to specified rules before it’s compiled.


Besides configuration options specified above, Spotless supports a lot of other ones - such as sorting class members, formatting annotations, adding license headers, etc. You can find more information about possible formatting options in the plugin documentation.


3. Global Configuration


A typical Liferay project contains multiple modules inside the Liferay workspace. To keep code consistent across the entire project - the same formatting rules should be applied for each of the modules. To avoid copy-pasting Spotless plugin configuration to each module - such configuration can be defined globally, in the root build.gradle file. Here are the steps needed for centralized configuration:

1. Specify plugin version in settings.gradle:

pluginManagement {

   plugins {

      id "com.diffplug.spotless" version "7.2.1"

   }

}


2. Define plugin in the root’s build.gradle:

plugins {

   id "com.diffplug.spotless" apply false

}

Notes:

  • Version is not specified here, as it’s defined in settings.gradle;

  • Plugin is registered, but not applied for the root module. 


3. Register plugin for subprojects in the root’s build.gradle:

subprojects {

   apply plugin: "java"

   if (!project.name.contains("headless")) {

       apply plugin: "com.diffplug.spotless"

       spotless {

           java {

               palantirJavaFormat()

               removeUnusedImports()

               importOrder("java", "com.liferay", "com.mycompany")

           }

       }

       compileJava.dependsOn "spotlessApply"

   }

}

Notes:

  • In the example above the Spotless plugin is applied for all submodules except Headless API modules - as those ones contain auto-generated code that can conflict with custom formatting rules;

  • The same exception can be applied for Service Builder modules.


The complete root build.gradle file is the following:

plugins {

   id "com.diffplug.spotless" apply false

}

subprojects {

   apply plugin: "java"

   if (!project.name.contains("headless")) {

       apply plugin: "com.diffplug.spotless"

       spotless {

           java {

               palantirJavaFormat()

               removeUnusedImports()

               importOrder("java", "com.liferay", "com.mycompany")

           }

       }

       compileJava.dependsOn "spotlessApply"

   }

}


With this setup no additional configuration is needed for child modules, and code will be auto-formatted for all the modules (except excluded ones) during each build.


Enjoy 😏



Comments

Popular posts from this blog

Liferay Search Container Example

Liferay Keycloak integration

Liferay Keycloak integration - SSO and SLO implementation