35

I'm looking for a way to force developers to use the same Java code formatting rules. My requirements are:

  1. Gradle integration
    1. Task that checks if code is correctly formatted. This will be used on CI to cause a build failure if incorrectly formatted code is submitted

    2. Task that fixes incorrectly formatted code (nice-to-have)

  2. IntelliJ integration
    1. Incorrectly formatted code can be fixed within the IDE via the "Reformat Code" action
    2. Code that is generated by the IDE (e.g. getter/setter generation) conforms to the rules
  3. Supports the OpenJDK/Oracle Java formatting rules

Currently I'm using Spotless with the following configuration

spotless {
  java {
    toggleOffOn()
    eclipse().configFile("${project.rootDir}/tools/eclipse-java-formatter.xml")
    indentWithSpaces()
    removeUnusedImports()
  }
}

For IntelliJ integration, I've installed the Eclipse Code Formatter plugin and configured it to use the same rules as Spotless.

This approach meets all of the requirements above except for 2.2 i.e. any code generated by IntelliJ must be reformatted before it conforms to the formatting rules. A further problem is that the imports seem to be arbitrarily reordered when code is reformatted. This generates a lot of spurious changes which makes pull requests more difficult to review.

Is there another approach (e.g. CheckStyle) that does not suffer from these shortcomings?

Antonio Dragos
  • 1,973
  • 2
  • 29
  • 52
  • 1
    for `Intellij` there is the `Save Actions` plugin that can organize imports and enforce code format on saving a file. will that help? – Eugene Nov 21 '20 at 15:11
  • @Eugene not really – Antonio Dragos Nov 23 '20 at 09:36
  • In IntelliJ, you can export all the rules as preferences to a file and ask the team to import those preferences before setting up the development environment. This will ensure everyone follows the same formatting rules and also IntelliJ will format the auto-generated code as well. If someone fails to import IntelliJ preferences you have a Gradle spotless plugin to take care of that scenario. If this works I can elaborate more as an answer with the solutions to other problems you noted as part of this question. – Lokesh Nov 23 '20 at 17:24
  • Can you elaborate why? you can import the same rules in intellij and have the same imports via Save Actions. – Eugene Nov 23 '20 at 19:13
  • @Lokesh the problem with your approach is that there's not easy way to share a formatting file between IntelliJ and Spotless, because Spotless only supports the Google fortmatting rules or an Eclipse file – Antonio Dragos Nov 24 '20 at 10:42
  • @Eugene your suggestion doesn't deal with Gradle integration – Antonio Dragos Nov 24 '20 at 10:42
  • @AntonioDragos ha? This is for intellij, it does not care gradle maven, or anything else – Eugene Nov 24 '20 at 12:08
  • @AntonioDragos - I don't know if there is a common format that is supported by both Intellij & Gradle plugin to solve the problem. Being said that I don't know many other things so not a surprise about this. I am watching this thread if there is any solution. – Lokesh Nov 25 '20 at 03:30
  • I am using the checkstyle, I think it can match your requirements except for 1.2. – davis dai Nov 26 '20 at 12:37
  • 1
    The Save Actions suggestion solves your 2.2. and can be used with Intellij formatting rules, so since you claim your existing solution only violates 2.2., what's the problem, again? – OhleC Nov 27 '20 at 09:17
  • @AntonioDragos does the solution below provide an answer to your question? Is there something we can enhance? – sashimi Nov 29 '20 at 19:41

5 Answers5

10

You could use the Google Java Format, which has plugins for the aforementioned IDEs (IntelliJ IDEA, Eclipse), it provides integrations with tools such as Maven, Gradle, or SBT, and provides means to run the formatter as pre-commit hook or when pushing the code to Github with Github actions.

In their README they also mention the imports issue and how to fix it for IntelliJ IDEA, and more insights are provided e.g.: on how to handle it on Spotless Gradle plugin, when using the Maven Spotless plugin, or for Github actions.

A drawback for your specific case may be that the tool enforces the Google Java style guide, which was praised and recommended by the Oracle Java team as described in the Oracle Java magazine. It also provides the option to use the AOSP code style.

Below a snippet for spotless Gradle configuration, considering imports ordering:

spotless {
    java {
        importOrder() // standard import order
        importOrder('java', 'javax', 'com.acme', '') // or importOrderFile
        // You probably want an empty string at the end - all of the
        // imports you didn't specify explicitly will go there.

        removeUnusedImports()

        googleJavaFormat() // has its own section below
        eclipse()          // has its own section below
        prettier()         // has its own section below
        clangFormat()      // has its own section below

        licenseHeader '/* (C) $YEAR */' // or licenseHeaderFile
    }
}
sashimi
  • 1,224
  • 2
  • 15
  • 23
1

Checkstyle supports most of your requirements.

Gradle Integration:

plugins {
    id 'checkstyle'
}

checkstyle {
    toolVersion = checkstyleVersion
    config = rootProject.resources.text.fromFile(checkstyleRulesRootPath)  # Loads configuration from a file
    ignoreFailures = false # Causes build to fail
    maxWarnings = 0 # Fails even for warnings
}

It do not fixes code automatically (AFAIK).

IntelliJ integration:

There's Checkstyle plugin which you can configure to display warnings as you're coding.

You can also configure IntelliJ autoformatting to use these rules.

Formatting rules

Here is the configuration for Oracle/Sun specifications in checkstyle.

Yayotrón
  • 1,759
  • 16
  • 27
1

I can help you here. Mainly, you have asked two main problems here:

Incorrectly formatted code can be fixed within the IDE via the "Reformat Code" action

For this, you need to write a code template. We use a specific code template in our organisation. Now, you need to import this XML code template under Settings > Code Style. Now the code will by default be formatted the way the template has been written. Or use Ctrl +Shift+ F as the eclipse shortcut(enabled in intelliJ). Support for the OpenJDK/Oracle Java formatting rules can be taken care of within the same template. Please refer their code template as default one provided in Eclipse.

Code that is generated by the IDE (e.g. getter/setter generation) conforms to the rules

This link will help. Please explore more on how to write the custom code templates.

To restrict all the developers to not to push the wrong format of the code, you need to write a GIT hook. It will not allow the code to be pushed unless the code complies with basic rules provided in the custom script of the hook. Nobody needs to do anything on local intelliJ, the git hook will act from the remote GIT repo. Here is one supporting link.

I have provided crisp information here because it is more the matter of customized rules that will be there in your code templates.

Other questions: Task that checks if code is correctly formatted. This will be used on CI to cause a build failure if incorrectly formatted code is submitted.

When you will restrict the committed code using git hooks, there shall never be any code unformatted on the repo. So, you don't need it as part of CI build. It may be done by providing a pipeline script that will trigger a method having the git location of your code. It looks a tedious thing to me. Hope, all your questions are answered.

hi.nitish
  • 2,732
  • 2
  • 14
  • 21
0

I think you can use it p3c plugin

l0s7r
  • 25
  • 9
0

I use formatter-maven-plugin and import-maven-plugin

Those plugins have validate/check goals that I use in our CI tool to validate incoming PRs.

They also have gradle variants. Checkout here

Ghokun
  • 3,345
  • 3
  • 26
  • 30