-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Execute the configuration actions lazily #618
Conversation
…utes lazily only if the task is configured.
@nedtwigg, I think your change makes sense to defer the possibly expensive configuration of each
Very long term, we'd like to deprecate and remove. In the meantime, it's just considered poor form. In this case it's usage probably won't bite, but when layering multiple plugins the multiple The use of One nice thing is that you can declare We are currently working on better documentation on what we consider to be idiomatic Gradle usage with Gradle 6+. Following these patterns will ensure that plugins/builds work better with the upcoming configuration-cache as well as providing a more concise, consistent user experience. |
I look forward to the docs! Fwiw, I'm a big fan of all the cool properties that you get from lazily computing immutable values, ala LazyForwardingEquality, so I think I should like the Property/Provider stuff. But so far I don't, because they seem difficult to coordinate. What I mean by coordinate, is that I usually don't need a lazily-computed immutable integer, or lazily computed immutable String - I need a lazily computed immutable state, which usually has multiple components, and the inputs which eventually determine that state often have a different shape than the state they determine. For example, if a user says Also, when determining that input, mutability is quite handy. It's nice to apply a plugin which sets a bunch of defaults, and then be able to override values here and there on a per-project basis. Definitely there can be some footguns there, but the beauty of the groovy scripts, imo, is how easy it is for naive scripting logic to do what people expect. So to me, the idea of "mutate inputs" -> afterEvaluate -> "now everything is frozen, compute immutable states out of the inputs" is easy to use and easy to reason about. The only problem is that composing You have thought about this much more than me, I'm sure, and I look forward to the future releases, but my hope is that Gradle continues to have as few Gradle-specific concepts as possible. So far it has mostly been "normal script operating on normal values builds a task graph". If it becomes "normal script operating on special gradle-y values builds a task graph", I worry a bit about how much "magic" script and plugin authors will have to master. But you guys are batting like 99%, so I'm on board.
|
Part of #601 |
The only substantive change is that instead of this in the legacy
SpotlessExtension
...spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtensionBase.java
Lines 203 to 206 in 1e2801d
...we add a field to
FormatExtension
, and populate it in each call toSpotlessExtension::format(name, clazz, action)
spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/FormatExtension.java
Line 60 in 1e2801d
spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtensionModern.java
Lines 52 to 54 in 1e2801d
Instead of executing the closures when they are declared, we store them, and only execute them when the task is configured:
spotless/plugin-gradle/src/main/java/com/diffplug/gradle/spotless/SpotlessExtensionModern.java
Lines 70 to 79 in 1e2801d
In my head, I thought that we would be able to remove the
afterEvaluate
block, but now I see that it was a mirage. If someone eagerly creates the task, and then callsjava { blah }
, it's important for thatblah
to have effect, but it wouldn't if you don't do theafterEvaluate
.It seems to me that this is as lazy as it could possibly be - we don't describe any of the properties of a task, or even execute the code that describes those those properties, until/unless that task is being configured. It also seems to me like it's quite difficult to avoid the
afterEvaluate
, which I guess is the point of theProvider<>
stuff. We could changeFormatExtension
so that it applied itself directly against theSpotlessTask
, rather than storing its own field forencoding
, etc. The only hard part against that is cases where a user setsUTF-8
at the level of the Spotless block, but has some legacy subproject where encoding isCP-1252
, cases like that.Is
afterEvaluate
in any long-term trouble? Whaddya think @bigdaz?