Skip to content

Commit

Permalink
Fix bugs in Gradle integration (#684)
Browse files Browse the repository at this point in the history
* Handle error when retrieving source set

* Don't add semanticdb plugin twice

javac seems to consider that an error, and it
can happen if there are multiple java compilation tasks
  • Loading branch information
keynmol authored Mar 14, 2024
1 parent e4c4ffb commit b866188
Showing 1 changed file with 92 additions and 50 deletions.
142 changes: 92 additions & 50 deletions semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.scala.ScalaCompile

class SemanticdbGradlePlugin extends Plugin[Project] {
import Logging._

override def apply(project: Project): Unit = {
val gradle = new GradleVersion(project.getGradle().getGradleVersion())
project.afterEvaluate { project =>
Expand All @@ -41,7 +43,7 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
.get("javacPluginJar")
.map(_.asInstanceOf[String])

val javacDep = javacPluginJar
val javacPluginDep = javacPluginJar
.map[Object](jar => project.files(jar))
// we fallback to javac plugin published to maven if there is no jar specified
// the JAR would usually be provided by auto-indexer
Expand Down Expand Up @@ -75,20 +77,24 @@ class SemanticdbGradlePlugin extends Plugin[Project] {

val compilerPluginAdded =
try {
project.getDependencies().add("compileOnly", javacDep)
if (hasAnnotationPath)
project.getDependencies().add("annotationProcessor", javacDep)
project.getDependencies().add("testCompileOnly", javacDep)
project.getDependencies().add("compileOnly", javacPluginDep)

if (hasAnnotationPath) {
project
.getDependencies()
.add("annotationProcessor", javacPluginDep)
}

project.getDependencies().add("testCompileOnly", javacPluginDep)

true
} catch {
case exc: Exception =>
// If the `compileOnly` configuration has already been evaluated
// by the build, we need to fallback on agent injected into javac
System
.err
.println(
s"Failed to add compiler plugin to javac, will go through the agent route: ${exc.getMessage()}"
)
warn(
s"Failed to add compiler plugin to javac, will go through the agent route: ${exc.getMessage()}"
)
false
}

Expand Down Expand Up @@ -155,10 +161,12 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
task.getOptions().setIncremental(false)

if (compilerPluginAdded) {
task
.getOptions()
.getCompilerArgs()
.addAll(
val args = task.getOptions().getCompilerArgs()

// It's important we don't add the plugin configuration more than
// once, as javac considers that an error
if (!args.asScala.exists(_.startsWith("-Xplugin:semanticdb"))) {
args.addAll(
List(
// We add this to ensure that the sources are _always_
// recompiled, so that Gradle doesn't cache any state
Expand All @@ -168,6 +176,7 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
s"-Xplugin:semanticdb -targetroot:$targetRoot -sourceroot:$sourceRoot -randomtimestamp=${System.nanoTime()}"
).asJava
)
}
}

/**
Expand Down Expand Up @@ -399,6 +408,8 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
}

class WriteDependencies extends DefaultTask {
import Logging._

@TaskAction
def printResolvedDependencies(): Unit = {

Expand All @@ -411,11 +422,20 @@ class WriteDependencies extends DefaultTask {

val deps = List.newBuilder[String]
val project = getProject()
val projectName = project.getName()

// List the project itself as a dependency so that we can assign project name/version to symbols that are defined in this project.
// The code below is roughly equivalent to the following with Groovy:
// deps += "$publication.groupId $publication.artifactId $publication.version $sourceSets.main.output.classesDirectory"

val crossRepoBanner =
"""
|This will not prevent a SCIP index from being created, but the symbols
|extracted from this project won't be available for cross-repository navigation,
|as this project doesn't define any Maven coordinates by which it can be referred back to.
|See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation
"""

Try(
project
.getExtensions()
Expand All @@ -425,45 +445,58 @@ class WriteDependencies extends DefaultTask {
.asScala
) match {
case Failure(exception) =>
System
.err
.println(
s"""
|Failed to extract Maven publication from the project `${project
.getName()}`.
|This will not prevent a SCIP index from being created, but the symbols
|extracted from this project won't be available for cross-repository navigation,
|as this project doesn't define any Maven coordinates by which it can be referred back to.
|See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation
|Here's the raw error message:
| "${exception.getMessage()}"
|Continuing without cross-repository support.
""".stripMargin.trim()
)
warn(s"""
|Failed to extract Maven publication from the project `$projectName`.
$crossRepoBanner
|Here's the raw error message:
| "${exception.getMessage()}"
|Continuing without cross-repository support.
""".stripMargin.trim())

case Success(publications) =>
publications.foreach { publication =>
project
.getExtensions()
.getByType(classOf[SourceSetContainer])
.getByName("main")
.getOutput()
.getClassesDirs()
.getFiles()
.asScala
.toList
.map(_.getAbsolutePath())
.sorted
.take(1)
.foreach { classesDirectory =>
deps +=
List(
publication.getGroupId(),
publication.getArtifactId(),
publication.getVersion(),
classesDirectory
).mkString("\t")
}
Try(
project
.getExtensions()
.getByType(classOf[SourceSetContainer])
.getByName("main")
) match {
case Failure(exception) =>
val publicationName = List(
publication.getGroupId(),
publication.getArtifactId(),
publication.getVersion()
).mkString(":")

warn(s"""
|Failed to extract `main` source set from publication `${publicationName}` in project `$projectName``.
$crossRepoBanner
|Here's the raw error message:
| "${exception.getMessage()}"
|Continuing without cross-repository support.
""".stripMargin.trim())

case Success(value) =>
value
.getOutput()
.getClassesDirs()
.getFiles()
.asScala
.toList
.map(_.getAbsolutePath())
.sorted
.take(1)
.foreach { classesDirectory =>
deps +=
List(
publication.getGroupId(),
publication.getArtifactId(),
publication.getVersion(),
classesDirectory
).mkString("\t")
}

}
}
}

Expand Down Expand Up @@ -511,3 +544,12 @@ class WriteDependencies extends DefaultTask {
}
}
}

private object Logging {
def info(msg: Any*) =
System.err.println(s"[INFO] [scip-java.gradle] ${msg.mkString(" ")}")

def warn(msg: Any*) =
System.err.println(s"[WARNING] [scip-java.gradle] ${msg.mkString(" ")}")

}

0 comments on commit b866188

Please sign in to comment.