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
Add toolchains support to Gradle plugin #5269
Conversation
I'm not sure what this PR will provide to our users. Let me explain what I think it will provide and you tell me if I'm wrong. If we run detekt-cli defining And then, if we run detekt using the plugin the And your last sentence means that the |
There's special handling in the Kotlin compiler that takes care of it. detekt calls this to make sure it's configured: https://github.com/JetBrains/kotlin/blob/v1.7.10/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/config/JvmContentRoots.kt#L91-L111 The problem is, if JDK home isn't provided, the compiler will use the JRE it's currently running in to populate the JDK class roots. When detekt is run from Gradle, that will be the JDK Gradle is running under. If the Kotlin compilation is using a different JDK version set through a toolchain, there's a mismatch between detekt's JDK home and the Kotlin compilation JDK home, which affects detekt's ability to analyse the project correctly.
Are you asking if the value will be set by default? Yes, it will be - if there's a toolchain setup. If not, detekt will run using the JDK that Gradle is running under.
For an example, you can run Gradle with Java 8, add java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
} Then call the forbidden method somewhere in the project.
The forbidden method call is not picked up as an error. When using this PR, and the toolchain's JDK path passed to detekt, it works correctly:
Gradle is still running Java 8, so detekt itself also runs on Java 8 but now performs analysis with JDK 11 passed as jdkHome, so the issue is flagged as expected. |
Thanks for the explanation. All clear now :) |
This aligns to the behaviour of toolchains in the Kotlin Gradle Plugin. KGP will set jvmTarget and jdkHome based on the enabled toolchain, assuming it hasn't been set elsewhere in the build script.
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.
Code looks great to me 👍
@Parameter( | ||
names = ["--jdk-home"], | ||
description = "EXPERIMENTAL: Use a custom JDK home directory to include into the classpath", | ||
converter = PathConverter::class | ||
) |
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 needs an update to the CLI page on the website as well
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.
On this page https://detekt.dev/docs/gettingstarted/cli? Isn't that auto generated now? Or have I misunderstood...
That said, it needs to be added to the Grade docs since they're manually maintained, will do that before merging.
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.
Isn't that auto generated now?
Yes you're right 👍 I forgot we autogenerate that 🚀
This will need some tweaking to make sure it works properly with incremental builds and build cache.
This toolchain support does what the Kotlin Gradle Plugin does, but for detekt. If a toolchain is configured for the project (either using
java
orkotlin
) that will then set bothjdkTarget
andjdkHome
defaults on anyDetekt
orDetektCreateBaseline
tasks.See here for more on the KGP design goals.
Notably this means that detekt itself will still run on the JDK that Gradle runs on - if Gradle is running on Java 8, then so will detekt. This means that despite what I said, I expect this PR will have no effect on #3396.
Closes #4120