Skip to content

Want a way to disable "combining closures with only one statement into one line" #721

@basil

Description

@basil

I use the Eclipse Groovy formatter via diffplug/spotless to automatically format my Gradle scripts (and other Groovy DSL scripts, such as Jenkins jobs) through Gradle. Unfortunately, there is an issue in the Eclipse Groovy formatter that prevents it from being suitable for formatting most Groovy DSL scripts, such as Gradle scripts, Jenkins Job DSL job definitions, and Jenkins pipeline definitions. This is a big market for the Eclipse Groovy formatter, as I am not aware of another solution for formatting Groovy source files that can be run easily from the command-line.

To see what I mean, take a look at this chapter in the Gradle documentation. Consider the examples provided there, which are typical examples of Groovy DSL scripts.

Example 1:

repositories {
    jcenter()
}

Example 2:

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}

Unfortunately, the Eclipse Groovy formatter will "combine closure[s] with only one statments [sic] with less than 5 tokens to one line". This results in the above snippets being formatted as follows:

Example 1:

repositories { jcenter() }

Example 2:

repositories { maven { url "http://repo.mycompany.com/maven2" } }

This makes the code more difficult to read. Similar examples could be given for Jenkins jobs.

I tried to find a way to disable this behavior, but (unfortunately) I found there was no preference for it. GroovyBeautifier#combineClosures always goes down the code path linked above, and GroovyBeautifier#getBeautifiEdits always calls GroovyBeautifier#combineClosures. Thus, in the current codebase, the only way of disabling this behavior is to disable the use of GroovyBeautifier entirely and use the Eclipse Groovy formatter just to perform indentation, not formatting. But this also disables many other useful features, such as formatting lists, correcting braces, and removing unnecessary semicolons. Therefore, I propose we add a way to opt out of the "combine closures with only one statement to one line" functionality without opting out of the many other benefits of GroovyBeautifier.

I considered making the hard-coded constant 10 in the relevant code customizable. The comment says that this "combine[s] closure[s] with only one statments [sic] with less than 5 tokens to one line", so presumably the number 10 in the code is related to the number 5 in the comment. Whether the comment is wrong or I am misunderstanding the code isn't clear, but one thing that is clear is that the token count is what is under consideration here. I don't think that most users who are customizing their formatter are concerned with internal implementation details like token count. In fact, exposing the token count to the user seems like it might be a bad idea if the implementation is ever changed to do something more clever (like taking into account line length), since then the option would have to be deprecated and removed. Instead, it made more sense to me to expose a boolean called "combine closures with only one statement to one line". This hides the implementation details of token count from the user and enables the implementation to be refactored later to use a better metric (for example, one that takes into account line length), while still allowing users to opt out of the undesired functionality today.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions