-
Notifications
You must be signed in to change notification settings - Fork 459
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
Task configuration avoidance (WIP) (#269) #277
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit (e6818c5) looks great. I like the API gradle has provided.
I can't find a way locally of consistently reproducing the Travis CI error, so I'll try pushing a minor polishing change and see what happens. |
@nedtwigg It seems that Travis CI complains with the following message:
But it's unclear to me why
Do you have any thoughts regarding this? |
At least in spotless/plugin-gradle/build.gradle Lines 29 to 42 in 2ac756d
So that's why it's attempting to load SelfTestCheck. As for why it can't be found, maybe gradle 4.9 changes what's on |
@nedtwigg Sorry for the kind of slow response! When I check the output produced by the debug statements I introduced in 18b70f0 (see https://travis-ci.org/diffplug/spotless/builds/412790310 for the Travis log), it apparently doesn't differ much to when I apply the same debug statements to The only difference I can see is that the Travis log has some artifacts whose names contain the term Thus I wonder if you have any other thoughts which may allow me to get unstuck and move forward with this? |
Sorry, I should have clarified that these debug statements specifically print the names of the files contained by |
This doesn't make sense to me. If you want to reproduce on your local machine, then it should match the CI server in every way possible. I think I'm misunderstanding something... |
Oops, sorry, I wasn't clear! And also I realise that I'm a bit confused in general, so I'll attempt to explain what I've understood so far. (Warning: heavy wall-of-text below.) When working from the Where I expected things to differ in a helpful way was if, rather than running You should find that if you clone my fork of Spotless (https://github.com/jbduncan/spotless), and compare the output of the debug statements in
However, this isn't helpful for me, because it doesn't explain to me why I hope this clears things up. |
Sorry, I meant to say: it doesn't explain to me why Gradle can find |
The travis error in the latest PR is:
I don't know why that's happening, but it doesn't jive with the earlier issues. I would revert that commit and get back to the original error. The heuristic I use when I'm stuck on something like this is to reduce the variables. Right now we have two: a new version of gradle, and code changes. Here's an experiment:
If any of those break, then we've narrowed down which version of gradle caused the problem, and have a better chance of making progress. If all of those work, then we've narrowed it down to your code changes. I can't imagine how they could change the classpath, so I'm fairly confident that one of the gradle upgrades caused the problem, and it will be easier to fix if we know that the only thing that changed was the gradle version. |
Agreed!
Yep, I'll do just that before retiring for tonight. :)
Sounds very sensible to me! Thanks again for your help; I'll get back to you with the result of this experiment when I find the time to tackle this PR again. :) |
So, this new API is only available in Gradle 4.9+ If we are, this change should prompt a major version bump for the plugin at least. |
Here's the summary:
If the only benefit is delayed attachment to check, then we might be able to pull off something with reflection to allow it to work on pre-4.9 and post-4.9 builds. If we see substantial benefit, then we'll evaluate other options. It all depends on what the profiler tells us. |
@nedtwigg It seems that there's another variable at play here. When I freshly clone https://github.com/jbduncan/spotless and checkout
FAILURE: Build failed with an exception.
* Where:
Build file 'C:\Users\Jonathan\dev\Java\IntelliJ\spotless\ide\build.gradle' line: 11
* What went wrong:
A problem occurred evaluating project ':ide'.
> A problem occurred configuring project ':plugin-gradle'.
> Cannot configure the 'publishing' extension after it has been accessed.
My next port of call is to try running the experiment off of an Ubuntu VM. WDYT about the results so far? |
I'm confused :) As of now, your PR is passing CI, which is great! By removing the debug statements, resolving the configuration is delayed. If the PR as-it-is is passing CI on Travis and on your box, then it seems to me that we don't have a problem. |
But sadly, that apparently isn't the case. On Travis, things are fine, but on my Windows box, things point to the supernatural (or so I like to think 😉). Let's see if I can get any better results by running the experiment off of my Ubuntu VM. Stay tuned. |
I finally found the time to tackle this PR again. Here are the results of running
|
🤦♂️ I think you're right @thc202! I'll reopen this for now. I hope to have the time to benchmark things again over the next few days. And whilst I'm at it, I'll see if I can benchmark things directly on my Windows setup rather than in a VM; that may reduce the skew of the timings a bit. |
Alright. New benchmarks, which show some promise!
|
@nedtwigg Combining my new benchmarks with @litpho's report over at #269 (comment), I'm now inclined to attempt to get Spotless to use Task Configuration Avoidance in a Gradle-2.14.1-compatible way. WDYT? |
It seems that it would be a small amount of reflection involved to make this work, and that it would be a noticeable improvement for users of cutting-edge gradle. I'm all for it! |
@jbduncan Don't hate me for this suggestion, but if you wrote this reflection as a third party library to support the future API and the old API side by side, I'd totally use it in my own plugins. I think you'd find that there are other API consumers that would also love it as well. You'd probably get such a library featured by the Gradle team's release notes or in the newsletter. |
@JLLeitschuh Nice idea! Although, I don't know if or when I'll have the confidence and time to do so, so please don't hold your breath. :) And probably more importantly, I'll need to think about how I'll even approach implementing it, since I'm still rather inexperienced with reflection. @nedtwigg @JLLeitschuh If either of you have any thoughts that may allow me to get started faster, I'd love to hear them. |
My easiest idea is to do it this way (doesn't involve much reflection)
interface SpotlessTaskSetup {
public static SpotlessTaskSetup detectAppropriateImplementation() {
try {
Class.forName("org.gradle.api.tasks.TaskProvider")
return new com.diffplug.gradle.spotless.SpotlessTaskSetupConfigAvoidance();
} catch (ClassNotFoundException e) {
return new com.diffplug.gradle.spotless.SpotlessTaskSetupLegacy();
}
}
void someMethod();
void someOtherMethod();
} A couple key things for this to work:
A couple key things to make this easy:
|
@nedtwigg Wow, thank you very much for such a detailed response (and sorry for only responding just now)! Since I have time again this weekend, I'll have a go soon at implementing your suggestion and see where that leads me. Stay tuned! |
…whilst keeping compatibility with Gradle 2.x
So work has been keeping me busy over the last two weeks, but I've finally found the time to push my most recent changes! I'm now stuck with understanding how to test my changes, so @nedtwigg @JLLeitschuh if either of you have any thoughts as to how I could do so, I'd love to hear them. :) |
Specifically, I need help understanding how to test my changes on both Gradle 2.14.1 and Gradle 4.9. |
I've found GradleTest to a useful tool for testing multiple versions of Gradle to verify Gradle plugins. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fantastic! Very cleanly done. Looks to me that it's just a few changes away from being merged and released.
lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java
Outdated
Show resolved
Hide resolved
plugin-gradle/src/main/java/com/diffplug/gradle/spotless/Constants.java
Outdated
Show resolved
Hide resolved
.withGradleVersion("2.14.1") | ||
// Gradle 4.9 required for Task Configuration Avoidance | ||
// (https://github.com/diffplug/spotless/issues/269) | ||
.withGradleVersion("4.9") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would actually keep this as withGradleVersion("2.14.1")
. That's how we make sure that our legacy support doesn't break.
Then, I would make a new GradleTaskConfigurationAvoidanceTest
, which uses gradle 4.9, and asserts that tasks are actually created lazily. I don't see a need to introduce the GradleTest plugin, but maybe @eriwen knows about value that I'm missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might be, but our gradle tests are already pretty darn slow. None of our steps rely on Gradle, so it's really just the SpotlessExtension
logic that we need to test. We compile against 4.9
, so there's no risk that we'll use API that doesn't exist in 4.9. But we might accidentally use API that was added after 2.14
, and that's what we'll catch by always running against 2.14
- problems with 4.9
will be caught at compile-time.
For gradle == 4.9, it's a good idea to test and make sure that the task avoidance is doing what we intend it to do. That will have the added bonus of being an integration test for the 4.9+
logic in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That all sounds good to me. I will revert this change and create GradleTaskConfigurationAvoidanceTest
as requested. :)
Hey @nedtwigg, thanks for following up on this! Sadly I won't be ready to meet the Monday release, as my new job has been taking energy away from me, and I'm not sure when I'll be able to work on this PR again, so please go ahead. :) |
@nedtwigg I've finally managed to find some time again to tackle this PR, so I'll respond to your earlier comments as soon as I can. @eriwen Thank you very much for the suggestion to use Gradle-Test! However I think @nedtwigg's suggestion makes more sense since it would be more achievable given the amount of free time I have nowadays. :) |
Hmm. The Gradle Runner-dependent tests seem tightly coupled to expecting that the Gradle version run is >= 4.9. When I revert back to 2.14.1, the tests go a bit berserk and go red in many places. I know that at least some of those tests go red because I changed them so that they'd pass when run against Gradle 4.9, so they don't pass any longer against 2.14.1. But I don't think all the tests are going red for that reason (and also my brain's a bit tired), so I'm stumped as to how to fix all the tests... I probably won't be able to tackle any more of this tonight, but @nedtwigg if you have any thoughts that might allow me to move forward when I next tackle this, then I'd love to hear them. :) |
@jbduncan Feel free to come bother me over in the Gradle Community Slack chat if you have any issues. |
Cheers @JLLeitschuh! Wow, okay. It's been a long time since I last looked at this PR. I'm sorry to say that I no longer have the time and interest to tackle it any further, but I am more than happy to help out anyone who's interested to take on it further! So, to summarise: the tests fail because they assume that they're running against Gradle 4.9, whereas they really need to be changed so that they can run against Gradle 2.14.1. |
To anyone who wants to work on this, feel free to copy the contents of this PR into your own branch, and if you need pointers, feel free to tag me with "@jbduncan", and I'll point you in the right direction. :) |
This is a WIP PR to show how task configuration avoidance may look like in the Spotless Gradle plugin (see issue #269).
No profiling against Spotless itself or against an external project has been done yet. Those are the next things which need to be done.
Feedback is more than welcome!
Resolves #269.