Skip to content

Commit

Permalink
feat: add setting to choose preferred build server
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Feb 16, 2024
1 parent 3228b3f commit 4c59ad7
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ trait BuildTool {
*/
def buildServerName = executableName

def possibleBuildServerNames: List[String] = List(buildServerName)

def isBspGenerated(workspace: AbsolutePath): Boolean =
possibleBuildServerNames
.map(name => workspace.resolve(".bsp").resolve(s"$name.json"))
.exists(_.isFile)
}

object BuildTool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ class ScalaCliBuildTool(

override val forcesBuildServer = true

def isBspGenerated(workspace: AbsolutePath): Boolean =
ScalaCliBuildTool.pathsToScalaCliBsp(workspace).exists(_.isFile)
override def possibleBuildServerNames = ScalaCli.names.toList

}

object ScalaCliBuildTool {
def name = "scala-cli"

def pathsToScalaCliBsp(root: AbsolutePath): List[AbsolutePath] =
ScalaCli.names.toList.map(name =>
root.resolve(".bsp").resolve(s"$name.json")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2091,23 +2091,25 @@ class MetalsLspService(
buildTool: Option[BuildTool.Found],
chosenBuildServer: Option[String],
): Future[BuildChange] = {
val isBloopOrEmpty = chosenBuildServer.isEmpty || chosenBuildServer.exists(
val preferredList =
userConfig.preferredBuildServes.map(_.trim().toLowerCase())
def isPreferredAboveBloop(buildServer: String) = {
val idx = preferredList.indexOf(buildServer)
if (idx >= 0) {
val bloopIdx = preferredList.indexOf("bloop")
bloopIdx < 0 || bloopIdx > idx
} else false
}
def isBloop = chosenBuildServer.exists(
_ == BloopServers.name
)

buildTool match {
case Some(BuildTool.Found(buildTool: BloopInstallProvider, digest))
if isBloopOrEmpty =>
if isBloop || (chosenBuildServer.isEmpty && !isPreferredAboveBloop(
buildTool.buildServerName
)) =>
slowConnectToBloopServer(forceImport, buildTool, digest)
case Some(BuildTool.Found(buildTool: ScalaCliBuildTool, _))
if !buildTool.isBspGenerated(folder) =>
tables.buildServers.chooseServer(buildTool.buildServerName)
buildTool
.generateBspConfig(
folder,
args => bspConfigGenerator.runUnconditionally(buildTool, args),
statusBar,
)
.flatMap(_ => quickConnectToBuildServer())
// If there is no .bazelbsp present, we ask user to write bsp config
// After that, we should fall into the last case and index workspace
case Some(BuildTool.Found(_: BazelBuildTool, _))
Expand All @@ -2122,12 +2124,26 @@ class MetalsLspService(
forceImport,
)
.flatMap(_ => quickConnectToBuildServer())
case Some(BuildTool.Found(buildTool: BuildServerProvider, _))
if !buildTool.isBspGenerated(folder) =>
tables.buildServers.chooseServer(buildTool.buildServerName)
buildTool
.generateBspConfig(
folder,
args => bspConfigGenerator.runUnconditionally(buildTool, args),
statusBar,
)
.flatMap(_ => quickConnectToBuildServer())
case Some(BuildTool.Found(buildTool, _))
if !chosenBuildServer.exists(
_ == buildTool.buildServerName
) && buildTool.forcesBuildServer =>
tables.buildServers.chooseServer(buildTool.buildServerName)
quickConnectToBuildServer()
case Some(BuildTool.Found(buildTool: BloopInstallProvider, _))
if chosenBuildServer.isEmpty =>
tables.buildServers.chooseServer(buildTool.buildServerName)
quickConnectToBuildServer()
case Some(found) =>
indexer.reloadWorkspaceAndIndex(
forceImport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ case class UserConfiguration(
verboseCompilation: Boolean = false,
automaticImportBuild: AutoImportBuildKind = AutoImportBuildKind.Off,
scalaCliLauncher: Option[String] = None,
preferredBuildServes: List[String] = Nil,
) {

def currentBloopVersion: String =
Expand Down Expand Up @@ -349,6 +350,19 @@ object UserConfiguration {
|only automatically import a build when a project is first opened, "all" will automate
|build imports after subsequent changes as well.""".stripMargin,
),
UserConfigurationOption(
"preferred-build-servers",
"[]",
"""["sbt"]""",
"List of preferred build servers.",
"""|If multiple build servers available, this list provides an order,
|that overrides the default partial order, in which the build server should be chosen.
|The default partial order is:
|1. `bloop`
|2. other build servers (asks user)
|3. fallback `scala-cli` (if no build server found)
|""".stripMargin,
),
)

def fromJson(
Expand Down Expand Up @@ -570,6 +584,11 @@ object UserConfiguration {
case _ => AutoImportBuildKind.Off
}

val scalaCliLauncher = getStringKey("scala-cli-launcher")

val preferredBuildServes =
getStringListKey("preferred-build-servers").getOrElse(Nil)

if (errors.isEmpty) {
Right(
UserConfiguration(
Expand Down Expand Up @@ -602,6 +621,8 @@ object UserConfiguration {
customProjectRoot,
verboseCompilation,
autoImportBuilds,
scalaCliLauncher,
preferredBuildServes,
)
)
} else {
Expand Down
71 changes: 71 additions & 0 deletions tests/slow/src/test/scala/tests/PreferredBuildServer.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package tests

import scala.meta.internal.metals.UserConfiguration
import scala.meta.internal.metals.{BuildInfo => V}

class PreferredBuildServer extends BaseLspSuite("preferred-build-server") {
override def userConfig: UserConfiguration =
super.userConfig.copy(preferredBuildServes = List("sbt"))

test("start-sbt-when-preferred-no-bsp") {
cleanWorkspace()

val fileLayout =
s"""|/project/build.properties
|sbt.version=${V.sbtVersion}
|/build.sbt
|${SbtBuildLayout.commonSbtSettings}
|ThisBuild / scalaVersion := "${V.scala213}"
|val a = project.in(file("a"))
|/a/src/main/scala/a/A.scala
|package a
|object A {
| val a = 1
|}
|""".stripMargin
FileLayout.fromString(fileLayout, workspace)

for {
_ <- server.initialize()
_ <- server.initialized()
_ <- server.server.buildServerPromise.future
_ = assertNoDiff(
server.server.tables.buildServers.selectedServer().get,
"sbt",
)
_ = assert(server.server.bspSession.exists(_.main.isSbt))
} yield ()
}

test("start-sbt-when-preferred-with-bsp") {
cleanWorkspace()

val fileLayout =
s"""|/project/build.properties
|sbt.version=${V.sbtVersion}
|/build.sbt
|${SbtBuildLayout.commonSbtSettings}
|ThisBuild / scalaVersion := "${V.scala213}"
|val a = project.in(file("a"))
|/a/src/main/scala/a/A.scala
|package a
|object A {
| val a = 1
|}
|""".stripMargin

FileLayout.fromString(fileLayout, workspace)
SbtServerInitializer.generateBspConfig(workspace, V.sbtVersion)

for {
_ <- server.initialize()
_ <- server.initialized()
_ <- server.server.buildServerPromise.future
_ = assertNoDiff(
server.server.tables.buildServers.selectedServer().get,
"sbt",
)
_ = assert(server.server.bspSession.exists(_.main.isSbt))
} yield ()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ object SbtServerInitializer extends BuildServerInitializer {
}
}

private def generateBspConfig(
def generateBspConfig(
workspace: AbsolutePath,
sbtVersion: String,
): Unit = {
Expand Down

0 comments on commit 4c59ad7

Please sign in to comment.