Skip to content

Commit 4e54fc2

Browse files
committed
Update the CONTRIBUTING.md for our new roundtrip serializable world.
1 parent ab1452d commit 4e54fc2

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

CONTRIBUTING.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,31 @@ Here's a checklist for creating a new step for Spotless:
9595

9696
- [ ] Class name ends in Step, `SomeNewStep`.
9797
- [ ] Class has a public static method named `create` that returns a `FormatterStep`.
98-
- [ ] Has a test class named `SomeNewStepTest`.
98+
- [ ] Has a test class named `SomeNewStepTest` that uses `StepHarness` or `StepHarnessWithFile` to test the step.
99+
- [ ] Start with `StepHarness.forStep(myStep).supportsRoundTrip(false)`, and then add round trip support as decribed in the next section.
99100
- [ ] Test class has test methods to verify behavior.
100101
- [ ] Test class has a test method `equality()` which tests equality using `StepEqualityTester` (see existing methods for examples).
101102

103+
### Serialization roundtrip
104+
105+
In order to support Gradle's configuration cache, all `FormatterStep` must be round-trip serializable. This is a bit tricky because step equality is based on the serialied form of the state, and `transient` is used to take absolute paths out of the equality check. To make this work, roundtrip compatible steps actually have *two* states
106+
107+
- `RoundtripState` which must be roundtrip serializable but has no equality constraints
108+
- `FileSignature.Promised` for settings files and `JarState.Promised` for the classpath
109+
- `EqualityState` which will never be reserialized and its serialized form is used for equality / hashCode checks
110+
- `FileSignature` for settings files and `JarState` for the classpath
111+
112+
```java
113+
FormatterStep create(String name,
114+
RoundtripState roundTrip,
115+
SerializedFunction<RoundtripState, EqualityState> equalityFunc,
116+
SerializedFunction<EqualityState, FormatterFunc> formatterFunc)
117+
FormatterStep createLazy(String name,
118+
Supplier<RoundtripState> roundTrip,
119+
SerializedFunction<RoundtripState, EqualityState> equalityFunc,
120+
SerializedFunction<EqualityState, FormatterFunc> formatterFunc)
121+
```
122+
102123
### Third-party dependencies via reflection or compile-only source sets
103124

104125
Most formatters are going to use some kind of third-party jar. Spotless integrates with many formatters, some of which have incompatible transitive dependencies. To address this, we resolve third-party dependencies using [`JarState`](https://github.com/diffplug/spotless/blob/b26f0972b185995d7c6a7aefa726c146d24d9a82/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java#L118). To call methods on the classes in that `JarState`, you can either use reflection or a compile-only source set. See [#524](https://github.com/diffplug/spotless/issues/524) for examples of both approaches.

0 commit comments

Comments
 (0)