openrewrite / rewrite-gradle-plugin

OpenRewrite's Gradle plugin.
Apache License 2.0
60 stars 37 forks source link

Add auto JDK download #272

Closed koppor closed 6 months ago

koppor commented 7 months ago

I have NixOS and no JDK17 installed. Therefore, I get

org.gradle.api.internal.provider.AbstractProperty$PropertyQueryException: Failed to calculate the value of task ':plugin:compileJava' property 'javaCompiler'.
...
Caused by: org.gradle.jvm.toolchain.internal.NoToolchainAvailableException: No matching toolchains found for requested specification: {languageVersion=17, vendor=any, implementation=vendor-specific} for LINUX on x86_64.
...
Caused by: org.gradle.jvm.toolchain.internal.ToolchainDownloadFailedException: No locally installed toolchains match and toolchain download repositories have not been configured.
    at org.gradle.jvm.toolchain.internal.install.DefaultJavaToolchainProvisioningService.tryInstall(DefaultJavaToolchainProvisioningService.java:110)

This can easily be solved with an auto JDK download:

https://github.com/gradle/foojay-toolchains#foojay-toolchains-plugin


I searched the issue list and did not find "foojay". Thus, I do not know if there is an ADR on that.

Hope, you like it!

timtebeek commented 7 months ago

hi @koppor ; so if a matching JDK can not be found one will be installed? That's perhaps somewhat unexpected, but could wrok. And this applies only to folks checking out openrewrite/rewrite-gradle-plugin locally, and not to users of the plugin?

shanman190 commented 7 months ago

Yeah, the Gradle tool chains feature tries to disconnect fully the client and tasks Java versions. The internals essentially are, if you can find a compatible Java runtime locally, then use it. Otherwise, if there are repository locations available download it to ~/.gradle/jdks.

To your other question, yes, this would only effect contributors building and contributing to the Gradle plugin. It would not effect users that are utilizing the Gradle plugin in their builds.

timtebeek commented 7 months ago

Thanks, that helps provide some context on what to expect. I noticed this plugin needs to go in settings.gradle[.kts]; does that rule out applying it broadly through the conventions we maintain in https://github.com/openrewrite/rewrite-build-gradle-plugin ? Ideally I'd think we don't have one project that differs from the others, and I do see the benefit for new contributors. Just wondering if this would then need to be applied to all projects with a per-repository code change. 🤔

Sorry for throwing up questions; the suggestion to add the plugin is appreciated, just want to make sure we consciously choose to adopt it, and if we do at the right level.

shanman190 commented 7 months ago

Absolutely true. You can have create settings plugins in these binary jars by instead of using implements Plugin<Project> having implements Plugin<Settings>. Then you apply it just like you would anything else.

koppor commented 7 months ago

@shanman190 It's the first time I hear about "settings plugins". Can you elaborate? Do you have experience with "global configurations"? -- Context: At palantir-java-format, it is not possible to update gradle, because of "Adding a Configuration as a dependency is no longer allowed as of Gradle 8.0.". I was a bit in that code, but I could come up with a solution NOT requiring each plugin to contain a copy of the configuration. (The issue is https://github.com/palantir/palantir-java-format/issues/977)

shanman190 commented 7 months ago

So I see what the issue is over on that other GitHub issue and it's appears to be a quick and easy fix, so I'll file a PR here after a little bit.

To elaborate on the settings plugin, it's just like a project plugin in effect, but the context is centered around providing configurations in the settings.gradle(.kts) file. A prime example is the Gradle Enterprise/Develocity plugin which as of Gradle 6+ is required to be applied within the settings.gradle(.kts) file. Some other high value use cases are things like configuring the Gradle Enterprise/Develocity plugin in a conventions manner for enterprise organizations to point to their internal Gradle Enterprise/Develocity instance. In this type of plugin, you have access to the entire org.gradle.api.initialization.Settings, so anything that you can do to it is possible.

In the Gradle docs it is called out, but it's kinda a footnote.

One thing to note is that a new instance of a plugin is created for each project it is applied to. Also note that the Plugin class is a generic type. This example has it receiving the Project type as a type parameter. A plugin can instead receive a parameter of type Settings, in which case the plugin can be applied in a settings script, or a parameter of type Gradle, in which case the plugin can be applied in an initialization script.

https://docs.gradle.org/current/userguide/custom_plugins.html

koppor commented 6 months ago

@shanman190 May I ask whether you could find time to support the other project (https://github.com/openrewrite/rewrite-gradle-plugin/pull/272#issuecomment-1919090177). 😅🤩

koppor commented 6 months ago

After reading the comment https://github.com/openrewrite/rewrite/issues/4018#issuecomment-1950276086, the "feature" should be included somewhere else. Thus, closing to reduce the number of opened PRs.

shanman190 commented 6 months ago

@koppor, I actually already submitted that PR and it was merged. :)

https://github.com/palantir/palantir-java-format/pull/997

koppor commented 6 months ago

@shanman190 OMG, I did not see. Thank you so much for bringing that project forward and clarifying the next steps!