Skip to content

Commit b866188

Browse files
authored
Fix bugs in Gradle integration (#684)
* 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
1 parent e4c4ffb commit b866188

File tree

1 file changed

+92
-50
lines changed

1 file changed

+92
-50
lines changed

semanticdb-gradle-plugin/src/main/scala/SemanticdbGradlePlugin.scala

Lines changed: 92 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import org.gradle.api.tasks.compile.JavaCompile
2121
import org.gradle.api.tasks.scala.ScalaCompile
2222

2323
class SemanticdbGradlePlugin extends Plugin[Project] {
24+
import Logging._
25+
2426
override def apply(project: Project): Unit = {
2527
val gradle = new GradleVersion(project.getGradle().getGradleVersion())
2628
project.afterEvaluate { project =>
@@ -41,7 +43,7 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
4143
.get("javacPluginJar")
4244
.map(_.asInstanceOf[String])
4345

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

7678
val compilerPluginAdded =
7779
try {
78-
project.getDependencies().add("compileOnly", javacDep)
79-
if (hasAnnotationPath)
80-
project.getDependencies().add("annotationProcessor", javacDep)
81-
project.getDependencies().add("testCompileOnly", javacDep)
80+
project.getDependencies().add("compileOnly", javacPluginDep)
81+
82+
if (hasAnnotationPath) {
83+
project
84+
.getDependencies()
85+
.add("annotationProcessor", javacPluginDep)
86+
}
87+
88+
project.getDependencies().add("testCompileOnly", javacPluginDep)
89+
8290
true
8391
} catch {
8492
case exc: Exception =>
8593
// If the `compileOnly` configuration has already been evaluated
8694
// by the build, we need to fallback on agent injected into javac
87-
System
88-
.err
89-
.println(
90-
s"Failed to add compiler plugin to javac, will go through the agent route: ${exc.getMessage()}"
91-
)
95+
warn(
96+
s"Failed to add compiler plugin to javac, will go through the agent route: ${exc.getMessage()}"
97+
)
9298
false
9399
}
94100

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

157163
if (compilerPluginAdded) {
158-
task
159-
.getOptions()
160-
.getCompilerArgs()
161-
.addAll(
164+
val args = task.getOptions().getCompilerArgs()
165+
166+
// It's important we don't add the plugin configuration more than
167+
// once, as javac considers that an error
168+
if (!args.asScala.exists(_.startsWith("-Xplugin:semanticdb"))) {
169+
args.addAll(
162170
List(
163171
// We add this to ensure that the sources are _always_
164172
// recompiled, so that Gradle doesn't cache any state
@@ -168,6 +176,7 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
168176
s"-Xplugin:semanticdb -targetroot:$targetRoot -sourceroot:$sourceRoot -randomtimestamp=${System.nanoTime()}"
169177
).asJava
170178
)
179+
}
171180
}
172181

173182
/**
@@ -399,6 +408,8 @@ class SemanticdbGradlePlugin extends Plugin[Project] {
399408
}
400409

401410
class WriteDependencies extends DefaultTask {
411+
import Logging._
412+
402413
@TaskAction
403414
def printResolvedDependencies(): Unit = {
404415

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

412423
val deps = List.newBuilder[String]
413424
val project = getProject()
425+
val projectName = project.getName()
414426

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

431+
val crossRepoBanner =
432+
"""
433+
|This will not prevent a SCIP index from being created, but the symbols
434+
|extracted from this project won't be available for cross-repository navigation,
435+
|as this project doesn't define any Maven coordinates by which it can be referred back to.
436+
|See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation
437+
"""
438+
419439
Try(
420440
project
421441
.getExtensions()
@@ -425,45 +445,58 @@ class WriteDependencies extends DefaultTask {
425445
.asScala
426446
) match {
427447
case Failure(exception) =>
428-
System
429-
.err
430-
.println(
431-
s"""
432-
|Failed to extract Maven publication from the project `${project
433-
.getName()}`.
434-
|This will not prevent a SCIP index from being created, but the symbols
435-
|extracted from this project won't be available for cross-repository navigation,
436-
|as this project doesn't define any Maven coordinates by which it can be referred back to.
437-
|See here for more details: https://sourcegraph.github.io/scip-java/docs/manual-configuration.html#step-5-optional-enable-cross-repository-navigation
438-
|Here's the raw error message:
439-
| "${exception.getMessage()}"
440-
|Continuing without cross-repository support.
441-
""".stripMargin.trim()
442-
)
448+
warn(s"""
449+
|Failed to extract Maven publication from the project `$projectName`.
450+
$crossRepoBanner
451+
|Here's the raw error message:
452+
| "${exception.getMessage()}"
453+
|Continuing without cross-repository support.
454+
""".stripMargin.trim())
443455

444456
case Success(publications) =>
445457
publications.foreach { publication =>
446-
project
447-
.getExtensions()
448-
.getByType(classOf[SourceSetContainer])
449-
.getByName("main")
450-
.getOutput()
451-
.getClassesDirs()
452-
.getFiles()
453-
.asScala
454-
.toList
455-
.map(_.getAbsolutePath())
456-
.sorted
457-
.take(1)
458-
.foreach { classesDirectory =>
459-
deps +=
460-
List(
461-
publication.getGroupId(),
462-
publication.getArtifactId(),
463-
publication.getVersion(),
464-
classesDirectory
465-
).mkString("\t")
466-
}
458+
Try(
459+
project
460+
.getExtensions()
461+
.getByType(classOf[SourceSetContainer])
462+
.getByName("main")
463+
) match {
464+
case Failure(exception) =>
465+
val publicationName = List(
466+
publication.getGroupId(),
467+
publication.getArtifactId(),
468+
publication.getVersion()
469+
).mkString(":")
470+
471+
warn(s"""
472+
|Failed to extract `main` source set from publication `${publicationName}` in project `$projectName``.
473+
$crossRepoBanner
474+
|Here's the raw error message:
475+
| "${exception.getMessage()}"
476+
|Continuing without cross-repository support.
477+
""".stripMargin.trim())
478+
479+
case Success(value) =>
480+
value
481+
.getOutput()
482+
.getClassesDirs()
483+
.getFiles()
484+
.asScala
485+
.toList
486+
.map(_.getAbsolutePath())
487+
.sorted
488+
.take(1)
489+
.foreach { classesDirectory =>
490+
deps +=
491+
List(
492+
publication.getGroupId(),
493+
publication.getArtifactId(),
494+
publication.getVersion(),
495+
classesDirectory
496+
).mkString("\t")
497+
}
498+
499+
}
467500
}
468501
}
469502

@@ -511,3 +544,12 @@ class WriteDependencies extends DefaultTask {
511544
}
512545
}
513546
}
547+
548+
private object Logging {
549+
def info(msg: Any*) =
550+
System.err.println(s"[INFO] [scip-java.gradle] ${msg.mkString(" ")}")
551+
552+
def warn(msg: Any*) =
553+
System.err.println(s"[WARNING] [scip-java.gradle] ${msg.mkString(" ")}")
554+
555+
}

0 commit comments

Comments
 (0)