Skip to content

Commit fb98dd4

Browse files
authored
Merge pull request #168 from olafurpg/gradle-7
Add support for Gradle v7, fixes #164
2 parents 8d9e262 + 6850592 commit fb98dd4

File tree

10 files changed

+229
-68
lines changed

10 files changed

+229
-68
lines changed

docs/getting-started.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,18 @@ of Java versions.
156156
Please open an issue if your build tool is not listed in the table below. Feel
157157
free to subscribe to the tracking issues to receive updates on your build tool.
158158

159-
| Build tool | Support | Tracking issue |
160-
| ---------- | ------- | -------------------------------------------------------------------------------- |
161-
| Gradle || |
162-
| Maven || |
163-
| Bazel || [sourcegraph/lsif-java#88](https://github.com/sourcegraph/lsif-java/issues/88) |
164-
| Buck || [sourcegraph/lsif-java#99](https://github.com/sourcegraph/lsif-java/issues/99) |
165-
| sbt || [sourcegraph/lsif-java#110](https://github.com/sourcegraph/lsif-java/issues/110) |
159+
| Build tool | Single repo navigation | Cross-repo navigation | Tracking issue |
160+
| -------------- | ---------------------- | --------------------- | -------------------------------------------------------------------------------- |
161+
| Maven ||| |
162+
| Gradle v4.0+ ||| |
163+
| Gradle v2.2.1+ ||| [sourcegraph/lsif-java#167](https://github.com/sourcegraph/lsif-java/issues/167) |
164+
| Bazel ||| [sourcegraph/lsif-java#88](https://github.com/sourcegraph/lsif-java/issues/88) |
165+
| Buck ||| [sourcegraph/lsif-java#99](https://github.com/sourcegraph/lsif-java/issues/99) |
166+
| sbt ||| [sourcegraph/lsif-java#110](https://github.com/sourcegraph/lsif-java/issues/110) |
166167

167168
****: automatic indexing is fully supported. Please report a bug if the
168169
`lsif-java index` command does not work on your codebase.
169170

170-
****: automatic inference is not supported but (!) you may still be able to
171-
use `lsif-java` by configuring it manually using the instructions
171+
****: automatic indexing is not supported but (!) you may still be able to use
172+
`lsif-java` by configuring it manually using the instructions
172173
[here](manual-configuration.md).

lsif-java/src/main/scala/com/sourcegraph/lsif_java/Embedded.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,20 @@ object Embedded {
2323
private def javacErrorpath(tmp: Path) = tmp.resolve("errorpath.txt")
2424

2525
def customJavac(sourceroot: Path, targetroot: Path, tmp: Path): Path = {
26-
val javac = tmp.resolve("javac")
26+
val bin = tmp.resolve("bin")
27+
val javac = bin.resolve("javac")
28+
val java = bin.resolve("java")
2729
val pluginpath = Embedded.semanticdbJar(tmp)
2830
val errorpath = javacErrorpath(tmp)
2931
val javacopts = targetroot.resolve("javacopts.txt")
3032
Files.createDirectories(targetroot)
33+
Files.createDirectories(bin)
34+
Files.write(
35+
java,
36+
"""#!/usr/bin/env bash
37+
|java "$@"
38+
|""".stripMargin.getBytes(StandardCharsets.UTF_8)
39+
)
3140
val newJavacopts = tmp.resolve("javac_newarguments")
3241
val injectSemanticdbArguments = List[String](
3342
"java",
@@ -60,6 +69,7 @@ object Embedded {
6069
|""".stripMargin
6170
Files.write(javac, script.getBytes(StandardCharsets.UTF_8))
6271
javac.toFile.setExecutable(true)
72+
java.toFile.setExecutable(true)
6373
javac
6474
}
6575

lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleBuildTool.scala

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,49 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
3737
else
3838
"gradle"
3939

40-
TemporaryFiles.withDirectory(index.cleanup) { tmp =>
40+
TemporaryFiles.withDirectory(index) { tmp =>
4141
val toolchains = GradleJavaToolchains
4242
.fromWorkspace(this, index, gradleCommand, tmp)
43-
val script = initScript(toolchains, tmp).toString
44-
45-
val buildCommand = ListBuffer.empty[String]
46-
buildCommand ++=
47-
List(
48-
gradleCommand,
49-
"--init-script",
50-
script,
51-
"-Porg.gradle.java.installations.auto-detect=false",
52-
"-Porg.gradle.java.installations.auto-download=false",
53-
s"-Porg.gradle.java.installations.paths=${toolchains.paths()}",
54-
s"--no-daemon"
55-
)
56-
buildCommand ++= index.finalBuildCommand(List("clean", "compileTestJava"))
57-
buildCommand += lsifJavaDependencies
43+
toolchains.gradleVersion match {
44+
case Some(gradleVersion)
45+
if gradleVersion.startsWith("6.7") &&
46+
toolchains.toolchains.nonEmpty =>
47+
index
48+
.app
49+
.error(
50+
"lsif-java does not support Gradle 6.7 when used together with Java toolchains. " +
51+
"To fix this problem, upgrade to Gradle version 6.8 or newer and try again."
52+
)
53+
CommandResult(1, Nil)
54+
case _ =>
55+
runCompileCommand(toolchains)
56+
}
57+
}
58+
}
5859

59-
val result = index.process(buildCommand.toList: _*)
60-
printDebugLogs(tmp)
61-
Embedded
62-
.reportUnexpectedJavacErrors(index.app.reporter, tmp)
63-
.getOrElse(result)
60+
private def runCompileCommand(
61+
toolchains: GradleJavaToolchains
62+
): CommandResult = {
63+
val script = initScript(toolchains, toolchains.tmp).toString
64+
val buildCommand = ListBuffer.empty[String]
65+
buildCommand += toolchains.gradleCommand
66+
buildCommand += s"--no-daemon"
67+
buildCommand += "--init-script"
68+
buildCommand += script
69+
if (toolchains.toolchains.nonEmpty) {
70+
buildCommand += "-Porg.gradle.java.installations.auto-detect=false"
71+
buildCommand += "-Porg.gradle.java.installations.auto-download=false"
72+
buildCommand +=
73+
s"-Porg.gradle.java.installations.paths=${toolchains.paths()}"
6474
}
75+
buildCommand ++= index.finalBuildCommand(List("clean", "compileTestJava"))
76+
buildCommand += lsifJavaDependencies
77+
78+
val result = index.process(buildCommand.toList: _*)
79+
printDebugLogs(toolchains.tmp)
80+
Embedded
81+
.reportUnexpectedJavacErrors(index.app.reporter, toolchains.tmp)
82+
.getOrElse(result)
6583
}
6684

6785
private def lsifJavaDependencies = "lsifJavaDependencies"

lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleJavaToolchains.scala

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ case class GradleJavaToolchains(
1313
toolchains: List[GradleJavaCompiler],
1414
tool: GradleBuildTool,
1515
index: IndexCommand,
16+
gradleVersion: Option[String],
17+
gradleCommand: String,
1618
tmp: Path
1719
) {
1820

@@ -53,9 +55,20 @@ object GradleJavaToolchains {
5355
): GradleJavaToolchains = {
5456
val scriptPath = tmp.resolve("java-toolchains.gradle")
5557
val toolchainsPath = tmp.resolve("java-toolchains.txt")
58+
val gradleVersionPath = tmp.resolve("gradle-version.txt")
5659
val taskName = "lsifDetectJavaToolchains"
5760
val script =
58-
s"""|allprojects {
61+
s"""|
62+
|try {
63+
| java.nio.file.Files.write(
64+
| java.nio.file.Paths.get('$gradleVersionPath'),
65+
| [gradle.gradleVersion],
66+
| java.nio.file.StandardOpenOption.TRUNCATE_EXISTING,
67+
| java.nio.file.StandardOpenOption.CREATE)
68+
|} catch (Exception e) {
69+
| // Ignore errors.
70+
|}
71+
|allprojects {
5972
| task $taskName {
6073
| def out = java.nio.file.Paths.get('$toolchainsPath')
6174
| doLast {
@@ -92,6 +105,20 @@ object GradleJavaToolchains {
92105
Nil
93106
}
94107

95-
GradleJavaToolchains(toolchains, tool, index, tmp)
108+
val gradleVersion =
109+
if (Files.isRegularFile(gradleVersionPath)) {
110+
Some(new String(Files.readAllBytes(gradleVersionPath)).trim)
111+
} else {
112+
None
113+
}
114+
115+
GradleJavaToolchains(
116+
toolchains,
117+
tool,
118+
index,
119+
gradleVersion = gradleVersion,
120+
gradleCommand = gradleCommand,
121+
tmp = tmp
122+
)
96123
}
97124
}

lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/MavenBuildTool.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class MavenBuildTool(index: IndexCommand) extends BuildTool("Maven", index) {
1717
Files.isRegularFile(index.workingDirectory.resolve("pom.xml"))
1818

1919
override def generateSemanticdb(): CommandResult = {
20-
TemporaryFiles.withDirectory(index.cleanup) { tmp =>
20+
TemporaryFiles.withDirectory(index) { tmp =>
2121
val mvnw = index.workingDirectory.resolve("mvnw")
2222
val mavenScript =
2323
if (Files.isRegularFile(mvnw))

lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/TemporaryFiles.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ import java.nio.file.Files
44
import java.nio.file.Path
55

66
import com.sourcegraph.io.DeleteVisitor
7+
import com.sourcegraph.lsif_java.commands.IndexCommand
78

89
object TemporaryFiles {
9-
def withDirectory[T](cleanup: Boolean)(fn: Path => T): T = {
10-
val tmp = Files.createTempDirectory("lsif-java")
11-
try fn(tmp)
12-
finally {
13-
if (cleanup) {
14-
Files.walkFileTree(tmp, new DeleteVisitor())
15-
}
10+
def withDirectory[T](index: IndexCommand)(fn: Path => T): T = {
11+
index.temporaryDirectory match {
12+
case Some(tmp) =>
13+
fn(tmp)
14+
case None =>
15+
val tmp = Files.createTempDirectory("lsif-java")
16+
try fn(tmp)
17+
finally {
18+
if (index.cleanup) {
19+
Files.walkFileTree(tmp, new DeleteVisitor())
20+
}
21+
}
1622
}
1723
}
1824
}

lsif-java/src/main/scala/com/sourcegraph/lsif_java/commands/IndexCommand.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ case class IndexCommand(
4949
@Description("URL to a PackageHub instance")
5050
@Hidden // Hidden because it's not supposed to be used yet by normal users.
5151
packagehub: Option[String] = None,
52+
@Hidden // Hidden because it's only used for testing purposes
53+
temporaryDirectory: Option[Path] = None,
5254
@Description(
5355
"Optional. The build command to use to compile all sources. " +
5456
"Defaults to a build-specific command. For example, the default command for Maven command is 'clean verify -DskipTests'." +

semanticdb-agent/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbAgent.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package com.sourcegraph.semanticdb_javac;
22

3-
import java.nio.charset.StandardCharsets;
4-
import net.bytebuddy.agent.builder.AgentBuilder;
5-
import net.bytebuddy.asm.Advice;
3+
import static net.bytebuddy.implementation.bytecode.assign.Assigner.Typing.DYNAMIC;
4+
import static net.bytebuddy.matcher.ElementMatchers.named;
65

76
import java.io.File;
87
import java.io.IOException;
98
import java.io.PrintStream;
109
import java.lang.instrument.Instrumentation;
10+
import java.nio.charset.StandardCharsets;
1111
import java.nio.file.Files;
1212
import java.nio.file.Paths;
1313
import java.nio.file.StandardOpenOption;
1414
import java.util.ArrayList;
1515
import java.util.List;
1616
import java.util.NoSuchElementException;
17-
18-
import static net.bytebuddy.implementation.bytecode.assign.Assigner.Typing.DYNAMIC;
19-
import static net.bytebuddy.matcher.ElementMatchers.named;
17+
import net.bytebuddy.agent.builder.AgentBuilder;
18+
import net.bytebuddy.asm.Advice;
2019

2120
/** Java agent that injects SemanticDB into the Java compilation process. */
2221
public class SemanticdbAgent {

tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tests
22

33
import java.nio.file.FileSystems
4+
import java.nio.file.Files
45
import java.nio.file.Path
56

67
import scala.meta.internal.io.FileIO
@@ -12,6 +13,7 @@ import moped.testkit.DeleteVisitor
1213
import moped.testkit.FileLayout
1314
import moped.testkit.MopedSuite
1415
import munit.TestOptions
16+
import os.Shellable
1517

1618
abstract class BaseBuildToolSuite extends MopedSuite(LsifJava.app) {
1719
override def environmentVariables: Map[String, String] = sys.env
@@ -36,23 +38,40 @@ abstract class BaseBuildToolSuite extends MopedSuite(LsifJava.app) {
3638
expectedSemanticdbFiles: Int = 0,
3739
extraArguments: List[String] = Nil,
3840
expectedError: String = "",
39-
expectedPackages: String = ""
41+
expectedPackages: String = "",
42+
initCommand: => List[String] = Nil
4043
): Unit = {
4144
test(options) {
45+
if (initCommand.nonEmpty) {
46+
os.proc(Shellable(initCommand)).call(os.Path(workingDirectory))
47+
}
4248
FileLayout.fromString(original, root = workingDirectory)
4349
val targetroot = workingDirectory.resolve("targetroot")
4450
val arguments =
45-
List("index", "--targetroot", targetroot.toString) ++ extraArguments
51+
List[String](
52+
"index",
53+
"--temporary-directory",
54+
Files.createDirectories(cacheDirectory).toString,
55+
"--targetroot",
56+
targetroot.toString
57+
) ++ extraArguments
4658
val exit = app().run(arguments)
59+
if (extraArguments.contains("--verbose")) {
60+
println(app.capturedOutput)
61+
}
4762
if (expectedError.nonEmpty) {
4863
assert(clue(exit) != 0, clues(app.capturedOutput))
4964
assertNoDiff(app.capturedOutput, expectedError)
5065
} else {
5166
assertEquals(exit, 0, clues(app.capturedOutput))
5267
}
53-
val semanticdbFiles = FileIO
54-
.listAllFilesRecursively(AbsolutePath(targetroot))
55-
.filter(p => semanticdbPattern.matches(p.toNIO))
68+
val semanticdbFiles =
69+
if (!Files.isDirectory(targetroot))
70+
Nil
71+
else
72+
FileIO
73+
.listAllFilesRecursively(AbsolutePath(targetroot))
74+
.filter(p => semanticdbPattern.matches(p.toNIO))
5675
if (semanticdbFiles.length != expectedSemanticdbFiles) {
5776
fail(
5877
s"Expected $expectedSemanticdbFiles SemanticDB file(s) to be generated.",

0 commit comments

Comments
 (0)