Skip to content

Commit 2ad0fde

Browse files
committed
Allow RequireExplicitNullMarking to be disabled on a per-task basis
See gh-23
1 parent 271ab51 commit 2ad0fde

File tree

5 files changed

+81
-4
lines changed

5 files changed

+81
-4
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ nullability {
3030
}
3131
```
3232

33+
The extension can also be used to disable the `RequireExplicitNullMarking` check:
34+
35+
```groovy
36+
nullability {
37+
requireExplicitNullMarking = false
38+
}
39+
```
40+
3341
## Types of Nullability Checking
3442

3543
The plugin supports two types of nullability checking, `main` and `tests`.
@@ -41,7 +49,7 @@ Checking using `tests` differs from `main`. It adds support for AssertJ's custom
4149
## Configuring Nullability Checking
4250

4351
The plugin adds a `nullability` extension to the `options` of all `JavaCompile` tasks.
44-
The extension provides a single property, `checking`, that can be used to configure the type of null checking that is performed.
52+
The extension provides a property, `checking`, that can be used to configure the type of null checking that is performed.
4553
It defaults to `main` for tasks whose name matches `compile(\\d+)?Java`.
4654
For all other `JavaCompile` tasks it defaults to `disabled`.
4755

@@ -51,3 +59,12 @@ The following enables `tests` nullability checking for `compileTestJava`:
5159
tasks.named("compileTestJava") {
5260
options.nullability.checking = "tests"
5361
}
62+
```
63+
64+
The task-level `nullability` extension also provides a property, `requireExplicitNullMarking`, that can be used to disable the `RequireExplicitNullMarking` check for a specific task:
65+
66+
```groovy
67+
tasks.named("compileTestJava") {
68+
options.nullability.requireExplicitNullMarking = false
69+
}
70+
```

src/main/java/io/spring/gradle/nullability/NullabilityOptions.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ public abstract class NullabilityOptions {
4747
*/
4848
@Inject
4949
public NullabilityOptions(ErrorProneOptions errorProne, NullabilityPluginExtension nullability) {
50+
getRequireExplicitNullMarking().convention(nullability.getRequireExplicitNullMarking());
5051
Provider<Checking> checkingAsEnum = getChecking()
5152
.map((string) -> Checking.valueOf(string.toUpperCase(Locale.ROOT)));
5253
errorProne.getEnabled().set(checkingAsEnum.map((checking) -> checking != Checking.DISABLED));
5354
errorProne.getDisableAllChecks().set(checkingAsEnum.map((checking) -> checking != Checking.DISABLED));
5455
errorProne.getCheckOptions().putAll(checkingAsEnum.map(this::checkOptions));
55-
errorProne.getChecks().putAll(checkingAsEnum.map((checking) -> checks(checking, nullability)));
56+
errorProne.getChecks().putAll(checkingAsEnum.map(this::checks));
5657
}
5758

5859
private Map<String, String> checkOptions(Checking checking) {
@@ -74,11 +75,11 @@ private Map<String, String> checkOptions(Checking checking) {
7475
return options;
7576
}
7677

77-
private Map<String, CheckSeverity> checks(Checking checking, NullabilityPluginExtension nullability) {
78+
private Map<String, CheckSeverity> checks(Checking checking) {
7879
if (checking != Checking.DISABLED) {
7980
Map<String, CheckSeverity> checks = new HashMap<>();
8081
checks.put("NullAway", CheckSeverity.ERROR);
81-
if (Boolean.TRUE.equals(nullability.getRequireExplicitNullMarking().get())) {
82+
if (Boolean.TRUE.equals(getRequireExplicitNullMarking().get())) {
8283
checks.put("RequireExplicitNullMarking", CheckSeverity.ERROR);
8384
}
8485
return checks;
@@ -92,6 +93,12 @@ private Map<String, CheckSeverity> checks(Checking checking, NullabilityPluginEx
9293
*/
9394
public abstract Property<String> getChecking();
9495

96+
/**
97+
* Whether explicit null marking is required.
98+
* @return the property for whether explicit null marking is required
99+
*/
100+
public abstract Property<Boolean> getRequireExplicitNullMarking();
101+
95102
/**
96103
* The type of null checking to perform for the {@link JavaCompile} task.
97104
*/

src/test/java/io/spring/gradle/nullability/NullabilityPluginIntegrationTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ void compileFailsForCodeThatIsNotNullMarked() throws IOException {
124124
assertThat(result.getOutput()).contains("[RequireExplicitNullMarking]");
125125
}
126126

127+
@Test
128+
void compileFailsForCodeThatIsNotNullMarkedWhenDisabledOnTheExtensionAndEnabledOnTheTask() throws IOException {
129+
Path pkg = createSrcDirectories("main");
130+
writeExampleClass(pkg);
131+
BuildResult result = this.gradleBuild.prepareRunner("compileJava").buildAndFail();
132+
assertThat(result.getOutput()).contains("[RequireExplicitNullMarking]");
133+
}
134+
127135
@Test
128136
void compileSucceedsForCodeThatIsNotNullMarkedWhenRequireExplicitNullMarkingIsDisabled() throws IOException {
129137
Path pkg = createSrcDirectories("main");
@@ -132,6 +140,15 @@ void compileSucceedsForCodeThatIsNotNullMarkedWhenRequireExplicitNullMarkingIsDi
132140
assertThat(result.task(":compileJava").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
133141
}
134142

143+
@Test
144+
void compileSucceedsForCodeThatIsNotNullMarkedWhenRequireExplicitNullMarkingIsDisabledOnTheTask()
145+
throws IOException {
146+
Path pkg = createSrcDirectories("main");
147+
writeExampleClass(pkg);
148+
BuildResult result = this.gradleBuild.prepareRunner("compileJava").build();
149+
assertThat(result.task(":compileJava").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
150+
}
151+
135152
private Path createSrcDirectories(String sourceSetName) {
136153
Path projectDir = this.gradleBuild.getProjectDir().toPath();
137154
Path pkg = projectDir.resolve("src/%s/java/com/example".formatted(sourceSetName));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
plugins {
2+
id "io.spring.nullability"
3+
id "java"
4+
}
5+
6+
repositories {
7+
mavenCentral()
8+
}
9+
10+
dependencies {
11+
testCompileOnly("org.jspecify:jspecify:1.0.0")
12+
}
13+
14+
nullability {
15+
requireExplicitNullMarking = false
16+
}
17+
18+
tasks.named("compileJava") {
19+
options.nullability.requireExplicitNullMarking = true
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
plugins {
2+
id "io.spring.nullability"
3+
id "java"
4+
}
5+
6+
repositories {
7+
mavenCentral()
8+
}
9+
10+
dependencies {
11+
testCompileOnly("org.jspecify:jspecify:1.0.0")
12+
}
13+
14+
tasks.named("compileJava") {
15+
options.nullability.requireExplicitNullMarking = false
16+
}

0 commit comments

Comments
 (0)