Skip to content

Commit f0e6f46

Browse files
authored
Auto build tool - choose the first one that applies (#582)
1 parent ac53452 commit f0e6f46

File tree

5 files changed

+113
-47
lines changed

5 files changed

+113
-47
lines changed

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,24 @@ abstract class BuildTool(val name: String, index: IndexCommand) {
1919

2020
object BuildTool {
2121
def all(index: IndexCommand): List[BuildTool] =
22+
// We don't support Bazel for auto-indexing, but if it's
23+
// detected, we should at least give a meaningful error message
24+
autoOrdered(index) :+ new BazelBuildTool(index)
25+
26+
def autoOrdered(index: IndexCommand): List[BuildTool] =
2227
List(
23-
new BazelBuildTool(index),
24-
new GradleBuildTool(index),
25-
new MavenBuildTool(index),
28+
// The order in this list is important -
29+
// first detected build tool will be used in `auto` mode
30+
// Bazel is missing because it isn't supported by auto-indexing
31+
32+
// first as it indicates user's intent to use SCIP auto-indexing
2633
new ScipBuildTool(index),
34+
// Maven first, then Gradle, then SBT
35+
// To match the order indicated in IntelliJ Java and Scala developer surveys 2022:
36+
// 1. https://www.jetbrains.com/lp/devecosystem-2022/java/#which-build-systems-do-you-regularly-use-if-any-
37+
// 2. https://www.jetbrains.com/lp/devecosystem-2022/scala/#which-build-systems-do-you-regularly-use-if-any-
38+
new MavenBuildTool(index),
39+
new GradleBuildTool(index),
2740
new SbtBuildTool(index),
2841
new MillBuildTool(index)
2942
)

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ import os.CommandResult
1515
class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
1616

1717
override def usedInCurrentDirectory(): Boolean = {
18-
Files.isRegularFile(index.workingDirectory.resolve("settings.gradle")) ||
19-
Files.isRegularFile(index.workingDirectory.resolve("gradlew")) ||
20-
Files.isRegularFile(index.workingDirectory.resolve("build.gradle")) ||
21-
Files.isRegularFile(index.workingDirectory.resolve("build.gradle.kts"))
18+
val gradleFiles = List(
19+
"settings.gradle",
20+
"gradlew",
21+
"build.gradle",
22+
"build.gradle.kts"
23+
)
24+
gradleFiles
25+
.exists(name => Files.isRegularFile(index.workingDirectory.resolve(name)))
2226
}
2327

2428
override def generateScip(): Int = {

scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala

Lines changed: 76 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -120,54 +120,92 @@ case class IndexCommand(
120120
}
121121
)
122122

123-
matchingBuildTools match {
124-
case Nil =>
125-
buildTool match {
126-
case Some(explicit) if usedBuildTools.nonEmpty =>
127-
val toFix =
128-
Levenshtein
129-
.closestCandidate(explicit, usedBuildTools.map(_.name)) match {
130-
case Some(closest) =>
131-
s"Did you mean --build-tool=$closest?"
132-
case None =>
133-
"To fix this problem, run again with the --build-tool flag set to one of the detected build tools."
134-
}
135-
val autoDetected = usedBuildTools.map(_.name).mkString(", ")
123+
buildTool match {
124+
case Some(auto) if auto.equalsIgnoreCase("auto") =>
125+
runAutoBuildTool()
126+
case _ =>
127+
matchingBuildTools match {
128+
case Nil =>
129+
unknownBuildTool(buildTool, usedBuildTools)
130+
case tool :: Nil =>
131+
tool.generateScip()
132+
case many =>
133+
val names = many.map(_.name).mkString(", ")
136134
app.error(
137-
s"Automatically detected the build tool(s) $autoDetected but none of them match the explicitly provided flag '--build-tool=$explicit'. " +
138-
toFix
135+
s"Multiple build tools detected: $names. " +
136+
s"To fix this problem, use the '--build-tool=BUILD_TOOL_NAME' flag to specify which build tool to run."
139137
)
140-
case _ =>
141-
if (Files.isDirectory(workingDirectory)) {
142-
app.error(
143-
s"No build tool detected in workspace '$workingDirectory'. " +
144-
s"At the moment, the only supported build tools are: ${BuildTool.allNames}."
145-
)
138+
1
139+
}
140+
}
141+
}
142+
143+
private def unknownBuildTool(
144+
buildTool: Option[String],
145+
usedBuildTools: List[BuildTool]
146+
): Int = {
147+
buildTool match {
148+
case Some(explicit) if usedBuildTools.nonEmpty =>
149+
val toFix =
150+
Levenshtein
151+
.closestCandidate(explicit, usedBuildTools.map(_.name)) match {
152+
case Some(closest) =>
153+
s"Did you mean --build-tool=$closest?"
154+
case None =>
155+
"To fix this problem, run again with the --build-tool flag set to one of the detected build tools."
156+
}
157+
val autoDetected = usedBuildTools.map(_.name).mkString(", ")
158+
app.error(
159+
s"Automatically detected the build tool(s) $autoDetected but none of them match the explicitly provided flag '--build-tool=$explicit'. " +
160+
toFix
161+
)
162+
case _ =>
163+
if (Files.isDirectory(workingDirectory)) {
164+
app.error(
165+
s"No build tool detected in workspace '$workingDirectory'. " +
166+
s"At the moment, the only supported build tools are: ${BuildTool.allNames}."
167+
)
168+
} else {
169+
val cause =
170+
if (Files.exists(workingDirectory)) {
171+
s"Workspace '$workingDirectory' is not a directory"
146172
} else {
147-
val cause =
148-
if (Files.exists(workingDirectory)) {
149-
s"Workspace '$workingDirectory' is not a directory"
150-
} else {
151-
s"The directory '$workingDirectory' does not exist"
152-
}
153-
app.error(
154-
cause +
155-
s". To fix this problem, make sure the working directory is an actual directory."
156-
)
173+
s"The directory '$workingDirectory' does not exist"
157174
}
175+
app.error(
176+
cause +
177+
s". To fix this problem, make sure the working directory is an actual directory."
178+
)
158179
}
159-
1
160-
case tool :: Nil =>
161-
tool.generateScip()
162-
case many =>
163-
val names = many.map(_.name).mkString(", ")
180+
}
181+
182+
1
183+
}
184+
185+
private def runAutoBuildTool(): Int = {
186+
val usedInOrder = BuildTool
187+
.autoOrdered(this)
188+
.filter(_.usedInCurrentDirectory())
189+
190+
usedInOrder match {
191+
case Nil =>
164192
app.error(
165-
s"Multiple build tools detected: $names. " +
166-
s"To fix this problem, use the '--build-tool=BUILD_TOOL_NAME' flag to specify which build tool to run."
193+
"Build tool mode set to `auto`, but no supported build tools were detected"
167194
)
168195
1
196+
case first :: rest =>
197+
val restMessage = rest
198+
.map(_.name)
199+
.mkString(", other tools that were detected: [", ", ", "]")
200+
201+
app.info(
202+
s"Auto mode: `${first.name}` will be used in this workspace${restMessage}"
203+
)
204+
205+
first.generateScip()
169206
}
170207
}
208+
171209
}
172210

173211
object IndexCommand {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package tests
2+
3+
class AutoBuildToolSuite extends BaseBuildToolSuite {
4+
checkErrorOutput(
5+
"no-tools-found",
6+
List("index", "--build-tool", "auto"),
7+
expectedOutput =
8+
"""error: Build tool mode set to `auto`, but no supported build tools were detected""",
9+
workingDirectoryLayout = ""
10+
)
11+
}

tests/buildTools/src/test/scala/tests/MissingBuildToolSuite.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class MissingBuildToolSuite extends BaseBuildToolSuite {
66
"basic",
77
List("index"),
88
expectedOutput =
9-
s"""|error: No build tool detected in workspace '${java.io.File.separator}workingDirectory'. At the moment, the only supported build tools are: Gradle, Maven, sbt, mill.
9+
s"""|error: No build tool detected in workspace '${java.io.File.separator}workingDirectory'. At the moment, the only supported build tools are: Maven, Gradle, sbt, mill.
1010
|""".stripMargin,
1111
workingDirectoryLayout = ""
1212
)
@@ -15,7 +15,7 @@ class MissingBuildToolSuite extends BaseBuildToolSuite {
1515
"ambiguous",
1616
List("index"),
1717
expectedOutput =
18-
"""|error: Multiple build tools detected: Gradle, Maven. To fix this problem, use the '--build-tool=BUILD_TOOL_NAME' flag to specify which build tool to run.
18+
"""|error: Multiple build tools detected: Maven, Gradle. To fix this problem, use the '--build-tool=BUILD_TOOL_NAME' flag to specify which build tool to run.
1919
|""".stripMargin,
2020
workingDirectoryLayout =
2121
"""|/pom.xml

0 commit comments

Comments
 (0)