Skip to content

Commit 4dddd32

Browse files
committed
Improve Gradle integration
This commit adds improved Gradle integration. The Java Format Gradle plugin now: - Reacts to the Checkstyle plugin being applied by adding a dependency on spring-javaformat-checkstyle - Provide a DSL extension that can be used to: - Apply the default checkstyle.xml configuration - Opt out of the automatic dependency configuration Closes gh-443 Closes gh-453
1 parent 2ba40a6 commit 4dddd32

File tree

10 files changed

+331
-12
lines changed

10 files changed

+331
-12
lines changed

README.adoc

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -162,34 +162,48 @@ tasks.withType(io.spring.javaformat.gradle.tasks.CheckFormat) {
162162

163163

164164
==== Checkstyle
165-
To enforce Checkstyle conventions, add the `checkstyle` plugin and include a dependency on `spring-javaformat-checkstyle`:
165+
To enforce Checkstyle conventions, apply the Checkstyle plugin in addition to the `io.spring.javaformat` plugin:
166166

167167
[source,groovy,indent=0,subs="normal"]
168168
----
169169
plugins {
170+
id "io.spring.javaformat" version "{release-version}"
170171
id "checkstyle"
171172
}
172173
174+
The Spring Java Format plugin will react to the Checkstyle plugin being applied and configure the necessary dependencies in the `checkstyle` configuration.
175+
176+
You should also configure Checkstyle's tool version:
177+
178+
[source,groovy,indent=0,subs="normal"]
179+
----
173180
checkstyle {
174181
toolVersion = "{checkstyle-version}"
175182
}
183+
----
184+
185+
To configure Checkstyle to use the default Spring checks, add the following configuration:
176186
177-
dependencies {
178-
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:{release-version}")
187+
[source,groovy,indent=0,subs="normal"]
188+
----
189+
springJavaFormat {
190+
checkstyle {
191+
applyDefaultConfig()
192+
}
179193
}
180194
----
181195
182-
To use the Spring checks, your `checkstyle.xml` file should look like this:
196+
Alternatively, provide your own `checkstyle.xml` that configures the `io.spring.javaformat.checkstyle.SpringChecks` module.
183197
184-
[source,xml,indent=0]
198+
If you want to use both Spring Java Format and Checkstyle but you do not want to use Spring Java Format's checks, disable the aforementioned dependency configuration:
199+
200+
[source,groovy,indent=0,subs="normal"]
185201
----
186-
<?xml version="1.0"?>
187-
<!DOCTYPE module PUBLIC
188-
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
189-
"https://checkstyle.org/dtds/configuration_1_3.dtd">
190-
<module name="com.puppycrawl.tools.checkstyle.Checker">
191-
<module name="io.spring.javaformat.checkstyle.SpringChecks" />
192-
</module>
202+
springJavaFormat {
203+
checkstyle {
204+
configureDependencies = false
205+
}
206+
}
193207
----
194208
195209

spring-javaformat-gradle/spring-javaformat-gradle-plugin/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@
115115
<artifactId>spring-javaformat-formatter-shaded</artifactId>
116116
<version>${project.version}</version>
117117
</dependency>
118+
<!-- Test -->
119+
<dependency>
120+
<groupId>io.spring.javaformat</groupId>
121+
<artifactId>spring-javaformat-checkstyle</artifactId>
122+
<version>${project.version}</version>
123+
</dependency>
118124
</dependencies>
119125
<profiles>
120126
<profile>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2017-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.javaformat.gradle;
18+
19+
import java.io.PrintWriter;
20+
import java.io.StringWriter;
21+
22+
import javax.inject.Inject;
23+
24+
import org.gradle.api.Action;
25+
import org.gradle.api.Project;
26+
import org.gradle.api.plugins.quality.CheckstyleExtension;
27+
import org.gradle.api.provider.Property;
28+
import org.gradle.api.resources.TextResource;
29+
30+
/**
31+
* DSL extension for Spring Java Format.
32+
*
33+
* @author Andy Wilkinson
34+
*/
35+
public abstract class SpringJavaFormatExtension {
36+
37+
private final Checkstyle checkstyle;
38+
39+
@Inject
40+
public SpringJavaFormatExtension(Project project) {
41+
this.checkstyle = project.getObjects().newInstance(Checkstyle.class, project);
42+
this.checkstyle.getConfigureDependencies().convention(true);
43+
}
44+
45+
public Checkstyle getCheckstyle() {
46+
return this.checkstyle;
47+
}
48+
49+
public void checkstyle(Action<Checkstyle> action) {
50+
action.execute(this.checkstyle);
51+
}
52+
53+
public abstract static class Checkstyle {
54+
55+
private final Project project;
56+
57+
@Inject
58+
public Checkstyle(Project project) {
59+
this.project = project;
60+
}
61+
62+
/**
63+
* Property that controls whether Checkstyle's dependencies should be configured to
64+
* use Spring Java Format's checks.
65+
* @return the property
66+
*/
67+
public abstract Property<Boolean> getConfigureDependencies();
68+
69+
/**
70+
* Applies Spring Java Format's default Checkstyle config, enabling all Spring checks.
71+
* @see CheckstyleExtension#setConfig(TextResource)
72+
*/
73+
public void applyDefaultConfig() {
74+
CheckstyleExtension extension = this.project.getExtensions().getByType(CheckstyleExtension.class);
75+
StringWriter defaultConfig = new StringWriter();
76+
PrintWriter writer = new PrintWriter(defaultConfig);
77+
writer.println("<?xml version=\"1.0\"?>");
78+
writer.println("<!DOCTYPE module PUBLIC");
79+
writer.println(" \"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN\"");
80+
writer.println(" \"https://checkstyle.org/dtds/configuration_1_3.dtd\">");
81+
writer.println("<module name=\"com.puppycrawl.tools.checkstyle.Checker\">");
82+
writer.println(" <module name=\"io.spring.javaformat.checkstyle.SpringChecks\">");
83+
writer.println(" </module>");
84+
writer.println("</module>");
85+
extension.setConfig(this.project.getResources().getText().fromString(defaultConfig.toString()));
86+
}
87+
88+
}
89+
90+
}

spring-javaformat-gradle/spring-javaformat-gradle-plugin/src/main/java/io/spring/javaformat/gradle/SpringJavaFormatPlugin.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,24 @@
1717
package io.spring.javaformat.gradle;
1818

1919
import java.io.File;
20+
import java.util.ArrayList;
21+
import java.util.List;
2022

2123
import org.gradle.api.Plugin;
2224
import org.gradle.api.Project;
2325
import org.gradle.api.Task;
26+
import org.gradle.api.artifacts.Dependency;
27+
import org.gradle.api.artifacts.DependencySet;
2428
import org.gradle.api.plugins.JavaBasePlugin;
2529
import org.gradle.api.plugins.JavaPluginExtension;
30+
import org.gradle.api.plugins.quality.CheckstyleExtension;
31+
import org.gradle.api.plugins.quality.CheckstylePlugin;
2632
import org.gradle.api.tasks.SourceSet;
2733
import org.gradle.api.tasks.TaskContainer;
2834
import org.gradle.api.tasks.TaskProvider;
2935

3036
import io.spring.javaformat.config.JavaFormatConfig;
37+
import io.spring.javaformat.formatter.Formatter;
3138
import io.spring.javaformat.gradle.tasks.CheckFormat;
3239
import io.spring.javaformat.gradle.tasks.Format;
3340
import io.spring.javaformat.gradle.tasks.FormatterTask;
@@ -46,6 +53,13 @@ public class SpringJavaFormatPlugin implements Plugin<Project> {
4653
public void apply(Project project) {
4754
this.project = project;
4855
addSourceTasks();
56+
SpringJavaFormatExtension extension = registerExtension();
57+
new CheckstyleConfigurer(project, extension).apply();
58+
}
59+
60+
private SpringJavaFormatExtension registerExtension() {
61+
SpringJavaFormatExtension extension = this.project.getExtensions().create("springJavaFormat", SpringJavaFormatExtension.class);
62+
return extension;
4963
}
5064

5165
private void addSourceTasks() {
@@ -90,4 +104,39 @@ private <T extends FormatterTask> TaskProvider<T> addFormatterTask(SourceSet sou
90104
return provider;
91105
}
92106

107+
private static final class CheckstyleConfigurer {
108+
109+
private final Project project;
110+
111+
private final SpringJavaFormatExtension extension;
112+
113+
private CheckstyleConfigurer(Project project, SpringJavaFormatExtension extension) {
114+
this.project = project;
115+
this.extension = extension;
116+
}
117+
118+
private void apply() {
119+
this.project.getPlugins().withType(CheckstylePlugin.class).configureEach((checkstylePlugin) -> {
120+
CheckstyleExtension checkstyle = this.project.getExtensions().getByType(CheckstyleExtension.class);
121+
DependencySet checkstyleDependencies = this.project.getConfigurations().getByName("checkstyle").getDependencies();
122+
checkstyleDependencies.addAllLater(this.project.provider(() -> checkstyleDependencies(checkstyle)));
123+
});
124+
}
125+
126+
private List<Dependency> checkstyleDependencies(CheckstyleExtension checkstyle) {
127+
List<Dependency> dependencies = new ArrayList<>();
128+
if (configuringCheckstyleDependencies()) {
129+
dependencies.add(this.project.getDependencies().create("com.puppycrawl.tools:checkstyle:" + checkstyle.getToolVersion()));
130+
dependencies.add(this.project.getDependencies().create("io.spring.javaformat:spring-javaformat-checkstyle:"
131+
+ Formatter.class.getPackage().getImplementationVersion()));
132+
}
133+
return dependencies;
134+
}
135+
136+
private boolean configuringCheckstyleDependencies() {
137+
return Boolean.TRUE.equals(this.extension.getCheckstyle().getConfigureDependencies().get());
138+
}
139+
140+
}
141+
93142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2017-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.javaformat.gradle;
18+
19+
import org.gradle.testkit.runner.BuildResult;
20+
import org.junit.jupiter.api.Test;
21+
import org.junit.jupiter.api.extension.ExtendWith;
22+
23+
import io.spring.javaformat.gradle.testkit.GradleBuild;
24+
import io.spring.javaformat.gradle.testkit.GradleBuildExtension;
25+
26+
import static org.assertj.core.api.Assertions.assertThat;
27+
28+
@ExtendWith(GradleBuildExtension.class)
29+
class CheckstyleTests {
30+
31+
private final GradleBuild gradleBuild = new GradleBuild();
32+
33+
@Test
34+
void configureCheckstyle() {
35+
BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-configure").build("checkstyleDependencies");
36+
assertThat(result.getOutput()).contains("io.spring.javaformat:spring-javaformat-checkstyle:");
37+
assertThat(result.getOutput()).contains("com.puppycrawl.tools:checkstyle:8.45.1");
38+
}
39+
40+
@Test
41+
void configureCheckstyleWithCustomToolVersion() {
42+
BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-configure-with-custom-tool-version").build("checkstyleDependencies");
43+
assertThat(result.getOutput()).contains("io.spring.javaformat:spring-javaformat-checkstyle:");
44+
assertThat(result.getOutput()).contains("com.puppycrawl.tools:checkstyle:10.26.1");
45+
}
46+
47+
@Test
48+
void doNotConfigureCheckstyle() {
49+
BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-do-not-configure").build("checkstyleDependencies");
50+
assertThat(result.getOutput()).doesNotContain("spring-javaformat-checkstyle");
51+
}
52+
53+
@Test
54+
void applyDefaultConfigToCheckstyle() {
55+
BuildResult result = this.gradleBuild.source("src/test/resources/checkstyle-apply-default-config").build("checkstyleConfig");
56+
assertThat(result.getOutput()).contains("<module name=\"io.spring.javaformat.checkstyle.SpringChecks\">");
57+
}
58+
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
buildscript {
2+
dependencies {
3+
classpath files(pluginClasspath.split(','))
4+
}
5+
}
6+
7+
apply plugin: 'checkstyle'
8+
apply plugin: 'java'
9+
apply plugin: 'io.spring.javaformat'
10+
11+
sourceCompatibility = 1.8
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
springJavaFormat {
18+
checkstyle {
19+
applyDefaultConfig()
20+
}
21+
}
22+
23+
tasks.register("checkstyleConfig") {
24+
doFirst {
25+
println checkstyle.config.asString()
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
buildscript {
2+
dependencies {
3+
classpath files(pluginClasspath.split(','))
4+
}
5+
}
6+
7+
apply plugin: 'checkstyle'
8+
apply plugin: 'java'
9+
apply plugin: 'io.spring.javaformat'
10+
11+
sourceCompatibility = 1.8
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
checkstyle {
18+
toolVersion = "10.26.1"
19+
}
20+
21+
tasks.register("checkstyleDependencies") {
22+
doFirst {
23+
configurations.checkstyle.dependencies.each { println "${it.group}:${it.name}:${it.version}" }
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
buildscript {
2+
dependencies {
3+
classpath files(pluginClasspath.split(','))
4+
}
5+
}
6+
7+
apply plugin: 'checkstyle'
8+
apply plugin: 'java'
9+
apply plugin: 'io.spring.javaformat'
10+
11+
sourceCompatibility = 1.8
12+
13+
repositories {
14+
mavenCentral()
15+
}
16+
17+
tasks.register("checkstyleDependencies") {
18+
doFirst {
19+
configurations.checkstyle.dependencies.each { println "${it.group}:${it.name}:${it.version}" }
20+
}
21+
}

0 commit comments

Comments
 (0)