spotless icon indicating copy to clipboard operation
spotless copied to clipboard

Groovy formatting is very limited - possible idea

Open sdoeringNew opened this issue 7 months ago • 6 comments

The current Groovy formatting using the Eclipse formatter is very limited. It can't even format apply({println it }) into something stringent. Let alone Spock tests written in Groovy.

The ways to format Groovy code are very limited. There is a npm-groovy-lint. That works better as the Eclipse formatter but has it own flaws (multi-line strings, ...). And fails on Spock tests, too.

My idea would be to use the IntelliJ formatter of the freely available community edition.

Here's the catch. That's a command line tool that has the necessary two working options. dry-run - just like spotless:check - checks a file or the files in a folder if they conform the expected formatting. If not, the files are reported. format - just like spotless:apply - formats a file or the files in a folder.

After reading the contribution guideline I think this IntelliJ approach fits hardly into the Spotless Formatter approach, where one single file is given into the method and the formatted result is returned.

Of course it's possible to write the file content into a temporary file, call IntelliJ format on that temporary file, read the file again and return it's result. I believe that's very cumbersome - especially on Windows with limited NTFS.

The necessary IntelliJ files could be packaged and provided as Maven dependency and then started as external process.

Is there a way to achieve better Groovy formation with Spotless?

(Of course, IntelliJ could format many other file types, too, but I'm mainly interested in Groovy.)

sdoeringNew avatar Jun 13 '25 18:06 sdoeringNew

I agree - greclipse is a super heavy download and the application is also slow and buggy at times. https://github.com/apache/lucene/issues/14787

The groovy project has an ast-parser... maybe it's time for some young, cheeky individual to write a formatter for it that is fast and self-contained? :)

dweiss avatar Jun 25 '25 08:06 dweiss

That's a command line tool that has the necessary two working options.

Can you point me at the docs or instructions on how to apply this?

dweiss avatar Jun 25 '25 08:06 dweiss

I agree - greclipse is a super heavy download and the application is also slow and buggy at times.

If you think "greclipse is a super heavy download" then you might want to take a tranquilizer for IntelliJ. That's at least ten times the size. And it's not just a jar, it's a zip with a stripped down version of the IntelliJ Community edition. Repackaging is allowed by their license.

That's a command line tool that has the necessary two working options.

Can you point me at the docs or instructions on how to apply this?

These are the options for the CLI formatting capabilties: https://www.jetbrains.com/help/idea/command-line-formatter.html#linux

sdoeringNew avatar Jun 27 '25 17:06 sdoeringNew

I had a little look at the spotless source code.

The GrEclipseFormatterStep converts the configuration into Properties. Those properties are given - using reflection - into the formatter class, format is called, etc.

So. There could be a IdeaFormatterStep class. This class knows the configuration on which folder the file format have to be checked or applied.
Before calling the common spotless format method, a IntelliJ CLI process is spawned using format on the configured folder. The result is parsed and saved on each file. Now we already know the result of each single file.
Now the common spotless format method is called for each single file. We simply return the former formatting result.

In such scenario the IntelliJ process is started once and not for each file.

sdoeringNew avatar Jun 27 '25 17:06 sdoeringNew

As the CLI tool does not have that many options the build plugin won't be that big either.

<plugin>
  <groupId>com.diffplug.spotless</groupId>
  <artifactId>spotless-maven-plugin</artifactId>
  <version>${spotless.version}</version>
  <configuration>
    <groovy>
      <ideaGroovyFormat>
        <paths>src/main/groovy,src/test/groovy</paths> <!-- optional target paths to format the files in, default: . -->
        <mask>*.jenkinsfile</mask> <!-- optional file mask, default: *.groovy -->
        <settings>corporation-format.xml</settings> <!-- optional Idea format, default: (n/a) -->
      </ideaGroovyFormat>
    </groovy>
  </configuration>
</plugin>

The groovy element already has an includes element containing files masks.
It would be hard to incorporate those in complex cases: src/main/**/com/diffplug/spotless/*/groovy/**/*.groovy

sdoeringNew avatar Jun 27 '25 18:06 sdoeringNew

If you think "greclipse is a super heavy download" then you might want to take a tranquilizer for IntelliJ. That's at least ten times the size. And it's not just a jar, it's a zip with a stripped down version of the IntelliJ Community edition. Repackaging is allowed by their license.

Oh, that's disappointing. I was hoping for some tool that is detached from the entire IDE. Thanks for enlightening me.

dweiss avatar Jun 27 '25 18:06 dweiss