Minor cleanups

This commit is contained in:
Dale Wijnand 2018-01-23 16:52:51 +00:00
parent 5daf10d6c7
commit 286758e2ba
No known key found for this signature in database
GPG Key ID: 4F256E3D151DF5EF
5 changed files with 72 additions and 98 deletions

View File

@ -132,7 +132,7 @@ private[sbt] object JLine {
def createReader(): ConsoleReader = createReader(None, JLine.makeInputStream(true))
def createReader(historyPath: Option[File], in: InputStream): ConsoleReader =
usingTerminal { t =>
usingTerminal { _ =>
val cr = new ConsoleReader(in, System.out)
cr.setExpandEvents(false) // https://issues.scala-lang.org/browse/SI-7650
cr.setBellEnabled(false)

View File

@ -19,8 +19,7 @@ import sjsonnew.JsonFormat
*/
abstract class CommandChannel {
private val commandQueue: ConcurrentLinkedQueue[Exec] = new ConcurrentLinkedQueue()
def append(exec: Exec): Boolean =
commandQueue.add(exec)
def append(exec: Exec): Boolean = commandQueue.add(exec)
def poll: Option[Exec] = Option(commandQueue.poll)
def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit

View File

@ -11,7 +11,7 @@ import sbt.internal.DslEntry
import sbt.librarymanagement.Configuration
private[sbt] trait BuildSyntax {
import language.experimental.macros
import scala.language.experimental.macros
def settingKey[T](description: String): SettingKey[T] = macro std.KeyMacro.settingKeyImpl[T]
def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T]
def inputKey[T](description: String): InputKey[T] = macro std.KeyMacro.inputKeyImpl[T]

View File

@ -7,14 +7,17 @@
package sbt
import java.io.PrintWriter
import java.util.Properties
import jline.TerminalFactory
import scala.annotation.tailrec
import scala.util.control.NonFatal
import jline.TerminalFactory
import sbt.io.{ IO, Using }
import sbt.internal.util.{ ErrorHandling, GlobalLogBacking }
import sbt.internal.util.complete.DefaultParsers
import sbt.internal.util.complete.Parser
import sbt.util.Logger
import sbt.protocol._
@ -25,9 +28,7 @@ object MainLoop {
// We've disabled jline shutdown hooks to prevent classloader leaks, and have been careful to always restore
// the jline terminal in finally blocks, but hitting ctrl+c prevents finally blocks from being executed, in that
// case the only way to restore the terminal is in a shutdown hook.
val shutdownHook = new Thread(new Runnable {
def run(): Unit = TerminalFactory.get().restore()
})
val shutdownHook = new Thread(() => TerminalFactory.get().restore())
try {
Runtime.getRuntime.addShutdownHook(shutdownHook)
@ -100,7 +101,7 @@ object MainLoop {
/** Runs the next sequence of commands with global logging in place. */
def runWithNewLog(state: State, logBacking: GlobalLogBacking): RunNext =
Using.fileWriter(append = true)(logBacking.file) { writer =>
val out = new java.io.PrintWriter(writer)
val out = new PrintWriter(writer)
val full = state.globalLogging.full
val newLogging = state.globalLogging.newAppender(full, out, logBacking)
// transferLevels(state, newLogging)
@ -124,7 +125,7 @@ object MainLoop {
final class KeepGlobalLog(val state: State) extends RunNext
final class Return(val result: xsbti.MainResult) extends RunNext
/** Runs the next sequence of commands that doesn't require global logging changes.*/
/** Runs the next sequence of commands that doesn't require global logging changes. */
@tailrec def run(state: State): RunNext =
state.next match {
case State.Continue => run(next(state))
@ -143,14 +144,11 @@ object MainLoop {
/** This is the main function State transfer function of the sbt command processing. */
def processCommand(exec: Exec, state: State): State = {
import DefaultParsers._
val channelName = exec.source map (_.channelName)
StandardMain.exchange publishEventMessage ExecStatusEvent("Processing",
channelName,
exec.execId,
Vector())
StandardMain.exchange publishEventMessage
ExecStatusEvent("Processing", channelName, exec.execId, Vector())
val parser = Command combine state.definedCommands
val newState = parse(exec.commandLine, parser(state)) match {
val newState = Parser.parse(exec.commandLine, parser(state)) match {
case Right(s) => s() // apply command. command side effects happen here
case Left(errMsg) =>
state.log error errMsg

View File

@ -46,46 +46,41 @@ private[sbt] final class CommandExchange {
private val autoStartServer =
sys.props get "sbt.server.autostart" forall (_.toLowerCase == "true")
private val lock = new AnyRef {}
private var server: Option[ServerInstance] = None
private val firstInstance: AtomicBoolean = new AtomicBoolean(true)
private var consoleChannel: Option[ConsoleChannel] = None
private val commandQueue: ConcurrentLinkedQueue[Exec] = new ConcurrentLinkedQueue()
private val channelBuffer: ListBuffer[CommandChannel] = new ListBuffer()
private val channelBufferLock = new AnyRef {}
private val nextChannelId: AtomicInteger = new AtomicInteger(0)
private lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {}
def channels: List[CommandChannel] = channelBuffer.toList
def subscribe(c: CommandChannel): Unit =
lock.synchronized {
channelBuffer.append(c)
}
def subscribe(c: CommandChannel): Unit = channelBufferLock.synchronized(channelBuffer.append(c))
// periodically move all messages from all the channels
@tailrec def blockUntilNextExec: Exec = {
@tailrec def slurpMessages(): Unit =
(((None: Option[Exec]) /: channels) { _ orElse _.poll }) match {
channels.foldLeft(Option.empty[Exec]) { _ orElse _.poll } match {
case None => ()
case Some(x) =>
commandQueue.add(x)
slurpMessages
case _ => ()
}
slurpMessages()
Option(commandQueue.poll) match {
case Some(x) => x
case _ =>
case None =>
Thread.sleep(50)
blockUntilNextExec
}
}
def run(s: State): State = {
consoleChannel match {
case Some(_) => // do nothing
case _ =>
val x = new ConsoleChannel("console0")
consoleChannel = Some(x)
subscribe(x)
if (consoleChannel.isEmpty) {
val console0 = new ConsoleChannel("console0")
consoleChannel = Some(console0)
subscribe(console0)
}
if (autoStartServer) runServer(s)
else s
@ -97,25 +92,12 @@ private[sbt] final class CommandExchange {
* Check if a server instance is running already, and start one if it isn't.
*/
private[sbt] def runServer(s: State): State = {
lazy val port = (s get serverPort) match {
case Some(x) => x
case None => 5001
}
lazy val host = (s get serverHost) match {
case Some(x) => x
case None => "127.0.0.1"
}
lazy val auth: Set[ServerAuthentication] = (s get serverAuthentication) match {
case Some(xs) => xs
case None => Set(ServerAuthentication.Token)
}
lazy val connectionType = (s get serverConnectionType) match {
case Some(x) => x
case None => ConnectionType.Tcp
}
lazy val level: Level.Value = (s get serverLogLevel)
.orElse(s get logLevel)
.getOrElse(Level.Warn)
lazy val port = s.get(serverPort).getOrElse(5001)
lazy val host = s.get(serverHost).getOrElse("127.0.0.1")
lazy val auth: Set[ServerAuthentication] =
s.get(serverAuthentication).getOrElse(Set(ServerAuthentication.Token))
lazy val connectionType = s.get(serverConnectionType).getOrElse(ConnectionType.Tcp)
lazy val level = s.get(serverLogLevel).orElse(s.get(logLevel)).getOrElse(Level.Warn)
def onIncomingSocket(socket: Socket, instance: ServerInstance): Unit = {
val name = newNetworkName
@ -131,55 +113,50 @@ private[sbt] final class CommandExchange {
new NetworkChannel(name, socket, Project structure s, auth, instance, logger)
subscribe(channel)
}
server match {
case Some(_) => // do nothing
case None if !firstInstance.get => // there's another server
case _ =>
val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json"
val h = Hash.halfHashString(IO.toURI(portfile).toString)
val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json"
val socketfile = BuildPaths.getGlobalBase(s) / "server" / h / "sock"
val pipeName = "sbt-server-" + h
val connection =
ServerConnection(connectionType,
host,
port,
auth,
portfile,
tokenfile,
socketfile,
pipeName)
val x = Server.start(connection, onIncomingSocket, s.log)
// don't throw exception when it times out
val d = "10s"
Try(Await.ready(x.ready, Duration(d)))
x.ready.value match {
case Some(Success(_)) =>
// remember to shutdown only when the server comes up
server = Some(x)
case Some(Failure(_: AlreadyRunningException)) =>
s.log.warn(
"sbt server could not start because there's another instance of sbt running on this build.")
s.log.warn("Running multiple instances is unsupported")
server = None
firstInstance.set(false)
case Some(Failure(e)) =>
s.log.error(e.toString)
server = None
case None =>
s.log.warn(s"sbt server could not start in $d")
server = None
firstInstance.set(false)
}
if (server.isEmpty && firstInstance.get) {
val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json"
val h = Hash.halfHashString(IO.toURI(portfile).toString)
val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json"
val socketfile = BuildPaths.getGlobalBase(s) / "server" / h / "sock"
val pipeName = "sbt-server-" + h
val connection = ServerConnection(
connectionType,
host,
port,
auth,
portfile,
tokenfile,
socketfile,
pipeName,
)
val serverInstance = Server.start(connection, onIncomingSocket, s.log)
// don't throw exception when it times out
val d = "10s"
Try(Await.ready(serverInstance.ready, Duration(d)))
serverInstance.ready.value match {
case Some(Success(())) =>
// remember to shutdown only when the server comes up
server = Some(serverInstance)
case Some(Failure(_: AlreadyRunningException)) =>
s.log.warn(
"sbt server could not start because there's another instance of sbt running on this build.")
s.log.warn("Running multiple instances is unsupported")
server = None
firstInstance.set(false)
case Some(Failure(e)) =>
s.log.error(e.toString)
server = None
case None =>
s.log.warn(s"sbt server could not start in $d")
server = None
firstInstance.set(false)
}
}
s
}
def shutdown(): Unit = {
channels foreach { c =>
c.shutdown()
}
channels foreach (_.shutdown())
// interrupt and kill the thread
server.foreach(_.shutdown())
server = None
@ -202,7 +179,7 @@ private[sbt] final class CommandExchange {
toDel.toList match {
case Nil => // do nothing
case xs =>
lock.synchronized {
channelBufferLock.synchronized {
channelBuffer --= xs
()
}
@ -241,7 +218,7 @@ private[sbt] final class CommandExchange {
toDel.toList match {
case Nil => // do nothing
case xs =>
lock.synchronized {
channelBufferLock.synchronized {
channelBuffer --= xs
()
}
@ -283,7 +260,7 @@ private[sbt] final class CommandExchange {
toDel.toList match {
case Nil => // do nothing
case xs =>
lock.synchronized {
channelBufferLock.synchronized {
channelBuffer --= xs
()
}
@ -325,7 +302,7 @@ private[sbt] final class CommandExchange {
toDel.toList match {
case Nil => // do nothing
case xs =>
lock.synchronized {
channelBufferLock.synchronized {
channelBuffer --= xs
()
}