Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ lazy val cli = project
version,
sbtVersion,
scalaVersion,
"semanticdbScalacVersions" ->
com
.sourcegraph
.sbtsourcegraph
.Versions
.cachedSemanticdbVersionsByScalaVersion,
"sbtSourcegraphVersion" ->
com.sourcegraph.sbtsourcegraph.BuildInfo.version,
"semanticdbVersion" -> V.scalameta,
Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,11 @@ com.sourcegraph.lsif_java.LsifJava.printHelp(Console.out)

## Supported programming languages

| Programming language | Gradle | Maven | sbt | Tracking issue |
| -------------------- | ------ | ----- | --- | --------------------------------------------------------------------------------------------------------------------------- |
| Java | ✅ | ✅ | ✅ | |
| Scala | | ❌ | ✅ | [Maven](https://github.com/sourcegraph/lsif-java/issues/301), [Gradle](https://github.com/sourcegraph/lsif-java/issues/302) |
| Kotlin | ❌ | ❌ | ❌ | [#302](https://github.com/sourcegraph/lsif-java/issues/302) |
| Programming language | Gradle | Maven | sbt | Tracking issue |
| -------------------- | ------ | ----- | --- | ----------------------------------------------------------- |
| Java | ✅ | ✅ | ✅ | |
| Scala | | ❌ | ✅ | [#302](https://github.com/sourcegraph/lsif-java/issues/302) |
| Kotlin | ❌ | ❌ | ❌ | [#304](https://github.com/sourcegraph/lsif-java/issues/304) |

### Java

Expand Down Expand Up @@ -216,7 +216,7 @@ projects. However, the following Gradle integrations are not yet supported:
| ----------- | --------- | -------------------------------------------------------------------------------- |
| Android | ❌ | [sourcegraph/lsif-java#304](https://github.com/sourcegraph/lsif-java/issues/304) |
| Kotlin | ❌ | [sourcegraph/lsif-java#177](https://github.com/sourcegraph/lsif-java/issues/177) |
| Scala | | [sourcegraph/lsif-java#302](https://github.com/sourcegraph/lsif-java/issues/302) |
| Scala | | |

### Maven

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import java.nio.file._
import scala.collection.mutable.ListBuffer
import scala.util.Properties

import com.sourcegraph.io.DeleteVisitor
import com.sourcegraph.lsif_java.BuildInfo
import com.sourcegraph.lsif_java.Embedded
import com.sourcegraph.lsif_java.commands.IndexCommand
import os.CommandResult
Expand Down Expand Up @@ -78,9 +80,20 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
buildCommand +=
s"-Porg.gradle.java.installations.paths=${toolchains.paths()}"
}
buildCommand ++= index.finalBuildCommand(List("clean", "compileTestJava"))
buildCommand ++=
index.finalBuildCommand(
List[Option[String]](
Some("clean"),
Some("compileTestJava"),
if (toolchains.isScalaEnabled)
Some("compileTestScala")
else
None
).flatten
)
buildCommand += lsifJavaDependencies

Files.walkFileTree(targetroot, new DeleteVisitor())
val result = index.process(buildCommand, env = Map("TERM" -> "dumb"))
printDebugLogs(toolchains.tmp)
Embedded
Expand Down Expand Up @@ -112,6 +125,11 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {

val agentpath = Embedded.agentJar(tmp)
val pluginpath = Embedded.semanticdbJar(tmp)
def handleExceptionGroovySyntax(): String =
if (index.verbose)
"e.printStackTrace()"
else
""
val dependenciesPath = targetroot.resolve("dependencies.txt")
Files.deleteIfExists(dependenciesPath)
val script =
Expand All @@ -137,6 +155,22 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
| // By enabling the SemanticDB Java agent on the Zinc daemon process, we manage
| // to configure Zinc to use the semanticdb-javac compiler plugin for Java compilation.
| tasks.withType(ScalaCompile) {
|
| if (scalaCompileOptions.additionalParameters == null) scalaCompileOptions.additionalParameters = []
| try {
| def scalaVersion = lsifJavaScalaVersion(project, configurations)
| def semanticdbVersion = lsifJavaSemanticdbScalacVersions(scalaVersion)
| def semanticdbScalacDependency ="org.scalameta:semanticdb-scalac_$$scalaVersion:$$semanticdbVersion"
| def semanticdbScalac = project.configurations.detachedConfiguration(dependencies.create(semanticdbScalacDependency)).files[0]
| scalaCompileOptions.additionalParameters << '-Xplugin:' + semanticdbScalac
| scalaCompileOptions.additionalParameters << '-P:semanticdb:sourceroot:$sourceroot'
| scalaCompileOptions.additionalParameters << '-P:semanticdb:targetroot:$targetroot'
| scalaCompileOptions.additionalParameters << '-P:semanticdb:exclude:(src/play/twirl|src/play/routes)' // Ignore autogenerated Playframework files
| scalaCompileOptions.additionalParameters << '-P:semanticdb:failures:warning'
| scalaCompileOptions.additionalParameters << '-Xplugin-require:semanticdb'
| } catch (Exception e) {
| ${handleExceptionGroovySyntax()}
| }
| scalaCompileOptions.forkOptions.with {
| jvmArgs << '-javaagent:$agentpath'
| jvmArgs << '-Dsemanticdb.pluginpath=$pluginpath'
Expand Down Expand Up @@ -180,11 +214,43 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
| }
| }
|}
""".stripMargin
|def lsifJavaSemanticdbScalacVersions(scalaVersion) {
| ${semanticdbScalacGroovySyntax()}[scalaVersion]
|}
|def lsifJavaScalaVersion(project, configurations) {
| for (config in configurations) {
| if (config.name == "zinc") continue
| if (config.canBeResolved) {
| def artifacts = config.incoming.artifactView { view ->
| view.lenient = true
| }.artifacts
| for (artifact in artifacts) {
| def id = artifact.id.componentIdentifier
| if (id instanceof org.gradle.api.artifacts.component.ModuleComponentIdentifier
| && id.group == "org.scala-lang"
| && id.module == "scala-library") {
| return id.version
| }
| }
| }
| }
| return null
|}
| """.stripMargin
Files.write(
tmp.resolve("init-script.gradle"),
script.getBytes(StandardCharsets.UTF_8)
)
}

def semanticdbScalacGroovySyntax(): String =
BuildInfo
.semanticdbScalacVersions
.removed(
"2.12.3"
) // Not supported because the last semanticdb-scalac_2.12.3 release doesn't support the option -P:semanticdb:targetroot:PATH.
.map { case (key, value) =>
s"'$key':'$value'"
}.mkString("[", ", ", "]")

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ case class GradleJavaToolchains(
tool: GradleBuildTool,
index: IndexCommand,
gradleVersion: Option[String],
isScalaEnabled: Boolean,
gradleCommand: String,
tmp: Path
) {
Expand Down Expand Up @@ -55,6 +56,7 @@ object GradleJavaToolchains {
): GradleJavaToolchains = {
val scriptPath = tmp.resolve("java-toolchains.gradle")
val toolchainsPath = tmp.resolve("java-toolchains.txt")
val scalaEnabledPath = tmp.resolve("scala-enabled.txt")
val gradleVersionPath = tmp.resolve("gradle-version.txt")
val taskName = "lsifDetectJavaToolchains"
val script =
Expand All @@ -70,7 +72,7 @@ object GradleJavaToolchains {
|}
|allprojects {
| task $taskName {
| def out = java.nio.file.Paths.get('$toolchainsPath')
| def toolchainsOut = java.nio.file.Paths.get('$toolchainsPath')
| doLast {
| tasks.withType(JavaCompile) {
| try {
Expand All @@ -79,14 +81,24 @@ object GradleJavaToolchains {
| def version = javaCompiler.get().getMetadata().getLanguageVersion().asInt()
| def line = "$$version $$path"
| java.nio.file.Files.write(
| out,
| toolchainsOut,
| [line],
| java.nio.file.StandardOpenOption.APPEND,
| java.nio.file.StandardOpenOption.CREATE)
| } catch (Exception e) {
| // Ignore errors.
| }
| }
| boolean isScalaEnabled = project.plugins.any {
| it.getClass().getName().endsWith("org.gradle.api.plugins.scala.ScalaPlugin")
| }
| if (isScalaEnabled) {
| java.nio.file.Files.write(
| java.nio.file.Paths.get('$scalaEnabledPath'),
| ["true"],
| java.nio.file.StandardOpenOption.APPEND,
| java.nio.file.StandardOpenOption.CREATE)
| }
| }
| }
|}
Expand Down Expand Up @@ -119,6 +131,7 @@ object GradleJavaToolchains {
tool,
index,
gradleVersion = gradleVersion,
isScalaEnabled = Files.isRegularFile(scalaEnabledPath),
gradleCommand = gradleCommand,
tmp = tmp
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ private void writeSemanticdb(Path output, Semanticdb.TextDocument textDocument)
try {
byte[] bytes =
Semanticdb.TextDocuments.newBuilder().addDocuments(textDocument).build().toByteArray();
Files.createDirectories(output.getParent());
Files.write(output, bytes);
} catch (IOException e) {
reporter.exception(e);
Expand Down Expand Up @@ -101,15 +102,7 @@ private Result<Path, String> semanticdbOutputPath(SemanticdbJavacOptions options
.resolve("semanticdb")
.resolve(relativePath)
.resolveSibling(filename);
try {
Files.createDirectories(semanticdbOutputPath.getParent());
return Result.ok(semanticdbOutputPath);
} catch (IOException exception) {
return Result.error(
String.format(
"failed to create parent directory for '%s'. Error message: %s",
semanticdbOutputPath, exception.getMessage()));
}
return Result.ok(semanticdbOutputPath);
} else {
return Result.error(
String.format(
Expand Down
29 changes: 29 additions & 0 deletions tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,33 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
2,
initCommand = gradleVersion("6.8.3")
)

checkBuild(
"scala",
"""|/build.gradle
|plugins {
| id 'scala'
|}
|repositories {
| mavenCentral()
|}
|dependencies {
| implementation 'org.scala-lang:scala-library:2.12.12'
|}
|/src/main/java/foo/JExample.java
|package foo;
|public class JExample {}
|/src/main/scala/foo/Example.scala
|package foo
|object Example {}
|/src/test/java/foo/JExampleSuite.java
|package foo;
|public class JExampleSuite {}
|/src/test/scala/foo/ExampleSuite.scala
|package foo
|class ExampleSuite {}
|""".stripMargin,
4
)

}