Fix for illegal mutation issue with predeclareDeps (#2892) · diffplug/spotless@db8dc1c (original) (raw)

File tree

Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
5 5 ## [Unreleased]
6 6 ### Added
7 7 - Add `tableTest` format type for standalone `.table` files.
8 +### Fixed
9 +- Fix illegal mutation when using predeclared dependencies.
8 10 ### Changes
9 11 - Bump default `tabletest-formatter` version `1.0.1` -> `1.1.1`, now works with Java 17+.
10 12
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ public SpotlessExtensionPredeclare(Project project, GradleProvisioner.Policy pol
32 32 super(project);
33 33 this.registerDependenciesTask = findRegisterDepsTask().get();
34 34 SpotlessTaskService taskService = getSpotlessTaskService().get();
35 -taskService.isUsingPredeclared = true;
35 +taskService.registerDependenciesTask = registerDependenciesTask;
36 36 taskService.predeclaredProvisioner = policy.dedupingProvisioner(project);
37 37 taskService.predeclaredP2Provisioner = policy.dedupingP2Provisioner(project);
38 38 project.afterEvaluate(unused -> toSetup.forEach((name, formatExtension) -> {
Original file line number Diff line number Diff line change
@@ -56,14 +56,14 @@
56 56 * apply already did).
57 57 */
58 58 public abstract class SpotlessTaskService implements BuildService<BuildServiceParameters.None>, AutoCloseable, OperationCompletionListener {
59 -protected boolean isUsingPredeclared;
60 59 private final Map<String, SpotlessApply> apply = Collections.synchronizedMap(new HashMap<>());
61 60 private final Map<String, SpotlessTask> source = Collections.synchronizedMap(new HashMap<>());
62 61 private final Map<String, Provisioner> provisioner = Collections.synchronizedMap(new HashMap<>());
63 62 private final Map<String, P2Provisioner> p2Provisioner = Collections.synchronizedMap(new HashMap<>());
64 63
65 64 @Nullable GradleProvisioner.DedupingProvisioner predeclaredProvisioner;
66 65 @Nullable GradleProvisioner.DedupingP2Provisioner predeclaredP2Provisioner;
66 +@Nullable RegisterDependenciesTask registerDependenciesTask;
67 67
68 68 Provisioner provisionerFor(SpotlessExtension spotless) {
69 69 if (spotless instanceof SpotlessExtensionPredeclare) {
@@ -129,12 +129,9 @@ static void usesServiceTolerateTestFailure(DefaultTask task, Provider<SpotlessTa
129 129 }
130 130
131 131 public void hookSubprojectTask(Project project, SpotlessTask task) {
132 -// This check allows isolated projects support by not accessing the root project tasks unless really needed
133 -if (!isUsingPredeclared) {
134 -return;
132 +if (registerDependenciesTask != null) {
133 +registerDependenciesTask.hookSubprojectTask(task);
135 134 }
136 -
137 -project.getRootProject().getTasks().withType(RegisterDependenciesTask.class, registerTask -> registerTask.hookSubprojectTask(task));
138 135 }
139 136
140 137 public static Provider<SpotlessTaskService> registerIfAbsent(Project project, String suffix) {
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
17 17
18 18 import java.io.IOException;
19 19
20 -import org.assertj.core.api.Assertions;
21 20 import org.gradle.testkit.runner.GradleRunner;
22 21 import org.junit.jupiter.api.Test;
23 22
@@ -85,7 +84,7 @@ void noRootIsSupported() throws IOException {
85 84 }
86 85
87 86 @Test
88 -void predeclaredIsUnsupported() throws IOException {
87 +void predeclaredIsSupported() throws IOException {
89 88 setFile("build.gradle").toLines(
90 89 "plugins {",
91 90 " id 'com.diffplug.spotless'",
@@ -96,7 +95,6 @@ void predeclaredIsUnsupported() throws IOException {
96 95 " kotlin { ktlint() }",
97 96 "}");
98 97 createNSubprojects();
99 -Assertions.assertThat(gradleRunner().withArguments("spotlessApply").buildAndFail().getOutput())
100 - .containsAnyOf("Cannot access project", "cannot access 'Project.tasks'");
98 +gradleRunner().withArguments("spotlessApply").build();
101 99 }
102 100 }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
1 1 /*
2 - * Copyright 2016-2025 DiffPlug
2 + * Copyright 2016-2026 DiffPlug
3 3 *
4 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 5 * you may not use this file except in compliance with the License.
@@ -137,6 +137,36 @@ public void predeclaredOrdering() throws IOException {
137 137 .contains("Could not find method spotlessPredeclare() for arguments");
138 138 }
139 139
140 +@Test
141 +public void predeclaredDepsRegression() throws IOException {
142 +setFile("settings.gradle").toContent("include 'sub'");
143 +setFile("build.gradle").toLines(
144 +"plugins { id 'com.diffplug.spotless' }",
145 +"repositories { mavenCentral() }",
146 +"spotless {",
147 +" predeclareDeps()",
148 +" java {",
149 +" target file('test.java')",
150 +" googleJavaFormat('1.17.0')",
151 +" }",
152 +"}",
153 +"spotlessPredeclare {",
154 +" java { googleJavaFormat('1.17.0') }",
155 +"}");
156 +setFile("test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
157 +setFile("sub/build.gradle").toLines(
158 +"plugins { id 'com.diffplug.spotless' }",
159 +"repositories { mavenCentral() }",
160 +"spotless {",
161 +" java {",
162 +" target file('test.java')",
163 +" googleJavaFormat('1.17.0')",
164 +" }",
165 +"}");
166 +setFile("sub/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
167 +gradleRunner().withGradleVersion("8.14").withArguments("spotlessApply").build();
168 + }
169 +
140 170 @Test
141 171 public void predeclaredUndeclared() throws IOException {
142 172 setFile("build.gradle").toLines(