Skip to content

Commit

Permalink
improvement: add restart sever for sbt
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek authored and tgodzik committed Jun 29, 2023
1 parent 5a8512d commit 749a182
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import java.nio.file.Files
import java.nio.file.Path
import java.util.Properties

import scala.concurrent.Future

import scala.meta.inputs.Input
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.metals._
Expand Down Expand Up @@ -61,6 +63,21 @@ case class SbtBuildTool(
composeArgs(bspConfigArgs, workspace, bspDir)
}

def shutdownBspServer(
shellRunner: ShellRunner,
workspace: AbsolutePath,
): Future[Int] = {
val shutdownArgs =
composeArgs(List("--client", "shutdown"), workspace, workspace.toNIO)
scribe.info(s"running ${shutdownArgs.mkString(" ")}")
shellRunner.run(
"Shutting down sbt server",
shutdownArgs,
workspace,
true,
)
}

private def composeArgs(
sbtArgs: List[String],
workspace: AbsolutePath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import scala.meta.internal.builds.BuildServerProvider
import scala.meta.internal.builds.BuildTool
import scala.meta.internal.builds.BuildToolSelector
import scala.meta.internal.builds.BuildTools
import scala.meta.internal.builds.SbtBuildTool
import scala.meta.internal.builds.ScalaCliBuildTool
import scala.meta.internal.builds.ShellRunner
import scala.meta.internal.builds.WorkspaceReload
Expand Down Expand Up @@ -1583,9 +1584,45 @@ class MetalsLspService(
indexer.indexWorkspaceSources(buildTargets.allWritableData)
}

def shutDownBloop(): Boolean = bloopServers.shutdownServer()
def restartBspServer(): Future[Boolean] = {
def emitMessage(msg: String) = {
languageClient.showMessage(new MessageParams(MessageType.Warning, msg))
}
// This is for `bloop` and `sbt`, for which `build/shutdown` doesn't shutdown the server.
val shutdownBsp =
bspSession match {
case Some(session) if session.main.isBloop =>
Future.successful(bloopServers.shutdownServer())
case Some(session) if session.main.isSbt =>
for {
currentBuildTool <- supportedBuildTool
res <- currentBuildTool match {
case Some(sbt: SbtBuildTool) =>
for {
_ <- disconnectOldBuildServer()
code <- sbt.shutdownBspServer(shellRunner, folder)
} yield code == 0
case _ => Future.successful(false)
}
} yield res
case s => Future.successful(s.nonEmpty)
}

def isBloop(): Boolean = bspSession.exists(_.main.isBloop)
for {
didShutdown <- shutdownBsp
_ = if (!didShutdown) {
bspSession match {
case Some(session) =>
emitMessage(
s"Could not shutdown ${session.main.name} server. Will try to reconnect."
)
case None =>
emitMessage("No build server connected. Will try to connect.")
}
}
_ <- autoConnectToBuildServer()
} yield didShutdown
}

def decodeFile(uri: String): Future[DecoderResponse] =
fileDecoderProvider.decodedFileContents(uri)
Expand Down Expand Up @@ -2530,7 +2567,7 @@ class MetalsLspService(

def resetWorkspace(): Future[Unit] = {
if (buildTools.isBloop) {
shutDownBloop()
bloopServers.shutdownServer()
}
disconnectOldBuildServer()
.map { _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,10 @@ class WorkspaceLspService(
case ServerCommands.ScanWorkspaceSources() =>
foreachSeq(_.indexSources(), ignoreValue = true)
case ServerCommands.RestartBuildServer() =>
folderServices.find(_.isBloop()).foreach(_.shutDownBloop())
foreachSeq(_.autoConnectToBuildServer())
onCurrentFolder(
_.restartBspServer().ignoreValue,
"restart BSP server",
).asJavaObject
case ServerCommands.GenerateBspConfig() =>
onCurrentFolder(
_.generateBspConfig(),
Expand Down
39 changes: 39 additions & 0 deletions tests/slow/src/test/scala/tests/sbt/SbtServerSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import scala.meta.io.AbsolutePath

import ch.epfl.scala.bsp4j.DebugSessionParamsDataKind
import ch.epfl.scala.bsp4j.ScalaMainClass
import scribe.LogRecord
import scribe.Logger
import scribe.output.LogOutput
import scribe.output.format.OutputFormat
import scribe.writer.Writer
import tests.BaseImportSuite
import tests.SbtBuildLayout
import tests.SbtServerInitializer
Expand Down Expand Up @@ -230,6 +235,40 @@ class SbtServerSuite
} yield ()
}

test("restart-server") {
val buffer = new StringBuilder()
val initHandlers = Logger.root.handlers
val writer = new Writer {
def write(
record: LogRecord,
output: LogOutput,
outputFormat: OutputFormat,
): Unit = buffer.append(output.plainText)
}
Logger.root.withHandler(writer = writer).replace()
cleanWorkspace()
for {
_ <- initialize(
s"""|/project/build.properties
|sbt.version=${V.sbtVersion}
|/build.sbt
|${SbtBuildLayout.commonSbtSettings}
|scalaVersion := "${V.scala213}"
|""".stripMargin
)
_ = buffer.clear()
_ <- server.server.restartBspServer()
} yield {
val logs = buffer.result()
assert(logs.contains("sbt server started"))
initHandlers
.foldLeft(Logger.root.clearHandlers())((logger, handler) =>
logger.withHandler(handler)
)
.replace()
}
}

test("debug") {
cleanWorkspace()
val mainClass = new ScalaMainClass(
Expand Down

0 comments on commit 749a182

Please sign in to comment.