Replace Gradle init scripts with a proper Gradle plugin#565
Conversation
Our approach can fail if the build modifies the compile classpath as part of the build definition: > Cannot change dependencies of dependency configuration ':compileOnly' after it has been included in dependency resolution. In this case we go the agent route
| val javacDep = javacPluginJar | ||
| .map[Object](jar => project.files(jar)) | ||
| .getOrElse(s"com.sourcegraph:semanticdb-javac:${javacPluginVersion}") |
There was a problem hiding this comment.
We fallback to javac plugin published to maven if there is no jar specified
There was a problem hiding this comment.
Could have been a decent inline comment instead of PR comment
| System | ||
| .err | ||
| .println( | ||
| s"Failed to add compiler plugin to javac, will go through the agent route: ${exc.getMessage()}" |
There was a problem hiding this comment.
At the time when the plugin is loaded, compileOnly configuration might already be resolved, if triggered by something in the build: https://sourcegraph.com/github.com/awslabs/smithy-language-server/-/blob/build.gradle?L212
| println( | ||
| task | ||
| .asInstanceOf[{ | ||
| def getToolChain(): Any | ||
| } | ||
| ] | ||
| .getToolChain() | ||
| ) |
There was a problem hiding this comment.
TODO: see what we can do about this.
There was a problem hiding this comment.
Given Gradle's compatibility matrix (only 7.3+ supports Java 17) this branch doesn't need anything.
I have a spearate PR coming that will clean this up among other things
| val host = System | ||
| .getProperty("java.version") | ||
| .split("\\.") | ||
| .headOption | ||
| .map(_.toInt) |
There was a problem hiding this comment.
only at play where there is no toolchain provided
olafurpg
left a comment
There was a problem hiding this comment.
This looks really really good 👏🏻 Nice work @keynmol
I love the plugin approach, it's a much cleaner solution than the unmaintainable init script. I can imagine us doing a lot more with Gradle using this plugin approach.
No blocking comments, just two nitpick suggestions to add type annotations. I'm fine with deleting the init script and moving into this bright new future 🌞
| s""" | ||
| | initscript { | ||
| | dependencies{ | ||
| | classpath(files("${gradlePluginPath}")) |
| | project.extra["javacPluginJar"] = "$pluginpath" | ||
| | project.extra["dependenciesOut"] = "$dependenciesPath" | ||
| | project.extra["javacAgentPath"] = "$agentpath" | ||
| | apply<SemanticdbGradlePlugin>() |
| val javacDep = javacPluginJar | ||
| .map[Object](jar => project.files(jar)) | ||
| .getOrElse(s"com.sourcegraph:semanticdb-javac:${javacPluginVersion}") |
There was a problem hiding this comment.
Could have been a decent inline comment instead of PR comment
| s"-Xplugin:$semanticdbScalac", | ||
| s"-P:semanticdb:sourceroot:$sourceRoot", | ||
| s"-P:semanticdb:targetroot:$targetRoot", | ||
| s"-P:semanticdb:exclude:(src/play/twirl|src/play/routes|src/${System.currentTimeMillis()})", // Ignore autogenerated Playframework files |
| // | ||
| // Instead, we commit the sins of reflection for our limited | ||
| // needs. | ||
| val compilerArgs = task |
scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala
Outdated
Show resolved
Hide resolved
semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala
Outdated
Show resolved
Hide resolved
semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala
Outdated
Show resolved
Hide resolved
Because compilation is much more likely to fail halfway through
This PR replicates the functionality of the init script injection with a proper Gradle plugin + a much smaller init script.
Benefits:
Additionally:
Old TODO list
TODO: - [x] Restore kotlin multi-platform support - [x] Add dependency dump task - [x] Modify tests to run on various gradle versions - [x] Disable publishing of the gradle plugin for _now_ Currently it's written in Scala as it allows for much faster prototyping. With it not being published but rather injected via assembly, it doesn't matter what language it's written in.Once we have this merged and tested in the wild, we can start the process of rewriting the plugin in Java (for maximum compatibility) and publish it - after that, the docs can be modified and all manual steps removed.
Old description from where I was just a young pup helplessly thrashing about
TODO: - [x] Kotlin support - [x] Rewrite init script > One main limitation of init scripts is that they cannot access classes in the buildSrc project (see [Using buildSrc to extract imperative logic](https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources) for details of this feature). Current plan:
GradleBuildToolSee https://github.com/scalacenter/gradle-bloop/blob/main/build.sbt as an example of publishing a Gradle plugin from SBT
Test plan