Skip to content

Commit fc9747b

Browse files
committed
Sign the formatter inside the plugin by its list, not its files
The Spotless step's signature, which the up-to-date check and the build cache key compare and which the configuration cache entry stores, now goes by the hash of jars.txt for the formatter inside the plugin. jars.txt holds every jar's name and sha256, so the signature changes with any of them as before, and still holds no path; but nothing on disk is read to make it. Storing a configuration cache entry no longer extracts the jars or checks for them, and a build after the extracted directory was deleted reuses the entry. The jars are extracted when the step makes its formatter, as the task runs. A formatter declared in palantirJavaFormat is still signed by its jars' names, sizes and contents.
1 parent 7a0a5e6 commit fc9747b

1 file changed

Lines changed: 40 additions & 13 deletions

File tree

‎gradle-open-java-format/src/main/java/com/palantir/javaformat/gradle/spotless/PalantirJavaFormatStep.java‎

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,17 @@ public static FormatterStep create(Configuration formatterClasspath, File gradle
4545
ensureImplementationNotDirectlyLoadable();
4646
// Spotless keeps a step in two forms, and neither can hold the configuration or a loaded formatter, which do
4747
// not serialize. The configuration cache stores the declared jars, resolved when the entry is written at the
48-
// earliest. The up-to-date check compares the signature of the jars the step formats with, so that another
49-
// formatter makes the task run again; Spotless takes it when the task runs. The formatter is loaded from the
50-
// jars on first use.
48+
// earliest. The up-to-date check compares the step's signature, so that another formatter makes the task run
49+
// again; Spotless takes it when the task runs, and stores it in the configuration cache entry too. The
50+
// formatter is loaded from the jars on first use, after the plugin's own are extracted if need be.
5151
return FormatterStep.createLazy(
5252
NAME,
5353
() -> new Jars(List.copyOf(formatterClasspath.getFiles()), gradleUserHome),
5454
Jars::sign,
5555
PalantirJavaFormatStep::createFormat);
5656
}
5757

58-
/**
59-
* The jars as the configuration cache stores them: those the build declared, or none, for the formatter inside the
60-
* plugin. That one's jars are found, or extracted again, when the step is signed: the directory they were extracted
61-
* into may be gone by the time a build reuses the entry.
62-
*/
58+
/** The jars as the configuration cache stores them: those the build declared, or none, for the plugin's own. */
6359
static final class Jars implements Serializable {
6460
private static final long serialVersionUID = 1L;
6561

@@ -71,14 +67,45 @@ static final class Jars implements Serializable {
7167
this.gradleUserHome = gradleUserHome;
7268
}
7369

74-
/** By name, size and content, not path: the build cache key holds for another directory and machine. */
75-
FileSignature sign() throws IOException {
76-
return FileSignature.signAsList(BundledFormatter.jarsUnlessOverridden(override, gradleUserHome));
70+
Signature sign() throws IOException {
71+
return new Signature(
72+
override.isEmpty() ? BundledFormatter.hash() : "",
73+
FileSignature.signAsList(override),
74+
gradleUserHome);
75+
}
76+
}
77+
78+
/**
79+
* What the up-to-date check and the build cache key compare, never a path, so that the key holds for another
80+
* directory and machine. The jars a build declared go by name, size and content. The plugin's own go by the hash of
81+
* their list, which holds every jar's sha256: nothing on disk is read, so storing a configuration cache entry does
82+
* not depend on whether the jars were extracted, and a build after they were deleted still reuses the entry.
83+
*/
84+
static final class Signature implements Serializable {
85+
private static final long serialVersionUID = 1L;
86+
87+
// Spotless compares the signature in its serialized form, and reads nothing out of it.
88+
@SuppressWarnings("UnusedVariable")
89+
private final String bundled;
90+
91+
private final FileSignature override;
92+
93+
/** Where to extract the plugin's own jars. Spotless formats with a signature it made, never one it read back. */
94+
private final transient File gradleUserHome;
95+
96+
Signature(String bundled, FileSignature override, File gradleUserHome) {
97+
this.bundled = bundled;
98+
this.override = override;
99+
this.gradleUserHome = gradleUserHome;
100+
}
101+
102+
List<File> jars() {
103+
return BundledFormatter.jarsUnlessOverridden(override.files(), gradleUserHome);
77104
}
78105
}
79106

80-
private static FormatterFunc createFormat(FileSignature jars) {
81-
FormatterService formatter = FormatterServiceLoader.load(jars.files());
107+
private static FormatterFunc createFormat(Signature signature) {
108+
FormatterService formatter = FormatterServiceLoader.load(signature.jars());
82109
return formatter::formatSourceReflowStringsAndFixImports;
83110
}
84111

0 commit comments

Comments
 (0)