Skip to content

Commit ca71301

Browse files
committed
Lazily initialize GitRatchetGradle to avoid loading JGit at configuration time
GitRatchetGradle is instantiated eagerly when SpotlessTaskService is created, which happens during Gradle configuration. Its static initializer installs a custom JGit SystemReader that reads ~/.gitconfig. This causes Gradle's configuration cache to fingerprint the file even when no Spotless tasks are requested. Defer instantiation to getRatchet(), which is only called during task execution. This avoids loading JGit classes and reading git config files at configuration time.
1 parent 46b8770 commit ca71301

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessTaskService.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,12 @@ void registerApplyAlreadyRan(SpotlessApply task) {
9999
}
100100

101101
// <GitRatchet>
102-
private final GitRatchetGradle ratchet = new GitRatchetGradle();
102+
private GitRatchetGradle ratchet;
103103

104104
GitRatchetGradle getRatchet() {
105+
if (ratchet == null) {
106+
ratchet = new GitRatchetGradle();
107+
}
105108
return ratchet;
106109
}
107110

@@ -112,7 +115,9 @@ public void onFinish(FinishEvent var1) {
112115

113116
@Override
114117
public void close() throws Exception {
115-
ratchet.close();
118+
if (ratchet != null) {
119+
ratchet.close();
120+
}
116121
}
117122
// </GitRatchet>
118123

plugin-gradle/src/test/java/com/diffplug/gradle/spotless/ConfigurationCacheTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@
1515
*/
1616
package com.diffplug.gradle.spotless;
1717

18+
import java.io.File;
1819
import java.io.IOException;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
1922

23+
import org.assertj.core.api.Assertions;
2024
import org.gradle.testkit.runner.GradleRunner;
2125
import org.junit.jupiter.api.Test;
2226

@@ -60,6 +64,52 @@ public void helpConfiguresIfTasksAreCreated() throws IOException {
6064
gradleRunner().withArguments("help").build();
6165
}
6266

67+
@Test
68+
public void configurationCacheNotInvalidatedByGitconfig() throws IOException {
69+
// ~/.gitconfig is read by JGit at class-load time via the SystemReader.
70+
// If GitRatchetGradle is loaded eagerly during configuration, Gradle's
71+
// configuration cache fingerprints ~/.gitconfig. When its content changes
72+
// (e.g. CI workers inject per-build auth tokens), the cache is invalidated.
73+
// This test verifies that changing ~/.gitconfig between runs does not
74+
// invalidate the configuration cache.
75+
Path gitconfig = Path.of(System.getProperty("user.home"), ".gitconfig");
76+
boolean existed = Files.exists(gitconfig);
77+
String originalContent = existed ? Files.readString(gitconfig) : null;
78+
try {
79+
Files.writeString(gitconfig, "[user]\n\tname = test\n");
80+
81+
setFile("build.gradle").toLines(
82+
"plugins {",
83+
" id 'com.diffplug.spotless'",
84+
"}",
85+
"repositories { mavenCentral() }",
86+
"apply plugin: 'java'",
87+
"spotless {",
88+
" java {",
89+
" googleJavaFormat()",
90+
" }",
91+
"}");
92+
setFile("src/main/java/test.java").toResource("java/googlejavaformat/JavaCodeUnformatted.test");
93+
94+
// first run stores the configuration cache
95+
gradleRunner().withArguments("help").build();
96+
97+
// change ~/.gitconfig content between runs
98+
Files.writeString(gitconfig, "[user]\n\tname = test\n[http]\n\textraheader = changed\n");
99+
100+
// second run must reuse the configuration cache despite the change
101+
String output = gradleRunner().withArguments("help").build().getOutput();
102+
Assertions.assertThat(output).contains("Reusing configuration cache.");
103+
} finally {
104+
// restore original ~/.gitconfig
105+
if (originalContent != null) {
106+
Files.writeString(gitconfig, originalContent);
107+
} else if (Files.exists(gitconfig)) {
108+
Files.delete(gitconfig);
109+
}
110+
}
111+
}
112+
63113
@Test
64114
public void multipleRuns() throws IOException {
65115
setFile("build.gradle").toLines(

0 commit comments

Comments
 (0)