Skip to content

Commit 006fca2

Browse files
committed
Allow exclusions of specific spring checks
Closes gh-200
1 parent 8f793f9 commit 006fca2

File tree

4 files changed

+123
-6
lines changed

4 files changed

+123
-6
lines changed

README.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ Spring Framework manually formats code, where as Spring Boot uses automatic form
212212
Formatting and Checkstyle alone are not enough to produce truly consistent code.
213213
Here are some tips that we've found useful when developing Spring Boot.
214214

215+
==== Excluding specific checks
216+
If you want most `SpringChecks` but need to exclude one or two, you can do something like this in your `checkstyle.xml`:
217+
218+
[source,xml,indent=0]
219+
----
220+
<?xml version="1.0"?>
221+
<!DOCTYPE module PUBLIC
222+
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
223+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
224+
<module name="com.puppycrawl.tools.checkstyle.Checker">
225+
<module name="io.spring.javaformat.checkstyle.SpringChecks">
226+
<property name="excludes" value="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck" />
227+
</module>
228+
</module>
229+
----
230+
215231
==== Disabling formatting for blocks of code
216232
Some code isn't particularly amenable to automatic formatting.
217233
For example, Spring Security configurations often work better when manually formatted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2017-2019 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.checkstyle;
18+
19+
import java.util.Set;
20+
21+
import com.puppycrawl.tools.checkstyle.ModuleFactory;
22+
import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent;
23+
import com.puppycrawl.tools.checkstyle.TreeWalkerFilter;
24+
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
25+
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
26+
27+
class FilteredModuleFactory implements ModuleFactory {
28+
29+
private final ModuleFactory moduleFactory;
30+
31+
private final Set<String> excludes;
32+
33+
FilteredModuleFactory(ModuleFactory moduleFactory, Set<String> excludes) {
34+
this.moduleFactory = moduleFactory;
35+
this.excludes = excludes;
36+
}
37+
38+
@Override
39+
public Object createModule(String name) throws CheckstyleException {
40+
Object module = this.moduleFactory.createModule(name);
41+
if (module instanceof AbstractCheck) {
42+
module = filter((AbstractCheck) module);
43+
}
44+
return module;
45+
}
46+
47+
private Object filter(AbstractCheck check) {
48+
if (this.excludes != null && this.excludes.contains(check.getClass().getName())) {
49+
return new FilteredCheck(check);
50+
}
51+
return check;
52+
}
53+
54+
static class FilteredCheck implements TreeWalkerFilter {
55+
56+
private final AbstractCheck check;
57+
58+
FilteredCheck(AbstractCheck check) {
59+
this.check = check;
60+
}
61+
62+
@Override
63+
public boolean accept(TreeWalkerAuditEvent treeWalkerAuditEvent) {
64+
return true;
65+
}
66+
67+
}
68+
69+
}

spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringChecks.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package io.spring.javaformat.checkstyle;
1818

1919
import java.io.File;
20+
import java.util.Arrays;
2021
import java.util.Collection;
22+
import java.util.HashSet;
2123
import java.util.LinkedHashSet;
2224
import java.util.Properties;
2325
import java.util.Set;
@@ -61,6 +63,8 @@ public class SpringChecks extends AbstractFileSetCheck implements ExternalResour
6163

6264
private String projectRootPackage = SpringImportOrderCheck.DEFAULT_PROJECT_ROOT_PACKAGE;
6365

66+
private Set<String> excludes;
67+
6468
/**
6569
* Sets classLoader to load class.
6670
* @param classLoader class loader to resolve classes with.
@@ -79,18 +83,18 @@ public void setModuleFactory(ModuleFactory moduleFactory) {
7983

8084
@Override
8185
public void finishLocalSetup() {
86+
ModuleFactory moduleFactory = new FilteredModuleFactory(this.moduleFactory, this.excludes);
8287
DefaultContext context = new DefaultContext();
8388
context.add("classLoader", this.classLoader);
8489
context.add("severity", getSeverity());
8590
context.add("tabWidth", String.valueOf(getTabWidth()));
86-
context.add("moduleFactory", this.moduleFactory);
91+
context.add("moduleFactory", moduleFactory);
8792
Properties properties = new Properties();
8893
put(properties, "headerType", this.headerType);
8994
put(properties, "headerCopyrightPattern", this.headerCopyrightPattern);
9095
put(properties, "headerFile", this.headerFile);
9196
put(properties, "projectRootPackage", this.projectRootPackage);
92-
this.checks = new SpringConfigurationLoader(context, this.moduleFactory)
93-
.load(new PropertiesExpander(properties));
97+
this.checks = new SpringConfigurationLoader(context, moduleFactory).load(new PropertiesExpander(properties));
9498
}
9599

96100
private void put(Properties properties, String name, Object value) {
@@ -153,4 +157,8 @@ public void setProjectRootPackage(String projectRootPackage) {
153157
this.projectRootPackage = projectRootPackage;
154158
}
155159

160+
public void setExcludes(String... excludes) {
161+
this.excludes = new HashSet<>(Arrays.asList(excludes));
162+
}
163+
156164
}

spring-javaformat/spring-javaformat-checkstyle/src/test/java/io/spring/javaformat/checkstyle/SpringConfigurationLoaderTests.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@
1717
package io.spring.javaformat.checkstyle;
1818

1919
import java.util.Collection;
20+
import java.util.Collections;
2021
import java.util.Properties;
22+
import java.util.Set;
2123

2224
import com.puppycrawl.tools.checkstyle.DefaultContext;
2325
import com.puppycrawl.tools.checkstyle.ModuleFactory;
2426
import com.puppycrawl.tools.checkstyle.PackageObjectFactory;
2527
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
2628
import com.puppycrawl.tools.checkstyle.PropertyResolver;
29+
import com.puppycrawl.tools.checkstyle.TreeWalker;
2730
import com.puppycrawl.tools.checkstyle.api.FileSetCheck;
31+
import org.assertj.core.extractor.Extractors;
2832
import org.junit.Test;
2933

3034
import io.spring.javaformat.checkstyle.check.SpringHeaderCheck;
@@ -41,14 +45,34 @@ public class SpringConfigurationLoaderTests {
4145

4246
@Test
4347
public void loadShouldLoadChecks() {
48+
Collection<FileSetCheck> checks = load(null);
49+
assertThat(checks).hasSize(3);
50+
TreeWalker treeWalker = (TreeWalker) checks.toArray()[2];
51+
Set<?> ordinaryChecks = (Set<?>) Extractors.byName("ordinaryChecks").extract(treeWalker);
52+
assertThat(ordinaryChecks).hasSize(60);
53+
}
54+
55+
@Test
56+
@SuppressWarnings({ "unchecked", "rawtypes" })
57+
public void loadWithExcludeShouldExcludeChecks() {
58+
Set<String> excludes = Collections
59+
.singleton("com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck");
60+
Collection<FileSetCheck> checks = load(excludes);
61+
assertThat(checks).hasSize(3);
62+
TreeWalker treeWalker = (TreeWalker) checks.toArray()[2];
63+
Set<?> ordinaryChecks = (Set<?>) Extractors.byName("ordinaryChecks").extract(treeWalker);
64+
assertThat(ordinaryChecks).hasSize(59);
65+
}
66+
67+
private Collection<FileSetCheck> load(Set<String> excludes) {
4468
DefaultContext context = new DefaultContext();
45-
context.add("moduleFactory",
46-
new PackageObjectFactory(getClass().getPackage().getName(), getClass().getClassLoader()));
4769
ModuleFactory moduleFactory = new PackageObjectFactory(getClass().getPackage().getName(),
4870
getClass().getClassLoader());
71+
moduleFactory = new FilteredModuleFactory(moduleFactory, excludes);
72+
context.add("moduleFactory", moduleFactory);
4973
Collection<FileSetCheck> checks = new SpringConfigurationLoader(context, moduleFactory)
5074
.load(getPropertyResolver());
51-
assertThat(checks).hasSize(3);
75+
return checks;
5276
}
5377

5478
private PropertyResolver getPropertyResolver() {

0 commit comments

Comments
 (0)