mirror of https://github.com/sbt/sbt.git
commit
e3f33ddf7d
23
build.sbt
23
build.sbt
|
|
@ -545,11 +545,6 @@ def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
|
|||
val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed
|
||||
// publishLocalBinAll.value // TODO: Restore scripted needing only binary jars.
|
||||
publishAll.value
|
||||
// These two projects need to be visible in a repo even if the default
|
||||
// local repository is hidden, so we publish them to an alternate location and add
|
||||
// that alternate repo to the running scripted test (in Scripted.scriptedpreScripted).
|
||||
// (altLocalPublish in interfaceProj).value
|
||||
// (altLocalPublish in compileInterfaceProj).value
|
||||
Scripted.doScripted(
|
||||
(sbtLaunchJar in bundledLauncherProj).value,
|
||||
(fullClasspath in scriptedSbtProj in Test).value,
|
||||
|
|
@ -607,7 +602,6 @@ def otherRootSettings =
|
|||
scripted := scriptedTask.evaluated,
|
||||
scriptedUnpublished := scriptedUnpublishedTask.evaluated,
|
||||
scriptedSource := (sourceDirectory in sbtProj).value / "sbt-test",
|
||||
// scriptedPrescripted := { addSbtAlternateResolver _ },
|
||||
scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server"),
|
||||
publishAll := { val _ = (publishLocal).all(ScopeFilter(inAnyProject)).value },
|
||||
publishLocalBinAll := { val _ = (publishLocalBin).all(ScopeFilter(inAnyProject)).value },
|
||||
|
|
@ -627,23 +621,6 @@ def otherRootSettings =
|
|||
scriptedSource := (sourceDirectory in sbtProj).value / "repo-override-test"
|
||||
))
|
||||
|
||||
// def addSbtAlternateResolver(scriptedRoot: File) = {
|
||||
// val resolver = scriptedRoot / "project" / "AddResolverPlugin.scala"
|
||||
// if (!resolver.exists) {
|
||||
// IO.write(resolver, s"""import sbt._
|
||||
// |import Keys._
|
||||
// |
|
||||
// |object AddResolverPlugin extends AutoPlugin {
|
||||
// | override def requires = sbt.plugins.JvmPlugin
|
||||
// | override def trigger = allRequirements
|
||||
// |
|
||||
// | override lazy val projectSettings = Seq(resolvers += alternativeLocalResolver)
|
||||
// | lazy val alternativeLocalResolver = Resolver.file("$altLocalRepoName", file("$altLocalRepoPath"))(Resolver.ivyStylePatterns)
|
||||
// |}
|
||||
// |""".stripMargin)
|
||||
// }
|
||||
// }
|
||||
|
||||
lazy val docProjects: ScopeFilter = ScopeFilter(
|
||||
inAnyProject -- inProjects(sbtRoot, sbtProj, scriptedSbtProj, scriptedPluginProj),
|
||||
inConfigurations(Compile)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ package sbt.internal.util
|
|||
import Types._
|
||||
import Classes.Applicative
|
||||
|
||||
/** Heterogeneous list with each element having type M[T] for some type T.*/
|
||||
/** A higher-kinded heterogeneous list of elements that share the same type constructor `M[_]`. */
|
||||
sealed trait KList[+M[_]] {
|
||||
type Transform[N[_]] <: KList[N]
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
package sbt
|
||||
|
||||
import scala.Predef.{ conforms => _, _ }
|
||||
import java.io.File
|
||||
import java.util.jar.{ Attributes, Manifest }
|
||||
import scala.collection.JavaConverters._
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import scala.annotation.tailrec
|
|||
import java.io.File
|
||||
import sbt.internal.inc.{ RawCompiler, ScalaInstance }
|
||||
|
||||
import Predef.{ conforms => _, _ }
|
||||
import sbt.io.syntax._
|
||||
import sbt.io.IO
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ object Scripted {
|
|||
// This is to workaround https://github.com/sbt/io/issues/110
|
||||
sys.props.put("jna.nosys", "true")
|
||||
|
||||
lazy val MavenResolverPluginTest = config("mavenResolverPluginTest") extend Compile
|
||||
lazy val RepoOverrideTest = config("repoOverrideTest") extend Compile
|
||||
val RepoOverrideTest = config("repoOverrideTest") extend Compile
|
||||
|
||||
import sbt.complete._
|
||||
import DefaultParsers._
|
||||
|
|
|
|||
Loading…
Reference in New Issue