From 6b8e716428fbebdef4d3cfbd57ef1673a7e71f08 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 11 Sep 2017 00:34:14 -0400 Subject: [PATCH 01/57] implement server handshake test --- .travis.yml | 2 +- .../sbt-test/server/handshake/Client.scala | 35 +++++++++++++++++++ sbt/src/sbt-test/server/handshake/build.sbt | 13 +++++++ sbt/src/sbt-test/server/handshake/test | 6 ++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 sbt/src/sbt-test/server/handshake/Client.scala create mode 100644 sbt/src/sbt-test/server/handshake/build.sbt create mode 100644 sbt/src/sbt-test/server/handshake/test diff --git a/.travis.yml b/.travis.yml index a33abc64e..32110046e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ env: - SBT_CMD="scripted dependency-management/*4of4" - SBT_CMD="scripted java/* package/* reporter/* run/* project-load/*" - SBT_CMD="scripted project/*1of2" - - SBT_CMD="scripted project/*2of2" + - SBT_CMD="scripted project/*2of2 server/*" - SBT_CMD="scripted source-dependencies/*1of3" - SBT_CMD="scripted source-dependencies/*2of3" - SBT_CMD="scripted source-dependencies/*3of3" diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala new file mode 100644 index 000000000..ee0255abf --- /dev/null +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -0,0 +1,35 @@ +package example + +import java.net.{ URI, Socket, InetAddress, SocketException } +import sbt.io._ +import sbt.io.syntax._ +import java.io.File + +object Client extends App { + val host = "127.0.0.1" + val port = 5123 + val delimiter: Byte = '\n'.toByte + + println("hello") + Thread.sleep(1000) + + val connection = getConnection + val out = connection.getOutputStream + val in = connection.getInputStream + + out.write("""{ "type": "ExecCommand", "commandLine": "exit" }""".getBytes("utf-8")) + out.write(delimiter.toInt) + out.flush + + val baseDirectory = new File(args(0)) + IO.write(baseDirectory / "ok.txt", "ok") + + def getConnection: Socket = + try { + new Socket(InetAddress.getByName(host), port) + } catch { + case _ => + Thread.sleep(1000) + getConnection + } +} diff --git a/sbt/src/sbt-test/server/handshake/build.sbt b/sbt/src/sbt-test/server/handshake/build.sbt new file mode 100644 index 000000000..9692ab267 --- /dev/null +++ b/sbt/src/sbt-test/server/handshake/build.sbt @@ -0,0 +1,13 @@ +lazy val runClient = taskKey[Unit]("") + +lazy val root = (project in file(".")) + .settings( + scalaVersion := "2.12.3", + serverPort in Global := 5123, + libraryDependencies += "org.scala-sbt" %% "io" % "1.0.1", + runClient := (Def.taskDyn { + val b = baseDirectory.value + (bgRun in Compile).toTask(s""" $b""") + }).value + ) + \ No newline at end of file diff --git a/sbt/src/sbt-test/server/handshake/test b/sbt/src/sbt-test/server/handshake/test new file mode 100644 index 000000000..9c2ba1cc1 --- /dev/null +++ b/sbt/src/sbt-test/server/handshake/test @@ -0,0 +1,6 @@ +> show serverPort +> runClient +-> shell + +$ sleep 1000 +$ exists ok.txt From 9d40404915f650579f787a88f1d2abc2c9ff17f2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 17 Sep 2017 19:08:45 -0400 Subject: [PATCH 02/57] JSON port file This implements JSON-based port file. Thoughout the lifetime of the sbt server there will be `cwd / "project" / "target" / "active.json"`, which contains `url` field. Using this `url` the potential client, such as IDEs can find out which port number to hit. Ref #3508 --- build.sbt | 4 ++ .../scala/sbt/internal/server/Server.scala | 38 +++++++++++++--- main/src/main/scala/sbt/Main.scala | 4 +- .../scala/sbt/internal/CommandExchange.scala | 7 ++- .../sbt/internal/protocol/PortFile.scala | 45 +++++++++++++++++++ .../sbt/internal/protocol/TokenFile.scala | 36 +++++++++++++++ .../protocol/codec/PortFileFormats.scala | 29 ++++++++++++ .../protocol/codec/TokenFileFormats.scala | 29 ++++++++++++ protocol/src/main/contraband/portfile.contra | 16 +++++++ .../sbt-test/server/handshake/Client.scala | 21 ++++++++- sbt/src/sbt-test/server/handshake/build.sbt | 1 + 11 files changed, 219 insertions(+), 11 deletions(-) create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala create mode 100644 protocol/src/main/contraband/portfile.contra diff --git a/build.sbt b/build.sbt index 7e4e6d751..a9e37dd37 100644 --- a/build.sbt +++ b/build.sbt @@ -290,6 +290,10 @@ lazy val commandProj = (project in file("main-command")) sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", contrabandFormatsForType in generateContrabands in Compile := ContrabandConfig.getFormats, mimaSettings, + mimaBinaryIssueFilters ++= Vector( + // Changed the signature of Server method. nacho cheese. + exclude[DirectMissingMethodProblem]("sbt.internal.server.Server.*") + ) ) .configure( addSbtIO, diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index 7b764225f..45ea5ad67 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -5,12 +5,17 @@ package sbt package internal package server +import java.io.File import java.net.{ SocketTimeoutException, InetAddress, ServerSocket, Socket } import java.util.concurrent.atomic.AtomicBoolean -import sbt.util.Logger -import sbt.internal.util.ErrorHandling import scala.concurrent.{ Future, Promise } import scala.util.{ Try, Success, Failure } +import sbt.internal.util.ErrorHandling +import sbt.internal.protocol.PortFile +import sbt.util.Logger +import sbt.io.IO +import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter } +import sbt.internal.protocol.codec._ private[sbt] sealed trait ServerInstance { def shutdown(): Unit @@ -18,14 +23,19 @@ private[sbt] sealed trait ServerInstance { } private[sbt] object Server { + sealed trait JsonProtocol + extends sjsonnew.BasicJsonProtocol + with PortFileFormats + with TokenFileFormats + object JsonProtocol extends JsonProtocol + def start(host: String, port: Int, onIncomingSocket: Socket => Unit, - /*onIncomingCommand: CommandMessage => Unit,*/ log: Logger): ServerInstance = + portfile: File, + tokenfile: File, + log: Logger): ServerInstance = new ServerInstance { - - // val lock = new AnyRef {} - // val clients: mutable.ListBuffer[ClientConnection] = mutable.ListBuffer.empty val running = new AtomicBoolean(false) val p: Promise[Unit] = Promise[Unit]() val ready: Future[Unit] = p.future @@ -41,6 +51,7 @@ private[sbt] object Server { case Success(serverSocket) => serverSocket.setSoTimeout(5000) log.info(s"sbt server started at $host:$port") + writePortfile() running.set(true) p.success(()) while (running.get()) { @@ -58,8 +69,21 @@ private[sbt] object Server { override def shutdown(): Unit = { log.info("shutting down server") + if (portfile.exists) { + IO.delete(portfile) + } + if (tokenfile.exists) { + IO.delete(tokenfile) + } running.set(false) } - } + // This file exists through the lifetime of the server. + def writePortfile(): Unit = { + import JsonProtocol._ + val p = PortFile(s"tcp://$host:$port", None) + val json = Converter.toJson(p).get + IO.write(portfile, CompactPrinter(json)) + } + } } diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index f4043f989..47a67a0fd 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -101,7 +101,9 @@ object StandardMain { val previous = TrapExit.installManager() try { try { - MainLoop.runLogged(s) + try { + MainLoop.runLogged(s) + } finally exchange.shutdown } finally DefaultBackgroundJobService.backgroundJobService.shutdown() } finally TrapExit.uninstallManager(previous) } diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index d56edb245..9cf8f6c62 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -15,6 +15,8 @@ import sjsonnew.JsonFormat import scala.concurrent.Await import scala.concurrent.duration.Duration import scala.util.{ Success, Failure } +import sbt.io.syntax._ +import sbt.io.Hash /** * The command exchange merges multiple command channels (e.g. network and console), @@ -87,7 +89,10 @@ private[sbt] final class CommandExchange { server match { case Some(x) => // do nothing case _ => - val x = Server.start("127.0.0.1", port, onIncomingSocket, s.log) + val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json" + val h = Hash.halfHashString(portfile.toURL.toString) + val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json" + val x = Server.start("127.0.0.1", port, onIncomingSocket, portfile, tokenfile, s.log) Await.ready(x.ready, Duration("10s")) x.ready.value match { case Some(Success(_)) => diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala new file mode 100644 index 000000000..542ab368f --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala @@ -0,0 +1,45 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +/** + * This file should exist throughout the lifetime of the server. + * It can be used to find out the transport protocol (port number etc). + */ +final class PortFile private ( + /** URL of the sbt server. */ + val url: String, + val tokenfile: Option[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: PortFile => (this.url == x.url) && (this.tokenfile == x.tokenfile) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.protocol.PortFile".##) + url.##) + tokenfile.##) + } + override def toString: String = { + "PortFile(" + url + ", " + tokenfile + ")" + } + protected[this] def copy(url: String = url, tokenfile: Option[String] = tokenfile): PortFile = { + new PortFile(url, tokenfile) + } + def withUrl(url: String): PortFile = { + copy(url = url) + } + def withTokenfile(tokenfile: Option[String]): PortFile = { + copy(tokenfile = tokenfile) + } + def withTokenfile(tokenfile: String): PortFile = { + copy(tokenfile = Option(tokenfile)) + } +} +object PortFile { + + def apply(url: String, tokenfile: Option[String]): PortFile = new PortFile(url, tokenfile) + def apply(url: String, tokenfile: String): PortFile = new PortFile(url, Option(tokenfile)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala new file mode 100644 index 000000000..12f1ac21c --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class TokenFile private ( + val url: String, + val token: String) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TokenFile => (this.url == x.url) && (this.token == x.token) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.protocol.TokenFile".##) + url.##) + token.##) + } + override def toString: String = { + "TokenFile(" + url + ", " + token + ")" + } + protected[this] def copy(url: String = url, token: String = token): TokenFile = { + new TokenFile(url, token) + } + def withUrl(url: String): TokenFile = { + copy(url = url) + } + def withToken(token: String): TokenFile = { + copy(token = token) + } +} +object TokenFile { + + def apply(url: String, token: String): TokenFile = new TokenFile(url, token) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala new file mode 100644 index 000000000..daac10706 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PortFileFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val PortFileFormat: JsonFormat[sbt.internal.protocol.PortFile] = new JsonFormat[sbt.internal.protocol.PortFile] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.protocol.PortFile = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val url = unbuilder.readField[String]("url") + val tokenfile = unbuilder.readField[Option[String]]("tokenfile") + unbuilder.endObject() + sbt.internal.protocol.PortFile(url, tokenfile) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.PortFile, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("url", obj.url) + builder.addField("tokenfile", obj.tokenfile) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala new file mode 100644 index 000000000..d812593b2 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait TokenFileFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val TokenFileFormat: JsonFormat[sbt.internal.protocol.TokenFile] = new JsonFormat[sbt.internal.protocol.TokenFile] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.protocol.TokenFile = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val url = unbuilder.readField[String]("url") + val token = unbuilder.readField[String]("token") + unbuilder.endObject() + sbt.internal.protocol.TokenFile(url, token) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.TokenFile, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("url", obj.url) + builder.addField("token", obj.token) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband/portfile.contra b/protocol/src/main/contraband/portfile.contra new file mode 100644 index 000000000..f10d9c170 --- /dev/null +++ b/protocol/src/main/contraband/portfile.contra @@ -0,0 +1,16 @@ +package sbt.internal.protocol +@target(Scala) +@codecPackage("sbt.internal.protocol.codec") + +## This file should exist throughout the lifetime of the server. +## It can be used to find out the transport protocol (port number etc). +type PortFile { + ## URL of the sbt server. + url: String! + tokenfile: String +} + +type TokenFile { + url: String! + token: String! +} diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala index ee0255abf..54b7097f3 100644 --- a/sbt/src/sbt-test/server/handshake/Client.scala +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -4,10 +4,11 @@ import java.net.{ URI, Socket, InetAddress, SocketException } import sbt.io._ import sbt.io.syntax._ import java.io.File +import sjsonnew.support.scalajson.unsafe.{ Parser, Converter, CompactPrinter } +import sjsonnew.shaded.scalajson.ast.unsafe.{ JValue, JObject, JString } object Client extends App { val host = "127.0.0.1" - val port = 5123 val delimiter: Byte = '\n'.toByte println("hello") @@ -24,9 +25,25 @@ object Client extends App { val baseDirectory = new File(args(0)) IO.write(baseDirectory / "ok.txt", "ok") + def getPort: Int = { + val portfile = baseDirectory / "project" / "target" / "active.json" + val json: JValue = Parser.parseFromFile(portfile).get + json match { + case JObject(fields) => + (fields find { _.field == "url" } map { _.value }) match { + case Some(JString(value)) => + val u = new URI(value) + u.getPort + case _ => + sys.error("json doesn't url field that is JString") + } + case _ => sys.error("json doesn't have url field") + } + } + def getConnection: Socket = try { - new Socket(InetAddress.getByName(host), port) + new Socket(InetAddress.getByName(host), getPort) } catch { case _ => Thread.sleep(1000) diff --git a/sbt/src/sbt-test/server/handshake/build.sbt b/sbt/src/sbt-test/server/handshake/build.sbt index 9692ab267..fd924f0e4 100644 --- a/sbt/src/sbt-test/server/handshake/build.sbt +++ b/sbt/src/sbt-test/server/handshake/build.sbt @@ -5,6 +5,7 @@ lazy val root = (project in file(".")) scalaVersion := "2.12.3", serverPort in Global := 5123, libraryDependencies += "org.scala-sbt" %% "io" % "1.0.1", + libraryDependencies += "com.eed3si9n" %% "sjson-new-scalajson" % "0.8.0", runClient := (Def.taskDyn { val b = baseDirectory.value (bgRun in Compile).toTask(s""" $b""") From c5bfc6775085594de58d5ff48fc33e14fd81e4bf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 17 Sep 2017 22:31:57 -0400 Subject: [PATCH 03/57] Fixes test --- main/src/test/scala/sbt/internal/server/SettingQueryTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala index f254cad6e..3ef94c83b 100644 --- a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala +++ b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala @@ -172,7 +172,7 @@ object SettingQueryTest extends org.specs2.mutable.Specification { def query(setting: String): String = { import sbt.protocol._ - val req: SettingQuery = protocol.SettingQuery(setting) + val req: SettingQuery = sbt.protocol.SettingQuery(setting) val rsp: SettingQueryResponse = server.SettingQuery.handleSettingQuery(req, structure) val bytes: Array[Byte] = Serialization serializeEventMessage rsp val payload: String = new String(bytes, java.nio.charset.StandardCharsets.UTF_8) From 8a8215cf1b25970d701a1c331533d73b8a63b977 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 18 Sep 2017 23:07:29 -0400 Subject: [PATCH 04/57] Use uri instead of url --- .../scala/sbt/internal/CommandExchange.scala | 2 +- .../sbt/internal/protocol/PortFile.scala | 22 +++++++++---------- .../sbt/internal/protocol/TokenFile.scala | 18 +++++++-------- .../protocol/codec/PortFileFormats.scala | 6 ++--- .../protocol/codec/TokenFileFormats.scala | 6 ++--- protocol/src/main/contraband/portfile.contra | 6 ++--- .../sbt-test/server/handshake/Client.scala | 6 ++--- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 9cf8f6c62..0902665bb 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -90,7 +90,7 @@ private[sbt] final class CommandExchange { case Some(x) => // do nothing case _ => val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json" - val h = Hash.halfHashString(portfile.toURL.toString) + val h = Hash.halfHashString(portfile.toURI.toString) val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json" val x = Server.start("127.0.0.1", port, onIncomingSocket, portfile, tokenfile, s.log) Await.ready(x.ready, Duration("10s")) diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala index 542ab368f..648ab25b5 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala @@ -9,27 +9,27 @@ package sbt.internal.protocol * It can be used to find out the transport protocol (port number etc). */ final class PortFile private ( - /** URL of the sbt server. */ - val url: String, + /** URI of the sbt server. */ + val uri: String, val tokenfile: Option[String]) extends Serializable { override def equals(o: Any): Boolean = o match { - case x: PortFile => (this.url == x.url) && (this.tokenfile == x.tokenfile) + case x: PortFile => (this.uri == x.uri) && (this.tokenfile == x.tokenfile) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.internal.protocol.PortFile".##) + url.##) + tokenfile.##) + 37 * (37 * (37 * (17 + "sbt.internal.protocol.PortFile".##) + uri.##) + tokenfile.##) } override def toString: String = { - "PortFile(" + url + ", " + tokenfile + ")" + "PortFile(" + uri + ", " + tokenfile + ")" } - protected[this] def copy(url: String = url, tokenfile: Option[String] = tokenfile): PortFile = { - new PortFile(url, tokenfile) + protected[this] def copy(uri: String = uri, tokenfile: Option[String] = tokenfile): PortFile = { + new PortFile(uri, tokenfile) } - def withUrl(url: String): PortFile = { - copy(url = url) + def withUri(uri: String): PortFile = { + copy(uri = uri) } def withTokenfile(tokenfile: Option[String]): PortFile = { copy(tokenfile = tokenfile) @@ -40,6 +40,6 @@ final class PortFile private ( } object PortFile { - def apply(url: String, tokenfile: Option[String]): PortFile = new PortFile(url, tokenfile) - def apply(url: String, tokenfile: String): PortFile = new PortFile(url, Option(tokenfile)) + def apply(uri: String, tokenfile: Option[String]): PortFile = new PortFile(uri, tokenfile) + def apply(uri: String, tokenfile: String): PortFile = new PortFile(uri, Option(tokenfile)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala index 12f1ac21c..e2019147e 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/TokenFile.scala @@ -5,26 +5,26 @@ // DO NOT EDIT MANUALLY package sbt.internal.protocol final class TokenFile private ( - val url: String, + val uri: String, val token: String) extends Serializable { override def equals(o: Any): Boolean = o match { - case x: TokenFile => (this.url == x.url) && (this.token == x.token) + case x: TokenFile => (this.uri == x.uri) && (this.token == x.token) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.internal.protocol.TokenFile".##) + url.##) + token.##) + 37 * (37 * (37 * (17 + "sbt.internal.protocol.TokenFile".##) + uri.##) + token.##) } override def toString: String = { - "TokenFile(" + url + ", " + token + ")" + "TokenFile(" + uri + ", " + token + ")" } - protected[this] def copy(url: String = url, token: String = token): TokenFile = { - new TokenFile(url, token) + protected[this] def copy(uri: String = uri, token: String = token): TokenFile = { + new TokenFile(uri, token) } - def withUrl(url: String): TokenFile = { - copy(url = url) + def withUri(uri: String): TokenFile = { + copy(uri = uri) } def withToken(token: String): TokenFile = { copy(token = token) @@ -32,5 +32,5 @@ final class TokenFile private ( } object TokenFile { - def apply(url: String, token: String): TokenFile = new TokenFile(url, token) + def apply(uri: String, token: String): TokenFile = new TokenFile(uri, token) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala index daac10706..8bed2e6f9 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala @@ -11,17 +11,17 @@ implicit lazy val PortFileFormat: JsonFormat[sbt.internal.protocol.PortFile] = n jsOpt match { case Some(js) => unbuilder.beginObject(js) - val url = unbuilder.readField[String]("url") + val uri = unbuilder.readField[String]("uri") val tokenfile = unbuilder.readField[Option[String]]("tokenfile") unbuilder.endObject() - sbt.internal.protocol.PortFile(url, tokenfile) + sbt.internal.protocol.PortFile(uri, tokenfile) case None => deserializationError("Expected JsObject but found None") } } override def write[J](obj: sbt.internal.protocol.PortFile, builder: Builder[J]): Unit = { builder.beginObject() - builder.addField("url", obj.url) + builder.addField("uri", obj.uri) builder.addField("tokenfile", obj.tokenfile) builder.endObject() } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala index d812593b2..74a15423f 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/TokenFileFormats.scala @@ -11,17 +11,17 @@ implicit lazy val TokenFileFormat: JsonFormat[sbt.internal.protocol.TokenFile] = jsOpt match { case Some(js) => unbuilder.beginObject(js) - val url = unbuilder.readField[String]("url") + val uri = unbuilder.readField[String]("uri") val token = unbuilder.readField[String]("token") unbuilder.endObject() - sbt.internal.protocol.TokenFile(url, token) + sbt.internal.protocol.TokenFile(uri, token) case None => deserializationError("Expected JsObject but found None") } } override def write[J](obj: sbt.internal.protocol.TokenFile, builder: Builder[J]): Unit = { builder.beginObject() - builder.addField("url", obj.url) + builder.addField("uri", obj.uri) builder.addField("token", obj.token) builder.endObject() } diff --git a/protocol/src/main/contraband/portfile.contra b/protocol/src/main/contraband/portfile.contra index f10d9c170..ccd3ec157 100644 --- a/protocol/src/main/contraband/portfile.contra +++ b/protocol/src/main/contraband/portfile.contra @@ -5,12 +5,12 @@ package sbt.internal.protocol ## This file should exist throughout the lifetime of the server. ## It can be used to find out the transport protocol (port number etc). type PortFile { - ## URL of the sbt server. - url: String! + ## URI of the sbt server. + uri: String! tokenfile: String } type TokenFile { - url: String! + uri: String! token: String! } diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala index 54b7097f3..4be0d8aad 100644 --- a/sbt/src/sbt-test/server/handshake/Client.scala +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -30,14 +30,14 @@ object Client extends App { val json: JValue = Parser.parseFromFile(portfile).get json match { case JObject(fields) => - (fields find { _.field == "url" } map { _.value }) match { + (fields find { _.field == "uri" } map { _.value }) match { case Some(JString(value)) => val u = new URI(value) u.getPort case _ => - sys.error("json doesn't url field that is JString") + sys.error("json doesn't uri field that is JString") } - case _ => sys.error("json doesn't have url field") + case _ => sys.error("json doesn't have uri field") } } From 62a1d42c555544dd5b203ec22af47bba5e966181 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 20 Sep 2017 23:18:37 -0400 Subject: [PATCH 05/57] Fix #3564: Filter scripted tests based on project/build.properties Skip scripted tests where the binary version configured in the build does not match the binary version of sbt used for cross-building. --- build.sbt | 2 +- .../changes/Fail.scala | 1 + .../changes/build.properties | 1 + .../scripted-skip-incompatible/changes/test | 2 ++ .../project/plugins.sbt | 3 ++ .../project/scripted-skip-incompatible/test | 17 +++++++++ .../main/scala/sbt/test/ScriptedTests.scala | 36 +++++++++++++++++-- 7 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 sbt/src/sbt-test/project/scripted-skip-incompatible/changes/Fail.scala create mode 100644 sbt/src/sbt-test/project/scripted-skip-incompatible/changes/build.properties create mode 100644 sbt/src/sbt-test/project/scripted-skip-incompatible/changes/test create mode 100644 sbt/src/sbt-test/project/scripted-skip-incompatible/project/plugins.sbt create mode 100644 sbt/src/sbt-test/project/scripted-skip-incompatible/test diff --git a/build.sbt b/build.sbt index 7e4e6d751..ff598da88 100644 --- a/build.sbt +++ b/build.sbt @@ -230,7 +230,7 @@ lazy val scriptedSbtProj = (project in scriptedPath / "sbt") libraryDependencies ++= Seq(launcherInterface % "provided"), mimaSettings, ) - .configure(addSbtIO, addSbtUtilLogging, addSbtCompilerInterface, addSbtUtilScripted) + .configure(addSbtIO, addSbtUtilLogging, addSbtCompilerInterface, addSbtUtilScripted, addSbtLmCore) lazy val scriptedPluginProj = (project in scriptedPath / "plugin") .dependsOn(sbtProj) diff --git a/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/Fail.scala b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/Fail.scala new file mode 100644 index 000000000..f011d53a4 --- /dev/null +++ b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/Fail.scala @@ -0,0 +1 @@ +object Skipped { diff --git a/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/build.properties b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/build.properties new file mode 100644 index 000000000..a8c2f849b --- /dev/null +++ b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/build.properties @@ -0,0 +1 @@ +sbt.version=0.12.0 diff --git a/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/test b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/test new file mode 100644 index 000000000..4ed0b761f --- /dev/null +++ b/sbt/src/sbt-test/project/scripted-skip-incompatible/changes/test @@ -0,0 +1,2 @@ +$ copy-file changes/Fail.scala Skipped.scala +> compile diff --git a/sbt/src/sbt-test/project/scripted-skip-incompatible/project/plugins.sbt b/sbt/src/sbt-test/project/scripted-skip-incompatible/project/plugins.sbt new file mode 100644 index 000000000..529e7d656 --- /dev/null +++ b/sbt/src/sbt-test/project/scripted-skip-incompatible/project/plugins.sbt @@ -0,0 +1,3 @@ +libraryDependencies += { + "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value +} diff --git a/sbt/src/sbt-test/project/scripted-skip-incompatible/test b/sbt/src/sbt-test/project/scripted-skip-incompatible/test new file mode 100644 index 000000000..704535d5b --- /dev/null +++ b/sbt/src/sbt-test/project/scripted-skip-incompatible/test @@ -0,0 +1,17 @@ +# Setup failing test that should be skipped when tests are discovered +$ copy-file changes/Fail.scala src/sbt-test/group/skipped/changes/Fail.scala +$ copy-file changes/build.properties src/sbt-test/group/skipped/project/build.properties +$ copy-file changes/test src/sbt-test/group/skipped/test + +# Should fail when run explicitly +-> scripted group/skipped + +# Should be skipped when discovered +> scripted + +# Setup the same test without a project/build.properties file +$ copy-file changes/Fail.scala src/sbt-test/group/not-skipped/changes/Fail.scala +$ copy-file changes/test src/sbt-test/group/not-skipped/test + +# Running discovered tests should fail +-> scripted diff --git a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala index 7094b8fb5..759c33358 100644 --- a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala +++ b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala @@ -6,6 +6,7 @@ package sbt package test import java.io.File +import java.util.Properties import scala.util.control.NonFatal import sbt.internal.scripted._ @@ -343,7 +344,9 @@ class ScriptedRunner { launchOpts: Array[String], prescripted: File => Unit): Unit = { val runner = new ScriptedTests(resourceBaseDirectory, bufferLog, bootProperties, launchOpts) - val allTests = get(tests, resourceBaseDirectory, logger) flatMap { + val sbtVersion = bootProperties.getName.dropWhile(!_.isDigit).dropRight(".jar".length) + val accept = isTestCompatible(resourceBaseDirectory, sbtVersion) _ + val allTests = get(tests, resourceBaseDirectory, accept, logger) flatMap { case ScriptedTest(group, name) => runner.singleScriptedTest(group, name, prescripted, logger) } @@ -399,17 +402,44 @@ class ScriptedRunner { reportErrors(tests.flatMap(test => test.apply().flatten.toSeq).toList) } + @deprecated("No longer used", "1.0.2") def get(tests: Seq[String], baseDirectory: File, log: Logger): Seq[ScriptedTest] = - if (tests.isEmpty) listTests(baseDirectory, log) else parseTests(tests) + get(tests, baseDirectory, _ => true, log) + def get(tests: Seq[String], + baseDirectory: File, + accept: ScriptedTest => Boolean, + log: Logger): Seq[ScriptedTest] = + if (tests.isEmpty) listTests(baseDirectory, accept, log) else parseTests(tests) + @deprecated("No longer used", "1.0.2") def listTests(baseDirectory: File, log: Logger): Seq[ScriptedTest] = - new ListTests(baseDirectory, _ => true, log).listTests + listTests(baseDirectory, _ => true, log) + def listTests(baseDirectory: File, + accept: ScriptedTest => Boolean, + log: Logger): Seq[ScriptedTest] = + (new ListTests(baseDirectory, accept, log)).listTests def parseTests(in: Seq[String]): Seq[ScriptedTest] = for (testString <- in) yield { val Array(group, name) = testString.split("/").map(_.trim) ScriptedTest(group, name) } + + private def isTestCompatible(resourceBaseDirectory: File, sbtVersion: String)( + test: ScriptedTest): Boolean = { + import sbt.internal.librarymanagement.cross.CrossVersionUtil.binarySbtVersion + val buildProperties = new Properties() + val testDir = new File(new File(resourceBaseDirectory, test.group), test.name) + val buildPropertiesFile = new File(new File(testDir, "project"), "build.properties") + + IO.load(buildProperties, buildPropertiesFile) + + Option(buildProperties.getProperty("sbt.version")) match { + case Some(version) => binarySbtVersion(version) == binarySbtVersion(sbtVersion) + case None => true + } + } + } final case class ScriptedTest(group: String, name: String) { From 348a07779715ba9cbd9da80c8dffa3f0b8eb52cd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 21 Sep 2017 23:05:48 -0400 Subject: [PATCH 06/57] implement tokenfile authentication --- build.sbt | 12 +++- .../scala/sbt/internal/util/Attributes.scala | 11 +++ .../ServerAuthenticationFormats.scala | 26 +++++++ .../sbt/ServerAuthentication.scala | 12 ++++ main-command/src/main/contraband/state.contra | 4 ++ .../src/main/scala/sbt/BasicKeys.scala | 9 +++ .../scala/sbt/internal/server/Server.scala | 69 +++++++++++++++++-- main/src/main/scala/sbt/Defaults.scala | 4 +- main/src/main/scala/sbt/Keys.scala | 2 + main/src/main/scala/sbt/Project.scala | 23 +++++-- .../scala/sbt/internal/CommandExchange.scala | 21 ++++-- .../sbt/internal/server/NetworkChannel.scala | 46 +++++++++++-- project/Dependencies.scala | 2 +- .../sbt/protocol/InitCommand.scala | 43 ++++++++++++ .../codec/CommandMessageFormats.scala | 4 +- .../protocol/codec/InitCommandFormats.scala | 29 ++++++++ .../sbt/protocol/codec/JsonProtocol.scala | 1 + protocol/src/main/contraband/server.contra | 5 ++ .../sbt-test/server/handshake/Client.scala | 32 +++++++++ 19 files changed, 322 insertions(+), 33 deletions(-) create mode 100644 main-command/src/main/contraband-scala/ServerAuthenticationFormats.scala create mode 100644 main-command/src/main/contraband-scala/sbt/ServerAuthentication.scala create mode 100644 protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala create mode 100644 protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala diff --git a/build.sbt b/build.sbt index a9e37dd37..6f2185958 100644 --- a/build.sbt +++ b/build.sbt @@ -132,6 +132,10 @@ val collectionProj = (project in file("internal") / "util-collection") name := "Collections", libraryDependencies ++= Seq(sjsonNewScalaJson.value), mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // Added private[sbt] method to capture State attributes. + exclude[ReversedMissingMethodProblem]("sbt.internal.util.AttributeMap.setCond"), + ), ) .configure(addSbtUtilPosition) @@ -292,7 +296,9 @@ lazy val commandProj = (project in file("main-command")) mimaSettings, mimaBinaryIssueFilters ++= Vector( // Changed the signature of Server method. nacho cheese. - exclude[DirectMissingMethodProblem]("sbt.internal.server.Server.*") + exclude[DirectMissingMethodProblem]("sbt.internal.server.Server.*"), + // Added method to ServerInstance. This is also internal. + exclude[ReversedMissingMethodProblem]("sbt.internal.server.ServerInstance.*"), ) ) .configure( @@ -365,6 +371,10 @@ lazy val mainProj = (project in file("main")) baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", mimaSettings, + mimaBinaryIssueFilters ++= Vector( + // Changed the signature of NetworkChannel ctor. internal. + exclude[DirectMissingMethodProblem]("sbt.internal.server.NetworkChannel.*"), + ) ) .configure( addSbtIO, diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index d70b3df8a..7c24cfd29 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -168,6 +168,11 @@ trait AttributeMap { /** `true` if there are no mappings in this map, `false` if there are. */ def isEmpty: Boolean + /** + * Adds the mapping `k -> opt.get` if opt is Some. + * Otherwise, it returns this map without the mapping for `k`. + */ + private[sbt] def setCond[T](k: AttributeKey[T], opt: Option[T]): AttributeMap } object AttributeMap { @@ -217,6 +222,12 @@ private class BasicAttributeMap(private val backing: Map[AttributeKey[_], Any]) def entries: Iterable[AttributeEntry[_]] = for ((k: AttributeKey[kt], v) <- backing) yield AttributeEntry(k, v.asInstanceOf[kt]) + private[sbt] def setCond[T](k: AttributeKey[T], opt: Option[T]): AttributeMap = + opt match { + case Some(v) => put(k, v) + case None => remove(k) + } + override def toString = entries.mkString("(", ", ", ")") } diff --git a/main-command/src/main/contraband-scala/ServerAuthenticationFormats.scala b/main-command/src/main/contraband-scala/ServerAuthenticationFormats.scala new file mode 100644 index 000000000..38bc9f9e1 --- /dev/null +++ b/main-command/src/main/contraband-scala/ServerAuthenticationFormats.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ServerAuthenticationFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ServerAuthenticationFormat: JsonFormat[sbt.ServerAuthentication] = new JsonFormat[sbt.ServerAuthentication] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.ServerAuthentication = { + jsOpt match { + case Some(js) => + unbuilder.readString(js) match { + case "Token" => sbt.ServerAuthentication.Token + } + case None => + deserializationError("Expected JsString but found None") + } + } + override def write[J](obj: sbt.ServerAuthentication, builder: Builder[J]): Unit = { + val str = obj match { + case sbt.ServerAuthentication.Token => "Token" + } + builder.writeString(str) + } +} +} diff --git a/main-command/src/main/contraband-scala/sbt/ServerAuthentication.scala b/main-command/src/main/contraband-scala/sbt/ServerAuthentication.scala new file mode 100644 index 000000000..b6f074b75 --- /dev/null +++ b/main-command/src/main/contraband-scala/sbt/ServerAuthentication.scala @@ -0,0 +1,12 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt +sealed abstract class ServerAuthentication extends Serializable +object ServerAuthentication { + + + case object Token extends ServerAuthentication +} diff --git a/main-command/src/main/contraband/state.contra b/main-command/src/main/contraband/state.contra index 929523505..79d0bcaab 100644 --- a/main-command/src/main/contraband/state.contra +++ b/main-command/src/main/contraband/state.contra @@ -12,3 +12,7 @@ type Exec { type CommandSource { channelName: String! } + +enum ServerAuthentication { + Token +} diff --git a/main-command/src/main/scala/sbt/BasicKeys.scala b/main-command/src/main/scala/sbt/BasicKeys.scala index 10f1215b1..f59f3f605 100644 --- a/main-command/src/main/scala/sbt/BasicKeys.scala +++ b/main-command/src/main/scala/sbt/BasicKeys.scala @@ -17,6 +17,15 @@ object BasicKeys { val watch = AttributeKey[Watched]("watch", "Continuous execution configuration.", 1000) val serverPort = AttributeKey[Int]("server-port", "The port number used by server command.", 10000) + + val serverHost = + AttributeKey[String]("serverHost", "The host used by server command.", 10000) + + val serverAuthentication = + AttributeKey[Set[ServerAuthentication]]("serverAuthentication", + "Method of authenticating server command.", + 10000) + private[sbt] val interactive = AttributeKey[Boolean]( "interactive", "True if commands are currently being entered from an interactive environment.", diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index 45ea5ad67..fce9d591a 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -7,19 +7,22 @@ package server import java.io.File import java.net.{ SocketTimeoutException, InetAddress, ServerSocket, Socket } -import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.{ AtomicBoolean, AtomicLong } +import java.nio.file.attribute.{ UserPrincipal, AclEntry, AclEntryPermission, AclEntryType } import scala.concurrent.{ Future, Promise } -import scala.util.{ Try, Success, Failure } +import scala.util.{ Try, Success, Failure, Random } import sbt.internal.util.ErrorHandling -import sbt.internal.protocol.PortFile +import sbt.internal.protocol.{ PortFile, TokenFile } import sbt.util.Logger import sbt.io.IO +import sbt.io.syntax._ import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter } import sbt.internal.protocol.codec._ private[sbt] sealed trait ServerInstance { def shutdown(): Unit def ready: Future[Unit] + def authenticate(challenge: String): Boolean } private[sbt] object Server { @@ -31,14 +34,16 @@ private[sbt] object Server { def start(host: String, port: Int, - onIncomingSocket: Socket => Unit, + onIncomingSocket: (Socket, ServerInstance) => Unit, + auth: Set[ServerAuthentication], portfile: File, tokenfile: File, log: Logger): ServerInstance = - new ServerInstance { + new ServerInstance { self => val running = new AtomicBoolean(false) val p: Promise[Unit] = Promise[Unit]() val ready: Future[Unit] = p.future + val token = new AtomicLong(Random.nextLong) val serverThread = new Thread("sbt-socket-server") { override def run(): Unit = { @@ -57,7 +62,7 @@ private[sbt] object Server { while (running.get()) { try { val socket = serverSocket.accept() - onIncomingSocket(socket) + onIncomingSocket(socket, self) } catch { case _: SocketTimeoutException => // its ok } @@ -67,6 +72,15 @@ private[sbt] object Server { } serverThread.start() + override def authenticate(challenge: String): Boolean = { + try { + val l = challenge.toLong + token.compareAndSet(l, Random.nextLong) + } catch { + case _: NumberFormatException => false + } + } + override def shutdown(): Unit = { log.info("shutting down server") if (portfile.exists) { @@ -78,10 +92,51 @@ private[sbt] object Server { running.set(false) } + def writeTokenfile(): Unit = { + import JsonProtocol._ + + val uri = s"tcp://$host:$port" + val t = TokenFile(uri, token.get.toString) + val jsonToken = Converter.toJson(t).get + + if (tokenfile.exists) { + IO.delete(tokenfile) + } + IO.touch(tokenfile) + ownerOnly(tokenfile) + IO.write(tokenfile, CompactPrinter(jsonToken), IO.utf8, true) + } + + /** Set the persmission of the file such that the only the owner can read/write it. */ + def ownerOnly(file: File): Unit = { + def acl(owner: UserPrincipal) = { + val builder = AclEntry.newBuilder + builder.setPrincipal(owner) + builder.setPermissions(AclEntryPermission.values(): _*) + builder.setType(AclEntryType.ALLOW) + builder.build + } + file match { + case _ if IO.isPosix => + IO.chmod("rw-------", file) + case _ if IO.hasAclFileAttributeView => + val view = file.aclFileAttributeView + view.setAcl(java.util.Collections.singletonList(acl(view.getOwner))) + case _ => () + } + } + // This file exists through the lifetime of the server. def writePortfile(): Unit = { import JsonProtocol._ - val p = PortFile(s"tcp://$host:$port", None) + + val uri = s"tcp://$host:$port" + val tokenRef = + if (auth(ServerAuthentication.Token)) { + writeTokenfile() + Some(tokenfile.toURI.toString) + } else None + val p = PortFile(uri, tokenRef) val json = Converter.toJson(p).get IO.write(portfile, CompactPrinter(json)) } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 1936641bf..638ccbe21 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -264,9 +264,11 @@ object Defaults extends BuildCommon { .getOrElse(GCUtil.defaultForceGarbageCollection), minForcegcInterval :== GCUtil.defaultMinForcegcInterval, interactionService :== CommandLineUIService, + serverHost := "127.0.0.1", serverPort := 5000 + (Hash .toHex(Hash(appConfiguration.value.baseDirectory.toString)) - .## % 1000) + .## % 1000), + serverAuthentication := Set(ServerAuthentication.Token), )) def defaultTestTasks(key: Scoped): Seq[Setting[_]] = diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 07d6d4d92..66c06b82e 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -127,6 +127,8 @@ object Keys { val historyPath = SettingKey(BasicKeys.historyPath) val shellPrompt = SettingKey(BasicKeys.shellPrompt) val serverPort = SettingKey(BasicKeys.serverPort) + val serverHost = SettingKey(BasicKeys.serverHost) + val serverAuthentication = SettingKey(BasicKeys.serverAuthentication) val analysis = AttributeKey[CompileAnalysis]("analysis", "Analysis of compilation, including dependencies and generated outputs.", DSetting) val watch = SettingKey(BasicKeys.watch) val suppressSbtShellNotification = settingKey[Boolean]("""True to suppress the "Executing in batch mode.." message.""").withRank(CSetting) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index b1aa71d06..6ad6e9d45 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -16,7 +16,9 @@ import Keys.{ sessionSettings, shellPrompt, templateResolverInfos, + serverHost, serverPort, + serverAuthentication, watch } import Scope.{ Global, ThisScope } @@ -509,23 +511,30 @@ object Project extends ProjectExtra { val prompt = get(shellPrompt) val trs = (templateResolverInfos in Global get structure.data).toList.flatten val watched = get(watch) + val host: Option[String] = get(serverHost) val port: Option[Int] = get(serverPort) + val authentication: Option[Set[ServerAuthentication]] = get(serverAuthentication) val commandDefs = allCommands.distinct.flatten[Command].map(_ tag (projectCommand, true)) val newDefinedCommands = commandDefs ++ BasicCommands.removeTagged(s.definedCommands, projectCommand) - val newAttrs0 = - setCond(Watched.Configuration, watched, s.attributes).put(historyPath.key, history) - val newAttrs = setCond(serverPort.key, port, newAttrs0) - .put(historyPath.key, history) - .put(templateResolverInfos.key, trs) + val newAttrs = + s.attributes + .setCond(Watched.Configuration, watched) + .put(historyPath.key, history) + .setCond(serverPort.key, port) + .setCond(serverHost.key, host) + .setCond(serverAuthentication.key, authentication) + .put(historyPath.key, history) + .put(templateResolverInfos.key, trs) + .setCond(shellPrompt.key, prompt) s.copy( - attributes = setCond(shellPrompt.key, prompt, newAttrs), + attributes = newAttrs, definedCommands = newDefinedCommands ) } def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap = - vopt match { case Some(v) => attributes.put(key, v); case None => attributes.remove(key) } + attributes.setCond(key, vopt) private[sbt] def checkTargets(data: Settings[Scope]): Option[String] = { val dups = overlappingTargets(allTargets(data)) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 0902665bb..574dfd8ce 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -6,10 +6,10 @@ import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.atomic.AtomicInteger import sbt.internal.server._ import sbt.internal.util.StringEvent -import sbt.protocol.{ EventMessage, Serialization, ChannelAcceptedEvent } +import sbt.protocol.{ EventMessage, Serialization } import scala.collection.mutable.ListBuffer import scala.annotation.tailrec -import BasicKeys.serverPort +import BasicKeys.{ serverHost, serverPort, serverAuthentication } import java.net.Socket import sjsonnew.JsonFormat import scala.concurrent.Await @@ -76,15 +76,22 @@ 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 = { - def port = (s get serverPort) match { + lazy val port = (s get serverPort) match { case Some(x) => x case None => 5001 } - def onIncomingSocket(socket: Socket): Unit = { + 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) + } + def onIncomingSocket(socket: Socket, instance: ServerInstance): Unit = { s.log.info(s"new client connected from: ${socket.getPort}") - val channel = new NetworkChannel(newChannelName, socket, Project structure s) + val channel = new NetworkChannel(newChannelName, socket, Project structure s, auth, instance) subscribe(channel) - channel.publishEventMessage(ChannelAcceptedEvent(channel.name)) } server match { case Some(x) => // do nothing @@ -92,7 +99,7 @@ private[sbt] final class CommandExchange { val portfile = (new File(".")).getAbsoluteFile / "project" / "target" / "active.json" val h = Hash.halfHashString(portfile.toURI.toString) val tokenfile = BuildPaths.getGlobalBase(s) / "server" / h / "token.json" - val x = Server.start("127.0.0.1", port, onIncomingSocket, portfile, tokenfile, s.log) + val x = Server.start(host, port, onIncomingSocket, auth, portfile, tokenfile, s.log) Await.ready(x.ready, Duration("10s")) x.ready.value match { case Some(Success(_)) => diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 22d51c5ce..eeaa8ed7c 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -10,11 +10,16 @@ import java.util.concurrent.atomic.AtomicBoolean import sbt.protocol._ import sjsonnew._ -final class NetworkChannel(val name: String, connection: Socket, structure: BuildStructure) +final class NetworkChannel(val name: String, + connection: Socket, + structure: BuildStructure, + auth: Set[ServerAuthentication], + instance: ServerInstance) extends CommandChannel { private val running = new AtomicBoolean(true) private val delimiter: Byte = '\n'.toByte private val out = connection.getOutputStream + private var initialized = false val thread = new Thread(s"sbt-networkchannel-${connection.getPort}") { override def run(): Unit = { @@ -42,12 +47,10 @@ final class NetworkChannel(val name: String, connection: Socket, structure: Buil ) delimPos = buffer.indexOf(delimiter) } - } catch { case _: SocketTimeoutException => // its ok } } - } finally { shutdown() } @@ -72,15 +75,44 @@ final class NetworkChannel(val name: String, connection: Socket, structure: Buil } def onCommand(command: CommandMessage): Unit = command match { + case x: InitCommand => onInitCommand(x) case x: ExecCommand => onExecCommand(x) case x: SettingQuery => onSettingQuery(x) } - private def onExecCommand(cmd: ExecCommand) = - append(Exec(cmd.commandLine, cmd.execId orElse Some(Exec.newExecId), Some(CommandSource(name)))) + private def onInitCommand(cmd: InitCommand): Unit = { + if (auth(ServerAuthentication.Token)) { + cmd.token match { + case Some(x) => + instance.authenticate(x) match { + case true => + initialized = true + publishEventMessage(ChannelAcceptedEvent(name)) + case _ => sys.error("invalid token") + } + case None => sys.error("init command but without token.") + } + } else { + initialized = true + } + } - private def onSettingQuery(req: SettingQuery) = - StandardMain.exchange publishEventMessage SettingQuery.handleSettingQuery(req, structure) + private def onExecCommand(cmd: ExecCommand) = { + if (initialized) { + append( + Exec(cmd.commandLine, cmd.execId orElse Some(Exec.newExecId), Some(CommandSource(name)))) + } else { + println(s"ignoring command $cmd before initialization") + } + } + + private def onSettingQuery(req: SettingQuery) = { + if (initialized) { + StandardMain.exchange publishEventMessage SettingQuery.handleSettingQuery(req, structure) + } else { + println(s"ignoring query $req before initialization") + } + } def shutdown(): Unit = { println("Shutting down client connection") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b1b31a0b4..8745f1dfb 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,7 +12,7 @@ object Dependencies { val baseScalaVersion = scala212 // sbt modules - private val ioVersion = "1.0.1" + private val ioVersion = "1.1.0" private val utilVersion = "1.0.1" private val lmVersion = "1.0.2" private val zincVersion = "1.0.1" diff --git a/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala b/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala new file mode 100644 index 000000000..e45b25c84 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/protocol/InitCommand.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol +final class InitCommand private ( + val token: Option[String], + val execId: Option[String]) extends sbt.protocol.CommandMessage() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: InitCommand => (this.token == x.token) && (this.execId == x.execId) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.protocol.InitCommand".##) + token.##) + execId.##) + } + override def toString: String = { + "InitCommand(" + token + ", " + execId + ")" + } + protected[this] def copy(token: Option[String] = token, execId: Option[String] = execId): InitCommand = { + new InitCommand(token, execId) + } + def withToken(token: Option[String]): InitCommand = { + copy(token = token) + } + def withToken(token: String): InitCommand = { + copy(token = Option(token)) + } + def withExecId(execId: Option[String]): InitCommand = { + copy(execId = execId) + } + def withExecId(execId: String): InitCommand = { + copy(execId = Option(execId)) + } +} +object InitCommand { + + def apply(token: Option[String], execId: Option[String]): InitCommand = new InitCommand(token, execId) + def apply(token: String, execId: String): InitCommand = new InitCommand(Option(token), Option(execId)) +} diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala index 650bf14dd..c80c7aaed 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/CommandMessageFormats.scala @@ -6,6 +6,6 @@ package sbt.protocol.codec import _root_.sjsonnew.JsonFormat -trait CommandMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats => -implicit lazy val CommandMessageFormat: JsonFormat[sbt.protocol.CommandMessage] = flatUnionFormat2[sbt.protocol.CommandMessage, sbt.protocol.ExecCommand, sbt.protocol.SettingQuery]("type") +trait CommandMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats => +implicit lazy val CommandMessageFormat: JsonFormat[sbt.protocol.CommandMessage] = flatUnionFormat3[sbt.protocol.CommandMessage, sbt.protocol.InitCommand, sbt.protocol.ExecCommand, sbt.protocol.SettingQuery]("type") } diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala new file mode 100644 index 000000000..8d3f50759 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/InitCommandFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.protocol.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InitCommandFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val InitCommandFormat: JsonFormat[sbt.protocol.InitCommand] = new JsonFormat[sbt.protocol.InitCommand] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.InitCommand = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val token = unbuilder.readField[Option[String]]("token") + val execId = unbuilder.readField[Option[String]]("execId") + unbuilder.endObject() + sbt.protocol.InitCommand(token, execId) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.protocol.InitCommand, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("token", obj.token) + builder.addField("execId", obj.execId) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala index 3b92fc46c..cc9d0fa90 100644 --- a/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala +++ b/protocol/src/main/contraband-scala/sbt/protocol/codec/JsonProtocol.scala @@ -5,6 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.protocol.codec trait JsonProtocol extends sjsonnew.BasicJsonProtocol + with sbt.protocol.codec.InitCommandFormats with sbt.protocol.codec.ExecCommandFormats with sbt.protocol.codec.SettingQueryFormats with sbt.protocol.codec.CommandMessageFormats diff --git a/protocol/src/main/contraband/server.contra b/protocol/src/main/contraband/server.contra index 31160a694..2976be229 100644 --- a/protocol/src/main/contraband/server.contra +++ b/protocol/src/main/contraband/server.contra @@ -7,6 +7,11 @@ package sbt.protocol interface CommandMessage { } +type InitCommand implements CommandMessage { + token: String + execId: String +} + ## Command to execute sbt command. type ExecCommand implements CommandMessage { commandLine: String! diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala index 4be0d8aad..6858ff238 100644 --- a/sbt/src/sbt-test/server/handshake/Client.scala +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -18,6 +18,10 @@ object Client extends App { val out = connection.getOutputStream val in = connection.getInputStream + out.write(s"""{ "type": "InitCommand", "token": "$getToken" }""".getBytes("utf-8")) + out.write(delimiter.toInt) + out.flush + out.write("""{ "type": "ExecCommand", "commandLine": "exit" }""".getBytes("utf-8")) out.write(delimiter.toInt) out.flush @@ -25,6 +29,34 @@ object Client extends App { val baseDirectory = new File(args(0)) IO.write(baseDirectory / "ok.txt", "ok") + def getToken: String = { + val tokenfile = new File(getTokenFile) + val json: JValue = Parser.parseFromFile(tokenfile).get + json match { + case JObject(fields) => + (fields find { _.field == "token" } map { _.value }) match { + case Some(JString(value)) => value + case _ => + sys.error("json doesn't token field that is JString") + } + case _ => sys.error("json doesn't have token field") + } + } + + def getTokenFile: URI = { + val portfile = baseDirectory / "project" / "target" / "active.json" + val json: JValue = Parser.parseFromFile(portfile).get + json match { + case JObject(fields) => + (fields find { _.field == "tokenfile" } map { _.value }) match { + case Some(JString(value)) => new URI(value) + case _ => + sys.error("json doesn't tokenfile field that is JString") + } + case _ => sys.error("json doesn't have tokenfile field") + } + } + def getPort: Int = { val portfile = baseDirectory / "project" / "target" / "active.json" val json: JValue = Parser.parseFromFile(portfile).get From 252e803de8c89a437f67b7e1120f5f24c511ee61 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Sep 2017 01:30:27 -0400 Subject: [PATCH 07/57] expand the token out to 128-bits --- .../scala/sbt/internal/server/Server.scala | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index fce9d591a..3ae06ae27 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -7,10 +7,12 @@ package server import java.io.File import java.net.{ SocketTimeoutException, InetAddress, ServerSocket, Socket } -import java.util.concurrent.atomic.{ AtomicBoolean, AtomicLong } +import java.util.concurrent.atomic.AtomicBoolean import java.nio.file.attribute.{ UserPrincipal, AclEntry, AclEntryPermission, AclEntryType } +import java.security.SecureRandom +import java.math.BigInteger import scala.concurrent.{ Future, Promise } -import scala.util.{ Try, Success, Failure, Random } +import scala.util.{ Try, Success, Failure } import sbt.internal.util.ErrorHandling import sbt.internal.protocol.{ PortFile, TokenFile } import sbt.util.Logger @@ -43,7 +45,8 @@ private[sbt] object Server { val running = new AtomicBoolean(false) val p: Promise[Unit] = Promise[Unit]() val ready: Future[Unit] = p.future - val token = new AtomicLong(Random.nextLong) + private[this] val rand = new SecureRandom + private[this] var token: String = nextToken val serverThread = new Thread("sbt-socket-server") { override def run(): Unit = { @@ -72,13 +75,17 @@ private[sbt] object Server { } serverThread.start() - override def authenticate(challenge: String): Boolean = { - try { - val l = challenge.toLong - token.compareAndSet(l, Random.nextLong) - } catch { - case _: NumberFormatException => false - } + override def authenticate(challenge: String): Boolean = synchronized { + if (token == challenge) { + token = nextToken + writeTokenfile() + true + } else false + } + + /** Generates 128-bit non-negative integer, and represent it as decimal string. */ + private[this] def nextToken: String = { + new BigInteger(128, rand).toString } override def shutdown(): Unit = { @@ -92,11 +99,11 @@ private[sbt] object Server { running.set(false) } - def writeTokenfile(): Unit = { + private[this] def writeTokenfile(): Unit = { import JsonProtocol._ val uri = s"tcp://$host:$port" - val t = TokenFile(uri, token.get.toString) + val t = TokenFile(uri, token) val jsonToken = Converter.toJson(t).get if (tokenfile.exists) { @@ -108,7 +115,7 @@ private[sbt] object Server { } /** Set the persmission of the file such that the only the owner can read/write it. */ - def ownerOnly(file: File): Unit = { + private[this] def ownerOnly(file: File): Unit = { def acl(owner: UserPrincipal) = { val builder = AclEntry.newBuilder builder.setPrincipal(owner) @@ -127,7 +134,7 @@ private[sbt] object Server { } // This file exists through the lifetime of the server. - def writePortfile(): Unit = { + private[this] def writePortfile(): Unit = { import JsonProtocol._ val uri = s"tcp://$host:$port" From d5e24979bff318a1f9089a533ef44c7e6f3c0806 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 25 Sep 2017 01:35:34 -0400 Subject: [PATCH 08/57] Reference token file using URI and full file path Node didn't seem to like read URI out of the box, and I am not sure if File -> URI -> File conversion is universally accepted. Ref sbt/sbt#3088 --- .../scala/sbt/internal/server/Server.scala | 14 +++++---- .../sbt/internal/protocol/PortFile.scala | 31 ++++++++++++------- .../protocol/codec/PortFileFormats.scala | 8 +++-- protocol/src/main/contraband/portfile.contra | 3 +- .../sbt-test/server/handshake/Client.scala | 6 ++-- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index 3ae06ae27..9c8d3ee95 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -138,12 +138,14 @@ private[sbt] object Server { import JsonProtocol._ val uri = s"tcp://$host:$port" - val tokenRef = - if (auth(ServerAuthentication.Token)) { - writeTokenfile() - Some(tokenfile.toURI.toString) - } else None - val p = PortFile(uri, tokenRef) + val p = + auth match { + case _ if auth(ServerAuthentication.Token) => + writeTokenfile() + PortFile(uri, Option(tokenfile.toString), Option(tokenfile.toURI.toString)) + case _ => + PortFile(uri, None, None) + } val json = Converter.toJson(p).get IO.write(portfile, CompactPrinter(json)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala index 648ab25b5..218aefdfb 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/PortFile.scala @@ -11,35 +11,42 @@ package sbt.internal.protocol final class PortFile private ( /** URI of the sbt server. */ val uri: String, - val tokenfile: Option[String]) extends Serializable { + val tokenfilePath: Option[String], + val tokenfileUri: Option[String]) extends Serializable { override def equals(o: Any): Boolean = o match { - case x: PortFile => (this.uri == x.uri) && (this.tokenfile == x.tokenfile) + case x: PortFile => (this.uri == x.uri) && (this.tokenfilePath == x.tokenfilePath) && (this.tokenfileUri == x.tokenfileUri) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.internal.protocol.PortFile".##) + uri.##) + tokenfile.##) + 37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.PortFile".##) + uri.##) + tokenfilePath.##) + tokenfileUri.##) } override def toString: String = { - "PortFile(" + uri + ", " + tokenfile + ")" + "PortFile(" + uri + ", " + tokenfilePath + ", " + tokenfileUri + ")" } - protected[this] def copy(uri: String = uri, tokenfile: Option[String] = tokenfile): PortFile = { - new PortFile(uri, tokenfile) + protected[this] def copy(uri: String = uri, tokenfilePath: Option[String] = tokenfilePath, tokenfileUri: Option[String] = tokenfileUri): PortFile = { + new PortFile(uri, tokenfilePath, tokenfileUri) } def withUri(uri: String): PortFile = { copy(uri = uri) } - def withTokenfile(tokenfile: Option[String]): PortFile = { - copy(tokenfile = tokenfile) + def withTokenfilePath(tokenfilePath: Option[String]): PortFile = { + copy(tokenfilePath = tokenfilePath) } - def withTokenfile(tokenfile: String): PortFile = { - copy(tokenfile = Option(tokenfile)) + def withTokenfilePath(tokenfilePath: String): PortFile = { + copy(tokenfilePath = Option(tokenfilePath)) + } + def withTokenfileUri(tokenfileUri: Option[String]): PortFile = { + copy(tokenfileUri = tokenfileUri) + } + def withTokenfileUri(tokenfileUri: String): PortFile = { + copy(tokenfileUri = Option(tokenfileUri)) } } object PortFile { - def apply(uri: String, tokenfile: Option[String]): PortFile = new PortFile(uri, tokenfile) - def apply(uri: String, tokenfile: String): PortFile = new PortFile(uri, Option(tokenfile)) + def apply(uri: String, tokenfilePath: Option[String], tokenfileUri: Option[String]): PortFile = new PortFile(uri, tokenfilePath, tokenfileUri) + def apply(uri: String, tokenfilePath: String, tokenfileUri: String): PortFile = new PortFile(uri, Option(tokenfilePath), Option(tokenfileUri)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala index 8bed2e6f9..0a60963d2 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/PortFileFormats.scala @@ -12,9 +12,10 @@ implicit lazy val PortFileFormat: JsonFormat[sbt.internal.protocol.PortFile] = n case Some(js) => unbuilder.beginObject(js) val uri = unbuilder.readField[String]("uri") - val tokenfile = unbuilder.readField[Option[String]]("tokenfile") + val tokenfilePath = unbuilder.readField[Option[String]]("tokenfilePath") + val tokenfileUri = unbuilder.readField[Option[String]]("tokenfileUri") unbuilder.endObject() - sbt.internal.protocol.PortFile(uri, tokenfile) + sbt.internal.protocol.PortFile(uri, tokenfilePath, tokenfileUri) case None => deserializationError("Expected JsObject but found None") } @@ -22,7 +23,8 @@ implicit lazy val PortFileFormat: JsonFormat[sbt.internal.protocol.PortFile] = n override def write[J](obj: sbt.internal.protocol.PortFile, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("uri", obj.uri) - builder.addField("tokenfile", obj.tokenfile) + builder.addField("tokenfilePath", obj.tokenfilePath) + builder.addField("tokenfileUri", obj.tokenfileUri) builder.endObject() } } diff --git a/protocol/src/main/contraband/portfile.contra b/protocol/src/main/contraband/portfile.contra index ccd3ec157..82f6567ef 100644 --- a/protocol/src/main/contraband/portfile.contra +++ b/protocol/src/main/contraband/portfile.contra @@ -7,7 +7,8 @@ package sbt.internal.protocol type PortFile { ## URI of the sbt server. uri: String! - tokenfile: String + tokenfilePath: String + tokenfileUri: String } type TokenFile { diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala index 6858ff238..2acbdb9bb 100644 --- a/sbt/src/sbt-test/server/handshake/Client.scala +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -30,7 +30,7 @@ object Client extends App { IO.write(baseDirectory / "ok.txt", "ok") def getToken: String = { - val tokenfile = new File(getTokenFile) + val tokenfile = new File(getTokenFileUri) val json: JValue = Parser.parseFromFile(tokenfile).get json match { case JObject(fields) => @@ -43,12 +43,12 @@ object Client extends App { } } - def getTokenFile: URI = { + def getTokenFileUri: URI = { val portfile = baseDirectory / "project" / "target" / "active.json" val json: JValue = Parser.parseFromFile(portfile).get json match { case JObject(fields) => - (fields find { _.field == "tokenfile" } map { _.value }) match { + (fields find { _.field == "tokenfileUri" } map { _.value }) match { case Some(JString(value)) => new URI(value) case _ => sys.error("json doesn't tokenfile field that is JString") From 632b14cf7875c53572f3503edb2d91036f979e3e Mon Sep 17 00:00:00 2001 From: Alexey Alekhin Date: Mon, 25 Sep 2017 15:06:17 +0200 Subject: [PATCH 09/57] Changed default version setting to 0.1.0-SNAPSHOT To make it compatible with semantic versioning. Fixes #3467. --- main/src/main/scala/sbt/Defaults.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 638ccbe21..33fac9d1b 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -187,7 +187,7 @@ object Defaults extends BuildCommon { }, crossVersion :== Disabled(), buildDependencies := Classpaths.constructBuildDependencies.value, - version :== "0.1-SNAPSHOT", + version :== "0.1.0-SNAPSHOT", classpathTypes :== Set("jar", "bundle") ++ CustomPomParser.JarPackagings, artifactClassifier :== None, checksums := Classpaths.bootChecksums(appConfiguration.value), From a08a93c5e639a0ffa72fb8cb80edca7554f52af1 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Mon, 25 Sep 2017 13:56:42 -0400 Subject: [PATCH 10/57] Set deprecation version to 1.1.0 --- scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala index 759c33358..00781be92 100644 --- a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala +++ b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala @@ -402,7 +402,7 @@ class ScriptedRunner { reportErrors(tests.flatMap(test => test.apply().flatten.toSeq).toList) } - @deprecated("No longer used", "1.0.2") + @deprecated("No longer used", "1.1.0") def get(tests: Seq[String], baseDirectory: File, log: Logger): Seq[ScriptedTest] = get(tests, baseDirectory, _ => true, log) def get(tests: Seq[String], @@ -411,7 +411,7 @@ class ScriptedRunner { log: Logger): Seq[ScriptedTest] = if (tests.isEmpty) listTests(baseDirectory, accept, log) else parseTests(tests) - @deprecated("No longer used", "1.0.2") + @deprecated("No longer used", "1.1.0") def listTests(baseDirectory: File, log: Logger): Seq[ScriptedTest] = listTests(baseDirectory, _ => true, log) def listTests(baseDirectory: File, From 3a666705a6fe8075410bbad51857a3c82b8d5ea0 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Mon, 25 Sep 2017 14:08:41 -0400 Subject: [PATCH 11/57] Add release note --- notes/1.1.0/filter-scripted-tests.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 notes/1.1.0/filter-scripted-tests.md diff --git a/notes/1.1.0/filter-scripted-tests.md b/notes/1.1.0/filter-scripted-tests.md new file mode 100644 index 000000000..4f216e9c2 --- /dev/null +++ b/notes/1.1.0/filter-scripted-tests.md @@ -0,0 +1,14 @@ +[@jonas]: https://github.com/jonas + +[#3564]: https://github.com/sbt/sbt/issues/3564 +[#3566]: https://github.com/sbt/sbt/pull/3566 + +### Improvements + +- Filter scripted tests based on optional `project/build.properties`. [#3564]/[#3566] by [@jonas] + +### Filtering scripted tests using `project/build.properties`. + +For all scripted tests in which `project/build.properties` exist, the value of the `sbt.version` property is read. If its binary version is different from `sbtBinaryVersion in pluginCrossBuild` the test will be skipped and a message indicating this will be logged. + +This allows you to define scripted tests that track the minimum supported sbt versions, e.g. 0.13.9 and 1.0.0-RC2. From e99aa6d7b3047b008016b318fa03284c73363209 Mon Sep 17 00:00:00 2001 From: Alexey Alekhin Date: Tue, 26 Sep 2017 01:22:44 +0200 Subject: [PATCH 12/57] Added release note for the `version` new default --- notes/1.1.0/new-version-default.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 notes/1.1.0/new-version-default.md diff --git a/notes/1.1.0/new-version-default.md b/notes/1.1.0/new-version-default.md new file mode 100644 index 000000000..c9aabd112 --- /dev/null +++ b/notes/1.1.0/new-version-default.md @@ -0,0 +1,3 @@ +### Improvements + +- Changes `version` setting default to `0.1.0-SNAPSHOT` for compatibility with Semantic Versioning From 402b9ef95c2a31c4dc7630cc5b4a7f93c4f8304f Mon Sep 17 00:00:00 2001 From: Alexey Alekhin Date: Tue, 26 Sep 2017 13:13:33 +0200 Subject: [PATCH 13/57] Fixed version in the package-delete-target test --- sbt/src/sbt-test/actions/package-delete-target/test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sbt/src/sbt-test/actions/package-delete-target/test b/sbt/src/sbt-test/actions/package-delete-target/test index a04dd25bd..7fa1b3ae7 100644 --- a/sbt/src/sbt-test/actions/package-delete-target/test +++ b/sbt/src/sbt-test/actions/package-delete-target/test @@ -1,4 +1,4 @@ -$ mkdir target/scala-2.12/delete-target_2.12-0.1-SNAPSHOT.jar -$ touch target/scala-2.12/delete-target_2.12-0.1-SNAPSHOT.jar/hello +$ mkdir target/scala-2.12/delete-target_2.12-0.1.0-SNAPSHOT.jar +$ touch target/scala-2.12/delete-target_2.12-0.1.0-SNAPSHOT.jar/hello -> package -$ exists target/scala-2.12/delete-target_2.12-0.1-SNAPSHOT.jar/hello +$ exists target/scala-2.12/delete-target_2.12-0.1.0-SNAPSHOT.jar/hello From 33a01f3ceb30e837508a79b3baae2527b15d4a25 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 27 Sep 2017 02:21:56 -0400 Subject: [PATCH 14/57] Unified slash syntax Fixes sbt/sbt#1812 This adds unified slash syntax for both sbt shell and the build.sbt DSL. Instead of the current `/config:intask::key`, this adds `//intask/key` where is the Scala identifier notation for the configurations like `Compile` and `Test`. This also adds a series of implicits called `SlashSyntax` that adds `/` operators to project refererences, configuration, and keys such that the same syntax works in build.sbt. These examples work for both from the shell and in build.sbt. Global / cancelable ThisBuild / scalaVersion Test / test root / Compile / compile / scalacOptions ProjectRef(uri("file:/xxx/helloworld/"),"root")/Compile/scalacOptions Zero / Zero / name The inspect command now outputs something that can be copy-pasted: > inspect compile [info] Task: sbt.inc.Analysis [info] Description: [info] Compiles sources. [info] Provided by: [info] ProjectRef(uri("file:/xxx/helloworld/"),"root")/Compile/compile [info] Defined at: [info] (sbt.Defaults) Defaults.scala:326 [info] Dependencies: [info] Compile/manipulateBytecode [info] Compile/incCompileSetup [info] Reverse dependencies: [info] Compile/printWarnings [info] Compile/products [info] Compile/discoveredSbtPlugins [info] Compile/discoveredMainClasses [info] Delegates: [info] Compile/compile [info] compile [info] ThisBuild/Compile/compile [info] ThisBuild/compile [info] Zero/Compile/compile [info] Global/compile [info] Related: [info] Test/compile --- build.sbt | 8 +- .../scala/sbt/internal/util/Attributes.scala | 5 + .../src/test/scala/SettingsTest.scala | 7 +- .../sbt/internal/util/complete/Parsers.scala | 9 ++ main-settings/src/main/scala/sbt/Def.scala | 32 +++- .../src/main/scala/sbt/Reference.scala | 2 +- main-settings/src/main/scala/sbt/Scope.scala | 89 +++++++++-- main/src/main/scala/sbt/Defaults.scala | 9 +- main/src/main/scala/sbt/SlashSyntax.scala | 148 ++++++++++++++++++ main/src/main/scala/sbt/internal/Act.scala | 100 ++++++++++-- .../main/scala/sbt/internal/KeyIndex.scala | 72 +++++++-- main/src/main/scala/sbt/internal/Load.scala | 9 +- main/src/test/scala/Delegates.scala | 3 +- main/src/test/scala/ParseKey.scala | 37 +++-- .../test/scala/sbt/internal/TestBuild.scala | 41 +++-- .../internal/server/SettingQueryTest.scala | 2 +- notes/1.1.0/unified-shell.markdown | 49 ++++++ sbt/src/main/scala/package.scala | 1 + .../actions/update-state-fail/build.sbt | 2 +- .../sbt-test/project/source-plugins/build.sbt | 2 +- .../source-plugins/project/plugins.sbt | 7 + sbt/src/sbt-test/project/unified/build.sbt | 70 +++++++++ .../unified/project/Dependencies.scala | 5 + .../src/test/scala/example/HelloTests.scala | 14 ++ sbt/src/sbt-test/project/unified/test | 28 ++++ 25 files changed, 673 insertions(+), 78 deletions(-) create mode 100644 main/src/main/scala/sbt/SlashSyntax.scala create mode 100644 notes/1.1.0/unified-shell.markdown create mode 100644 sbt/src/sbt-test/project/source-plugins/project/plugins.sbt create mode 100644 sbt/src/sbt-test/project/unified/build.sbt create mode 100644 sbt/src/sbt-test/project/unified/project/Dependencies.scala create mode 100644 sbt/src/sbt-test/project/unified/src/test/scala/example/HelloTests.scala create mode 100644 sbt/src/sbt-test/project/unified/test diff --git a/build.sbt b/build.sbt index df0ee03e5..5e695c989 100644 --- a/build.sbt +++ b/build.sbt @@ -45,7 +45,8 @@ def commonSettings: Seq[Setting[_]] = resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", concurrentRestrictions in Global += Util.testExclusiveRestriction, - testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), + testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), + testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), crossScalaVersions := Seq(baseScalaVersion), bintrayPackage := (bintrayPackage in ThisBuild).value, @@ -374,6 +375,11 @@ lazy val mainProj = (project in file("main")) mimaBinaryIssueFilters ++= Vector( // Changed the signature of NetworkChannel ctor. internal. exclude[DirectMissingMethodProblem]("sbt.internal.server.NetworkChannel.*"), + // ctor for ConfigIndex. internal. + exclude[DirectMissingMethodProblem]("sbt.internal.ConfigIndex.*"), + // New and changed methods on KeyIndex. internal. + exclude[ReversedMissingMethodProblem]("sbt.internal.KeyIndex.*"), + exclude[DirectMissingMethodProblem]("sbt.internal.KeyIndex.*"), ) ) .configure( diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index 7c24cfd29..80de459b2 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -92,6 +92,11 @@ object AttributeKey { rank0: Int )(implicit mf: Manifest[T], ojw: OptJsonWriter[T]): AttributeKey[T] = new SharedAttributeKey[T] { + require(name.headOption match { + case Some(c) => c.isLower + case None => false + }, s"A named attribute key must start with a lowercase letter: $name") + def manifest = mf val label = Util.hyphenToCamel(name) def description = description0 diff --git a/internal/util-collection/src/test/scala/SettingsTest.scala b/internal/util-collection/src/test/scala/SettingsTest.scala index 4dc8421d6..65878a59c 100644 --- a/internal/util-collection/src/test/scala/SettingsTest.scala +++ b/internal/util-collection/src/test/scala/SettingsTest.scala @@ -80,7 +80,12 @@ object SettingsTest extends Properties("settings") { private def mkAttrKeys[T](nr: Int)(implicit mf: Manifest[T]): Gen[List[AttributeKey[T]]] = { import Gen._ val nonEmptyAlphaStr = - nonEmptyListOf(alphaChar).map(_.mkString).suchThat(_.forall(_.isLetter)) + nonEmptyListOf(alphaChar) + .map({ xs: List[Char] => + val s = xs.mkString + s.take(1).toLowerCase + s.drop(1) + }) + .suchThat(_.forall(_.isLetter)) (for { list <- Gen.listOfN(nr, nonEmptyAlphaStr) suchThat (l => l.size == l.distinct.size) diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala index 55dea1033..3e15f3a14 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala @@ -43,6 +43,12 @@ trait Parsers { /** Parses a single letter, according to Char.isLetter, into a Char. */ lazy val Letter = charClass(_.isLetter, "letter") + /** Parses a single letter, according to Char.isUpper, into a Char. */ + lazy val Upper = charClass(_.isUpper, "upper") + + /** Parses a single letter, according to Char.isLower, into a Char. */ + lazy val Lower = charClass(_.isLower, "lower") + /** Parses the first Char in an sbt identifier, which must be a [[Letter]].*/ def IDStart = Letter @@ -67,6 +73,9 @@ trait Parsers { /** Parses a non-symbolic Scala-like identifier. The identifier must start with [[IDStart]] and contain zero or more [[ScalaIDChar]]s after that.*/ lazy val ScalaID = identifier(IDStart, ScalaIDChar) + /** Parses a non-symbolic Scala-like identifier. The identifier must start with [[Upper]] and contain zero or more [[ScalaIDChar]]s after that.*/ + lazy val CapitalizedID = identifier(Upper, ScalaIDChar) + /** Parses a String that starts with `start` and is followed by zero or more characters parsed by `rep`.*/ def identifier(start: Parser[Char], rep: Parser[Char]): Parser[String] = start ~ rep.* map { case x ~ xs => (x +: xs).mkString } diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index 534e674e3..8f3eca2e4 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -57,17 +57,36 @@ object Def extends Init[Scope] with TaskMacroExtra { ref => displayBuildRelative(currentBuild, multi, ref) )) + /** + * Returns a String expression for the given [[Reference]] (BuildRef, [[ProjectRef]], etc) + * relative to the current project. + */ + def displayRelativeReference(current: ProjectRef, project: Reference): String = + displayRelative(current, project, false) + + @deprecated("Use displayRelativeReference", "1.1.0") def displayRelative(current: ProjectRef, multi: Boolean, project: Reference): String = + displayRelative(current, project, true) + + /** + * Constructs the String of a given [[Reference]] relative to current. + * Note that this no longer takes "multi" parameter, and omits the subproject id at all times. + */ + private[sbt] def displayRelative(current: ProjectRef, + project: Reference, + trailingSlash: Boolean): String = { + val trailing = if (trailingSlash) "/" else "" project match { - case BuildRef(current.build) => "{.}/" - case `current` => if (multi) current.project + "/" else "" - case ProjectRef(current.build, x) => x + "/" - case _ => Reference.display(project) + "/" + case BuildRef(current.build) => "ThisBuild" + trailing + case `current` => "" + case ProjectRef(current.build, x) => x + trailing + case _ => Reference.display(project) + trailing } + } def displayBuildRelative(currentBuild: URI, multi: Boolean, project: Reference): String = project match { - case BuildRef(`currentBuild`) => "{.}/" + case BuildRef(`currentBuild`) => "ThisBuild/" case ProjectRef(`currentBuild`, x) => x + "/" case _ => Reference.display(project) + "/" } @@ -80,6 +99,9 @@ object Def extends Init[Scope] with TaskMacroExtra { def displayMasked(scoped: ScopedKey[_], mask: ScopeMask): String = Scope.displayMasked(scoped.scope, scoped.key.label, mask) + def displayMasked(scoped: ScopedKey[_], mask: ScopeMask, showZeroConfig: Boolean): String = + Scope.displayMasked(scoped.scope, scoped.key.label, mask, showZeroConfig) + def withColor(s: String, color: Option[String]): String = { val useColor = ConsoleAppender.formatEnabledInEnv color match { diff --git a/main-settings/src/main/scala/sbt/Reference.scala b/main-settings/src/main/scala/sbt/Reference.scala index cd7e3c08a..2867bed95 100644 --- a/main-settings/src/main/scala/sbt/Reference.scala +++ b/main-settings/src/main/scala/sbt/Reference.scala @@ -91,7 +91,7 @@ object Reference { case LocalRootProject => "{}" case LocalProject(id) => "{}" + id case RootProject(uri) => "{" + uri + " }" - case ProjectRef(uri, id) => "{" + uri + "}" + id + case ProjectRef(uri, id) => s"""ProjectRef(uri("$uri"),"$id")""" } def buildURI(ref: ResolvedReference): URI = ref match { diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 25dd46c85..2fa44221f 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -123,29 +123,84 @@ object Scope { case BuildRef(uri) => BuildRef(resolveBuild(current, uri)) } - def display(config: ConfigKey): String = config.name + ":" + def display(config: ConfigKey): String = guessConfigIdent(config.name) + "/" + + private[sbt] val configIdents: Map[String, String] = + Map( + "it" -> "IntegrationTest", + "scala-tool" -> "ScalaTool", + "plugin" -> "CompilerPlugin" + ) + private[sbt] val configIdentsInverse: Map[String, String] = + configIdents map { _.swap } + + private[sbt] def guessConfigIdent(conf: String): String = + configIdents.applyOrElse(conf, (x: String) => x.capitalize) + + private[sbt] def unguessConfigIdent(conf: String): String = + configIdentsInverse.applyOrElse(conf, (x: String) => x.take(1).toLowerCase + x.drop(1)) + + def displayConfigKey012Style(config: ConfigKey): String = config.name + ":" def display(scope: Scope, sep: String): String = displayMasked(scope, sep, showProject, ScopeMask()) - def displayMasked(scope: Scope, sep: String, mask: ScopeMask): String = - displayMasked(scope, sep, showProject, mask) - def display(scope: Scope, sep: String, showProject: Reference => String): String = displayMasked(scope, sep, showProject, ScopeMask()) - def displayMasked( - scope: Scope, - sep: String, - showProject: Reference => String, - mask: ScopeMask - ): String = { + private[sbt] def displayPedantic(scope: Scope, sep: String): String = + displayMasked(scope, sep, showProject, ScopeMask(), true) + + def displayMasked(scope: Scope, sep: String, mask: ScopeMask): String = + displayMasked(scope, sep, showProject, mask) + + def displayMasked(scope: Scope, sep: String, mask: ScopeMask, showZeroConfig: Boolean): String = + displayMasked(scope, sep, showProject, mask, showZeroConfig) + + def displayMasked(scope: Scope, + sep: String, + showProject: Reference => String, + mask: ScopeMask): String = + displayMasked(scope, sep, showProject, mask, false) + + /** + * unified slash style introduced in sbt 1.1.0. + * By default, sbt will no longer display the Zero-config, + * so `name` will render as `name` as opposed to `{uri}proj/Zero/name`. + * Technically speaking an unspecified configuration axis defaults to + * the scope delegation (first configuration defining the key, then Zero). + */ + def displayMasked(scope: Scope, + sep: String, + showProject: Reference => String, + mask: ScopeMask, + showZeroConfig: Boolean): String = { import scope.{ project, config, task, extra } - val configPrefix = config.foldStrict(display, "*:", ".:") + val zeroConfig = if (showZeroConfig) "Zero/" else "" + val configPrefix = config.foldStrict(display, zeroConfig, "./") + val taskPrefix = task.foldStrict(_.label + "/", "", "./") + val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil) + val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")") + if (scope == GlobalScope) "Global/" + sep + postfix + else + mask.concatShow(projectPrefix(project, showProject), configPrefix, taskPrefix, sep, postfix) + } + + // sbt 0.12 style + def display012StyleMasked(scope: Scope, + sep: String, + showProject: Reference => String, + mask: ScopeMask): String = { + import scope.{ project, config, task, extra } + val configPrefix = config.foldStrict(displayConfigKey012Style, "*:", ".:") val taskPrefix = task.foldStrict(_.label + "::", "", ".::") val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil) val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")") - mask.concatShow(projectPrefix(project, showProject), configPrefix, taskPrefix, sep, postfix) + mask.concatShow(projectPrefix012Style(project, showProject), + configPrefix, + taskPrefix, + sep, + postfix) } def equal(a: Scope, b: Scope, mask: ScopeMask): Boolean = @@ -154,10 +209,12 @@ object Scope { (!mask.task || a.task == b.task) && (!mask.extra || a.extra == b.extra) - def projectPrefix( - project: ScopeAxis[Reference], - show: Reference => String = showProject - ): String = + def projectPrefix(project: ScopeAxis[Reference], + show: Reference => String = showProject): String = + project.foldStrict(show, "Zero/", "./") + + def projectPrefix012Style(project: ScopeAxis[Reference], + show: Reference => String = showProject): String = project.foldStrict(show, "*/", "./") def showProject = (ref: Reference) => Reference.display(ref) + "/" diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 638ccbe21..8a4ceab4a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2336,13 +2336,20 @@ object Classpaths { else Def.task((evictionWarningOptions in update).value) }.value + val extracted = (Project extract state0) + val isPlugin = sbtPlugin.value + val thisRef = thisProjectRef.value + val label = + if (isPlugin) Reference.display(thisRef) + else Def.displayRelativeReference(extracted.currentRef, thisRef) + LibraryManagement.cachedUpdate( // LM API lm = dependencyResolution.value, // Ivy-free ModuleDescriptor module = ivyModule.value, s.cacheStoreFactory.sub(updateCacheName.value), - Reference.display(thisProjectRef.value), + label = label, updateConf, substituteScalaFiles(scalaOrganization.value, _)(providedScalaJars), skip = (skip in update).value, diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala new file mode 100644 index 000000000..b6a8b560b --- /dev/null +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -0,0 +1,148 @@ +package sbt + +import java.io.File +import sbt.librarymanagement.Configuration + +/** + * SlashSyntax implements the slash syntax to scope keys for build.sbt DSL. + * The implicits are set up such that the order that the scope components + * must appear in the order of the project axis, the configuration axis, and + * the task axis. This ordering is the same as the shell syntax. + * + * @example + * {{{ + * Global / cancelable := true + * ThisBuild / scalaVersion := "2.12.2" + * Test / test := () + * console / scalacOptions += "-deprecation" + * Compile / console / scalacOptions += "-Ywarn-numeric-widen" + * projA / Compile / console / scalacOptions += "-feature" + * Zero / Zero / name := "foo" + * }}} + */ +trait SlashSyntax { + import SlashSyntax._ + + implicit def sbtScopeSyntaxRichReference(r: Reference): RichReference = + new RichReference(Scope(Select(r), This, This, This)) + + implicit def sbtScopeSyntaxRichProject(p: Project): RichReference = + new RichReference(Scope(Select(p), This, This, This)) + + implicit def sbtScopeSyntaxRichConfiguration(c: Configuration): RichConfiguration = + new RichConfiguration(Scope(This, Select(c), This, This)) + + implicit def sbtScopeSyntaxRichScope(s: Scope): RichScope = + new RichScope(s) + + implicit def sbtScopeSyntaxRichScopeFromScoped(t: Scoped): RichScope = + new RichScope(Scope(This, This, Select(t.key), This)) + + implicit def sbtScopeSyntaxRichScopeAxis(a: ScopeAxis[Reference]): RichScopeAxis = + new RichScopeAxis(a) + + // Materialize the setting key thunk + implicit def sbtScopeSyntaxSettingKeyThunkMaterialize[A]( + thunk: SettingKeyThunk[A]): SettingKey[A] = + thunk.materialize + + implicit def sbtScopeSyntaxSettingKeyThunkKeyRescope[A](thunk: SettingKeyThunk[A]): RichScope = + thunk.rescope + + // Materialize the task key thunk + implicit def sbtScopeSyntaxTaskKeyThunkMaterialize[A](thunk: TaskKeyThunk[A]): TaskKey[A] = + thunk.materialize + + implicit def sbtScopeSyntaxTaskKeyThunkRescope[A](thunk: TaskKeyThunk[A]): RichScope = + thunk.rescope + + // Materialize the input key thunk + implicit def sbtScopeSyntaxInputKeyThunkMaterialize[A](thunk: InputKeyThunk[A]): InputKey[A] = + thunk.materialize + + implicit def sbtScopeSyntaxInputKeyThunkRescope[A](thunk: InputKeyThunk[A]): RichScope = + thunk.rescope +} + +object SlashSyntax { + + /** RichReference wraps a project to provide the `/` operator for scoping. */ + final class RichReference(s: Scope) { + def /(c: Configuration): RichConfiguration = new RichConfiguration(s in c) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(s, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(s, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(s, key) + } + + /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ + final class RichConfiguration(s: Scope) { + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(s, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(s, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(s, key) + } + + /** RichScope wraps a general scope to provide the `/` operator for scoping. */ + final class RichScope(scope: Scope) { + def /[A](key: SettingKey[A]): SettingKey[A] = key in scope + def /[A](key: TaskKey[A]): TaskKey[A] = key in scope + def /[A](key: InputKey[A]): InputKey[A] = key in scope + } + + /** RichScopeAxis wraps a project axis to provide the `/` operator to `Zero` for scoping. */ + final class RichScopeAxis(a: ScopeAxis[Reference]) { + private[this] def toScope: Scope = Scope(a, This, This, This) + + def /(c: Configuration): RichConfiguration = new RichConfiguration(toScope in c) + + // This is for handling `Zero / Zero / name`. + def /(configAxis: ScopeAxis[ConfigKey]): RichConfiguration = + new RichConfiguration(toScope.copy(config = configAxis)) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(toScope, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(toScope, key) + + // We don't know what the key is for yet, so just capture in a thunk. + def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(toScope, key) + } + + /** + * SettingKeyThunk is a thunk used to hold a scope and a key + * while we're not sure if the key is terminal or task-scoping. + */ + final class SettingKeyThunk[A](base: Scope, key: SettingKey[A]) { + private[sbt] def materialize: SettingKey[A] = key in base + private[sbt] def rescope: RichScope = new RichScope(base in key.key) + } + + /** + * TaskKeyThunk is a thunk used to hold a scope and a key + * while we're not sure if the key is terminal or task-scoping. + */ + final class TaskKeyThunk[A](base: Scope, key: TaskKey[A]) { + private[sbt] def materialize: TaskKey[A] = key in base + private[sbt] def rescope: RichScope = new RichScope(base in key.key) + } + + /** + * InputKeyThunk is a thunk used to hold a scope and a key + * while we're not sure if the key is terminal or task-scoping. + */ + final class InputKeyThunk[A](base: Scope, key: InputKey[A]) { + private[sbt] def materialize: InputKey[A] = key in base + private[sbt] def rescope: RichScope = new RichScope(base in key.key) + } +} diff --git a/main/src/main/scala/sbt/internal/Act.scala b/main/src/main/scala/sbt/internal/Act.scala index c34640143..c72e89dda 100644 --- a/main/src/main/scala/sbt/internal/Act.scala +++ b/main/src/main/scala/sbt/internal/Act.scala @@ -19,6 +19,13 @@ final class ParsedKey(val key: ScopedKey[_], val mask: ScopeMask) object Act { val ZeroString = "*" + private[sbt] val GlobalIdent = "Global" + private[sbt] val ZeroIdent = "Zero" + private[sbt] val ThisBuildIdent = "ThisBuild" + + // new separator for unified shell syntax. this allows optional whitespace around /. + private[sbt] val spacedSlash: Parser[Unit] = + token(OptSpace ~> '/' <~ OptSpace).examples("/").map(_ => ()) // this does not take aggregation into account def scopedKey(index: KeyIndex, @@ -52,12 +59,29 @@ object Act { current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String], keyMap: Map[String, AttributeKey[_]]): Parser[Seq[Parser[ParsedKey]]] = { - for { - rawProject <- optProjectRef(index, current) - proj = resolveProject(rawProject, current) - confAmb <- config(index configs proj) - partialMask = ScopeMask(rawProject.isExplicit, confAmb.isExplicit, false, false) - } yield taskKeyExtra(index, defaultConfigs, keyMap, proj, confAmb, partialMask) + def fullKey = + for { + rawProject <- optProjectRef(index, current) + proj = resolveProject(rawProject, current) + confAmb <- configIdent(index configs proj, + index configIdents proj, + index.fromConfigIdent(proj)) + partialMask = ScopeMask(rawProject.isExplicit, confAmb.isExplicit, false, false) + } yield taskKeyExtra(index, defaultConfigs, keyMap, proj, confAmb, partialMask) + + val globalIdent = token(GlobalIdent ~ spacedSlash) ^^^ ParsedGlobal + def globalKey = + for { + g <- globalIdent + } yield + taskKeyExtra(index, + defaultConfigs, + keyMap, + None, + ParsedZero, + ScopeMask(true, true, false, false)) + + globalKey | fullKey } def taskKeyExtra( @@ -148,6 +172,23 @@ object Act { token((ZeroString ^^^ ParsedZero | value(examples(ID, confs, "configuration"))) <~ sep) ?? Omitted } + // New configuration parser that's able to parse configuration ident trailed by slash. + private[sbt] def configIdent(confs: Set[String], + idents: Set[String], + fromIdent: String => String): Parser[ParsedAxis[String]] = { + val oldSep: Parser[Char] = ':' + val sep: Parser[Unit] = spacedSlash !!! "Expected '/'" + token( + ((ZeroString ^^^ ParsedZero) <~ oldSep) + | ((ZeroString ^^^ ParsedZero) <~ sep) + | ((ZeroIdent ^^^ ParsedZero) <~ sep) + | (value(examples(ID, confs, "configuration")) <~ oldSep) + | (value(examples(CapitalizedID, idents, "configuration ident") map { + fromIdent(_) + }) <~ sep) + ) ?? Omitted + } + def configs(explicit: ParsedAxis[String], defaultConfigs: Option[ResolvedReference] => Seq[String], proj: Option[ResolvedReference], @@ -156,8 +197,8 @@ object Act { case Omitted => None +: defaultConfigurations(proj, index, defaultConfigs).flatMap( nonEmptyConfig(index, proj)) - case ParsedZero => None :: Nil - case pv: ParsedValue[x] => Some(pv.value) :: Nil + case ParsedZero | ParsedGlobal => None :: Nil + case pv: ParsedValue[x] => Some(pv.value) :: Nil } def defaultConfigurations( @@ -220,11 +261,15 @@ object Act { val valid = allKnown ++ normKeys val suggested = normKeys.map(_._1).toSet val keyP = filterStrings(examples(ID, suggested, "key"), valid.keySet, "key") map valid - (token(value(keyP) | ZeroString ^^^ ParsedZero) <~ token("::".id)) ?? Omitted + (token( + value(keyP) + | ZeroString ^^^ ParsedZero + | ZeroIdent ^^^ ParsedZero) <~ (token("::".id) | spacedSlash)) ?? Omitted } + def resolveTask(task: ParsedAxis[AttributeKey[_]]): Option[AttributeKey[_]] = task match { - case ParsedZero | Omitted => None + case ParsedZero | ParsedGlobal | Omitted => None case t: ParsedValue[AttributeKey[_]] @unchecked => Some(t.value) } @@ -260,10 +305,36 @@ object Act { } def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedAxis[ResolvedReference]] = { - val zero = token(ZeroString ~ '/') ^^^ ParsedZero - val trailing = '/' !!! "Expected '/' (if selecting a project)" - zero | value(resolvedReference(index, currentBuild, trailing)) + val global = token(ZeroString ~ spacedSlash) ^^^ ParsedZero + val zeroIdent = token(ZeroIdent ~ spacedSlash) ^^^ ParsedZero + val thisBuildIdent = value(token(ThisBuildIdent ~ spacedSlash) ^^^ BuildRef(currentBuild)) + val trailing = spacedSlash !!! "Expected '/' (if selecting a project)" + global | zeroIdent | thisBuildIdent | + value(resolvedReferenceIdent(index, currentBuild, trailing)) | + value(resolvedReference(index, currentBuild, trailing)) } + + private[sbt] def resolvedReferenceIdent(index: KeyIndex, + currentBuild: URI, + trailing: Parser[_]): Parser[ResolvedReference] = { + def projectID(uri: URI) = + token( + DQuoteChar ~> examplesStrict(ID, index projects uri, "project ID") <~ DQuoteChar <~ OptSpace <~ ")" <~ trailing) + def projectRef(uri: URI) = projectID(uri) map { id => + ProjectRef(uri, id) + } + + val uris = index.buildURIs + val resolvedURI = Uri(uris).map(uri => Scope.resolveBuild(currentBuild, uri)) + + val buildRef = token( + "ProjectRef(" ~> OptSpace ~> "uri(" ~> OptSpace ~> DQuoteChar ~> + resolvedURI <~ DQuoteChar <~ OptSpace <~ ")" <~ spacedComma) + buildRef flatMap { uri => + projectRef(uri) + } + } + def resolvedReference(index: KeyIndex, currentBuild: URI, trailing: Parser[_]): Parser[ResolvedReference] = { @@ -284,11 +355,13 @@ object Act { } def optProjectRef(index: KeyIndex, current: ProjectRef): Parser[ParsedAxis[ResolvedReference]] = projectRef(index, current.build) ?? Omitted + def resolveProject(parsed: ParsedAxis[ResolvedReference], current: ProjectRef): Option[ResolvedReference] = parsed match { case Omitted => Some(current) case ParsedZero => None + case ParsedGlobal => None case pv: ParsedValue[rr] => Some(pv.value) } @@ -375,6 +448,7 @@ object Act { sealed trait ParsedAxis[+T] { final def isExplicit = this != Omitted } + final object ParsedGlobal extends ParsedAxis[Nothing] final object ParsedZero extends ParsedAxis[Nothing] final object Omitted extends ParsedAxis[Nothing] final class ParsedValue[T](val value: T) extends ParsedAxis[T] diff --git a/main/src/main/scala/sbt/internal/KeyIndex.scala b/main/src/main/scala/sbt/internal/KeyIndex.scala index 48ce42d27..573fed713 100644 --- a/main/src/main/scala/sbt/internal/KeyIndex.scala +++ b/main/src/main/scala/sbt/internal/KeyIndex.scala @@ -9,20 +9,32 @@ import Def.ScopedKey import sbt.internal.util.complete.DefaultParsers.validID import sbt.internal.util.Types.some import sbt.internal.util.{ AttributeKey, Relation } +import sbt.librarymanagement.Configuration object KeyIndex { def empty: ExtendableKeyIndex = new KeyIndex0(emptyBuildIndex) - def apply(known: Iterable[ScopedKey[_]], projects: Map[URI, Set[String]]): ExtendableKeyIndex = - (base(projects) /: known) { _ add _ } + def apply(known: Iterable[ScopedKey[_]], + projects: Map[URI, Set[String]], + configurations: Map[String, Seq[Configuration]]): ExtendableKeyIndex = + (base(projects, configurations) /: known) { _ add _ } def aggregate(known: Iterable[ScopedKey[_]], extra: BuildUtil[_], - projects: Map[URI, Set[String]]): ExtendableKeyIndex = - (base(projects) /: known) { (index, key) => + projects: Map[URI, Set[String]], + configurations: Map[String, Seq[Configuration]]): ExtendableKeyIndex = + (base(projects, configurations) /: known) { (index, key) => index.addAggregated(key, extra) } - private[this] def base(projects: Map[URI, Set[String]]): ExtendableKeyIndex = { - val data = for ((uri, ids) <- projects) yield { - val data = ids.map(id => Option(id) -> new ConfigIndex(Map.empty)) + private[this] def base(projects: Map[URI, Set[String]], + configurations: Map[String, Seq[Configuration]]): ExtendableKeyIndex = { + val data = for { + (uri, ids) <- projects + } yield { + val data = ids map { id => + val configs = configurations.getOrElse(id, Seq()) + Option(id) -> new ConfigIndex(Map.empty, Map(configs map { c => + (c.name, c.id) + }: _*)) + } Option(uri) -> new ProjectIndex(data.toMap) } new KeyIndex0(new BuildIndex(data.toMap)) @@ -33,6 +45,14 @@ object KeyIndex { def projects(uri: URI) = concat(_.projects(uri)) def exists(project: Option[ResolvedReference]): Boolean = indices.exists(_ exists project) def configs(proj: Option[ResolvedReference]) = concat(_.configs(proj)) + private[sbt] def configIdents(proj: Option[ResolvedReference]) = concat(_.configIdents(proj)) + private[sbt] def fromConfigIdent(proj: Option[ResolvedReference])(configIdent: String): String = + (indices find { idx => + idx.exists(proj) + }) match { + case Some(idx) => idx.fromConfigIdent(proj)(configIdent) + case _ => Scope.unguessConfigIdent(configIdent) + } def tasks(proj: Option[ResolvedReference], conf: Option[String]) = concat(_.tasks(proj, conf)) def tasks(proj: Option[ResolvedReference], conf: Option[String], key: String) = concat(_.tasks(proj, conf, key)) @@ -46,7 +66,7 @@ object KeyIndex { private[sbt] def getOr[A, B](m: Map[A, B], key: A, or: B): B = m.getOrElse(key, or) private[sbt] def keySet[A, B](m: Map[Option[A], B]): Set[A] = m.keys.flatten.toSet private[sbt] val emptyAKeyIndex = new AKeyIndex(Relation.empty) - private[sbt] val emptyConfigIndex = new ConfigIndex(Map.empty) + private[sbt] val emptyConfigIndex = new ConfigIndex(Map.empty, Map.empty) private[sbt] val emptyProjectIndex = new ProjectIndex(Map.empty) private[sbt] val emptyBuildIndex = new BuildIndex(Map.empty) } @@ -73,6 +93,8 @@ trait KeyIndex { def keys(proj: Option[ResolvedReference], conf: Option[String], task: Option[AttributeKey[_]]): Set[String] + private[sbt] def configIdents(project: Option[ResolvedReference]): Set[String] + private[sbt] def fromConfigIdent(proj: Option[ResolvedReference])(configIdent: String): String } trait ExtendableKeyIndex extends KeyIndex { def add(scoped: ScopedKey[_]): ExtendableKeyIndex @@ -87,13 +109,34 @@ private[sbt] final class AKeyIndex(val data: Relation[Option[AttributeKey[_]], S def tasks: Set[AttributeKey[_]] = data._1s.flatten.toSet def tasks(key: String): Set[AttributeKey[_]] = data.reverse(key).flatten.toSet } -private[sbt] final class ConfigIndex(val data: Map[Option[String], AKeyIndex]) { + +/* + * data contains the mapping between a configuration and keys. + * identData contains the mapping between a configuration and its identifier. + */ +private[sbt] final class ConfigIndex(val data: Map[Option[String], AKeyIndex], + val identData: Map[String, String]) { def add(config: Option[String], task: Option[AttributeKey[_]], - key: AttributeKey[_]): ConfigIndex = - new ConfigIndex(data updated (config, keyIndex(config).add(task, key))) + key: AttributeKey[_]): ConfigIndex = { + new ConfigIndex(data updated (config, keyIndex(config).add(task, key)), this.identData) + } + def keyIndex(conf: Option[String]): AKeyIndex = getOr(data, conf, emptyAKeyIndex) def configs: Set[String] = keySet(data) + + private[sbt] val configIdentsInverse: Map[String, String] = + identData map { _.swap } + + private[sbt] lazy val idents: Set[String] = + configs map { config => + identData.getOrElse(config, Scope.guessConfigIdent(config)) + } + + // guess Configuration name from an identifier. + // There's a guessing involved because we could have scoped key that Project is not aware of. + private[sbt] def fromConfigIdent(ident: String): String = + configIdentsInverse.getOrElse(ident, Scope.unguessConfigIdent(ident)) } private[sbt] final class ProjectIndex(val data: Map[Option[String], ConfigIndex]) { def add(id: Option[String], @@ -122,6 +165,13 @@ private[sbt] final class KeyIndex0(val data: BuildIndex) extends ExtendableKeyIn data.data.get(build).flatMap(_.data.get(project)).isDefined } def configs(project: Option[ResolvedReference]): Set[String] = confIndex(project).configs + + private[sbt] def configIdents(project: Option[ResolvedReference]): Set[String] = + confIndex(project).idents + + private[sbt] def fromConfigIdent(proj: Option[ResolvedReference])(configIdent: String): String = + confIndex(proj).fromConfigIdent(configIdent) + def tasks(proj: Option[ResolvedReference], conf: Option[String]): Set[AttributeKey[_]] = keyIndex(proj, conf).tasks def tasks(proj: Option[ResolvedReference], diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 30e802782..0ed05e692 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -324,8 +324,13 @@ private[sbt] object Load { val attributeKeys = Index.attributeKeys(data) ++ keys.map(_.key) val scopedKeys = keys ++ data.allKeys((s, k) => ScopedKey(s, k)).toVector val projectsMap = projects.mapValues(_.defined.keySet) - val keyIndex = KeyIndex(scopedKeys.toVector, projectsMap) - val aggIndex = KeyIndex.aggregate(scopedKeys.toVector, extra(keyIndex), projectsMap) + val configsMap: Map[String, Seq[Configuration]] = Map(projects.values.toSeq flatMap { bu => + bu.defined map { + case (k, v) => (k, v.configurations) + } + }: _*) + val keyIndex = KeyIndex(scopedKeys.toVector, projectsMap, configsMap) + val aggIndex = KeyIndex.aggregate(scopedKeys.toVector, extra(keyIndex), projectsMap, configsMap) new StructureIndex( Index.stringToKeyMap(attributeKeys), Index.taskToKeyMap(data), diff --git a/main/src/test/scala/Delegates.scala b/main/src/test/scala/Delegates.scala index 7136b943d..df2dec96b 100644 --- a/main/src/test/scala/Delegates.scala +++ b/main/src/test/scala/Delegates.scala @@ -3,12 +3,13 @@ package sbt import Project._ import sbt.internal.util.Types.idFun import sbt.internal.TestBuild._ +import sbt.librarymanagement.Configuration import org.scalacheck._ import Prop._ import Gen._ object Delegates extends Properties("delegates") { - property("generate non-empty configs") = forAll { (c: Seq[Config]) => + property("generate non-empty configs") = forAll { (c: Seq[Configuration]) => c.nonEmpty } property("generate non-empty tasks") = forAll { (t: Seq[Taskk]) => diff --git a/main/src/test/scala/ParseKey.scala b/main/src/test/scala/ParseKey.scala index 2d2198f10..a0b62d8c3 100644 --- a/main/src/test/scala/ParseKey.scala +++ b/main/src/test/scala/ParseKey.scala @@ -22,13 +22,17 @@ object ParseKey extends Properties("Key parser test") { property("An explicitly specified axis is always parsed to that explicit value") = forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) => - import skm.{ structure, key, mask } + import skm.{ structure, key, mask => mask0 } + val hasZeroConfig = key.scope.config == Zero + val mask = if (hasZeroConfig) mask0.copy(project = true) else mask0 val expected = resolve(structure, key, mask) - val string = displayMasked(key, mask) - - ("Key: " + displayFull(key)) |: - parseExpected(structure, string, expected, mask) + // Note that this explicitly displays the configuration axis set to Zero. + // This is to disambiguate `proj/Zero/name`, which could render potentially + // as `Zero/name`, but could be interpretted as `Zero/Zero/name`. + val s = displayMasked(key, mask, hasZeroConfig) + ("Key: " + displayPedantic(key)) |: + parseExpected(structure, s, expected, mask) } property("An unspecified project axis resolves to the current project") = @@ -37,13 +41,16 @@ object ParseKey extends Properties("Key parser test") { val mask = skm.mask.copy(project = false) val string = displayMasked(key, mask) + // skip when config axis is set to Zero + val hasZeroConfig = key.scope.config == Zero - ("Key: " + displayFull(key)) |: + ("Key: " + displayPedantic(key)) |: ("Mask: " + mask) |: ("Current: " + structure.current) |: parse(structure, string) { - case Left(err) => false - case Right(sk) => sk.scope.project == Select(structure.current) + case Left(err) => false + case Right(sk) if hasZeroConfig => true + case Right(sk) => sk.scope.project == Select(structure.current) } } @@ -53,7 +60,7 @@ object ParseKey extends Properties("Key parser test") { val mask = skm.mask.copy(task = false) val string = displayMasked(key, mask) - ("Key: " + displayFull(key)) |: + ("Key: " + displayPedantic(key)) |: ("Mask: " + mask) |: parse(structure, string) { case Left(err) => false @@ -69,15 +76,18 @@ object ParseKey extends Properties("Key parser test") { val string = displayMasked(key, mask) val resolvedConfig = Resolve.resolveConfig(structure.extra, key.key, mask)(key.scope).config - ("Key: " + displayFull(key)) |: + ("Key: " + displayPedantic(key)) |: ("Mask: " + mask) |: ("Expected configuration: " + resolvedConfig.map(_.name)) |: parse(structure, string) { - case Right(sk) => sk.scope.config == resolvedConfig + case Right(sk) => (sk.scope.config == resolvedConfig) || (sk.scope == Scope.GlobalScope) case Left(err) => false } } + def displayPedantic(scoped: ScopedKey[_]): String = + Scope.displayPedantic(scoped.scope, scoped.key.label) + lazy val structureDefinedKey: Gen[StructureKeyMask] = structureKeyMask { s => for (scope <- TestBuild.scope(s.env); key <- oneOf(s.allAttributeKeys.toSeq)) yield ScopedKey(scope, key) @@ -101,7 +111,10 @@ object ParseKey extends Properties("Key parser test") { ("Mask: " + mask) |: parse(structure, s) { case Left(err) => false - case Right(sk) => Project.equal(sk, expected, mask) + case Right(sk) => + (s"${sk}.key == ${expected}.key: ${sk.key == expected.key}") |: + (s"${sk.scope} == ${expected.scope}: ${Scope.equal(sk.scope, expected.scope, mask)}") |: + Project.equal(sk, expected, mask) } def parse(structure: Structure, s: String)(f: Either[String, ScopedKey[_]] => Prop): Prop = { diff --git a/main/src/test/scala/sbt/internal/TestBuild.scala b/main/src/test/scala/sbt/internal/TestBuild.scala index 5f0a1dda4..96a4b1383 100644 --- a/main/src/test/scala/sbt/internal/TestBuild.scala +++ b/main/src/test/scala/sbt/internal/TestBuild.scala @@ -5,6 +5,7 @@ import Def.{ ScopedKey, Setting } import sbt.internal.util.{ AttributeKey, AttributeMap, Relation, Settings } import sbt.internal.util.Types.{ const, some } import sbt.internal.util.complete.Parser +import sbt.librarymanagement.Configuration import java.net.URI import org.scalacheck._ @@ -119,7 +120,7 @@ abstract class TestBuild { lazy val allProjects = builds.flatMap(_.allProjects) def rootProject(uri: URI): String = buildMap(uri).root.id def inheritConfig(ref: ResolvedReference, config: ConfigKey) = - projectFor(ref).confMap(config.name).extended map toConfigKey + projectFor(ref).confMap(config.name).extendsConfigs map toConfigKey def inheritTask(task: AttributeKey[_]) = taskMap.get(task) match { case None => Nil; case Some(t) => t.delegates map getKey } @@ -144,7 +145,7 @@ abstract class TestBuild { } yield Scope(project = ref, config = c, task = t, extra = Zero) } def getKey: Taskk => AttributeKey[_] = _.key - def toConfigKey: Config => ConfigKey = c => ConfigKey(c.name) + def toConfigKey: Configuration => ConfigKey = c => ConfigKey(c.name) final class Build(val uri: URI, val projects: Seq[Proj]) { override def toString = "Build " + uri.toString + " :\n " + projects.mkString("\n ") val allProjects = projects map { p => @@ -156,7 +157,7 @@ abstract class TestBuild { final class Proj( val id: String, val delegates: Seq[ProjectRef], - val configurations: Seq[Config] + val configurations: Seq[Configuration] ) { override def toString = "Project " + id + "\n Delegates:\n " + delegates.mkString("\n ") + @@ -164,9 +165,6 @@ abstract class TestBuild { val confMap = mapBy(configurations)(_.name) } - final class Config(val name: String, val extended: Seq[Config]) { - override def toString = name + " (extends: " + extended.map(_.name).mkString(", ") + ")" - } final class Taskk(val key: AttributeKey[String], val delegates: Seq[Taskk]) { override def toString = key.label + " (delegates: " + delegates.map(_.key.label).mkString(", ") + ")" @@ -222,7 +220,15 @@ abstract class TestBuild { val keys = data.allKeys((s, key) => ScopedKey(s, key)) val keyMap = keys.map(k => (k.key.label, k.key)).toMap[String, AttributeKey[_]] val projectsMap = env.builds.map(b => (b.uri, b.projects.map(_.id).toSet)).toMap - new Structure(env, current, data, KeyIndex(keys, projectsMap), keyMap) + val confs = for { + b <- env.builds.toVector + p <- b.projects.toVector + c <- p.configurations.toVector + } yield c + val confMap = Map(confs map { c => + (c.name, Seq(c)) + }: _*) + new Structure(env, current, data, KeyIndex(keys, projectsMap, confMap), keyMap) } implicit lazy val mkEnv: Gen[Env] = { @@ -239,7 +245,14 @@ abstract class TestBuild { } implicit lazy val idGen: Gen[String] = - for (size <- chooseShrinkable(1, MaxIDSize); cs <- listOfN(size, alphaChar)) yield cs.mkString + for { + size <- chooseShrinkable(1, MaxIDSize) + cs <- listOfN(size, alphaChar) + } yield { + val xs = cs.mkString + xs.take(1).toLowerCase + xs.drop(1) + } + implicit lazy val optIDGen: Gen[Option[String]] = frequency((1, idGen map some.fn), (1, None)) implicit lazy val uriGen: Gen[URI] = for (sch <- idGen; ssp <- idGen; frag <- optIDGen) yield new URI(sch, ssp, frag.orNull) @@ -256,7 +269,7 @@ abstract class TestBuild { implicit def genProjects(build: URI)(implicit genID: Gen[String], maxDeps: Gen[Int], count: Gen[Int], - confs: Gen[Seq[Config]]): Gen[Seq[Proj]] = + confs: Gen[Seq[Configuration]]): Gen[Seq[Proj]] = genAcyclic(maxDeps, genID, count) { (id: String) => for (cs <- confs) yield { (deps: Seq[Proj]) => new Proj(id, deps.map { dep => @@ -264,10 +277,16 @@ abstract class TestBuild { }, cs) } } + def genConfigs(implicit genName: Gen[String], maxDeps: Gen[Int], - count: Gen[Int]): Gen[Seq[Config]] = - genAcyclicDirect[Config, String](maxDeps, genName, count)((key, deps) => new Config(key, deps)) + count: Gen[Int]): Gen[Seq[Configuration]] = + genAcyclicDirect[Configuration, String](maxDeps, genName, count)( + (key, deps) => + Configuration + .of(key.capitalize, key) + .withExtendsConfigs(deps.toVector)) + def genTasks(implicit genName: Gen[String], maxDeps: Gen[Int], count: Gen[Int]): Gen[Seq[Taskk]] = genAcyclicDirect[Taskk, String](maxDeps, genName, count)((key, deps) => new Taskk(AttributeKey[String](key), deps)) diff --git a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala index 3ef94c83b..c928e108f 100644 --- a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala +++ b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala @@ -202,7 +202,7 @@ object SettingQueryTest extends org.specs2.mutable.Specification { "scalaVersion" in qko("Not a valid project ID: scalaVersion\\nscalaVersion\\n ^") "t/scalacOptions" in qko( - s"Key {$baseUri}t/compile:scalacOptions is a task, can only query settings") + s"""Key ProjectRef(uri(\\"$baseUri\\"),\\"t\\")/Compile/scalacOptions is a task, can only query settings""") "t/fooo" in qko( "Expected ':' (if selecting a configuration)\\nNot a valid key: fooo (similar: fork)\\nt/fooo\\n ^") } diff --git a/notes/1.1.0/unified-shell.markdown b/notes/1.1.0/unified-shell.markdown new file mode 100644 index 000000000..f10435046 --- /dev/null +++ b/notes/1.1.0/unified-shell.markdown @@ -0,0 +1,49 @@ + +### Fixes with compatibility implications + +- + +### Improvements + +- Unifies sbt shell and build.sbt syntax. See below. + +### Bug fixes + +- + +### Unified slash syntax for sbt shell and build.sbt + +This adds unified slash syntax for both sbt shell and the build.sbt DSL. +Instead of the current `/config:intask::key`, this adds +`//intask/key` where `` is the Scala identifier +notation for the configurations like `Compile` and `Test`. (The old shell syntax will continue to function) + +These examples work both from the shell and in build.sbt. + + Global / cancelable + ThisBuild / scalaVersion + Test / test + root / Compile / compile / scalacOptions + ProjectRef(uri("file:/xxx/helloworld/"),"root")/Compile/scalacOptions + Zero / Zero / name + +The inspect command now outputs something that can be copy-pasted: + + > inspect compile + [info] Task: sbt.inc.Analysis + [info] Description: + [info] Compiles sources. + [info] Provided by: + [info] ProjectRef(uri("file:/xxx/helloworld/"),"root")/Compile/compile + [info] Defined at: + [info] (sbt.Defaults) Defaults.scala:326 + [info] Dependencies: + [info] Compile/manipulateBytecode + [info] Compile/incCompileSetup + .... + +[#3434][3434] by [@eed3si9n][@eed3si9n] + + [3434]: https://github.com/sbt/sbt/pull/3434 + [@eed3si9n]: https://github.com/eed3si9n + [@dwijnand]: http://github.com/dwijnand diff --git a/sbt/src/main/scala/package.scala b/sbt/src/main/scala/package.scala index 94603839f..0954f8306 100644 --- a/sbt/src/main/scala/package.scala +++ b/sbt/src/main/scala/package.scala @@ -16,6 +16,7 @@ package object sbt with sbt.ScopeFilter.Make with sbt.BuildSyntax with sbt.OptionSyntax + with sbt.SlashSyntax with sbt.Import { // IO def uri(s: String): URI = new URI(s) diff --git a/sbt/src/sbt-test/actions/update-state-fail/build.sbt b/sbt/src/sbt-test/actions/update-state-fail/build.sbt index cb3695fd4..6a5c0fc9f 100644 --- a/sbt/src/sbt-test/actions/update-state-fail/build.sbt +++ b/sbt/src/sbt-test/actions/update-state-fail/build.sbt @@ -1,4 +1,4 @@ -lazy val akey = AttributeKey[Int]("TestKey") +lazy val akey = AttributeKey[Int]("testKey") lazy val testTask = taskKey[String]("") lazy val check = inputKey[Unit]("") diff --git a/sbt/src/sbt-test/project/source-plugins/build.sbt b/sbt/src/sbt-test/project/source-plugins/build.sbt index 1e0d4c099..0b5906837 100644 --- a/sbt/src/sbt-test/project/source-plugins/build.sbt +++ b/sbt/src/sbt-test/project/source-plugins/build.sbt @@ -4,4 +4,4 @@ organization := "org.example" proguardSettings -useJGit \ No newline at end of file +useJGit diff --git a/sbt/src/sbt-test/project/source-plugins/project/plugins.sbt b/sbt/src/sbt-test/project/source-plugins/project/plugins.sbt new file mode 100644 index 000000000..6dc6ae42e --- /dev/null +++ b/sbt/src/sbt-test/project/source-plugins/project/plugins.sbt @@ -0,0 +1,7 @@ +lazy val plugins = (project in file(".")) + .dependsOn(proguard, git) + +// e7b4732969c137db1b5 +// d4974f7362bf55d3f52 +lazy val proguard = uri("git://github.com/sbt/sbt-proguard.git#e7b4732969c137db1b5") +lazy val git = uri("git://github.com/sbt/sbt-git.git#2e7c2503850698d60bb") diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt new file mode 100644 index 000000000..fdbdaf2c0 --- /dev/null +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -0,0 +1,70 @@ +import Dependencies._ +import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } +import sbt.internal.Inspect + +lazy val root = (project in file(".")) + .settings( + Global / cancelable := true, + ThisBuild / scalaVersion := "2.12.3", + console / scalacOptions += "-deprecation", + Compile / console / scalacOptions += "-Ywarn-numeric-widen", + projA / Compile / console / scalacOptions += "-feature", + Zero / Zero / name := "foo", + + libraryDependencies += uTest % Test, + testFrameworks += new TestFramework("utest.runner.Framework"), + + commands += Command("inspectCheck", inspectBrief, inspectDetailed)(Inspect.parser) { + case (s, (option, sk)) => + val actual = Inspect.output(s, option, sk) + val expected = s"""Task: Unit +Description: +\tExecutes all tests. +Provided by: +\tProjectRef(uri("${baseDirectory.value.toURI}"),"root")/Test/test +Defined at: +\t(sbt.Defaults.testTasks) Defaults.scala:670 +Dependencies: +\tTest/executeTests +\tTest/test/streams +\tTest/state +\tTest/test/testResultLogger +Delegates: +\tTest/test +\tRuntime/test +\tCompile/test +\ttest +\tThisBuild/Test/test +\tThisBuild/Runtime/test +\tThisBuild/Compile/test +\tThisBuild/test +\tZero/Test/test +\tZero/Runtime/test +\tZero/Compile/test +\tGlobal/test +Related: +\tprojA/Test/test""" + + if (processText(actual) == processText(expected)) () + else { + sys.error(s"""actual: +$actual + +expected: +$expected +""") + } + s.log.info(actual) + s + } + ) + +lazy val projA = (project in file("a")) + +def processText(s: String): Vector[String] = { + val xs = s.split(IO.Newline).toVector + .map( _.trim ) + // declared location of the task is unstable. + .filterNot( _.contains("Defaults.scala") ) + xs +} diff --git a/sbt/src/sbt-test/project/unified/project/Dependencies.scala b/sbt/src/sbt-test/project/unified/project/Dependencies.scala new file mode 100644 index 000000000..0d84ec7d4 --- /dev/null +++ b/sbt/src/sbt-test/project/unified/project/Dependencies.scala @@ -0,0 +1,5 @@ +import sbt._ + +object Dependencies { + val uTest = "com.lihaoyi" %% "utest" % "0.5.3" +} diff --git a/sbt/src/sbt-test/project/unified/src/test/scala/example/HelloTests.scala b/sbt/src/sbt-test/project/unified/src/test/scala/example/HelloTests.scala new file mode 100644 index 000000000..a9b386667 --- /dev/null +++ b/sbt/src/sbt-test/project/unified/src/test/scala/example/HelloTests.scala @@ -0,0 +1,14 @@ +package example + +import utest._ + +import java.nio.file.{ Files, Path, Paths } + +object HelloTests extends TestSuite { + val tests = Tests { + 'test1 - { + val p = Paths.get("target", "foo") + Files.createFile(p) + } + } +} diff --git a/sbt/src/sbt-test/project/unified/test b/sbt/src/sbt-test/project/unified/test new file mode 100644 index 000000000..bbfaab29b --- /dev/null +++ b/sbt/src/sbt-test/project/unified/test @@ -0,0 +1,28 @@ +> root/Compile/compile + +# "Global" now works in shell. +> show Global/cancelable + +# "Global" now works in shell. optional whitespace around / +> show Global / cancelable + +# "ThisBuild" now works in shell. +> show ThisBuild/scalaVersion + +# "ThisBuild" now works in shell. optional whitespace around / +> show ThisBuild / scalaVersion + +$ mkdir target +> Test/test +# Check the side-effect of executing uTest +$ exists target/foo + +# use all axes +> show root/Compile/compile/scalacOptions + +# use all axes. optional whitespace around / +> show root / Compile / compile / scalacOptions + +> show Zero / Zero / name + +> inspectCheck test From b0306b738ee99a7e781e371930a718389ee65498 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 28 Sep 2017 01:42:23 -0400 Subject: [PATCH 15/57] Add whitespaces in Show of scoped keys ``` Provided by: ProjectRef(uri("...."), "root") / Test / test Dependencies: Test / executeTests Test / test / streams Test / state Test / test / testResultLogger ``` --- main-settings/src/main/scala/sbt/Def.scala | 8 ++-- .../src/main/scala/sbt/Reference.scala | 2 +- main-settings/src/main/scala/sbt/Scope.scala | 26 +++++++---- .../internal/server/SettingQueryTest.scala | 2 +- sbt/src/sbt-test/project/unified/build.sbt | 43 +++++++++++-------- 5 files changed, 49 insertions(+), 32 deletions(-) diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index 8f3eca2e4..70e8c460d 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -75,7 +75,7 @@ object Def extends Init[Scope] with TaskMacroExtra { private[sbt] def displayRelative(current: ProjectRef, project: Reference, trailingSlash: Boolean): String = { - val trailing = if (trailingSlash) "/" else "" + val trailing = if (trailingSlash) " /" else "" project match { case BuildRef(current.build) => "ThisBuild" + trailing case `current` => "" @@ -86,9 +86,9 @@ object Def extends Init[Scope] with TaskMacroExtra { def displayBuildRelative(currentBuild: URI, multi: Boolean, project: Reference): String = project match { - case BuildRef(`currentBuild`) => "ThisBuild/" - case ProjectRef(`currentBuild`, x) => x + "/" - case _ => Reference.display(project) + "/" + case BuildRef(`currentBuild`) => "ThisBuild /" + case ProjectRef(`currentBuild`, x) => x + " /" + case _ => Reference.display(project) + " /" } def displayFull(scoped: ScopedKey[_]): String = displayFull(scoped, None) diff --git a/main-settings/src/main/scala/sbt/Reference.scala b/main-settings/src/main/scala/sbt/Reference.scala index 2867bed95..07a4b268a 100644 --- a/main-settings/src/main/scala/sbt/Reference.scala +++ b/main-settings/src/main/scala/sbt/Reference.scala @@ -91,7 +91,7 @@ object Reference { case LocalRootProject => "{}" case LocalProject(id) => "{}" + id case RootProject(uri) => "{" + uri + " }" - case ProjectRef(uri, id) => s"""ProjectRef(uri("$uri"),"$id")""" + case ProjectRef(uri, id) => s"""ProjectRef(uri("$uri"), "$id")""" } def buildURI(ref: ResolvedReference): URI = ref match { diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 2fa44221f..80661eb6b 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -123,7 +123,7 @@ object Scope { case BuildRef(uri) => BuildRef(resolveBuild(current, uri)) } - def display(config: ConfigKey): String = guessConfigIdent(config.name) + "/" + def display(config: ConfigKey): String = guessConfigIdent(config.name) + " /" private[sbt] val configIdents: Map[String, String] = Map( @@ -176,16 +176,24 @@ object Scope { mask: ScopeMask, showZeroConfig: Boolean): String = { import scope.{ project, config, task, extra } - val zeroConfig = if (showZeroConfig) "Zero/" else "" + val zeroConfig = if (showZeroConfig) "Zero /" else "" val configPrefix = config.foldStrict(display, zeroConfig, "./") - val taskPrefix = task.foldStrict(_.label + "/", "", "./") + val taskPrefix = task.foldStrict(_.label + " /", "", "./") val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil) val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")") - if (scope == GlobalScope) "Global/" + sep + postfix + if (scope == GlobalScope) "Global / " + sep + postfix else - mask.concatShow(projectPrefix(project, showProject), configPrefix, taskPrefix, sep, postfix) + mask.concatShow(appendSpace(projectPrefix(project, showProject)), + appendSpace(configPrefix), + appendSpace(taskPrefix), + sep, + postfix) } + private[sbt] def appendSpace(s: String): String = + if (s == "") "" + else s + " " + // sbt 0.12 style def display012StyleMasked(scope: Scope, sep: String, @@ -196,7 +204,7 @@ object Scope { val taskPrefix = task.foldStrict(_.label + "::", "", ".::") val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil) val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")") - mask.concatShow(projectPrefix012Style(project, showProject), + mask.concatShow(projectPrefix012Style(project, showProject012Style), configPrefix, taskPrefix, sep, @@ -211,13 +219,15 @@ object Scope { def projectPrefix(project: ScopeAxis[Reference], show: Reference => String = showProject): String = - project.foldStrict(show, "Zero/", "./") + project.foldStrict(show, "Zero /", "./") def projectPrefix012Style(project: ScopeAxis[Reference], show: Reference => String = showProject): String = project.foldStrict(show, "*/", "./") - def showProject = (ref: Reference) => Reference.display(ref) + "/" + def showProject = (ref: Reference) => Reference.display(ref) + " /" + + def showProject012Style = (ref: Reference) => Reference.display(ref) + "/" def transformTaskName(s: String) = { val parts = s.split("-+") diff --git a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala index c928e108f..d7c88e71c 100644 --- a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala +++ b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala @@ -202,7 +202,7 @@ object SettingQueryTest extends org.specs2.mutable.Specification { "scalaVersion" in qko("Not a valid project ID: scalaVersion\\nscalaVersion\\n ^") "t/scalacOptions" in qko( - s"""Key ProjectRef(uri(\\"$baseUri\\"),\\"t\\")/Compile/scalacOptions is a task, can only query settings""") + s"""Key ProjectRef(uri(\\"$baseUri\\"), \\"t\\") / Compile / scalacOptions is a task, can only query settings""") "t/fooo" in qko( "Expected ':' (if selecting a configuration)\\nNot a valid key: fooo (similar: fork)\\nt/fooo\\n ^") } diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt index fdbdaf2c0..935e32855 100644 --- a/sbt/src/sbt-test/project/unified/build.sbt +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -21,29 +21,29 @@ lazy val root = (project in file(".")) Description: \tExecutes all tests. Provided by: -\tProjectRef(uri("${baseDirectory.value.toURI}"),"root")/Test/test +\tProjectRef(uri("${baseDirectory.value.toURI}"), "root") / Test / test Defined at: \t(sbt.Defaults.testTasks) Defaults.scala:670 Dependencies: -\tTest/executeTests -\tTest/test/streams -\tTest/state -\tTest/test/testResultLogger +\tTest / executeTests +\tTest / test / streams +\tTest / state +\tTest / test / testResultLogger Delegates: -\tTest/test -\tRuntime/test -\tCompile/test +\tTest / test +\tRuntime / test +\tCompile / test \ttest -\tThisBuild/Test/test -\tThisBuild/Runtime/test -\tThisBuild/Compile/test -\tThisBuild/test -\tZero/Test/test -\tZero/Runtime/test -\tZero/Compile/test -\tGlobal/test +\tThisBuild / Test / test +\tThisBuild / Runtime / test +\tThisBuild / Compile / test +\tThisBuild / test +\tZero / Test / test +\tZero / Runtime / test +\tZero / Compile / test +\tGlobal / test Related: -\tprojA/Test/test""" +\tprojA / Test / test""" if (processText(actual) == processText(expected)) () else { @@ -52,7 +52,14 @@ $actual expected: $expected -""") + +diff: +""" + +( + processText(actual) + zip processText(expected) + filter { case ( a, b) => a != b } +)) } s.log.info(actual) s From 30e81398fd14f3b2c2dc736f2c07acb3795e9ba4 Mon Sep 17 00:00:00 2001 From: Age Mooij Date: Thu, 28 Sep 2017 13:37:38 +0200 Subject: [PATCH 16/57] Removed unused local val --- main/src/main/scala/sbt/Defaults.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 428d1046d..c96d8d83d 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2215,7 +2215,6 @@ object Classpaths { val ref = thisProjectRef.value if (skp) Def.task { s.log.debug(s"Skipping publish* for ${ref.project}") } else Def.task { - val cfg = config.value IvyActions.publish(ivyModule.value, config.value, s.log) } } tag (Tags.Publish, Tags.Network) From 0c1c380f7100815d78143853dcb87ecbea9d9ced Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 2 Oct 2017 03:33:29 -0400 Subject: [PATCH 17/57] begins language server protocol This is the first cut for the Language Server Protocol on top of server that is still work in progress. With this change, sbt is able to invoke `compile` task on saving files in VS Code. --- .gitignore | 5 + build.sbt | 35 + .../scala/sbt/internal/CommandChannel.scala | 1 + .../scala/sbt/internal/ConsoleChannel.scala | 2 + main/src/main/scala/sbt/Defaults.scala | 11 +- .../scala/sbt/internal/CommandExchange.scala | 79 +- .../scala/sbt/internal/RelayAppender.scala | 17 +- .../server/LanguageServerProtocol.scala | 127 + .../server/LanguageServerReporter.scala | 122 + .../sbt/internal/server/NetworkChannel.scala | 267 +- project/Dependencies.scala | 4 +- project/plugins.sbt | 2 +- .../InitializeResultFormats.scala | 26 + .../ServerCapabilitiesFormats.scala | 26 + .../langserver/ClientCapabilities.scala | 29 + .../sbt/internal/langserver/Diagnostic.scala | 73 + .../langserver/InitializeParams.scala | 72 + .../langserver/InitializeResult.scala | 33 + .../sbt/internal/langserver/Location.scala | 37 + .../sbt/internal/langserver/Position.scala | 42 + .../langserver/PublishDiagnosticsParams.scala | 39 + .../sbt/internal/langserver/Range.scala | 42 + .../sbt/internal/langserver/SaveOptions.scala | 37 + .../langserver/ServerCapabilities.scala | 44 + .../langserver/TextDocumentSyncOptions.scala | 64 + .../codec/ClientCapabilitiesFormats.scala | 27 + .../langserver/codec/DiagnosticFormats.scala | 35 + .../codec/InitializeParamsFormats.scala | 37 + .../codec/InitializeResultFormats.scala | 27 + .../langserver/codec/JsonProtocol.scala | 20 + .../langserver/codec/LocationFormats.scala | 29 + .../langserver/codec/PositionFormats.scala | 29 + .../PublishDiagnosticsParamsFormats.scala | 29 + .../langserver/codec/RangeFormats.scala | 29 + .../langserver/codec/SaveOptionsFormats.scala | 27 + .../codec/ServerCapabilitiesFormats.scala | 29 + .../TextDocumentSyncOptionsFormats.scala | 35 + .../internal/protocol/InitializeOption.scala | 36 + .../internal/protocol/JsonRpcMessage.scala | 27 + .../protocol/JsonRpcNotificationMessage.scala | 46 + .../protocol/JsonRpcRequestMessage.scala | 51 + .../protocol/JsonRpcResponseError.scala | 50 + .../protocol/JsonRpcResponseMessage.scala | 60 + .../codec/InitializeOptionFormats.scala | 27 + protocol/src/main/contraband/jsonrpc.contra | 74 + protocol/src/main/contraband/lsp.contra | 112 + protocol/src/main/contraband/portfile.contra | 4 + .../langserver/DiagnosticSeverity.scala | 26 + .../sbt/internal/langserver/ErrorCodes.scala | 19 + .../protocol/codec/JsonRPCProtocol.scala | 13 + .../JsonRpcNotificationMessageFormats.scala | 40 + .../codec/JsonRpcRequestMessageFormats.scala | 45 + .../codec/JsonRpcResponseErrorFormats.scala | 39 + .../codec/JsonRpcResponseMessageFormats.scala | 52 + .../scala/sbt/protocol/Serialization.scala | 62 + .../sbt-test/server/handshake/Client.scala | 40 +- sbt/src/sbt-test/server/handshake/test | 2 +- vscode-sbt-scala/.vscode/launch.json | 33 + vscode-sbt-scala/.vscode/settings.json | 10 + vscode-sbt-scala/.vscode/tasks.json | 79 + vscode-sbt-scala/client/.vscodeignore | 9 + vscode-sbt-scala/client/README.md | 6 + .../client/images/sbt-logo-455x262.png | Bin 0 -> 6715 bytes vscode-sbt-scala/client/images/sbt-logo.svg | 26 + vscode-sbt-scala/client/package-lock.json | 2256 +++++++++++++++++ vscode-sbt-scala/client/package.json | 35 + vscode-sbt-scala/client/src/extension.ts | 45 + vscode-sbt-scala/client/tsconfig.json | 19 + vscode-sbt-scala/package-lock.json | 26 + vscode-sbt-scala/package.json | 26 + vscode-sbt-scala/server/package-lock.json | 41 + vscode-sbt-scala/server/package.json | 24 + vscode-sbt-scala/server/src/server.ts | 33 + vscode-sbt-scala/server/tsconfig.json | 17 + 74 files changed, 5035 insertions(+), 64 deletions(-) create mode 100644 main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala create mode 100644 main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala create mode 100644 protocol/src/main/contraband-scala/InitializeResultFormats.scala create mode 100644 protocol/src/main/contraband-scala/ServerCapabilitiesFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/ClientCapabilities.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/Diagnostic.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeParams.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeResult.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/Location.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/Position.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/PublishDiagnosticsParams.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/Range.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/SaveOptions.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/ServerCapabilities.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/TextDocumentSyncOptions.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ClientCapabilitiesFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeParamsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PositionFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/RangeFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SaveOptionsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentSyncOptionsFormats.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcMessage.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcNotificationMessage.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcRequestMessage.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseError.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseMessage.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala create mode 100644 protocol/src/main/contraband/jsonrpc.contra create mode 100644 protocol/src/main/contraband/lsp.contra create mode 100644 protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala create mode 100644 protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala create mode 100644 protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala create mode 100644 protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala create mode 100644 protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala create mode 100644 protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala create mode 100644 protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala create mode 100644 vscode-sbt-scala/.vscode/launch.json create mode 100644 vscode-sbt-scala/.vscode/settings.json create mode 100644 vscode-sbt-scala/.vscode/tasks.json create mode 100644 vscode-sbt-scala/client/.vscodeignore create mode 100644 vscode-sbt-scala/client/README.md create mode 100644 vscode-sbt-scala/client/images/sbt-logo-455x262.png create mode 100644 vscode-sbt-scala/client/images/sbt-logo.svg create mode 100644 vscode-sbt-scala/client/package-lock.json create mode 100644 vscode-sbt-scala/client/package.json create mode 100644 vscode-sbt-scala/client/src/extension.ts create mode 100644 vscode-sbt-scala/client/tsconfig.json create mode 100644 vscode-sbt-scala/package-lock.json create mode 100644 vscode-sbt-scala/package.json create mode 100644 vscode-sbt-scala/server/package-lock.json create mode 100644 vscode-sbt-scala/server/package.json create mode 100644 vscode-sbt-scala/server/src/server.ts create mode 100644 vscode-sbt-scala/server/tsconfig.json diff --git a/.gitignore b/.gitignore index 9dfa96975..3996caad8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ target/ __pycache__ toolbox.classpath +out +node_modules +vscode-sbt-scala/client/server +npm-debug.log +*.vsix diff --git a/build.sbt b/build.sbt index 5e695c989..fec97e6be 100644 --- a/build.sbt +++ b/build.sbt @@ -407,6 +407,41 @@ lazy val sbtProj = (project in file("sbt")) ) .configure(addSbtCompilerBridge) +lazy val vscodePlugin = (project in file("vscode-sbt-scala")) + .settings( + crossPaths := false, + crossScalaVersions := Seq(baseScalaVersion), + skip in publish := true, + compile in Compile := { + val u = update.value + import sbt.internal.inc.Analysis + import scala.sys.process._ + Process(s"npm run compile", Option(baseDirectory.value)).! + Analysis.empty + }, + update := { + val old = update.value + val t = target.value / "updated" + val base = baseDirectory.value + if (t.exists) () + else { + import scala.sys.process._ + Process("npm install", Option(base)).! + IO.touch(t) + } + old + }, + cleanFiles ++= { + val base = baseDirectory.value + Vector( + target.value / "updated", + base / "node_modules", base / "client" / "node_modules", + base / "client" / "server", + base / "client" / "out", + base / "server" / "node_modules") filter { _.exists } + } + ) + lazy val sbtIgnoredProblems = { Seq( // Added more items to Import trait. diff --git a/main-command/src/main/scala/sbt/internal/CommandChannel.scala b/main-command/src/main/scala/sbt/internal/CommandChannel.scala index 0f9eb963e..ec46a0738 100644 --- a/main-command/src/main/scala/sbt/internal/CommandChannel.scala +++ b/main-command/src/main/scala/sbt/internal/CommandChannel.scala @@ -16,6 +16,7 @@ abstract class CommandChannel { commandQueue.add(exec) def poll: Option[Exec] = Option(commandQueue.poll) + def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit def publishEvent[A: JsonFormat](event: A): Unit def publishEventMessage(event: EventMessage): Unit def publishBytes(bytes: Array[Byte]): Unit diff --git a/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala b/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala index ddbf747e1..eff9abf9e 100644 --- a/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala +++ b/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala @@ -31,6 +31,8 @@ private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel def publishBytes(bytes: Array[Byte]): Unit = () + def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit = () + def publishEvent[A: JsonFormat](event: A): Unit = () def publishEventMessage(event: EventMessage): Unit = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 428d1046d..851c25f8b 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -23,6 +23,7 @@ import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } +import sbt.internal.server.LanguageServerReporter import sbt.internal.testing.TestLogger import sbt.internal.util._ import sbt.internal.util.Attributed.data @@ -1402,6 +1403,14 @@ object Defaults extends BuildCommon { val compilers: Compilers = ci.compilers val i = ci.withCompilers(onArgs(compilers)) try { + val prev = i.previousResult + prev.analysis.toOption map { analysis => + i.setup.reporter match { + case r: LanguageServerReporter => + r.resetPrevious(analysis) + case _ => () + } + } incCompiler.compile(i, s.log) } finally x.close() // workaround for #937 } @@ -1441,7 +1450,7 @@ object Defaults extends BuildCommon { compileOrder.value ), compilerReporter := { - new ManagedLoggedReporter( + new LanguageServerReporter( maxErrors.value, streams.value.log, foldMappers(sourcePositionMappers.value) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 574dfd8ce..66702e677 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -4,19 +4,21 @@ package internal import java.net.SocketException import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.atomic.AtomicInteger -import sbt.internal.server._ -import sbt.internal.util.StringEvent -import sbt.protocol.{ EventMessage, Serialization } import scala.collection.mutable.ListBuffer import scala.annotation.tailrec import BasicKeys.{ serverHost, serverPort, serverAuthentication } import java.net.Socket import sjsonnew.JsonFormat +import sjsonnew.shaded.scalajson.ast.unsafe._ import scala.concurrent.Await import scala.concurrent.duration.Duration import scala.util.{ Success, Failure } import sbt.io.syntax._ import sbt.io.Hash +import sbt.internal.server._ +import sbt.internal.util.{ StringEvent, ObjectEvent } +import sbt.internal.util.codec.JValueFormats +import sbt.protocol.{ EventMessage, Serialization, ChannelAcceptedEvent } /** * The command exchange merges multiple command channels (e.g. network and console), @@ -34,6 +36,8 @@ private[sbt] final class CommandExchange { private val commandQueue: ConcurrentLinkedQueue[Exec] = new ConcurrentLinkedQueue() private val channelBuffer: ListBuffer[CommandChannel] = new ListBuffer() 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 { @@ -121,9 +125,31 @@ private[sbt] final class CommandExchange { server = None } + // This is an interface to directly notify events. + private[sbt] def notifyEvent[A: JsonFormat](method: String, params: A): Unit = { + val toDel: ListBuffer[CommandChannel] = ListBuffer.empty + channels.foreach { + case c: ConsoleChannel => + // c.publishEvent(event) + case c: NetworkChannel => + try { + c.notifyEvent(method, params) + } catch { + case e: SocketException => + toDel += c + } + } + toDel.toList match { + case Nil => // do nothing + case xs => + lock.synchronized { + channelBuffer --= xs + } + } + } + def publishEvent[A: JsonFormat](event: A): Unit = { val toDel: ListBuffer[CommandChannel] = ListBuffer.empty - val bytes = Serialization.serializeEvent(event) event match { case entry: StringEvent => channels.foreach { @@ -134,7 +160,7 @@ private[sbt] final class CommandExchange { case c: NetworkChannel => try { if (entry.channelName == Some(c.name)) { - c.publishBytes(bytes) + c.publishEvent(event) } } catch { case e: SocketException => @@ -147,7 +173,7 @@ private[sbt] final class CommandExchange { c.publishEvent(event) case c: NetworkChannel => try { - c.publishBytes(bytes) + c.publishEvent(event) } catch { case e: SocketException => toDel += c @@ -163,6 +189,43 @@ private[sbt] final class CommandExchange { } } + /** + * This publishes object events. The type information has been + * erased because it went through logging. + */ + private[sbt] def publishObjectEvent(event: ObjectEvent[_]): Unit = { + import jsonFormat._ + val toDel: ListBuffer[CommandChannel] = ListBuffer.empty + def json: JValue = JObject( + JField("type", JString(event.contentType)), + (Vector(JField("message", event.json), JField("level", JString(event.level.toString))) ++ + (event.channelName.toVector map { channelName => + JField("channelName", JString(channelName)) + }) ++ + (event.execId.toVector map { execId => + JField("execId", JString(execId)) + })): _* + ) + channels.foreach { + case c: ConsoleChannel => + c.publishEvent(json) + case c: NetworkChannel => + try { + c.publishObjectEvent(event) + } catch { + case e: SocketException => + toDel += c + } + } + toDel.toList match { + case Nil => // do nothing + case xs => + lock.synchronized { + channelBuffer --= xs + } + } + } + // fanout publishEvent def publishEventMessage(event: EventMessage): Unit = { val toDel: ListBuffer[CommandChannel] = ListBuffer.empty @@ -177,14 +240,12 @@ private[sbt] final class CommandExchange { case c: ConsoleChannel => c.publishEventMessage(e) } case _ => - // TODO do not do this on the calling thread - val bytes = Serialization.serializeEventMessage(event) channels.foreach { case c: ConsoleChannel => c.publishEventMessage(event) case c: NetworkChannel => try { - c.publishBytes(bytes) + c.publishEventMessage(event) } catch { case e: SocketException => toDel += c diff --git a/main/src/main/scala/sbt/internal/RelayAppender.scala b/main/src/main/scala/sbt/internal/RelayAppender.scala index 8f833d376..7509ecbae 100644 --- a/main/src/main/scala/sbt/internal/RelayAppender.scala +++ b/main/src/main/scala/sbt/internal/RelayAppender.scala @@ -10,12 +10,10 @@ import sbt.util.Level import sbt.internal.util._ import sbt.protocol.LogEvent import sbt.internal.util.codec._ -import sjsonnew.shaded.scalajson.ast.unsafe._ class RelayAppender(name: String) extends AbstractAppender(name, null, PatternLayout.createDefaultLayout(), true) { lazy val exchange = StandardMain.exchange - lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {} def append(event: XLogEvent): Unit = { val level = ConsoleAppender.toLevel(event.getLevel) @@ -36,20 +34,7 @@ class RelayAppender(name: String) import JsonProtocol._ exchange.publishEvent(x: AbstractEntry) } - case x: ObjectEvent[_] => { - import jsonFormat._ - val json = JObject( - JField("type", JString(x.contentType)), - (Vector(JField("message", x.json), JField("level", JString(x.level.toString))) ++ - (x.channelName.toVector map { channelName => - JField("channelName", JString(channelName)) - }) ++ - (x.execId.toVector map { execId => - JField("execId", JString(execId)) - })): _* - ) - exchange.publishEvent(json: JValue) - } + case x: ObjectEvent[_] => exchange.publishObjectEvent(x) case _ => println(s"appendEvent: ${event.getClass}") () diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala new file mode 100644 index 000000000..988d5678c --- /dev/null +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -0,0 +1,127 @@ +package sbt +package internal +package server + +import sjsonnew.JsonFormat +import sjsonnew.support.scalajson.unsafe.Converter +import sbt.protocol.Serialization +import sbt.internal.protocol._ +import sbt.internal.protocol.codec._ +import sbt.internal.langserver._ +import sbt.internal.util.ObjectEvent + +private[sbt] case class LangServerError(code: Long, message: String) extends Throwable(message) + +/** + * Implements Language Server Protocol . + */ +private[sbt] trait LanguageServerProtocol extends CommandChannel { + + lazy val internalJsonProtocol = new InitializeOptionFormats with sjsonnew.BasicJsonProtocol {} + + protected def authenticate(token: String): Boolean + protected def authOptions: Set[ServerAuthentication] + protected def setInitialized(value: Boolean): Unit + + protected def onRequestMessage(request: JsonRpcRequestMessage): Unit = { + + import sbt.internal.langserver.codec.JsonProtocol._ + import internalJsonProtocol._ + + println(s"onRequestMessage: $request") + request.method match { + case "initialize" => + if (authOptions(ServerAuthentication.Token)) { + val json = + request.params.getOrElse( + throw LangServerError(ErrorCodes.InvalidParams, + "param is expected on 'initialize' method.")) + val param = Converter.fromJson[InitializeParams](json).get + val optionJson = param.initializationOptions.getOrElse( + throw LangServerError(ErrorCodes.InvalidParams, + "initializationOptions is expected on 'initialize' param.")) + val opt = Converter.fromJson[InitializeOption](optionJson).get + val token = opt.token.getOrElse(sys.error("'token' is missing.")) + if (authenticate(token)) () + else throw LangServerError(ErrorCodes.InvalidRequest, "invalid token") + } else () + setInitialized(true) + langRespond(InitializeResult(serverCapabilities), Option(request.id)) + case "textDocument/didSave" => + append(Exec("compile", Some(request.id), Some(CommandSource(name)))) + case _ => () + } + } + + /** + * This reacts to various events that happens inside sbt, sometime + * in response to the previous requests. + * The type information has been erased because it went through logging. + */ + protected def onObjectEvent(event: ObjectEvent[_]): Unit = { + // import sbt.internal.langserver.codec.JsonProtocol._ + + val msgContentType = event.contentType + msgContentType match { + // LanguageServerReporter sends PublishDiagnosticsParams + case "sbt.internal.langserver.PublishDiagnosticsParams" => + // val p = event.message.asInstanceOf[PublishDiagnosticsParams] + // langNotify("textDocument/publishDiagnostics", p) + case "xsbti.Problem" => + () // ignore + case _ => + // println(event) + () + } + } + + /** + * Respond back to Language Server's client. + */ + private[sbt] def langRespond[A: JsonFormat](event: A, execId: Option[String]): Unit = { + val m = + JsonRpcResponseMessage("2.0", execId, Option(Converter.toJson[A](event).get), None) + val bytes = Serialization.serializeResponseMessage(m) + publishBytes(bytes) + } + + /** + * Respond back to Language Server's client. + */ + private[sbt] def langError(execId: Option[String], code: Long, message: String): Unit = { + val e = JsonRpcResponseError(code, message, None) + val m = JsonRpcResponseMessage("2.0", execId, None, Option(e)) + val bytes = Serialization.serializeResponseMessage(m) + publishBytes(bytes) + } + + /** + * Respond back to Language Server's client. + */ + private[sbt] def langError[A: JsonFormat](execId: Option[String], + code: Long, + message: String, + data: A): Unit = { + val e = JsonRpcResponseError(code, message, Option(Converter.toJson[A](data).get)) + val m = JsonRpcResponseMessage("2.0", execId, None, Option(e)) + val bytes = Serialization.serializeResponseMessage(m) + publishBytes(bytes) + } + + /** + * Notify to Language Server's client. + */ + private[sbt] def langNotify[A: JsonFormat](method: String, params: A): Unit = { + val m = + JsonRpcNotificationMessage("2.0", method, Option(Converter.toJson[A](params).get)) + println(s"langNotify: $m") + val bytes = Serialization.serializeNotificationMessage(m) + publishBytes(bytes) + } + + private[sbt] lazy val serverCapabilities: ServerCapabilities = { + ServerCapabilities(textDocumentSync = + TextDocumentSyncOptions(true, 0, false, false, SaveOptions(false)), + hoverProvider = false) + } +} diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala b/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala new file mode 100644 index 000000000..5d550c41f --- /dev/null +++ b/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala @@ -0,0 +1,122 @@ +package sbt +package internal +package server + +import java.io.File +import sbt.internal.inc.ManagedLoggedReporter +import sbt.internal.util.ManagedLogger +import xsbti.{ Problem, Position => XPosition, Severity } +import xsbti.compile.CompileAnalysis +import sbt.internal.langserver.{ + PublishDiagnosticsParams, + Position, + Diagnostic, + Range, + DiagnosticSeverity +} +import sbt.internal.inc.JavaInterfaceUtil._ +import scala.collection.mutable +import scala.collection.JavaConverters._ + +/** + * Defines a compiler reporter that uses event logging provided by a [[ManagedLogger]]. + * + * @param maximumErrors The maximum errors. + * @param logger The event managed logger. + * @param sourcePositionMapper The position mapper. + */ +class LanguageServerReporter( + maximumErrors: Int, + logger: ManagedLogger, + sourcePositionMapper: XPosition => XPosition = identity[XPosition] +) extends ManagedLoggedReporter(maximumErrors, logger, sourcePositionMapper) { + lazy val exchange = StandardMain.exchange + + private[sbt] lazy val problemsByFile = new mutable.HashMap[File, List[Problem]] + + override def reset(): Unit = { + super.reset() + problemsByFile.clear() + } + + override def log(problem: Problem): Unit = { + val pos = problem.position + pos.sourceFile.toOption foreach { sourceFile: File => + problemsByFile.get(sourceFile) match { + case Some(xs: List[Problem]) => problemsByFile(sourceFile) = problem :: xs + case _ => problemsByFile(sourceFile) = List(problem) + } + } + super.log(problem) + } + + override def logError(problem: Problem): Unit = { + aggregateProblems(problem) + + // console channel can keep using the xsbi.Problem + super.logError(problem) + } + + override def logWarning(problem: Problem): Unit = { + aggregateProblems(problem) + + // console channel can keep using the xsbi.Problem + super.logWarning(problem) + } + + override def logInfo(problem: Problem): Unit = { + aggregateProblems(problem) + + // console channel can keep using the xsbi.Problem + super.logInfo(problem) + } + + private[sbt] def resetPrevious(analysis: CompileAnalysis): Unit = { + import sbt.internal.langserver.codec.JsonProtocol._ + val files = analysis.readSourceInfos.getAllSourceInfos.keySet.asScala + println(files) + files foreach { f => + val params = PublishDiagnosticsParams(f.toURI.toString, Vector()) + exchange.notifyEvent("textDocument/publishDiagnostics", params) + } + } + + private[sbt] def aggregateProblems(problem: Problem): Unit = { + import sbt.internal.langserver.codec.JsonProtocol._ + val pos = problem.position + pos.sourceFile.toOption foreach { sourceFile: File => + problemsByFile.get(sourceFile) match { + case Some(xs: List[Problem]) => + val ds = toDiagnostics(xs) + val params = PublishDiagnosticsParams(sourceFile.toURI.toString, ds) + exchange.notifyEvent("textDocument/publishDiagnostics", params) + case _ => + } + } + } + + private[sbt] def toDiagnostics(ps: List[Problem]): Vector[Diagnostic] = { + for { + problem <- ps.toVector + pos = problem.position + line0 <- pos.line.toOption.toVector + pointer0 <- pos.pointer.toOption.toVector + } yield { + val line = line0.toLong - 1L + val pointer = pointer0.toLong + Diagnostic( + Range(start = Position(line, pointer), end = Position(line, pointer + 1)), + Option(toDiagnosticSeverity(problem.severity)), + None, + Option("sbt"), + problem.message + ) + } + } + + private[sbt] def toDiagnosticSeverity(severity: Severity): Long = severity match { + case Severity.Info => DiagnosticSeverity.Information + case Severity.Warn => DiagnosticSeverity.Warning + case Severity.Error => DiagnosticSeverity.Error + } +} diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index eeaa8ed7c..ca1de8ea8 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -7,21 +7,58 @@ package server import java.net.{ Socket, SocketTimeoutException } import java.util.concurrent.atomic.AtomicBoolean -import sbt.protocol._ + import sjsonnew._ +import sjsonnew.support.scalajson.unsafe.Converter +import scala.annotation.tailrec +import sbt.protocol._ +import sbt.internal.langserver.ErrorCodes +import sbt.internal.protocol.JsonRpcResponseMessage +import sbt.internal.util.ObjectEvent +import sbt.internal.util.codec.JValueFormats final class NetworkChannel(val name: String, connection: Socket, structure: BuildStructure, auth: Set[ServerAuthentication], instance: ServerInstance) - extends CommandChannel { + extends CommandChannel + with LanguageServerProtocol { + import NetworkChannel._ + private val running = new AtomicBoolean(true) private val delimiter: Byte = '\n'.toByte + private val RetByte = '\r'.toByte private val out = connection.getOutputStream private var initialized = false + private val Curly = '{'.toByte + private val ContentLength = """^Content\-Length\:\s*(\d+)""".r + private val ContentType = """^Content\-Type\:\s*(.+)""".r + private var _contentType: String = "" + private val SbtX1Protocol = "application/sbt-x1" + private val VsCode = sbt.protocol.Serialization.VsCode + private val VsCodeOld = "application/vscode-jsonrpc; charset=utf8" + private lazy val jsonFormat = new sjsonnew.BasicJsonProtocol with JValueFormats {} + + def setContentType(ct: String): Unit = synchronized { + _contentType = ct + } + def contentType: String = _contentType + + protected def authenticate(token: String): Boolean = { + instance.authenticate(token) + } + + protected def setInitialized(value: Boolean): Unit = { + initialized = value + } + + protected def authOptions: Set[ServerAuthentication] = auth val thread = new Thread(s"sbt-networkchannel-${connection.getPort}") { + var contentLength: Int = 0 + var state: ChannelState = SingleLine + override def run(): Unit = { try { val readBuffer = new Array[Byte](4096) @@ -29,48 +66,221 @@ final class NetworkChannel(val name: String, connection.setSoTimeout(5000) var buffer: Vector[Byte] = Vector.empty var bytesRead = 0 + def resetChannelState(): Unit = { + contentLength = 0 + // contentType = "" + state = SingleLine + } + + def tillEndOfLine: Option[Vector[Byte]] = { + val delimPos = buffer.indexOf(delimiter) + if (delimPos > 0) { + val chunk0 = buffer.take(delimPos) + buffer = buffer.drop(delimPos + 1) + // remove \r at the end of line. + if (chunk0.size > 0 && chunk0.indexOf(RetByte) == chunk0.size - 1) + Some(chunk0.dropRight(1)) + else Some(chunk0) + } else None // no EOL yet, so skip this turn. + } + + def tillContentLength: Option[Vector[Byte]] = { + if (contentLength <= buffer.size) { + val chunk = buffer.take(contentLength) + buffer = buffer.drop(contentLength) + resetChannelState() + Some(chunk) + } else None // have not read enough yet, so skip this turn. + } + + @tailrec def process(): Unit = { + // handle un-framing + state match { + case SingleLine => + tillEndOfLine match { + case Some(chunk) => + chunk.headOption match { + case None => // ignore blank line + case Some(Curly) => + Serialization + .deserializeCommand(chunk) + .fold( + errorDesc => + println( + s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc), + onCommand + ) + resetChannelState() + case Some(_) => + val str = (new String(chunk.toArray, "UTF-8")).trim + handleHeader(str) match { + case Some(_) => + state = InHeader + process() + case _ => println("Got invalid chunk from client: " + str) + } + } + case _ => () + } + case InHeader => + tillEndOfLine match { + case Some(chunk) => + val str = (new String(chunk.toArray, "UTF-8")).trim + if (str == "") { + state = InBody + process() + } else + handleHeader(str) match { + case Some(_) => process() + case _ => + println("Got invalid header from client: " + str) + resetChannelState() + } + case _ => () + } + case InBody => + tillContentLength match { + case Some(chunk) => + handleBody(chunk) + process() + case _ => () + } + } + } + + // keep going unless the socket has closed while (bytesRead != -1 && running.get) { try { bytesRead = in.read(readBuffer) - buffer = buffer ++ readBuffer.toVector.take(bytesRead) - // handle un-framing - var delimPos = buffer.indexOf(delimiter) - while (delimPos > -1) { - val chunk = buffer.take(delimPos) - buffer = buffer.drop(delimPos + 1) - - Serialization - .deserializeCommand(chunk) - .fold( - errorDesc => println("Got invalid chunk from client: " + errorDesc), - onCommand - ) - delimPos = buffer.indexOf(delimiter) + println(s"bytesRead: $bytesRead") + if (bytesRead > 0) { + buffer = buffer ++ readBuffer.toVector.take(bytesRead) } + process() } catch { case _: SocketTimeoutException => // its ok } - } + } // while } finally { shutdown() } } + + def handleBody(chunk: Vector[Byte]): Unit = { + if (isLanguageServerProtocol) { + Serialization.deserializeJsonRequest(chunk) match { + case Right(req) => + try { + onRequestMessage(req) + } catch { + case LangServerError(code, message) => + println(s"sending error: $code: $message") + langError(Option(req.id), code, message) + } + case Left(errorDesc) => + val msg = s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc + langError(None, ErrorCodes.ParseError, msg) + } + } else { + contentType match { + case SbtX1Protocol => + Serialization + .deserializeCommand(chunk) + .fold( + errorDesc => + println( + s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc), + onCommand + ) + case _ => + println(s"Unknown Content-Type: $contentType") + } + } // if-else + } + + def handleHeader(str: String): Option[Unit] = { + str match { + case ContentLength(len) => + contentLength = len.toInt + Some(()) + case ContentType(ct) => + setContentType(ct) + Some(()) + case _ => None + } + } } thread.start() - def publishEvent[A: JsonFormat](event: A): Unit = { - val bytes = Serialization.serializeEvent(event) - publishBytes(bytes) + private[sbt] def isLanguageServerProtocol: Boolean = { + contentType match { + case "" | VsCode | VsCodeOld => true + case _ => false + } } + private[sbt] def notifyEvent[A: JsonFormat](method: String, params: A): Unit = { + if (isLanguageServerProtocol) { + langNotify(method, params) + } else { + () + } + } + + def publishEvent[A: JsonFormat](event: A, execId: Option[String]): Unit = { + if (isLanguageServerProtocol) { + langRespond(event, execId) + } else { + contentType match { + case SbtX1Protocol => + val bytes = Serialization.serializeEvent(event) + publishBytes(bytes, true) + case _ => + } + } + } + + def publishEvent[A: JsonFormat](event: A): Unit = publishEvent(event, None) + def publishEventMessage(event: EventMessage): Unit = { - val bytes = Serialization.serializeEventMessage(event) - publishBytes(bytes) + contentType match { + case SbtX1Protocol => + val bytes = Serialization.serializeEventMessage(event) + publishBytes(bytes, true) + case _ => + } } - def publishBytes(event: Array[Byte]): Unit = { + /** + * This publishes object events. The type information has been + * erased because it went through logging. + */ + private[sbt] def publishObjectEvent(event: ObjectEvent[_]): Unit = { + import sjsonnew.shaded.scalajson.ast.unsafe._ + if (isLanguageServerProtocol) onObjectEvent(event) + else { + import jsonFormat._ + val json: JValue = JObject( + JField("type", JString(event.contentType)), + (Vector(JField("message", event.json), JField("level", JString(event.level.toString))) ++ + (event.channelName.toVector map { channelName => + JField("channelName", JString(channelName)) + }) ++ + (event.execId.toVector map { execId => + JField("execId", JString(execId)) + })): _* + ) + publishEvent(json) + } + } + + def publishBytes(event: Array[Byte]): Unit = publishBytes(event, false) + + def publishBytes(event: Array[Byte], delimit: Boolean): Unit = { out.write(event) - out.write(delimiter.toInt) + if (delimit) { + out.write(delimiter.toInt) + } out.flush() } @@ -84,7 +294,7 @@ final class NetworkChannel(val name: String, if (auth(ServerAuthentication.Token)) { cmd.token match { case Some(x) => - instance.authenticate(x) match { + authenticate(x) match { case true => initialized = true publishEventMessage(ChannelAcceptedEvent(name)) @@ -120,3 +330,10 @@ final class NetworkChannel(val name: String, out.close() } } + +object NetworkChannel { + sealed trait ChannelState + case object SingleLine extends ChannelState + case object InHeader extends ChannelState + case object InBody extends ChannelState +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8745f1dfb..f714cbc82 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,9 +13,9 @@ object Dependencies { // sbt modules private val ioVersion = "1.1.0" - private val utilVersion = "1.0.1" + private val utilVersion = "1.0.2" private val lmVersion = "1.0.2" - private val zincVersion = "1.0.1" + private val zincVersion = "1.0.2" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/plugins.sbt b/project/plugins.sbt index 2eec0f9bd..f9064f32f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -8,6 +8,6 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") // addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.2.0") addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.1") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.1") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0-M1") addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.10") diff --git a/protocol/src/main/contraband-scala/InitializeResultFormats.scala b/protocol/src/main/contraband-scala/InitializeResultFormats.scala new file mode 100644 index 000000000..33827daee --- /dev/null +++ b/protocol/src/main/contraband-scala/InitializeResultFormats.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InitializeResultFormats { self: ServerCapabilitiesFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InitializeResultFormat: JsonFormat[sbt.internal.langserver.InitializeResult] = new JsonFormat[sbt.internal.langserver.InitializeResult] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeResult = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val capabilities = unbuilder.readField[Option[sbt.internal.langserver.ServerCapabilities]]("capabilities") + unbuilder.endObject() + sbt.internal.langserver.InitializeResult(capabilities) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.InitializeResult, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("capabilities", obj.capabilities) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/ServerCapabilitiesFormats.scala b/protocol/src/main/contraband-scala/ServerCapabilitiesFormats.scala new file mode 100644 index 000000000..3dbef6ccc --- /dev/null +++ b/protocol/src/main/contraband-scala/ServerCapabilitiesFormats.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ServerCapabilitiesFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ServerCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ServerCapabilities] = new JsonFormat[sbt.internal.langserver.ServerCapabilities] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ServerCapabilities = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val hoverProvider = unbuilder.readField[Option[Boolean]]("hoverProvider") + unbuilder.endObject() + sbt.internal.langserver.ServerCapabilities(hoverProvider) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.ServerCapabilities, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("hoverProvider", obj.hoverProvider) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/ClientCapabilities.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/ClientCapabilities.scala new file mode 100644 index 000000000..7bbfe152a --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/ClientCapabilities.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class ClientCapabilities private () extends Serializable { + + + +override def equals(o: Any): Boolean = o match { + case x: ClientCapabilities => true + case _ => false +} +override def hashCode: Int = { + 37 * (17 + "sbt.internal.langserver.ClientCapabilities".##) +} +override def toString: String = { + "ClientCapabilities()" +} +protected[this] def copy(): ClientCapabilities = { + new ClientCapabilities() +} + +} +object ClientCapabilities { + + def apply(): ClientCapabilities = new ClientCapabilities() +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/Diagnostic.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/Diagnostic.scala new file mode 100644 index 000000000..c28bc9b38 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/Diagnostic.scala @@ -0,0 +1,73 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** + * Represents a diagnostic, such as a compiler error or warning. + * Diagnostic objects are only valid in the scope of a resource. + */ +final class Diagnostic private ( + /** The range at which the message applies. */ + val range: sbt.internal.langserver.Range, + /** + * The diagnostic's severity. Can be omitted. If omitted it is up to the + * client to interpret diagnostics as error, warning, info or hint. + */ + val severity: Option[Long], + /** The diagnostic's code. Can be omitted. */ + val code: Option[String], + /** + * A human-readable string describing the source of this + * diagnostic, e.g. 'typescript' or 'super lint'. + */ + val source: Option[String], + /** The diagnostic's message. */ + val message: String) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Diagnostic => (this.range == x.range) && (this.severity == x.severity) && (this.code == x.code) && (this.source == x.source) && (this.message == x.message) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.Diagnostic".##) + range.##) + severity.##) + code.##) + source.##) + message.##) + } + override def toString: String = { + "Diagnostic(" + range + ", " + severity + ", " + code + ", " + source + ", " + message + ")" + } + protected[this] def copy(range: sbt.internal.langserver.Range = range, severity: Option[Long] = severity, code: Option[String] = code, source: Option[String] = source, message: String = message): Diagnostic = { + new Diagnostic(range, severity, code, source, message) + } + def withRange(range: sbt.internal.langserver.Range): Diagnostic = { + copy(range = range) + } + def withSeverity(severity: Option[Long]): Diagnostic = { + copy(severity = severity) + } + def withSeverity(severity: Long): Diagnostic = { + copy(severity = Option(severity)) + } + def withCode(code: Option[String]): Diagnostic = { + copy(code = code) + } + def withCode(code: String): Diagnostic = { + copy(code = Option(code)) + } + def withSource(source: Option[String]): Diagnostic = { + copy(source = source) + } + def withSource(source: String): Diagnostic = { + copy(source = Option(source)) + } + def withMessage(message: String): Diagnostic = { + copy(message = message) + } +} +object Diagnostic { + + def apply(range: sbt.internal.langserver.Range, severity: Option[Long], code: Option[String], source: Option[String], message: String): Diagnostic = new Diagnostic(range, severity, code, source, message) + def apply(range: sbt.internal.langserver.Range, severity: Long, code: String, source: String, message: String): Diagnostic = new Diagnostic(range, Option(severity), Option(code), Option(source), message) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeParams.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeParams.scala new file mode 100644 index 000000000..b96dc9478 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeParams.scala @@ -0,0 +1,72 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class InitializeParams private ( + val processId: Option[Long], + /** The rootPath of the workspace. */ + val rootPath: Option[String], + val rootUri: Option[String], + val initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], + val capabilities: Option[sbt.internal.langserver.ClientCapabilities], + val trace: Option[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: InitializeParams => (this.processId == x.processId) && (this.rootPath == x.rootPath) && (this.rootUri == x.rootUri) && (this.initializationOptions == x.initializationOptions) && (this.capabilities == x.capabilities) && (this.trace == x.trace) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.InitializeParams".##) + processId.##) + rootPath.##) + rootUri.##) + initializationOptions.##) + capabilities.##) + trace.##) + } + override def toString: String = { + "InitializeParams(" + processId + ", " + rootPath + ", " + rootUri + ", " + initializationOptions + ", " + capabilities + ", " + trace + ")" + } + protected[this] def copy(processId: Option[Long] = processId, rootPath: Option[String] = rootPath, rootUri: Option[String] = rootUri, initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = initializationOptions, capabilities: Option[sbt.internal.langserver.ClientCapabilities] = capabilities, trace: Option[String] = trace): InitializeParams = { + new InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace) + } + def withProcessId(processId: Option[Long]): InitializeParams = { + copy(processId = processId) + } + def withProcessId(processId: Long): InitializeParams = { + copy(processId = Option(processId)) + } + def withRootPath(rootPath: Option[String]): InitializeParams = { + copy(rootPath = rootPath) + } + def withRootPath(rootPath: String): InitializeParams = { + copy(rootPath = Option(rootPath)) + } + def withRootUri(rootUri: Option[String]): InitializeParams = { + copy(rootUri = rootUri) + } + def withRootUri(rootUri: String): InitializeParams = { + copy(rootUri = Option(rootUri)) + } + def withInitializationOptions(initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): InitializeParams = { + copy(initializationOptions = initializationOptions) + } + def withInitializationOptions(initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue): InitializeParams = { + copy(initializationOptions = Option(initializationOptions)) + } + def withCapabilities(capabilities: Option[sbt.internal.langserver.ClientCapabilities]): InitializeParams = { + copy(capabilities = capabilities) + } + def withCapabilities(capabilities: sbt.internal.langserver.ClientCapabilities): InitializeParams = { + copy(capabilities = Option(capabilities)) + } + def withTrace(trace: Option[String]): InitializeParams = { + copy(trace = trace) + } + def withTrace(trace: String): InitializeParams = { + copy(trace = Option(trace)) + } +} +object InitializeParams { + + def apply(processId: Option[Long], rootPath: Option[String], rootUri: Option[String], initializationOptions: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], capabilities: Option[sbt.internal.langserver.ClientCapabilities], trace: Option[String]): InitializeParams = new InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace) + def apply(processId: Long, rootPath: String, rootUri: String, initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue, capabilities: sbt.internal.langserver.ClientCapabilities, trace: String): InitializeParams = new InitializeParams(Option(processId), Option(rootPath), Option(rootUri), Option(initializationOptions), Option(capabilities), Option(trace)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeResult.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeResult.scala new file mode 100644 index 000000000..440844dd6 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/InitializeResult.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class InitializeResult private ( + /** The capabilities the language server provides. */ + val capabilities: sbt.internal.langserver.ServerCapabilities) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: InitializeResult => (this.capabilities == x.capabilities) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.langserver.InitializeResult".##) + capabilities.##) + } + override def toString: String = { + "InitializeResult(" + capabilities + ")" + } + protected[this] def copy(capabilities: sbt.internal.langserver.ServerCapabilities = capabilities): InitializeResult = { + new InitializeResult(capabilities) + } + def withCapabilities(capabilities: sbt.internal.langserver.ServerCapabilities): InitializeResult = { + copy(capabilities = capabilities) + } +} +object InitializeResult { + + def apply(capabilities: sbt.internal.langserver.ServerCapabilities): InitializeResult = new InitializeResult(capabilities) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/Location.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/Location.scala new file mode 100644 index 000000000..900a426d4 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/Location.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** Represents a location inside a resource, such as a line inside a text file. */ +final class Location private ( + val uri: String, + val range: sbt.internal.langserver.Range) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Location => (this.uri == x.uri) && (this.range == x.range) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.langserver.Location".##) + uri.##) + range.##) + } + override def toString: String = { + "Location(" + uri + ", " + range + ")" + } + protected[this] def copy(uri: String = uri, range: sbt.internal.langserver.Range = range): Location = { + new Location(uri, range) + } + def withUri(uri: String): Location = { + copy(uri = uri) + } + def withRange(range: sbt.internal.langserver.Range): Location = { + copy(range = range) + } +} +object Location { + + def apply(uri: String, range: sbt.internal.langserver.Range): Location = new Location(uri, range) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/Position.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/Position.scala new file mode 100644 index 000000000..f36a278f1 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/Position.scala @@ -0,0 +1,42 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** + * Position in a text document expressed as zero-based line and zero-based character offset. + * A position is between two characters like an 'insert' cursor in a editor. + */ +final class Position private ( + /** Line position in a document (zero-based). */ + val line: Long, + /** Character offset on a line in a document (zero-based). */ + val character: Long) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Position => (this.line == x.line) && (this.character == x.character) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.langserver.Position".##) + line.##) + character.##) + } + override def toString: String = { + "Position(" + line + ", " + character + ")" + } + protected[this] def copy(line: Long = line, character: Long = character): Position = { + new Position(line, character) + } + def withLine(line: Long): Position = { + copy(line = line) + } + def withCharacter(character: Long): Position = { + copy(character = character) + } +} +object Position { + + def apply(line: Long, character: Long): Position = new Position(line, character) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/PublishDiagnosticsParams.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/PublishDiagnosticsParams.scala new file mode 100644 index 000000000..25f7ab729 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/PublishDiagnosticsParams.scala @@ -0,0 +1,39 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** Diagnostics notification are sent from the server to the client to signal results of validation runs. */ +final class PublishDiagnosticsParams private ( + /** The URI for which diagnostic information is reported. */ + val uri: String, + /** An array of diagnostic information items. */ + val diagnostics: Vector[sbt.internal.langserver.Diagnostic]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: PublishDiagnosticsParams => (this.uri == x.uri) && (this.diagnostics == x.diagnostics) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.langserver.PublishDiagnosticsParams".##) + uri.##) + diagnostics.##) + } + override def toString: String = { + "PublishDiagnosticsParams(" + uri + ", " + diagnostics + ")" + } + protected[this] def copy(uri: String = uri, diagnostics: Vector[sbt.internal.langserver.Diagnostic] = diagnostics): PublishDiagnosticsParams = { + new PublishDiagnosticsParams(uri, diagnostics) + } + def withUri(uri: String): PublishDiagnosticsParams = { + copy(uri = uri) + } + def withDiagnostics(diagnostics: Vector[sbt.internal.langserver.Diagnostic]): PublishDiagnosticsParams = { + copy(diagnostics = diagnostics) + } +} +object PublishDiagnosticsParams { + + def apply(uri: String, diagnostics: Vector[sbt.internal.langserver.Diagnostic]): PublishDiagnosticsParams = new PublishDiagnosticsParams(uri, diagnostics) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/Range.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/Range.scala new file mode 100644 index 000000000..929bbec5b --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/Range.scala @@ -0,0 +1,42 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** + * A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor. + * Therefore the end position is exclusive. + */ +final class Range private ( + /** The range's start position. */ + val start: sbt.internal.langserver.Position, + /** The range's end position. */ + val end: sbt.internal.langserver.Position) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Range => (this.start == x.start) && (this.end == x.end) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.langserver.Range".##) + start.##) + end.##) + } + override def toString: String = { + "Range(" + start + ", " + end + ")" + } + protected[this] def copy(start: sbt.internal.langserver.Position = start, end: sbt.internal.langserver.Position = end): Range = { + new Range(start, end) + } + def withStart(start: sbt.internal.langserver.Position): Range = { + copy(start = start) + } + def withEnd(end: sbt.internal.langserver.Position): Range = { + copy(end = end) + } +} +object Range { + + def apply(start: sbt.internal.langserver.Position, end: sbt.internal.langserver.Position): Range = new Range(start, end) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/SaveOptions.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/SaveOptions.scala new file mode 100644 index 000000000..347dfca25 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/SaveOptions.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class SaveOptions private ( + /** The client is supposed to include the content on save. */ + val includeText: Option[Boolean]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: SaveOptions => (this.includeText == x.includeText) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.langserver.SaveOptions".##) + includeText.##) + } + override def toString: String = { + "SaveOptions(" + includeText + ")" + } + protected[this] def copy(includeText: Option[Boolean] = includeText): SaveOptions = { + new SaveOptions(includeText) + } + def withIncludeText(includeText: Option[Boolean]): SaveOptions = { + copy(includeText = includeText) + } + def withIncludeText(includeText: Boolean): SaveOptions = { + copy(includeText = Option(includeText)) + } +} +object SaveOptions { + + def apply(includeText: Option[Boolean]): SaveOptions = new SaveOptions(includeText) + def apply(includeText: Boolean): SaveOptions = new SaveOptions(Option(includeText)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/ServerCapabilities.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/ServerCapabilities.scala new file mode 100644 index 000000000..c40b895e5 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/ServerCapabilities.scala @@ -0,0 +1,44 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class ServerCapabilities private ( + val textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions], + /** The server provides hover support. */ + val hoverProvider: Option[Boolean]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ServerCapabilities => (this.textDocumentSync == x.textDocumentSync) && (this.hoverProvider == x.hoverProvider) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.internal.langserver.ServerCapabilities".##) + textDocumentSync.##) + hoverProvider.##) + } + override def toString: String = { + "ServerCapabilities(" + textDocumentSync + ", " + hoverProvider + ")" + } + protected[this] def copy(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions] = textDocumentSync, hoverProvider: Option[Boolean] = hoverProvider): ServerCapabilities = { + new ServerCapabilities(textDocumentSync, hoverProvider) + } + def withTextDocumentSync(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions]): ServerCapabilities = { + copy(textDocumentSync = textDocumentSync) + } + def withTextDocumentSync(textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions): ServerCapabilities = { + copy(textDocumentSync = Option(textDocumentSync)) + } + def withHoverProvider(hoverProvider: Option[Boolean]): ServerCapabilities = { + copy(hoverProvider = hoverProvider) + } + def withHoverProvider(hoverProvider: Boolean): ServerCapabilities = { + copy(hoverProvider = Option(hoverProvider)) + } +} +object ServerCapabilities { + + def apply(textDocumentSync: Option[sbt.internal.langserver.TextDocumentSyncOptions], hoverProvider: Option[Boolean]): ServerCapabilities = new ServerCapabilities(textDocumentSync, hoverProvider) + def apply(textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions, hoverProvider: Boolean): ServerCapabilities = new ServerCapabilities(Option(textDocumentSync), Option(hoverProvider)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/TextDocumentSyncOptions.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/TextDocumentSyncOptions.scala new file mode 100644 index 000000000..d94f50428 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/TextDocumentSyncOptions.scala @@ -0,0 +1,64 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +final class TextDocumentSyncOptions private ( + val openClose: Option[Boolean], + val change: Option[Long], + val willSave: Option[Boolean], + val willSaveWaitUntil: Option[Boolean], + val save: Option[sbt.internal.langserver.SaveOptions]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: TextDocumentSyncOptions => (this.openClose == x.openClose) && (this.change == x.change) && (this.willSave == x.willSave) && (this.willSaveWaitUntil == x.willSaveWaitUntil) && (this.save == x.save) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.langserver.TextDocumentSyncOptions".##) + openClose.##) + change.##) + willSave.##) + willSaveWaitUntil.##) + save.##) + } + override def toString: String = { + "TextDocumentSyncOptions(" + openClose + ", " + change + ", " + willSave + ", " + willSaveWaitUntil + ", " + save + ")" + } + protected[this] def copy(openClose: Option[Boolean] = openClose, change: Option[Long] = change, willSave: Option[Boolean] = willSave, willSaveWaitUntil: Option[Boolean] = willSaveWaitUntil, save: Option[sbt.internal.langserver.SaveOptions] = save): TextDocumentSyncOptions = { + new TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save) + } + def withOpenClose(openClose: Option[Boolean]): TextDocumentSyncOptions = { + copy(openClose = openClose) + } + def withOpenClose(openClose: Boolean): TextDocumentSyncOptions = { + copy(openClose = Option(openClose)) + } + def withChange(change: Option[Long]): TextDocumentSyncOptions = { + copy(change = change) + } + def withChange(change: Long): TextDocumentSyncOptions = { + copy(change = Option(change)) + } + def withWillSave(willSave: Option[Boolean]): TextDocumentSyncOptions = { + copy(willSave = willSave) + } + def withWillSave(willSave: Boolean): TextDocumentSyncOptions = { + copy(willSave = Option(willSave)) + } + def withWillSaveWaitUntil(willSaveWaitUntil: Option[Boolean]): TextDocumentSyncOptions = { + copy(willSaveWaitUntil = willSaveWaitUntil) + } + def withWillSaveWaitUntil(willSaveWaitUntil: Boolean): TextDocumentSyncOptions = { + copy(willSaveWaitUntil = Option(willSaveWaitUntil)) + } + def withSave(save: Option[sbt.internal.langserver.SaveOptions]): TextDocumentSyncOptions = { + copy(save = save) + } + def withSave(save: sbt.internal.langserver.SaveOptions): TextDocumentSyncOptions = { + copy(save = Option(save)) + } +} +object TextDocumentSyncOptions { + + def apply(openClose: Option[Boolean], change: Option[Long], willSave: Option[Boolean], willSaveWaitUntil: Option[Boolean], save: Option[sbt.internal.langserver.SaveOptions]): TextDocumentSyncOptions = new TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save) + def apply(openClose: Boolean, change: Long, willSave: Boolean, willSaveWaitUntil: Boolean, save: sbt.internal.langserver.SaveOptions): TextDocumentSyncOptions = new TextDocumentSyncOptions(Option(openClose), Option(change), Option(willSave), Option(willSaveWaitUntil), Option(save)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ClientCapabilitiesFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ClientCapabilitiesFormats.scala new file mode 100644 index 000000000..56686a509 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ClientCapabilitiesFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ClientCapabilitiesFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ClientCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ClientCapabilities] = new JsonFormat[sbt.internal.langserver.ClientCapabilities] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ClientCapabilities = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.internal.langserver.ClientCapabilities() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.ClientCapabilities, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala new file mode 100644 index 000000000..84db48020 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/DiagnosticFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait DiagnosticFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val DiagnosticFormat: JsonFormat[sbt.internal.langserver.Diagnostic] = new JsonFormat[sbt.internal.langserver.Diagnostic] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Diagnostic = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val range = unbuilder.readField[sbt.internal.langserver.Range]("range") + val severity = unbuilder.readField[Option[Long]]("severity") + val code = unbuilder.readField[Option[String]]("code") + val source = unbuilder.readField[Option[String]]("source") + val message = unbuilder.readField[String]("message") + unbuilder.endObject() + sbt.internal.langserver.Diagnostic(range, severity, code, source, message) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.Diagnostic, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("range", obj.range) + builder.addField("severity", obj.severity) + builder.addField("code", obj.code) + builder.addField("source", obj.source) + builder.addField("message", obj.message) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeParamsFormats.scala new file mode 100644 index 000000000..1172ead12 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeParamsFormats.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InitializeParamsFormats { self: sbt.internal.util.codec.JValueFormats with sbt.internal.langserver.codec.ClientCapabilitiesFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InitializeParamsFormat: JsonFormat[sbt.internal.langserver.InitializeParams] = new JsonFormat[sbt.internal.langserver.InitializeParams] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeParams = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val processId = unbuilder.readField[Option[Long]]("processId") + val rootPath = unbuilder.readField[Option[String]]("rootPath") + val rootUri = unbuilder.readField[Option[String]]("rootUri") + val initializationOptions = unbuilder.readField[Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]]("initializationOptions") + val capabilities = unbuilder.readField[Option[sbt.internal.langserver.ClientCapabilities]]("capabilities") + val trace = unbuilder.readField[Option[String]]("trace") + unbuilder.endObject() + sbt.internal.langserver.InitializeParams(processId, rootPath, rootUri, initializationOptions, capabilities, trace) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.InitializeParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("processId", obj.processId) + builder.addField("rootPath", obj.rootPath) + builder.addField("rootUri", obj.rootUri) + builder.addField("initializationOptions", obj.initializationOptions) + builder.addField("capabilities", obj.capabilities) + builder.addField("trace", obj.trace) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala new file mode 100644 index 000000000..bcad303fe --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/InitializeResultFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InitializeResultFormats { self: sbt.internal.langserver.codec.ServerCapabilitiesFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InitializeResultFormat: JsonFormat[sbt.internal.langserver.InitializeResult] = new JsonFormat[sbt.internal.langserver.InitializeResult] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.InitializeResult = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val capabilities = unbuilder.readField[sbt.internal.langserver.ServerCapabilities]("capabilities") + unbuilder.endObject() + sbt.internal.langserver.InitializeResult(capabilities) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.InitializeResult, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("capabilities", obj.capabilities) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala new file mode 100644 index 000000000..24ca637e4 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala @@ -0,0 +1,20 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +trait JsonProtocol extends sjsonnew.BasicJsonProtocol + with sbt.internal.langserver.codec.PositionFormats + with sbt.internal.langserver.codec.RangeFormats + with sbt.internal.langserver.codec.LocationFormats + with sbt.internal.langserver.codec.DiagnosticFormats + with sbt.internal.util.codec.JValueFormats + with sbt.internal.langserver.codec.ClientCapabilitiesFormats + with sbt.internal.langserver.codec.InitializeParamsFormats + with sbt.internal.langserver.codec.SaveOptionsFormats + with sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats + with sbt.internal.langserver.codec.ServerCapabilitiesFormats + with sbt.internal.langserver.codec.InitializeResultFormats + with sbt.internal.langserver.codec.PublishDiagnosticsParamsFormats +object JsonProtocol extends JsonProtocol \ No newline at end of file diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala new file mode 100644 index 000000000..28a116054 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/LocationFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait LocationFormats { self: sbt.internal.langserver.codec.RangeFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val LocationFormat: JsonFormat[sbt.internal.langserver.Location] = new JsonFormat[sbt.internal.langserver.Location] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Location = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val uri = unbuilder.readField[String]("uri") + val range = unbuilder.readField[sbt.internal.langserver.Range]("range") + unbuilder.endObject() + sbt.internal.langserver.Location(uri, range) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.Location, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("uri", obj.uri) + builder.addField("range", obj.range) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PositionFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PositionFormats.scala new file mode 100644 index 000000000..0b5b4b6d9 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PositionFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PositionFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val PositionFormat: JsonFormat[sbt.internal.langserver.Position] = new JsonFormat[sbt.internal.langserver.Position] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Position = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val line = unbuilder.readField[Long]("line") + val character = unbuilder.readField[Long]("character") + unbuilder.endObject() + sbt.internal.langserver.Position(line, character) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.Position, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("line", obj.line) + builder.addField("character", obj.character) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala new file mode 100644 index 000000000..42e3d710f --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/PublishDiagnosticsParamsFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PublishDiagnosticsParamsFormats { self: sbt.internal.langserver.codec.DiagnosticFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val PublishDiagnosticsParamsFormat: JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] = new JsonFormat[sbt.internal.langserver.PublishDiagnosticsParams] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.PublishDiagnosticsParams = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val uri = unbuilder.readField[String]("uri") + val diagnostics = unbuilder.readField[Vector[sbt.internal.langserver.Diagnostic]]("diagnostics") + unbuilder.endObject() + sbt.internal.langserver.PublishDiagnosticsParams(uri, diagnostics) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.PublishDiagnosticsParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("uri", obj.uri) + builder.addField("diagnostics", obj.diagnostics) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/RangeFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/RangeFormats.scala new file mode 100644 index 000000000..5541227fb --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/RangeFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait RangeFormats { self: sbt.internal.langserver.codec.PositionFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val RangeFormat: JsonFormat[sbt.internal.langserver.Range] = new JsonFormat[sbt.internal.langserver.Range] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.Range = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val start = unbuilder.readField[sbt.internal.langserver.Position]("start") + val end = unbuilder.readField[sbt.internal.langserver.Position]("end") + unbuilder.endObject() + sbt.internal.langserver.Range(start, end) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.Range, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("start", obj.start) + builder.addField("end", obj.end) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SaveOptionsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SaveOptionsFormats.scala new file mode 100644 index 000000000..c59938a0b --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SaveOptionsFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait SaveOptionsFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val SaveOptionsFormat: JsonFormat[sbt.internal.langserver.SaveOptions] = new JsonFormat[sbt.internal.langserver.SaveOptions] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.SaveOptions = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val includeText = unbuilder.readField[Option[Boolean]]("includeText") + unbuilder.endObject() + sbt.internal.langserver.SaveOptions(includeText) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.SaveOptions, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("includeText", obj.includeText) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala new file mode 100644 index 000000000..4bac79256 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/ServerCapabilitiesFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ServerCapabilitiesFormats { self: sbt.internal.langserver.codec.TextDocumentSyncOptionsFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ServerCapabilitiesFormat: JsonFormat[sbt.internal.langserver.ServerCapabilities] = new JsonFormat[sbt.internal.langserver.ServerCapabilities] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.ServerCapabilities = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val textDocumentSync = unbuilder.readField[Option[sbt.internal.langserver.TextDocumentSyncOptions]]("textDocumentSync") + val hoverProvider = unbuilder.readField[Option[Boolean]]("hoverProvider") + unbuilder.endObject() + sbt.internal.langserver.ServerCapabilities(textDocumentSync, hoverProvider) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.ServerCapabilities, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("textDocumentSync", obj.textDocumentSync) + builder.addField("hoverProvider", obj.hoverProvider) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentSyncOptionsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentSyncOptionsFormats.scala new file mode 100644 index 000000000..e1130ee5d --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/TextDocumentSyncOptionsFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait TextDocumentSyncOptionsFormats { self: sbt.internal.langserver.codec.SaveOptionsFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val TextDocumentSyncOptionsFormat: JsonFormat[sbt.internal.langserver.TextDocumentSyncOptions] = new JsonFormat[sbt.internal.langserver.TextDocumentSyncOptions] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.TextDocumentSyncOptions = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val openClose = unbuilder.readField[Option[Boolean]]("openClose") + val change = unbuilder.readField[Option[Long]]("change") + val willSave = unbuilder.readField[Option[Boolean]]("willSave") + val willSaveWaitUntil = unbuilder.readField[Option[Boolean]]("willSaveWaitUntil") + val save = unbuilder.readField[Option[sbt.internal.langserver.SaveOptions]]("save") + unbuilder.endObject() + sbt.internal.langserver.TextDocumentSyncOptions(openClose, change, willSave, willSaveWaitUntil, save) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.TextDocumentSyncOptions, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("openClose", obj.openClose) + builder.addField("change", obj.change) + builder.addField("willSave", obj.willSave) + builder.addField("willSaveWaitUntil", obj.willSaveWaitUntil) + builder.addField("save", obj.save) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala new file mode 100644 index 000000000..eeda8fa2c --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/InitializeOption.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class InitializeOption private ( + val token: Option[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: InitializeOption => (this.token == x.token) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.protocol.InitializeOption".##) + token.##) + } + override def toString: String = { + "InitializeOption(" + token + ")" + } + protected[this] def copy(token: Option[String] = token): InitializeOption = { + new InitializeOption(token) + } + def withToken(token: Option[String]): InitializeOption = { + copy(token = token) + } + def withToken(token: String): InitializeOption = { + copy(token = Option(token)) + } +} +object InitializeOption { + + def apply(token: Option[String]): InitializeOption = new InitializeOption(token) + def apply(token: String): InitializeOption = new InitializeOption(Option(token)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcMessage.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcMessage.scala new file mode 100644 index 000000000..6ae2a51ab --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcMessage.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +/** A general message as defined by JSON-RPC. */ +abstract class JsonRpcMessage( + val jsonrpc: String) extends Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: JsonRpcMessage => (this.jsonrpc == x.jsonrpc) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.protocol.JsonRpcMessage".##) + jsonrpc.##) + } + override def toString: String = { + "JsonRpcMessage(" + jsonrpc + ")" + } +} +object JsonRpcMessage { + +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcNotificationMessage.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcNotificationMessage.scala new file mode 100644 index 000000000..aa55a3639 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcNotificationMessage.scala @@ -0,0 +1,46 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class JsonRpcNotificationMessage private ( + jsonrpc: String, + /** The method to be invoked. */ + val method: String, + /** The method's params. */ + val params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: JsonRpcNotificationMessage => (this.jsonrpc == x.jsonrpc) && (this.method == x.method) && (this.params == x.params) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcNotificationMessage".##) + jsonrpc.##) + method.##) + params.##) + } + override def toString: String = { + s"""JsonRpcNotificationMessage($jsonrpc, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)})""" + } + protected[this] def copy(jsonrpc: String = jsonrpc, method: String = method, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = params): JsonRpcNotificationMessage = { + new JsonRpcNotificationMessage(jsonrpc, method, params) + } + def withJsonrpc(jsonrpc: String): JsonRpcNotificationMessage = { + copy(jsonrpc = jsonrpc) + } + def withMethod(method: String): JsonRpcNotificationMessage = { + copy(method = method) + } + def withParams(params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcNotificationMessage = { + copy(params = params) + } + def withParams(params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcNotificationMessage = { + copy(params = Option(params)) + } +} +object JsonRpcNotificationMessage { + + def apply(jsonrpc: String, method: String, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcNotificationMessage = new JsonRpcNotificationMessage(jsonrpc, method, params) + def apply(jsonrpc: String, method: String, params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcNotificationMessage = new JsonRpcNotificationMessage(jsonrpc, method, Option(params)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcRequestMessage.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcRequestMessage.scala new file mode 100644 index 000000000..f5943e1f7 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcRequestMessage.scala @@ -0,0 +1,51 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class JsonRpcRequestMessage private ( + jsonrpc: String, + /** The request id. */ + val id: String, + /** The method to be invoked. */ + val method: String, + /** The method's params. */ + val params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: JsonRpcRequestMessage => (this.jsonrpc == x.jsonrpc) && (this.id == x.id) && (this.method == x.method) && (this.params == x.params) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcRequestMessage".##) + jsonrpc.##) + id.##) + method.##) + params.##) + } + override def toString: String = { + s"""JsonRpcRequestMessage($jsonrpc, $id, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)}})""" + } + protected[this] def copy(jsonrpc: String = jsonrpc, id: String = id, method: String = method, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = params): JsonRpcRequestMessage = { + new JsonRpcRequestMessage(jsonrpc, id, method, params) + } + def withJsonrpc(jsonrpc: String): JsonRpcRequestMessage = { + copy(jsonrpc = jsonrpc) + } + def withId(id: String): JsonRpcRequestMessage = { + copy(id = id) + } + def withMethod(method: String): JsonRpcRequestMessage = { + copy(method = method) + } + def withParams(params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcRequestMessage = { + copy(params = params) + } + def withParams(params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcRequestMessage = { + copy(params = Option(params)) + } +} +object JsonRpcRequestMessage { + + def apply(jsonrpc: String, id: String, method: String, params: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcRequestMessage = new JsonRpcRequestMessage(jsonrpc, id, method, params) + def apply(jsonrpc: String, id: String, method: String, params: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcRequestMessage = new JsonRpcRequestMessage(jsonrpc, id, method, Option(params)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseError.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseError.scala new file mode 100644 index 000000000..9ece99852 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseError.scala @@ -0,0 +1,50 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class JsonRpcResponseError private ( + /** A number indicating the error type that occurred. */ + val code: Long, + /** A string providing a short description of the error. */ + val message: String, + /** + * A Primitive or Structured value that contains additional + * information about the error. Can be omitted. + */ + val data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: JsonRpcResponseError => (this.code == x.code) && (this.message == x.message) && (this.data == x.data) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcResponseError".##) + code.##) + message.##) + data.##) + } + override def toString: String = { + s"""JsonRpcResponseError($code, $message, ${sbt.protocol.Serialization.compactPrintJsonOpt(data)})""" + } + protected[this] def copy(code: Long = code, message: String = message, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = data): JsonRpcResponseError = { + new JsonRpcResponseError(code, message, data) + } + def withCode(code: Long): JsonRpcResponseError = { + copy(code = code) + } + def withMessage(message: String): JsonRpcResponseError = { + copy(message = message) + } + def withData(data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseError = { + copy(data = data) + } + def withData(data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseError = { + copy(data = Option(data)) + } +} +object JsonRpcResponseError { + + def apply(code: Long, message: String, data: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseError = new JsonRpcResponseError(code, message, data) + def apply(code: Long, message: String, data: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseError = new JsonRpcResponseError(code, message, Option(data)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseMessage.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseMessage.scala new file mode 100644 index 000000000..dd01ae0d3 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/JsonRpcResponseMessage.scala @@ -0,0 +1,60 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol +final class JsonRpcResponseMessage private ( + jsonrpc: String, + /** The request id. */ + val id: Option[String], + /** + * The result of a request. This can be omitted in + * the case of an error. + */ + val result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], + /** The error object in case a request fails. */ + val error: Option[sbt.internal.protocol.JsonRpcResponseError]) extends sbt.internal.protocol.JsonRpcMessage(jsonrpc) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: JsonRpcResponseMessage => (this.jsonrpc == x.jsonrpc) && (this.id == x.id) && (this.result == x.result) && (this.error == x.error) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.protocol.JsonRpcResponseMessage".##) + jsonrpc.##) + id.##) + result.##) + error.##) + } + override def toString: String = { + s"""JsonRpcResponseMessage($jsonrpc, $id, ${sbt.protocol.Serialization.compactPrintJsonOpt(result)}, $error)""" + } + protected[this] def copy(jsonrpc: String = jsonrpc, id: Option[String] = id, result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue] = result, error: Option[sbt.internal.protocol.JsonRpcResponseError] = error): JsonRpcResponseMessage = { + new JsonRpcResponseMessage(jsonrpc, id, result, error) + } + def withJsonrpc(jsonrpc: String): JsonRpcResponseMessage = { + copy(jsonrpc = jsonrpc) + } + def withId(id: Option[String]): JsonRpcResponseMessage = { + copy(id = id) + } + def withId(id: String): JsonRpcResponseMessage = { + copy(id = Option(id)) + } + def withResult(result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue]): JsonRpcResponseMessage = { + copy(result = result) + } + def withResult(result: sjsonnew.shaded.scalajson.ast.unsafe.JValue): JsonRpcResponseMessage = { + copy(result = Option(result)) + } + def withError(error: Option[sbt.internal.protocol.JsonRpcResponseError]): JsonRpcResponseMessage = { + copy(error = error) + } + def withError(error: sbt.internal.protocol.JsonRpcResponseError): JsonRpcResponseMessage = { + copy(error = Option(error)) + } +} +object JsonRpcResponseMessage { + + def apply(jsonrpc: String, id: Option[String], result: Option[sjsonnew.shaded.scalajson.ast.unsafe.JValue], error: Option[sbt.internal.protocol.JsonRpcResponseError]): JsonRpcResponseMessage = new JsonRpcResponseMessage(jsonrpc, id, result, error) + def apply(jsonrpc: String, id: String, result: sjsonnew.shaded.scalajson.ast.unsafe.JValue, error: sbt.internal.protocol.JsonRpcResponseError): JsonRpcResponseMessage = new JsonRpcResponseMessage(jsonrpc, Option(id), Option(result), Option(error)) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala new file mode 100644 index 000000000..0329d19cd --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/protocol/codec/InitializeOptionFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.protocol.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InitializeOptionFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val InitializeOptionFormat: JsonFormat[sbt.internal.protocol.InitializeOption] = new JsonFormat[sbt.internal.protocol.InitializeOption] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.protocol.InitializeOption = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val token = unbuilder.readField[Option[String]]("token") + unbuilder.endObject() + sbt.internal.protocol.InitializeOption(token) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.InitializeOption, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("token", obj.token) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband/jsonrpc.contra b/protocol/src/main/contraband/jsonrpc.contra new file mode 100644 index 000000000..9495b4a7a --- /dev/null +++ b/protocol/src/main/contraband/jsonrpc.contra @@ -0,0 +1,74 @@ +package sbt.internal.protocol +@target(Scala) + +## A general message as defined by JSON-RPC. +interface JsonRpcMessage +@generateCodec(false) +{ + jsonrpc: String! +} + +type JsonRpcRequestMessage implements JsonRpcMessage +@generateCodec(false) +{ + jsonrpc: String! + + ## The request id. + id: String! + + ## The method to be invoked. + method: String! + + ## The method's params. + params: sjsonnew.shaded.scalajson.ast.unsafe.JValue + + #xtostring s"""JsonRpcRequestMessage($jsonrpc, $id, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)}})""" +} + +type JsonRpcResponseMessage implements JsonRpcMessage +@generateCodec(false) +{ + jsonrpc: String! + + ## The request id. + id: String + + ## The result of a request. This can be omitted in + ## the case of an error. + result: sjsonnew.shaded.scalajson.ast.unsafe.JValue + + ## The error object in case a request fails. + error: sbt.internal.protocol.JsonRpcResponseError + + #xtostring s"""JsonRpcResponseMessage($jsonrpc, $id, ${sbt.protocol.Serialization.compactPrintJsonOpt(result)}, $error)""" +} + +type JsonRpcResponseError +@generateCodec(false) +{ + ## A number indicating the error type that occurred. + code: Long! + + ## A string providing a short description of the error. + message: String! + + ## A Primitive or Structured value that contains additional + ## information about the error. Can be omitted. + data: sjsonnew.shaded.scalajson.ast.unsafe.JValue + + #xtostring s"""JsonRpcResponseError($code, $message, ${sbt.protocol.Serialization.compactPrintJsonOpt(data)})""" +} + +type JsonRpcNotificationMessage implements JsonRpcMessage +@generateCodec(false) +{ + jsonrpc: String! + + ## The method to be invoked. + method: String! + + ## The method's params. + params: sjsonnew.shaded.scalajson.ast.unsafe.JValue + + #xtostring s"""JsonRpcNotificationMessage($jsonrpc, $method, ${sbt.protocol.Serialization.compactPrintJsonOpt(params)})""" +} diff --git a/protocol/src/main/contraband/lsp.contra b/protocol/src/main/contraband/lsp.contra new file mode 100644 index 000000000..cfc43ae69 --- /dev/null +++ b/protocol/src/main/contraband/lsp.contra @@ -0,0 +1,112 @@ +package sbt.internal.langserver +@target(Scala) +@codecPackage("sbt.internal.langserver.codec") +@fullCodec("JsonProtocol") + +# Basic structure + +## Position in a text document expressed as zero-based line and zero-based character offset. +## A position is between two characters like an 'insert' cursor in a editor. +type Position { + ## Line position in a document (zero-based). + line: Long! + + ## Character offset on a line in a document (zero-based). + character: Long! +} + +## A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor. +## Therefore the end position is exclusive. +type Range { + ## The range's start position. + start: sbt.internal.langserver.Position! + + ## The range's end position. + end: sbt.internal.langserver.Position! +} + +## Represents a location inside a resource, such as a line inside a text file. +type Location { + uri: String! + range: sbt.internal.langserver.Range! +} + +## Represents a diagnostic, such as a compiler error or warning. +## Diagnostic objects are only valid in the scope of a resource. +type Diagnostic { + ## The range at which the message applies. + range: sbt.internal.langserver.Range! + + ## The diagnostic's severity. Can be omitted. If omitted it is up to the + ## client to interpret diagnostics as error, warning, info or hint. + severity: Long + + ## The diagnostic's code. Can be omitted. + code: String + + ## A human-readable string describing the source of this + ## diagnostic, e.g. 'typescript' or 'super lint'. + source: String + + ## The diagnostic's message. + message: String! +} + +# initialize request +# https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#initialize-request + +type InitializeParams { + processId: Long + + ## The rootPath of the workspace. + rootPath: String + + rootUri: String + + initializationOptions: sjsonnew.shaded.scalajson.ast.unsafe.JValue + + capabilities: sbt.internal.langserver.ClientCapabilities + + trace: String +} + +type ClientCapabilities { +} + +type InitializeResult { + ## The capabilities the language server provides. + capabilities: sbt.internal.langserver.ServerCapabilities! +} + +type ServerCapabilities { + textDocumentSync: sbt.internal.langserver.TextDocumentSyncOptions + + ## The server provides hover support. + hoverProvider: Boolean +} + +type TextDocumentSyncOptions { + openClose: Boolean + change: Long + willSave: Boolean + willSaveWaitUntil: Boolean + save: sbt.internal.langserver.SaveOptions +} + +type SaveOptions { + ## The client is supposed to include the content on save. + includeText: Boolean +} + +# Document + +# PublishDiagnostics Notification https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_publishDiagnostics + +## Diagnostics notification are sent from the server to the client to signal results of validation runs. +type PublishDiagnosticsParams { + ## The URI for which diagnostic information is reported. + uri: String! + + ## An array of diagnostic information items. + diagnostics: [sbt.internal.langserver.Diagnostic] +} diff --git a/protocol/src/main/contraband/portfile.contra b/protocol/src/main/contraband/portfile.contra index 82f6567ef..d27df166b 100644 --- a/protocol/src/main/contraband/portfile.contra +++ b/protocol/src/main/contraband/portfile.contra @@ -15,3 +15,7 @@ type TokenFile { uri: String! token: String! } + +type InitializeOption { + token: String +} diff --git a/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala b/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala new file mode 100644 index 000000000..7f208114e --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala @@ -0,0 +1,26 @@ +package sbt +package internal +package langserver + +object DiagnosticSeverity { + + /** + * Reports an error. + */ + val Error = 1L + + /** + * Reports a warning. + */ + val Warning = 2L + + /** + * Reports an information. + */ + val Information = 3L + + /** + * Reports a hint. + */ + val Hint = 4L +} diff --git a/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala b/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala new file mode 100644 index 000000000..b6483d032 --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala @@ -0,0 +1,19 @@ +package sbt +package internal +package langserver + +object ErrorCodes { + // Defined by JSON RPC + val ParseError = -32700L + val InvalidRequest = -32600L + val MethodNotFound = -32601L + val InvalidParams = -32602L + val InternalError = -32603L + val serverErrorStart = -32099L + val serverErrorEnd = -32000L + val ServerNotInitialized = -32002L + val UnknownErrorCode = -32001L + + // Defined by the protocol. + val RequestCancelled = -32800L +} diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala new file mode 100644 index 000000000..5a8a96aaa --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala @@ -0,0 +1,13 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.internal.protocol.codec +trait JsonRPCProtocol + extends sbt.internal.util.codec.JValueFormats + with sjsonnew.BasicJsonProtocol + with sbt.internal.protocol.codec.JsonRpcRequestMessageFormats + with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats + with sbt.internal.protocol.codec.JsonRpcResponseMessageFormats + with sbt.internal.protocol.codec.JsonRpcNotificationMessageFormats + +object JsonRPCProtocol extends JsonRPCProtocol diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala new file mode 100644 index 000000000..387a45e03 --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala @@ -0,0 +1,40 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.internal.protocol.codec + +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +import sjsonnew.shaded.scalajson.ast.unsafe.JValue + +trait JsonRpcNotificationMessageFormats { + self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => + implicit lazy val JsonRpcNotificationMessageFormat + : JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] = + new JsonFormat[sbt.internal.protocol.JsonRpcNotificationMessage] { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcNotificationMessage = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val jsonrpc = unbuilder.readField[String]("jsonrpc") + val method = unbuilder.readField[String]("method") + val params = unbuilder.lookupField("params") map { + case x: JValue => x + } + unbuilder.endObject() + sbt.internal.protocol.JsonRpcNotificationMessage(jsonrpc, method, params) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.JsonRpcNotificationMessage, + builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("jsonrpc", obj.jsonrpc) + builder.addField("method", obj.method) + builder.addField("params", obj.params) + builder.endObject() + } + } +} diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala new file mode 100644 index 000000000..5ef60b221 --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala @@ -0,0 +1,45 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.internal.protocol.codec + +import sjsonnew.shaded.scalajson.ast.unsafe.JValue +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } + +trait JsonRpcRequestMessageFormats { + self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => + implicit lazy val JsonRpcRequestMessageFormat + : JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] = + new JsonFormat[sbt.internal.protocol.JsonRpcRequestMessage] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcRequestMessage = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val jsonrpc = unbuilder.readField[String]("jsonrpc") + val id = try { + unbuilder.readField[String]("id") + } catch { + case _ => unbuilder.readField[Long]("id").toString + } + val method = unbuilder.readField[String]("method") + val params = unbuilder.lookupField("params") map { + case x: JValue => x + } + unbuilder.endObject() + sbt.internal.protocol.JsonRpcRequestMessage(jsonrpc, id, method, params) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.JsonRpcRequestMessage, + builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("jsonrpc", obj.jsonrpc) + builder.addField("id", obj.id) + builder.addField("method", obj.method) + builder.addField("params", obj.params) + builder.endObject() + } + } +} diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala new file mode 100644 index 000000000..6db41174f --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala @@ -0,0 +1,39 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.internal.protocol.codec + +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +import sjsonnew.shaded.scalajson.ast.unsafe.JValue + +trait JsonRpcResponseErrorFormats { + self: sbt.internal.util.codec.JValueFormats with sjsonnew.BasicJsonProtocol => + implicit lazy val JsonRpcResponseErrorFormat + : JsonFormat[sbt.internal.protocol.JsonRpcResponseError] = + new JsonFormat[sbt.internal.protocol.JsonRpcResponseError] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcResponseError = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val code = unbuilder.readField[Long]("code") + val message = unbuilder.readField[String]("message") + val data = unbuilder.lookupField("data") map { + case x: JValue => x + } + unbuilder.endObject() + sbt.internal.protocol.JsonRpcResponseError(code, message, data) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.JsonRpcResponseError, + builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("code", obj.code) + builder.addField("message", obj.message) + builder.addField("data", obj.data) + builder.endObject() + } + } +} diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala new file mode 100644 index 000000000..b786d7f2a --- /dev/null +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala @@ -0,0 +1,52 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.internal.protocol.codec + +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +import sjsonnew.shaded.scalajson.ast.unsafe.JValue + +trait JsonRpcResponseMessageFormats { + self: sbt.internal.util.codec.JValueFormats + with sbt.internal.protocol.codec.JsonRpcResponseErrorFormats + with sjsonnew.BasicJsonProtocol => + implicit lazy val JsonRpcResponseMessageFormat + : JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] = + new JsonFormat[sbt.internal.protocol.JsonRpcResponseMessage] { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.internal.protocol.JsonRpcResponseMessage = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val jsonrpc = unbuilder.readField[String]("jsonrpc") + val id = try { + unbuilder.readField[Option[String]]("id") + } catch { + case _ => unbuilder.readField[Option[Long]]("id") map { _.toString } + } + + val result = unbuilder.lookupField("result") map { + case x: JValue => x + } + + val error = + unbuilder.readField[Option[sbt.internal.protocol.JsonRpcResponseError]]("error") + + unbuilder.endObject() + sbt.internal.protocol.JsonRpcResponseMessage(jsonrpc, id, result, error) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.protocol.JsonRpcResponseMessage, + builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("jsonrpc", obj.jsonrpc) + builder.addField("id", obj.id) + builder.addField("result", obj.result) + builder.addField("error", obj.error) + builder.endObject() + } + } +} diff --git a/protocol/src/main/scala/sbt/protocol/Serialization.scala b/protocol/src/main/scala/sbt/protocol/Serialization.scala index 422d9bb51..d363b31ec 100644 --- a/protocol/src/main/scala/sbt/protocol/Serialization.scala +++ b/protocol/src/main/scala/sbt/protocol/Serialization.scala @@ -10,8 +10,15 @@ import sjsonnew.shaded.scalajson.ast.unsafe.{ JValue, JObject, JString } import java.nio.ByteBuffer import scala.util.{ Success, Failure } import sbt.internal.util.StringEvent +import sbt.internal.protocol.{ + JsonRpcRequestMessage, + JsonRpcResponseMessage, + JsonRpcNotificationMessage +} object Serialization { + private[sbt] val VsCode = "application/vscode-jsonrpc; charset=utf-8" + def serializeEvent[A: JsonFormat](event: A): Array[Byte] = { val json: JValue = Converter.toJson[A](event).get CompactPrinter(json).getBytes("UTF-8") @@ -29,6 +36,39 @@ object Serialization { CompactPrinter(json).getBytes("UTF-8") } + /** + * This formats the message according to JSON-RPC. + * http://www.jsonrpc.org/specification + */ + private[sbt] def serializeResponseMessage(message: JsonRpcResponseMessage): Array[Byte] = { + import sbt.internal.protocol.codec.JsonRPCProtocol._ + val json: JValue = Converter.toJson[JsonRpcResponseMessage](message).get + val body = CompactPrinter(json) + val bodyBytes = body.getBytes("UTF-8") + + (s"Content-Length: ${bodyBytes.size}\r\n" + + s"Content-Type: $VsCode\r\n" + + "\r\n" + + body).getBytes("UTF-8") + } + + /** + * This formats the message according to JSON-RPC. + * http://www.jsonrpc.org/specification + */ + private[sbt] def serializeNotificationMessage( + message: JsonRpcNotificationMessage): Array[Byte] = { + import sbt.internal.protocol.codec.JsonRPCProtocol._ + val json: JValue = Converter.toJson[JsonRpcNotificationMessage](message).get + val body = CompactPrinter(json) + val bodyBytes = body.getBytes("UTF-8") + + (s"Content-Length: ${bodyBytes.size}\r\n" + + s"Content-Type: $VsCode\r\n" + + "\r\n" + + body).getBytes("UTF-8") + } + /** * @return A command or an invalid input description */ @@ -98,4 +138,26 @@ object Serialization { Left(s"Parse error: ${e.getMessage}") } } + + private[sbt] def deserializeJsonRequest( + bytes: Seq[Byte]): Either[String, JsonRpcRequestMessage] = { + val buffer = ByteBuffer.wrap(bytes.toArray) + Parser.parseFromByteBuffer(buffer) match { + case Success(json) => + import sbt.internal.protocol.codec.JsonRPCProtocol._ + Converter.fromJson[JsonRpcRequestMessage](json) match { + case Success(msg) => Right(msg) + case Failure(e) => throw e + } + case Failure(e) => + Left(s"Parse error: ${e.getMessage}") + } + } + + private[sbt] def compactPrintJsonOpt(jsonOpt: Option[JValue]): String = { + jsonOpt match { + case Some(x) => CompactPrinter(x) + case _ => "" + } + } } diff --git a/sbt/src/sbt-test/server/handshake/Client.scala b/sbt/src/sbt-test/server/handshake/Client.scala index 2acbdb9bb..2f41f4c18 100644 --- a/sbt/src/sbt-test/server/handshake/Client.scala +++ b/sbt/src/sbt-test/server/handshake/Client.scala @@ -11,19 +11,25 @@ object Client extends App { val host = "127.0.0.1" val delimiter: Byte = '\n'.toByte - println("hello") - Thread.sleep(1000) + lazy val connection = getConnection + lazy val out = connection.getOutputStream + lazy val in = connection.getInputStream - val connection = getConnection - val out = connection.getOutputStream - val in = connection.getInputStream + val t = getToken + val msg0 = s"""{ "type": "InitCommand", "token": "$t" }""" - out.write(s"""{ "type": "InitCommand", "token": "$getToken" }""".getBytes("utf-8")) - out.write(delimiter.toInt) + writeLine(s"Content-Length: ${ msg0.size + 2 }") + writeLine("Content-Type: application/sbt-x1") + writeLine("") + writeLine(msg0) out.flush - out.write("""{ "type": "ExecCommand", "commandLine": "exit" }""".getBytes("utf-8")) - out.write(delimiter.toInt) + writeLine("Content-Length: 49") + writeLine("Content-Type: application/sbt-x1") + writeLine("") + // 12345678901234567890123456789012345678901234567890 + writeLine("""{ "type": "ExecCommand", "commandLine": "exit" }""") + writeLine("") out.flush val baseDirectory = new File(args(0)) @@ -81,4 +87,20 @@ object Client extends App { Thread.sleep(1000) getConnection } + + def writeLine(s: String): Unit = { + if (s != "") { + out.write(s.getBytes("UTF-8")) + } + writeEndLine + } + + def writeEndLine(): Unit = { + val retByte: Byte = '\r'.toByte + val delimiter: Byte = '\n'.toByte + + out.write(retByte.toInt) + out.write(delimiter.toInt) + out.flush + } } diff --git a/sbt/src/sbt-test/server/handshake/test b/sbt/src/sbt-test/server/handshake/test index 9c2ba1cc1..703942376 100644 --- a/sbt/src/sbt-test/server/handshake/test +++ b/sbt/src/sbt-test/server/handshake/test @@ -1,6 +1,6 @@ > show serverPort > runClient + -> shell -$ sleep 1000 $ exists ok.txt diff --git a/vscode-sbt-scala/.vscode/launch.json b/vscode-sbt-scala/.vscode/launch.json new file mode 100644 index 000000000..5201e0897 --- /dev/null +++ b/vscode-sbt-scala/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + "version": "0.2.0", + // List of configurations. Add new configurations or edit existing ones. + "configurations": [ + { + "name": "Launch Client", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}/client" + ], + "stopOnEntry": false, + "sourceMaps": true, + "outFiles": [ + "${workspaceRoot}/client/out/**/*.js" + ] + // "preLaunchTask": "Client Watch" + }, + { + "name": "Attach to Server", + "type": "node", + "request": "attach", + "port": 6009, + "sourceMaps": true, + "outFiles": [ + "${workspaceRoot}/client/server/**/*.js" + ], + "protocol": "legacy" + // "preLaunchTask": "Server Watch" + } + ] +} \ No newline at end of file diff --git a/vscode-sbt-scala/.vscode/settings.json b/vscode-sbt-scala/.vscode/settings.json new file mode 100644 index 000000000..ed40daef9 --- /dev/null +++ b/vscode-sbt-scala/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + "typescript.tsdk": "./node_modules/typescript/lib", + "typescript.tsc.autoDetect": "off" +} \ No newline at end of file diff --git a/vscode-sbt-scala/.vscode/tasks.json b/vscode-sbt-scala/.vscode/tasks.json new file mode 100644 index 000000000..51026cd2d --- /dev/null +++ b/vscode-sbt-scala/.vscode/tasks.json @@ -0,0 +1,79 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "taskName": "compile", + "dependsOn": [ + "compile:client", + "compile:server" + ], + "problemMatcher": [] + }, + { + "label": "compile:client", + "type": "npm", + "script": "compile:client", + "group": "build", + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc" + ] + }, + { + "label": "compile:server", + "type": "npm", + "script": "compile:server", + "group": "build", + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc" + ] + }, + { + "taskName": "watch", + "dependsOn": [ + "watch:client", + "watch:server" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "watch:client", + "type": "npm", + "script": "watch:client", + "isBackground": true, + "group": "build", + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc-watch" + ] + }, + { + "label": "watch:server", + "type": "npm", + "script": "watch:server", + "isBackground": true, + "group": "build", + "presentation": { + "panel": "dedicated", + "reveal": "never" + }, + "problemMatcher": [ + "$tsc-watch" + ] + } + ] +} \ No newline at end of file diff --git a/vscode-sbt-scala/client/.vscodeignore b/vscode-sbt-scala/client/.vscodeignore new file mode 100644 index 000000000..93e28ff2f --- /dev/null +++ b/vscode-sbt-scala/client/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +typings/** +out/test/** +test/** +src/** +**/*.map +.gitignore +tsconfig.json +vsc-extension-quickstart.md diff --git a/vscode-sbt-scala/client/README.md b/vscode-sbt-scala/client/README.md new file mode 100644 index 000000000..5c1838a76 --- /dev/null +++ b/vscode-sbt-scala/client/README.md @@ -0,0 +1,6 @@ +Scala language support using sbt +================================ + +This is an experimental Scala language support using sbt as the language server. + +To try this, use sbt 1.1.0-M1 and above. Saving `*.scala` will trigger `compile` task. diff --git a/vscode-sbt-scala/client/images/sbt-logo-455x262.png b/vscode-sbt-scala/client/images/sbt-logo-455x262.png new file mode 100644 index 0000000000000000000000000000000000000000..82f485ef9692ede8f09d296bce9df0ae9c23aa80 GIT binary patch literal 6715 zcmZ`;2T)T{m!=z<5(3f!h9q4Xl303slvBhrzkqOs76ph74ip$bxzCQYP>qBKQH zD1sE}2$)c$2-2nQ(|>k$XLdF-nPkrW?)koR?!D)|cOL$VsR26+KMM^F4ZD#c8cRb% z+W~x;Kumyz!_YAw_~E;!Z+p+e@A^G|7n}!;uDhSB2h8ZEi>C+H!^J)DPN#skhkuVkCt5->`O_$;Kt)aVscyWB=|J^N$%wY9AKbp2wt_Zf=JVEYVdrq25e`q>{# zuB~0p{m6CU;KkQCCMNnJs)CcfcWe^5hup&ho<4;f`c<0Lxp(kGzai${X+X*U_i^Su zj)K#S_GusQj0~Ra_cb3LHJ|LBR7kK#ya~_)(@aWr$j&9=kE@C`%fgSBr&UroXmAXM z=7eyq^+cQdE^uQSDu@`#>r}dTn$eC9W)QJB7hrw-^xYnJsZ#B0^^!cj$0T z);R9kHg(5K|Fzu49oA5q>Hf`l-WsqHmTzWf-CgNa!W=OhfB|@g1!mTu>1K|Qt?Odd z=rkHMfhGz=XxbGBy^=l`dBb+pyGE8hto(T&J;ETOp8iX2yY>$dN{{BIved*+t74D+ zlB(IGu8s|5>fm+EmD#Wm_-Kvn@^4T%Mt+| z_517gb~^JvFA=$&|BKpL`($sz$tgt}^F$kdknqn9sTllEz&|NO#6S6%|0@K*04lsL z(HtZYjxaGXM&xrsC^~b5IYNggUhjCF4E{S8VE!uyK!QA)f5&G2)rU?1Qa}bs;C~Yk z0sWW5%2NRSzx@4A_y7i2Xp8>@pfd#Wu6_Xm#N!zDGPw2sJBJaXmD7K-7y-!E_$@tK z{G;{ewB>pF#ejuCwz0#C;k}W4%c!X*@7^Oi=v{I_G^k9Xi*>N*`LLuh#tSJ`Sd8YO%c=I6Pui72W3pr`p8?=uCycCmH$+(hg zWc5}@>)t|g>LY9vfdL}&$FOY`NPqcabZu*t*F7+MetujHg_&-05A=uXt! zxDPMu2Ug@ETYyx2MSK#PBN|qPXnnX@Z7lSVcNdSP){)jql4(>!THHgofh_aR8^vJD z^U6Sv_jp#r+HGf;r8%>kRctKp=V{}c}YX%!3)JQi*~i59;Pb6Va!>T?Jm4deba*3iZ(-D#d~&ZBtN z&%9to-_+uRx7hp?FzTZO7@x2>pP4MUpUtL`e* z=dx7EwmToUuQ1;&UG-b7Q{a8#A(#RMyZMnL)Fryr;~a?dhz`xr8T9f(u%N!ZEWB%} z*I6R!Zi2Yc9&HT{x{`%(T@mC97_tA=4;~N8cf29&Pw!`WHu=%`tlk9NpDD_YiG*;4 zvPrDLvAXt&{3F%7qI^X`6NC2oZ7CD31SBmAjxmlJxFoBIA!v40NpEVuS@l%>oU4;W zd<(6eMPLM^;Sl$;9~UT32PjDnKkYmt6sflLr%%hl$ugqX+)5Q#nx^?2hJUIwQfXlO zdV{_iDreL6>h_i)+FwbArElByX25yv$dB6nXRC^J(i|U1or`Ohpp4c3P8^d+(A5D!u zt}PIA4T0Dl=o2cX3~kGzj5i#3w!!{12Le;!}LUtapN7}W3WFQGY9H`&uH|_F5k$uKMWq8IH=&RI zX_vo@Re@bEx;QT06dD|l;yohvht7g^E8fV$4OIF4m{F3n%Qb%j$LzwEvGKv^K!n2R zM&R77>98hrJQ=L^a%QgcLLHQzw|oP8b}jmlMm-N&ze-A%xt?eqCr8BdvL#-|q))c7 zn5@4q_X(`bw3`SQ*Y2yG_+{QCtG-r(NzqEX=9b8d=dZu`7V2)5e|tip!u4qc+21y$ zPbw<+)g`9*TC?&kb^AZk2ESV=H;!xiStO}9oM7Poy9uH%E9}~RSzJ?a`!hdOEsm~C-cT;ZN9(sjiV{4hGv64yB zTTKOq+COgUe$9ol_er`feyvX`_y46aAIe1yxbV0_#?W#r?sA%<)PB3oL7XA+z34|; z4RQ^+d0MEFoobB--{DVA-ex(l4CjgEn3Xk6UI zO)`9?HJldpS$S5w88FYGD8qHF#aiD*Jo{%6NNsC@#A-fV!hNXi#nr_T*02uqh)MuzBq zJH?Y~D|nmdgJn=gkmk2E+lvhc$_s5|Vl`Asx1x)%p1CCEv!$cEjYg1BN+5~u-yQMI zTvP-3Z$vj^zS}W}w=zQ5Es5yF2xwXFb91V3CLIpxgC-Kvy`ub3KAyIxY?<8NO+_E- zaCx7h0GClYE#3Ke`WbZ`TWIA|)D9faPjXv|Ov!pAp>(Qgu8yri0~wprNbZxag?G?1 zh3yDXxTqQ*T^;)e*t*RJ$3{qOWX2>k0i9sPf`d9YPk-&YVL)hsS3l%4I?Zs90K)0u zeArO%4hphU@D&>13)8J$i-9((94{L(+OZFJV~NwqJJIED@6D0J+_oa2q^xLYy|Yl@ z`-J;+mBVoibp)C7C{Cp!VZ%HFs^Qk?y$3&U$#U-LDgHdOBLFU7L=EJU+<1B%?D;Gq z*&H_%Gu{2FLj&y@QAG%HyuBWwNubd|N5kxmgGgpdW9Ny>m{OB2{;0ixp>seIw^GpW zgw*P;kgX3Jlv;`r|D1*}ce9T~6UbGA;<5Cl6Udw~Q*>Zg4ik=HFcMm|5e2RHSsx+L z*Y4`4;HJJ~`plXNA-CkhX6bO3&4_$T|Hg5zCQ)ri&I`#KC23CDqG5={u}?8a?MTLd zly5#Y-}Q#Bd3D?7cj@W>QT|kDQ--7B78Ds#FEB*65%yzt`kwy0l$h!dH(;snQm&@D z=_apSBffu_*wTc+t=ycsNHln0Du~QW2R3UZf^3Y4Le&G+%W|(d?a?t0<{J%uoyz zalKfiS57|>8qGmXRSx33Kdvw$F8?N@!U|PAZK%$N?E?0%6>(&4^BF~1FxQ;w?VOuY z4F2UYQ@9KM>oJY0-XUN1y0?MNB_s6+19GO*2b7zDuxWN3w}MeBZ`>*t;OEc%A+v=m zQw`OH0r^D?5*?b3?^oNJeM`%@-%orW@v$OW1Dgo3%0SGwGwR~TRu{;)MOC{Pv^ zw)=CC$l4SV=0Dj#jv-nTdTa%^M*YwP;JCj*&ar&B^QQ-jSMMNpcc<`e#qht%KS+@F zrNiBT8QI-x6wh^1lH@e+`i}GzIX53dMxWXdcvuXU-jHsWE%f6^U&vFYF>IoSf1EuJvJ5DcuyXW>!bJL)G`Ft|1Uw@U_;wulO$fAc(T9oKRndY#8 z_z@B&nG;pmbf|W2F%MT3<@jmcnSMur7PTXL38fw=!K^vA$(pyao5c8!m*~b@-B9k) zG%wRwIMT4N*uU{S8o1Mk8H_^At&Ly9yHW@-TYQ@K|B3Jbrpt=bGfAm8K%bTQBMjlOutA+ciWB7hZP=R2SGQ)cUXBhe?vZ9vLy3O!An4R!Lv-`!|F~bJ zL+KftJ1z;n{+8s+7T-<&^@h^?dC7xqMdk0^{i1o&w#W!C5@mAlD?;r;|E43ZkYX52O;8J!(n6Y+^>(DYTu5F((19PYJ4 zYOGX5_k^0M#+jfM6}=dUII!_vycEZ(g@d}wGk#AmKsaTH2#A;tfu42a(y55r?L|3Z zl#F6EBXw`E0PhZ^f{s`=%DOsmtw~s_Dpoh=t6Fr_5k`lwek7^p8I1on0plhc`!f>3{Mc-*T*5bcbuD?6YIpXoR zMLAs*oJ@P6Zkn6~)T~BGgQ&u~>DHcvHHxWvItGU4_m?QjGi)%Hnw!)b(N*LIOp z=#3t#j#y^UEs_GBqo|{0yqn`EA|;#Wiet~&_SkP%Ej(p(lm*FaqGXhwL5XfJu^JM& zeYZ}o&U?;jAGCagJVv`7JA$ew+`ATF7Jc*nnCh& zS%HYCRKxpd^&EC718%q3Oxc%4pNi7HWd3gCaL+S;Qh3zPjw_hfUM+snd`qG|b_u?y z&B+&01U?-kx2ggsE9SAKS@QKAcAK}=t!uz82^&}UdbcVpSa?cVB#t2>FV|*gSqO&h z>yxj#InEX172^n6W#k7E9lG$TxGbPV`ch+H5E3P}-m+2N%#jdO7yjKs%)Tw9ztlY6 z0}nG`81p#LzVjf>3eSI(6wTkGu{~7h@7MT~9}h2!A5I6evBmKQ>(c?(IQfcV5<2S^ z2p8fjV$irfZ`|iPslsst{;^W<0Hs$>*U2f!#^L^Sm6`>hmfo$f`X!UxZaTlKgknWj zLO>om^44LARTu(Do)#rj9Q#XD=!IanFS6ro^g;dgq9lzP4e@Wi5l?W2XHm*L$Y9$< zGtTo{QTlvJjuwciv^$28A>+^GZ0HY07yb8}&e_Ewa|Hz0dgD!{8@lBBkJ>}2AH>eQ z6}xh`G*3l0jLk)VP8{X4VGJfeS1Hv`Iu~s^*`KZ+&iV$T9N6LBt{MTO_ZCAZXzreR zr+LR&En{O$E~=i@-$ZMK_7WUsH*dew&!-sFwau&)JFcj)tK`B~hcL8Bn-hp_$pRiM z4?I`i25&qLYMXq8Hsj==Tk@uqL^9G27OF{63Qw zpoO*0 zbRa8tSd6S*8K&BVix&FDnN&$huiii;Yd%{eUl9^=d=Ldn@>3=xmE>{It?dNRM8EkjPK3 z-u2-uF|9CWBemIHnb0rAO7?bFg^=BA``tNxp=UqBaGrD!^7f6hURgviy_#L-m6MLm zo{s4X<8qvf3J>F>i@#hF_H~C|8)ayG@+o0;$5CxvTjL%x4;Wj0^cSlx2%R4uR zMq~#-j~3-jh=vGip2hS%=~WkYSJp%Q4mY0&A5aS_p^?-5xoC#`o62;U8X); z&7H>X@MD6q0Hg2C1r@Hg?9@}^yF}b17+J%uuJF@nWTAn&+l@_&#Zhmi(?vTPsag)d z2Yhca&v428T79PS#*ZFXE}0+Vh#IbsF8Z3Wb$>eBJk3wU&bS6GHh$KcKK0X!WVJL( z3%6TZm+ncLE^DMlgjndINKnS_fjjf1e!chKf8|p53tps1e>d;$gqpA<#rF(FP3*E} zUm$q#(05lU!(^cEl(&@PdM^fgWAqC#ct?E%58hE9?rK z?{!n3C^X&}JZnDJ@UyXM+|-7!N>jF~dB&U5>rHs}B3f~{YV^2zNt1hX{AORe+}<0? z!PT?yaJ=szYwbi+u6*H92C>y}BVoE}`%_y+{MjO?uR{8JgmESFV+_Uy|6tK#cQ2UP z;HJd^80mVsSo=KOcVV{cj+msXKXL`yGX5v<#Px=`hbF!C`p&#RgLh;qB_jOXk=N`G zyX)*ugxapa5|TT{VoE?Fr=}0LE;DpR+D zT0)X|8CUol<#xB^Z>egH{ zZ^t6xFglL@ z7q*zo&V?3ut5Au&3-3IK&8k^D4fHf6&6^(l7Sh*?1zN|?Q;|+}6BD_vPPl8uT%9_M zKqvlG+=itHU$VH3WE&%18327u7gyl_>KjwVeE;~CJjfJ0AA;Iv3oPXCfRVl_x + + + + + + + + + + + + + diff --git a/vscode-sbt-scala/client/package-lock.json b/vscode-sbt-scala/client/package-lock.json new file mode 100644 index 000000000..4d7cb9f41 --- /dev/null +++ b/vscode-sbt-scala/client/package-lock.json @@ -0,0 +1,2256 @@ +{ + "name": "vscode-sbt-scala", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "1.1.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "2.0.3" + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "clone": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "cloneable-readable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", + "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "requires": { + "inherits": "2.0.3", + "process-nextick-args": "1.0.7", + "through2": "2.0.3" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.10.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "dateformat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=" + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "requires": { + "ms": "2.0.0" + } + }, + "deep-assign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", + "requires": { + "is-obj": "1.0.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "duplexify": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "requires": { + "end-of-stream": "1.4.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "requires": { + "once": "1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "requires": { + "duplexer": "0.1.1", + "from": "0.1.7", + "map-stream": "0.1.0", + "pause-stream": "0.0.11", + "split": "0.3.3", + "stream-combiner": "0.0.4", + "through": "2.3.8" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "2.2.3" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "requires": { + "chalk": "1.1.3", + "time-stamp": "1.1.0" + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "requires": { + "pend": "1.2.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "1.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "1.0.2" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "requires": { + "extend": "3.0.1", + "glob": "5.0.15", + "glob-parent": "3.1.0", + "micromatch": "2.3.11", + "ordered-read-streams": "0.3.0", + "through2": "0.6.5", + "to-absolute-glob": "0.1.1", + "unique-stream": "2.2.1" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + } + } + }, + "glogg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "requires": { + "sparkles": "1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + }, + "gulp-chmod": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz", + "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=", + "requires": { + "deep-assign": "1.0.0", + "stat-mode": "0.2.2", + "through2": "2.0.3" + } + }, + "gulp-filter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.0.1.tgz", + "integrity": "sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A==", + "requires": { + "gulp-util": "3.0.8", + "multimatch": "2.1.0", + "streamfilter": "1.0.5" + } + }, + "gulp-gunzip": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/gulp-gunzip/-/gulp-gunzip-0.0.3.tgz", + "integrity": "sha1-e24HsPWP09QlFcSOrVpj3wVy9i8=", + "requires": { + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "gulp-remote-src": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/gulp-remote-src/-/gulp-remote-src-0.4.3.tgz", + "integrity": "sha1-VyjP1kNDPdSEXd7wlp8PlxoqtKE=", + "requires": { + "event-stream": "3.3.4", + "node.extend": "1.1.6", + "request": "2.79.0", + "through2": "2.0.3", + "vinyl": "2.0.2" + }, + "dependencies": { + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.4.3", + "uuid": "3.1.0" + } + }, + "vinyl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.0.2.tgz", + "integrity": "sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw=", + "requires": { + "clone": "1.0.2", + "clone-buffer": "1.0.0", + "clone-stats": "1.0.0", + "cloneable-readable": "1.0.0", + "is-stream": "1.1.0", + "remove-trailing-separator": "1.1.0", + "replace-ext": "1.0.0" + } + } + } + }, + "gulp-sourcemaps": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", + "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=", + "requires": { + "convert-source-map": "1.5.0", + "graceful-fs": "4.1.11", + "strip-bom": "2.0.0", + "through2": "2.0.3", + "vinyl": "1.2.0" + }, + "dependencies": { + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulp-symdest": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-symdest/-/gulp-symdest-1.1.0.tgz", + "integrity": "sha1-wWUyBzLRks5W/ZQnH/oSMjS/KuA=", + "requires": { + "event-stream": "3.3.4", + "mkdirp": "0.5.1", + "queue": "3.1.0", + "vinyl-fs": "2.4.4" + } + }, + "gulp-untar": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.6.tgz", + "integrity": "sha1-1r3v3n6ajgVMnxYjhaB4LEvnQAA=", + "requires": { + "event-stream": "3.3.4", + "gulp-util": "3.0.8", + "streamifier": "0.1.1", + "tar": "2.2.1", + "through2": "2.0.3" + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "requires": { + "array-differ": "1.0.0", + "array-uniq": "1.0.3", + "beeper": "1.1.1", + "chalk": "1.1.3", + "dateformat": "2.0.0", + "fancy-log": "1.3.0", + "gulplog": "1.0.0", + "has-gulplog": "0.1.0", + "lodash._reescape": "3.0.0", + "lodash._reevaluate": "3.0.0", + "lodash._reinterpolate": "3.0.0", + "lodash.template": "3.6.2", + "minimist": "1.2.0", + "multipipe": "0.1.2", + "object-assign": "3.0.0", + "replace-ext": "0.0.1", + "through2": "2.0.3", + "vinyl": "0.5.3" + } + }, + "gulp-vinyl-zip": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-1.4.0.tgz", + "integrity": "sha1-VjgvLMtXIxuwR4x4c3zNVylzvuE=", + "requires": { + "event-stream": "3.3.4", + "queue": "3.1.0", + "through2": "0.6.5", + "vinyl": "0.4.6", + "vinyl-fs": "2.4.4", + "yauzl": "2.8.0", + "yazl": "2.4.2" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "requires": { + "glogg": "1.0.0" + } + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.1", + "pinkie-promise": "2.0.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "requires": { + "sparkles": "1.0.0" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "is": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", + "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=" + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "3.2.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "requires": { + "lodash._basecopy": "3.0.1", + "lodash.keys": "3.1.2" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=" + }, + "lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "requires": { + "lodash._baseassign": "3.2.0", + "lodash._basecreate": "3.0.3", + "lodash._isiterateecall": "3.0.9" + } + }, + "lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "requires": { + "lodash._basecopy": "3.0.1", + "lodash._basetostring": "3.0.1", + "lodash._basevalues": "3.0.0", + "lodash._isiterateecall": "3.0.9", + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0", + "lodash.keys": "3.1.2", + "lodash.restparam": "3.6.1", + "lodash.templatesettings": "3.1.1" + } + }, + "lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "requires": { + "lodash._reinterpolate": "3.0.0", + "lodash.escape": "3.2.0" + } + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "requires": { + "array-differ": "1.0.0", + "array-union": "1.0.2", + "arrify": "1.0.1", + "minimatch": "3.0.4" + } + }, + "multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "requires": { + "duplexer2": "0.0.2" + } + }, + "node.extend": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", + "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=", + "requires": { + "is": "3.2.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "requires": { + "is-stream": "1.1.0", + "readable-stream": "2.3.3" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "1.0.0" + } + } + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "requires": { + "through": "2.3.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=" + }, + "querystringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", + "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=" + }, + "queue": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/queue/-/queue-3.1.0.tgz", + "integrity": "sha1-bEnQHwCeIlZ4h4nyv/rGuLmZBYU=", + "requires": { + "inherits": "2.0.3" + } + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "1.1.5" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.2", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + }, + "dependencies": { + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + } + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.16.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "requires": { + "source-map": "0.5.7" + } + }, + "sparkles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=" + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "requires": { + "through": "2.3.8" + } + }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "stat-mode": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", + "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=" + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "requires": { + "duplexer": "0.1.1" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "streamfilter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.5.tgz", + "integrity": "sha1-h1BxEb644phFFxe1Ec/tjwAqv1M=", + "requires": { + "readable-stream": "2.3.3" + } + }, + "streamifier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", + "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "requires": { + "first-chunk-stream": "1.0.0", + "strip-bom": "2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "requires": { + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "requires": { + "extend-shallow": "2.0.1" + } + }, + "tough-cookie": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" + } + }, + "url-parse": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz", + "integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=", + "requires": { + "querystringify": "1.0.0", + "requires-port": "1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz", + "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", + "requires": { + "duplexify": "3.5.1", + "glob-stream": "5.3.5", + "graceful-fs": "4.1.11", + "gulp-sourcemaps": "1.6.0", + "is-valid-glob": "0.3.0", + "lazystream": "1.0.0", + "lodash.isequal": "4.5.0", + "merge-stream": "1.0.1", + "mkdirp": "0.5.1", + "object-assign": "4.1.1", + "readable-stream": "2.3.3", + "strip-bom": "2.0.0", + "strip-bom-stream": "1.0.0", + "through2": "2.0.3", + "through2-filter": "2.0.0", + "vali-date": "1.0.0", + "vinyl": "1.2.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "requires": { + "clone": "1.0.2", + "clone-stats": "0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "vinyl-source-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz", + "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", + "requires": { + "through2": "0.6.5", + "vinyl": "0.4.6" + }, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": "1.0.34", + "xtend": "4.0.1" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "requires": { + "clone": "0.2.0", + "clone-stats": "0.0.1" + } + } + } + }, + "vscode": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.5.tgz", + "integrity": "sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ=", + "requires": { + "glob": "7.1.2", + "gulp-chmod": "2.0.0", + "gulp-filter": "5.0.1", + "gulp-gunzip": "0.0.3", + "gulp-remote-src": "0.4.3", + "gulp-symdest": "1.1.0", + "gulp-untar": "0.0.6", + "gulp-vinyl-zip": "1.4.0", + "mocha": "3.5.3", + "request": "2.81.0", + "semver": "5.4.1", + "source-map-support": "0.4.18", + "url-parse": "1.1.9", + "vinyl-source-stream": "1.1.0" + } + }, + "vscode-jsonrpc": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.4.0.tgz", + "integrity": "sha1-qpWsWDvzHYD3JdV8J8CfTCz+n6k=" + }, + "vscode-languageclient": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.4.2.tgz", + "integrity": "sha1-LtbuoHJVC6q8m9MkgP8CeHVZiXI=", + "requires": { + "vscode-languageserver-protocol": "3.4.1" + } + }, + "vscode-languageserver-protocol": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.4.1.tgz", + "integrity": "sha1-lrfIo+1opOvTCkB7BCenY3k1/h8=", + "requires": { + "vscode-jsonrpc": "3.4.0", + "vscode-languageserver-types": "3.4.0" + } + }, + "vscode-languageserver-types": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.4.0.tgz", + "integrity": "sha1-UEOuR+5KwWrwe7PQylYSNeDA0vo=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + }, + "yazl": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.4.2.tgz", + "integrity": "sha1-FMsZCD4eJacAksFYiqvg9OTdTYg=", + "requires": { + "buffer-crc32": "0.2.13" + } + } + } +} diff --git a/vscode-sbt-scala/client/package.json b/vscode-sbt-scala/client/package.json new file mode 100644 index 000000000..7f1760155 --- /dev/null +++ b/vscode-sbt-scala/client/package.json @@ -0,0 +1,35 @@ +{ + "name": "vscode-sbt-scala", + "displayName": "Scala (sbt)", + "version": "0.0.1", + "author": "Lightbend, Inc.", + "license": "BSD-3-Clause", + "publisher": "lightbend", + "repository": { + "type": "git", + "url": "https://github.com/sbt/sbt" + }, + "description": "Scala language support using sbt", + "icon": "images/sbt-logo-455x262.png", + "engines": { + "vscode": "^1.16.0" + }, + "categories": [ + "Languages" + ], + "activationEvents": [ + "workspaceContains:build.sbt" + ], + "main": "./out/src/extension", + "scripts": { + "vscode:prepublish": "tsc -p ./", + "compile": "tsc -p ./", + "watch": "tsc -w -p ./", + "update-vscode": "node ./node_modules/vscode/bin/install", + "postinstall": "node ./node_modules/vscode/bin/install" + }, + "dependencies": { + "vscode": "^1.1.5", + "vscode-languageclient": "^3.4.2" + } +} diff --git a/vscode-sbt-scala/client/src/extension.ts b/vscode-sbt-scala/client/src/extension.ts new file mode 100644 index 000000000..f4a3eabb4 --- /dev/null +++ b/vscode-sbt-scala/client/src/extension.ts @@ -0,0 +1,45 @@ +'use strict'; + +import * as path from 'path'; + +let fs = require('fs'); +import { ExtensionContext, workspace } from 'vscode'; // workspace, +import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; + +export function activate(context: ExtensionContext) { + // The server is implemented in node + let serverModule = context.asAbsolutePath(path.join('server', 'server.js')); + // The debug options for the server + // let debugOptions = { execArgv: ["--nolazy", "--debug=6009"] }; + + // If the extension is launched in debug mode then the debug server options are used + // Otherwise the run options are used + let serverOptions: ServerOptions = { + run : { module: serverModule, transport: TransportKind.stdio }, + debug: { module: serverModule, transport: TransportKind.stdio } + } + + // Options to control the language client + let clientOptions: LanguageClientOptions = { + documentSelector: [{ language: 'scala', scheme: 'file' }, { language: 'java', scheme: 'file' }], + initializationOptions: () => { + return { + token: discoverToken() + }; + } + } + + // the port file is hardcoded to a particular location relative to the build. + function discoverToken(): String { + let pf = path.join(workspace.rootPath, 'project', 'target', 'active.json'); + let portfile = JSON.parse(fs.readFileSync(pf)); + let tf = portfile.tokenfilePath; + let tokenfile = JSON.parse(fs.readFileSync(tf)); + return tokenfile.token; + } + + // Create the language client and start the client. + let disposable = new LanguageClient('lspSbtScala', 'sbt Scala Language Server', serverOptions, clientOptions).start(); + + context.subscriptions.push(disposable); +} diff --git a/vscode-sbt-scala/client/tsconfig.json b/vscode-sbt-scala/client/tsconfig.json new file mode 100644 index 000000000..c10ad282c --- /dev/null +++ b/vscode-sbt-scala/client/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "rootDir": ".", + "outDir": "out", + "lib": [ "es2016" ], + "sourceMap": true + }, + "exclude": [ + "node_modules", + "server" + ] +} \ No newline at end of file diff --git a/vscode-sbt-scala/package-lock.json b/vscode-sbt-scala/package-lock.json new file mode 100644 index 000000000..5b8616285 --- /dev/null +++ b/vscode-sbt-scala/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "vscode-sbt-scala", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mocha": { + "version": "2.2.43", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.43.tgz", + "integrity": "sha512-xNlAmH+lRJdUMXClMTI9Y0pRqIojdxfm7DHsIxoB2iTzu3fnPmSMEN8SsSx0cdwV36d02PWCWaDUoZPDSln+xw==", + "dev": true + }, + "@types/node": { + "version": "6.0.88", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.88.tgz", + "integrity": "sha512-bYDPZTX0/s1aihdjLuAgogUAT5M+TpoWChEMea2p0yOcfn5bu3k6cJb9cp6nw268XeSNIGGr+4+/8V5K6BGzLQ==", + "dev": true + }, + "typescript": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz", + "integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=", + "dev": true + } + } +} diff --git a/vscode-sbt-scala/package.json b/vscode-sbt-scala/package.json new file mode 100644 index 000000000..e57bb7b9a --- /dev/null +++ b/vscode-sbt-scala/package.json @@ -0,0 +1,26 @@ +{ + "name": "vscode-sbt-scala", + "displayName": "Scala (sbt)", + "version": "0.0.1", + "author": "Lightbend, Inc.", + "license": "BSD-3-Clause", + "publisher": "lightbend", + "description": "Scala language support for Visual Studio Code using sbt", + "repository": { + "type": "git", + "url": "https://github.com/sbt/sbt" + }, + "scripts": { + "postinstall": "cd server && npm install && cd ../client && npm install && cd ..", + "compile": "tsc -p client/tsconfig.json && cd server && npm run installServer && cd .. && tsc -p server/tsconfig.json", + "compile:client": "tsc -p client/tsconfig.json", + "watch:client": "tsc -w -p client/tsconfig.json", + "compile:server": "cd server && npm run installServer && cd .. && tsc -p server/tsconfig.json", + "watch:server": "cd server && npm run installServer && cd .. && tsc -w -p server/tsconfig.json" + }, + "devDependencies": { + "@types/mocha": "^2.2.42", + "@types/node": "^6.0.88", + "typescript": "^2.5.2" + } +} diff --git a/vscode-sbt-scala/server/package-lock.json b/vscode-sbt-scala/server/package-lock.json new file mode 100644 index 000000000..d56b2fe0e --- /dev/null +++ b/vscode-sbt-scala/server/package-lock.json @@ -0,0 +1,41 @@ +{ + "name": "vscode-sbt-scala", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "vscode-jsonrpc": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.4.0.tgz", + "integrity": "sha1-qpWsWDvzHYD3JdV8J8CfTCz+n6k=" + }, + "vscode-languageserver": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.4.2.tgz", + "integrity": "sha1-CMvlDuJpAdN91LXcUsJbkJNjwfE=", + "requires": { + "vscode-languageserver-protocol": "3.4.1", + "vscode-uri": "1.0.1" + } + }, + "vscode-languageserver-protocol": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.4.1.tgz", + "integrity": "sha1-lrfIo+1opOvTCkB7BCenY3k1/h8=", + "requires": { + "vscode-jsonrpc": "3.4.0", + "vscode-languageserver-types": "3.4.0" + } + }, + "vscode-languageserver-types": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.4.0.tgz", + "integrity": "sha1-UEOuR+5KwWrwe7PQylYSNeDA0vo=" + }, + "vscode-uri": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.1.tgz", + "integrity": "sha1-Eahr7+rDxKo+wIYjZRo8gabQu8g=" + } + } +} diff --git a/vscode-sbt-scala/server/package.json b/vscode-sbt-scala/server/package.json new file mode 100644 index 000000000..dd14d02a2 --- /dev/null +++ b/vscode-sbt-scala/server/package.json @@ -0,0 +1,24 @@ +{ + "name": "vscode-sbt-scala", + "displayName": "Scala (sbt)", + "version": "0.0.1", + "author": "Lightbend, Inc.", + "license": "BSD-3-Clause", + "publisher": "lightbend", + "description": "Relay server to sbt server.", + "repository": { + "type": "git", + "url": "https://github.com/sbt/sbt" + }, + "engines": { + "node": "*" + }, + "dependencies": { + "vscode-languageserver": "^3.4.2" + }, + "scripts": { + "installServer": "installServerIntoExtension ../client ./package.json ./tsconfig.json", + "compile": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -p .", + "watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -w -p ." + } +} diff --git a/vscode-sbt-scala/server/src/server.ts b/vscode-sbt-scala/server/src/server.ts new file mode 100644 index 000000000..bef7e50a9 --- /dev/null +++ b/vscode-sbt-scala/server/src/server.ts @@ -0,0 +1,33 @@ +'use strict'; + +import * as path from 'path'; +import * as url from 'url'; +let net = require('net'), + fs = require('fs'), + stdin = process.stdin, + stdout = process.stdout; + +let u = discoverUrl(); + +let socket = net.Socket(); +socket.on('data', (chunk: any) => { + // send it back to stdout + stdout.write(chunk); +}).on('end', () => { + stdin.pause(); +}); +socket.connect(u.port, '127.0.0.1'); + +stdin.resume(); +stdin.on('data', (chunk: any) => { + socket.write(chunk); +}).on('end', () => { + socket.end(); +}); + +// the port file is hardcoded to a particular location relative to the build. +function discoverUrl(): url.Url { + let pf = path.join(process.cwd(), 'project', 'target', 'active.json'); + let portfile = JSON.parse(fs.readFileSync(pf)); + return url.parse(portfile.uri); +} diff --git a/vscode-sbt-scala/server/tsconfig.json b/vscode-sbt-scala/server/tsconfig.json new file mode 100644 index 000000000..1ae7a021a --- /dev/null +++ b/vscode-sbt-scala/server/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "lib" : [ "es2016" ], + "outDir": "../client/server" + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file From e7b893fdc5297ce25ca3cd0f2be5c0d3bfddab66 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 2 Oct 2017 16:37:12 +0100 Subject: [PATCH 18/57] Cleanup and improve the unified slash syntax --- main/src/main/scala/sbt/SlashSyntax.scala | 144 ++++++------------ .../main/scala/sbt/internal/KeyIndex.scala | 4 +- main/src/main/scala/sbt/internal/Load.scala | 7 +- .../test/scala/sbt/internal/TestBuild.scala | 4 +- 4 files changed, 50 insertions(+), 109 deletions(-) diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index b6a8b560b..14d6d476c 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -1,6 +1,5 @@ package sbt -import java.io.File import sbt.librarymanagement.Configuration /** @@ -23,126 +22,75 @@ import sbt.librarymanagement.Configuration trait SlashSyntax { import SlashSyntax._ - implicit def sbtScopeSyntaxRichReference(r: Reference): RichReference = - new RichReference(Scope(Select(r), This, This, This)) + implicit def sbtSlashSyntaxRichReferenceAxis(a: ScopeAxis[Reference]): RichReference = + new RichReference(Scope(a, This, This, This)) - implicit def sbtScopeSyntaxRichProject(p: Project): RichReference = - new RichReference(Scope(Select(p), This, This, This)) + implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r) + implicit def sbtSlashSyntaxRichProject(p: Project): RichReference = (p: Reference) - implicit def sbtScopeSyntaxRichConfiguration(c: Configuration): RichConfiguration = + implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration = new RichConfiguration(Scope(This, Select(c), This, This)) - implicit def sbtScopeSyntaxRichScope(s: Scope): RichScope = - new RichScope(s) + implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = (c: ConfigKey) - implicit def sbtScopeSyntaxRichScopeFromScoped(t: Scoped): RichScope = + implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope = new RichScope(Scope(This, This, Select(t.key), This)) - implicit def sbtScopeSyntaxRichScopeAxis(a: ScopeAxis[Reference]): RichScopeAxis = - new RichScopeAxis(a) + implicit def sbtSlashSyntaxRichScope(s: Scope): RichScope = new RichScope(s) - // Materialize the setting key thunk - implicit def sbtScopeSyntaxSettingKeyThunkMaterialize[A]( - thunk: SettingKeyThunk[A]): SettingKey[A] = - thunk.materialize + implicit def sbtSlashSyntaxScopeAndKeyRescope(scopeAndKey: ScopeAndKey[_]): TerminalScope = + scopeAndKey.rescope - implicit def sbtScopeSyntaxSettingKeyThunkKeyRescope[A](thunk: SettingKeyThunk[A]): RichScope = - thunk.rescope - - // Materialize the task key thunk - implicit def sbtScopeSyntaxTaskKeyThunkMaterialize[A](thunk: TaskKeyThunk[A]): TaskKey[A] = - thunk.materialize - - implicit def sbtScopeSyntaxTaskKeyThunkRescope[A](thunk: TaskKeyThunk[A]): RichScope = - thunk.rescope - - // Materialize the input key thunk - implicit def sbtScopeSyntaxInputKeyThunkMaterialize[A](thunk: InputKeyThunk[A]): InputKey[A] = - thunk.materialize - - implicit def sbtScopeSyntaxInputKeyThunkRescope[A](thunk: InputKeyThunk[A]): RichScope = - thunk.rescope + implicit def sbtSlashSyntaxScopeAndKeyMaterialize[K <: Key[K]](scopeAndKey: ScopeAndKey[K]): K = + scopeAndKey.materialize } object SlashSyntax { - /** RichReference wraps a project to provide the `/` operator for scoping. */ - final class RichReference(s: Scope) { - def /(c: Configuration): RichConfiguration = new RichConfiguration(s in c) - - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(s, key) - - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(s, key) - - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(s, key) - } - - /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ - final class RichConfiguration(s: Scope) { - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(s, key) - - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(s, key) - - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(s, key) - } - - /** RichScope wraps a general scope to provide the `/` operator for scoping. */ - final class RichScope(scope: Scope) { - def /[A](key: SettingKey[A]): SettingKey[A] = key in scope - def /[A](key: TaskKey[A]): TaskKey[A] = key in scope - def /[A](key: InputKey[A]): InputKey[A] = key in scope - } - - /** RichScopeAxis wraps a project axis to provide the `/` operator to `Zero` for scoping. */ - final class RichScopeAxis(a: ScopeAxis[Reference]) { - private[this] def toScope: Scope = Scope(a, This, This, This) - - def /(c: Configuration): RichConfiguration = new RichConfiguration(toScope in c) + /** RichReference wraps a reference to provide the `/` operator for scoping. */ + final class RichReference(protected val scope: Scope) extends RichScopeLike { + def /(c: Configuration): RichConfiguration = new RichConfiguration(scope in c) // This is for handling `Zero / Zero / name`. def /(configAxis: ScopeAxis[ConfigKey]): RichConfiguration = - new RichConfiguration(toScope.copy(config = configAxis)) + new RichConfiguration(scope.copy(config = configAxis)) + } - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: SettingKey[A]): SettingKeyThunk[A] = new SettingKeyThunk(toScope, key) + /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ + final class RichConfiguration(protected val scope: Scope) extends RichScopeLike - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: TaskKey[A]): TaskKeyThunk[A] = new TaskKeyThunk(toScope, key) + /** Both `Scoped.ScopingSetting` and `Scoped` are parents of `SettingKey`, `TaskKey` and + * `InputKey`. We'll need both, so this is a convenient type alias. */ + type Key[K] = Scoped.ScopingSetting[K] with Scoped - // We don't know what the key is for yet, so just capture in a thunk. - def /[A](key: InputKey[A]): InputKeyThunk[A] = new InputKeyThunk(toScope, key) + sealed trait RichScopeLike { + protected def scope: Scope + + // We don't know what the key is for yet, so just capture for now. + def /[K <: Key[K]](key: K): ScopeAndKey[K] = new ScopeAndKey(scope, key) + } + + /** RichScope wraps a general scope to provide the `/` operator for scoping. */ + final class RichScope(protected val scope: Scope) extends RichScopeLike + + /** TerminalScope provides the last `/` for scoping. */ + final class TerminalScope(scope: Scope) { + def /[K <: Key[K]](key: K): K = key in scope } /** - * SettingKeyThunk is a thunk used to hold a scope and a key - * while we're not sure if the key is terminal or task-scoping. + * ScopeAndKey is a synthetic DSL construct necessary to capture both the built-up scope with a + * given key, while we're not sure if the given key is terminal or task-scoping. The "materialize" + * method will be used if it's terminal, returning the scoped key, while "rescope" will be used + * if we're task-scoping. + * + * @param scope the built-up scope + * @param key a given key + * @tparam K the type of the given key, necessary to type "materialize" */ - final class SettingKeyThunk[A](base: Scope, key: SettingKey[A]) { - private[sbt] def materialize: SettingKey[A] = key in base - private[sbt] def rescope: RichScope = new RichScope(base in key.key) + final class ScopeAndKey[K <: Key[K]](scope: Scope, key: K) { + private[sbt] def materialize: K = key in scope + private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key) } - /** - * TaskKeyThunk is a thunk used to hold a scope and a key - * while we're not sure if the key is terminal or task-scoping. - */ - final class TaskKeyThunk[A](base: Scope, key: TaskKey[A]) { - private[sbt] def materialize: TaskKey[A] = key in base - private[sbt] def rescope: RichScope = new RichScope(base in key.key) - } - - /** - * InputKeyThunk is a thunk used to hold a scope and a key - * while we're not sure if the key is terminal or task-scoping. - */ - final class InputKeyThunk[A](base: Scope, key: InputKey[A]) { - private[sbt] def materialize: InputKey[A] = key in base - private[sbt] def rescope: RichScope = new RichScope(base in key.key) - } } diff --git a/main/src/main/scala/sbt/internal/KeyIndex.scala b/main/src/main/scala/sbt/internal/KeyIndex.scala index 573fed713..ebbf80ca8 100644 --- a/main/src/main/scala/sbt/internal/KeyIndex.scala +++ b/main/src/main/scala/sbt/internal/KeyIndex.scala @@ -31,9 +31,7 @@ object KeyIndex { } yield { val data = ids map { id => val configs = configurations.getOrElse(id, Seq()) - Option(id) -> new ConfigIndex(Map.empty, Map(configs map { c => - (c.name, c.id) - }: _*)) + Option(id) -> new ConfigIndex(Map.empty, configs.map(c => (c.name, c.id)).toMap) } Option(uri) -> new ProjectIndex(data.toMap) } diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 0ed05e692..133d7b39f 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -324,11 +324,8 @@ private[sbt] object Load { val attributeKeys = Index.attributeKeys(data) ++ keys.map(_.key) val scopedKeys = keys ++ data.allKeys((s, k) => ScopedKey(s, k)).toVector val projectsMap = projects.mapValues(_.defined.keySet) - val configsMap: Map[String, Seq[Configuration]] = Map(projects.values.toSeq flatMap { bu => - bu.defined map { - case (k, v) => (k, v.configurations) - } - }: _*) + val configsMap: Map[String, Seq[Configuration]] = + projects.values.flatMap(bu => bu.defined map { case (k, v) => (k, v.configurations) }).toMap val keyIndex = KeyIndex(scopedKeys.toVector, projectsMap, configsMap) val aggIndex = KeyIndex.aggregate(scopedKeys.toVector, extra(keyIndex), projectsMap, configsMap) new StructureIndex( diff --git a/main/src/test/scala/sbt/internal/TestBuild.scala b/main/src/test/scala/sbt/internal/TestBuild.scala index 96a4b1383..47874cb7e 100644 --- a/main/src/test/scala/sbt/internal/TestBuild.scala +++ b/main/src/test/scala/sbt/internal/TestBuild.scala @@ -225,9 +225,7 @@ abstract class TestBuild { p <- b.projects.toVector c <- p.configurations.toVector } yield c - val confMap = Map(confs map { c => - (c.name, Seq(c)) - }: _*) + val confMap = confs.map(c => (c.name, Seq(c))).toMap new Structure(env, current, data, KeyIndex(keys, projectsMap, confMap), keyMap) } From 4fe0d08ab07d1b7a0f1dabfd7eacb4b2cbefda28 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 2 Oct 2017 15:42:55 -0400 Subject: [PATCH 19/57] substitute println with logger --- .../scala/sbt/internal/CommandExchange.scala | 15 ++++++++++-- .../server/LanguageServerProtocol.scala | 8 ++++--- .../sbt/internal/server/NetworkChannel.scala | 24 ++++++++++--------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 66702e677..6daf56ab0 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -16,9 +16,10 @@ import scala.util.{ Success, Failure } import sbt.io.syntax._ import sbt.io.Hash import sbt.internal.server._ -import sbt.internal.util.{ StringEvent, ObjectEvent } +import sbt.internal.util.{ StringEvent, ObjectEvent, ConsoleOut, MainAppender } import sbt.internal.util.codec.JValueFormats import sbt.protocol.{ EventMessage, Serialization, ChannelAcceptedEvent } +import sbt.util.{ Level, Logger, LogExchange } /** * The command exchange merges multiple command channels (e.g. network and console), @@ -92,9 +93,19 @@ private[sbt] final class CommandExchange { case Some(xs) => xs case None => Set(ServerAuthentication.Token) } + val serverLogLevel: Level.Value = Level.Debug def onIncomingSocket(socket: Socket, instance: ServerInstance): Unit = { s.log.info(s"new client connected from: ${socket.getPort}") - val channel = new NetworkChannel(newChannelName, socket, Project structure s, auth, instance) + val logger: Logger = { + val loggerName = s"network-${socket.getPort}" + val log = LogExchange.logger(loggerName, None, None) + LogExchange.unbindLoggerAppenders(loggerName) + val appender = MainAppender.defaultScreen(s.globalLogging.console) + LogExchange.bindLoggerAppenders(loggerName, List(appender -> serverLogLevel)) + log + } + val channel = + new NetworkChannel(newChannelName, socket, Project structure s, auth, instance, logger) subscribe(channel) } server match { diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index 988d5678c..ea84fbed7 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -9,6 +9,7 @@ import sbt.internal.protocol._ import sbt.internal.protocol.codec._ import sbt.internal.langserver._ import sbt.internal.util.ObjectEvent +import sbt.util.Logger private[sbt] case class LangServerError(code: Long, message: String) extends Throwable(message) @@ -22,13 +23,14 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { protected def authenticate(token: String): Boolean protected def authOptions: Set[ServerAuthentication] protected def setInitialized(value: Boolean): Unit + protected def log: Logger protected def onRequestMessage(request: JsonRpcRequestMessage): Unit = { import sbt.internal.langserver.codec.JsonProtocol._ import internalJsonProtocol._ - println(s"onRequestMessage: $request") + log.debug(s"onRequestMessage: $request") request.method match { case "initialize" => if (authOptions(ServerAuthentication.Token)) { @@ -70,7 +72,7 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { case "xsbti.Problem" => () // ignore case _ => - // println(event) + // log.debug(event) () } } @@ -114,7 +116,7 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { private[sbt] def langNotify[A: JsonFormat](method: String, params: A): Unit = { val m = JsonRpcNotificationMessage("2.0", method, Option(Converter.toJson[A](params).get)) - println(s"langNotify: $m") + log.debug(s"langNotify: $m") val bytes = Serialization.serializeNotificationMessage(m) publishBytes(bytes) } diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index ca1de8ea8..43c01e343 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -16,12 +16,14 @@ import sbt.internal.langserver.ErrorCodes import sbt.internal.protocol.JsonRpcResponseMessage import sbt.internal.util.ObjectEvent import sbt.internal.util.codec.JValueFormats +import sbt.util.Logger final class NetworkChannel(val name: String, connection: Socket, structure: BuildStructure, auth: Set[ServerAuthentication], - instance: ServerInstance) + instance: ServerInstance, + val log: Logger) extends CommandChannel with LanguageServerProtocol { import NetworkChannel._ @@ -106,7 +108,7 @@ final class NetworkChannel(val name: String, .deserializeCommand(chunk) .fold( errorDesc => - println( + log.error( s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc), onCommand ) @@ -117,7 +119,7 @@ final class NetworkChannel(val name: String, case Some(_) => state = InHeader process() - case _ => println("Got invalid chunk from client: " + str) + case _ => log.error("Got invalid chunk from client: " + str) } } case _ => () @@ -133,7 +135,7 @@ final class NetworkChannel(val name: String, handleHeader(str) match { case Some(_) => process() case _ => - println("Got invalid header from client: " + str) + log.error("Got invalid header from client: " + str) resetChannelState() } case _ => () @@ -152,7 +154,7 @@ final class NetworkChannel(val name: String, while (bytesRead != -1 && running.get) { try { bytesRead = in.read(readBuffer) - println(s"bytesRead: $bytesRead") + // log.debug(s"bytesRead: $bytesRead") if (bytesRead > 0) { buffer = buffer ++ readBuffer.toVector.take(bytesRead) } @@ -174,7 +176,7 @@ final class NetworkChannel(val name: String, onRequestMessage(req) } catch { case LangServerError(code, message) => - println(s"sending error: $code: $message") + log.debug(s"sending error: $code: $message") langError(Option(req.id), code, message) } case Left(errorDesc) => @@ -188,12 +190,12 @@ final class NetworkChannel(val name: String, .deserializeCommand(chunk) .fold( errorDesc => - println( + log.error( s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc), onCommand ) case _ => - println(s"Unknown Content-Type: $contentType") + log.error(s"Unknown Content-Type: $contentType") } } // if-else } @@ -312,7 +314,7 @@ final class NetworkChannel(val name: String, append( Exec(cmd.commandLine, cmd.execId orElse Some(Exec.newExecId), Some(CommandSource(name)))) } else { - println(s"ignoring command $cmd before initialization") + log.warn(s"ignoring command $cmd before initialization") } } @@ -320,12 +322,12 @@ final class NetworkChannel(val name: String, if (initialized) { StandardMain.exchange publishEventMessage SettingQuery.handleSettingQuery(req, structure) } else { - println(s"ignoring query $req before initialization") + log.warn(s"ignoring query $req before initialization") } } def shutdown(): Unit = { - println("Shutting down client connection") + log.info("Shutting down client connection") running.set(false) out.close() } From 5d7641ee1866a3ab93a24a298113b21d35c8b42e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 2 Oct 2017 15:52:02 -0400 Subject: [PATCH 20/57] Filtering out mima issues --- build.sbt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.sbt b/build.sbt index fec97e6be..e59cc8169 100644 --- a/build.sbt +++ b/build.sbt @@ -300,6 +300,8 @@ lazy val commandProj = (project in file("main-command")) exclude[DirectMissingMethodProblem]("sbt.internal.server.Server.*"), // Added method to ServerInstance. This is also internal. exclude[ReversedMissingMethodProblem]("sbt.internal.server.ServerInstance.*"), + // Added method to CommandChannel. internal. + exclude[ReversedMissingMethodProblem]("sbt.internal.CommandChannel.*"), ) ) .configure( @@ -380,6 +382,8 @@ lazy val mainProj = (project in file("main")) // New and changed methods on KeyIndex. internal. exclude[ReversedMissingMethodProblem]("sbt.internal.KeyIndex.*"), exclude[DirectMissingMethodProblem]("sbt.internal.KeyIndex.*"), + // Removed unused val. internal. + exclude[DirectMissingMethodProblem]("sbt.internal.RelayAppender.jsonFormat"), ) ) .configure( From f188e60d8f73e23a1630a954c21d6d00e5eaaf30 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 2 Oct 2017 17:12:15 -0400 Subject: [PATCH 21/57] Update test --- main/src/test/scala/sbt/internal/server/SettingQueryTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala index d7c88e71c..c77d38ed7 100644 --- a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala +++ b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala @@ -196,7 +196,7 @@ object SettingQueryTest extends org.specs2.mutable.Specification { "scala.collection.Seq[java.lang.String]") "t/libraryDependencies" in qok( - """[{"organization":"org.scala-lang","name":"scala-library","revision":"2.12.1","isChanging":false,"isTransitive":true,"isForce":false,"crossVersion":{"type":"Disabled"}}]""", + """[{"organization":"org.scala-lang","name":"scala-library","revision":"2.12.1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}]""", "scala.collection.Seq[sbt.librarymanagement.ModuleID]" ) From a8e770c446fb1e962226005a2eb9a9e08a5c4d84 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Oct 2017 00:18:58 -0400 Subject: [PATCH 22/57] handle exec as "sbt/exec" --- .../server/LanguageServerProtocol.scala | 11 ++++--- .../sbt/internal/server/NetworkChannel.scala | 14 +++----- .../internal/langserver/SbtExecParams.scala | 33 +++++++++++++++++++ .../langserver/codec/JsonProtocol.scala | 1 + .../codec/SbtExecParamsFormats.scala | 27 +++++++++++++++ protocol/src/main/contraband/lsp.contra | 7 ++++ server.md | 10 +++--- 7 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/SbtExecParams.scala create mode 100644 protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SbtExecParamsFormats.scala diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index ea84fbed7..ba713c631 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -30,14 +30,14 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { import sbt.internal.langserver.codec.JsonProtocol._ import internalJsonProtocol._ + def json = + request.params.getOrElse( + throw LangServerError(ErrorCodes.InvalidParams, + s"param is expected on '${request.method}' method.")) log.debug(s"onRequestMessage: $request") request.method match { case "initialize" => if (authOptions(ServerAuthentication.Token)) { - val json = - request.params.getOrElse( - throw LangServerError(ErrorCodes.InvalidParams, - "param is expected on 'initialize' method.")) val param = Converter.fromJson[InitializeParams](json).get val optionJson = param.initializationOptions.getOrElse( throw LangServerError(ErrorCodes.InvalidParams, @@ -51,6 +51,9 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { langRespond(InitializeResult(serverCapabilities), Option(request.id)) case "textDocument/didSave" => append(Exec("compile", Some(request.id), Some(CommandSource(name)))) + case "sbt/exec" => + val param = Converter.fromJson[SbtExecParams](json).get + append(Exec(param.commandLine, Some(request.id), Some(CommandSource(name)))) case _ => () } } diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 43c01e343..12d9b33d8 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -102,17 +102,11 @@ final class NetworkChannel(val name: String, tillEndOfLine match { case Some(chunk) => chunk.headOption match { - case None => // ignore blank line + case None => // ignore blank line case Some(Curly) => - Serialization - .deserializeCommand(chunk) - .fold( - errorDesc => - log.error( - s"Got invalid chunk from client (${new String(chunk.toArray, "UTF-8")}): " + errorDesc), - onCommand - ) - resetChannelState() + // When Content-Length header is not found, interpret the line as JSON message. + handleBody(chunk) + process() case Some(_) => val str = (new String(chunk.toArray, "UTF-8")).trim handleHeader(str) match { diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/SbtExecParams.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/SbtExecParams.scala new file mode 100644 index 000000000..d60cc441b --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/SbtExecParams.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver +/** Command to execute sbt command. */ +final class SbtExecParams private ( + val commandLine: String) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: SbtExecParams => (this.commandLine == x.commandLine) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.langserver.SbtExecParams".##) + commandLine.##) + } + override def toString: String = { + "SbtExecParams(" + commandLine + ")" + } + protected[this] def copy(commandLine: String = commandLine): SbtExecParams = { + new SbtExecParams(commandLine) + } + def withCommandLine(commandLine: String): SbtExecParams = { + copy(commandLine = commandLine) + } +} +object SbtExecParams { + + def apply(commandLine: String): SbtExecParams = new SbtExecParams(commandLine) +} diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala index 24ca637e4..a40a00bbe 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/JsonProtocol.scala @@ -17,4 +17,5 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol with sbt.internal.langserver.codec.ServerCapabilitiesFormats with sbt.internal.langserver.codec.InitializeResultFormats with sbt.internal.langserver.codec.PublishDiagnosticsParamsFormats + with sbt.internal.langserver.codec.SbtExecParamsFormats object JsonProtocol extends JsonProtocol \ No newline at end of file diff --git a/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SbtExecParamsFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SbtExecParamsFormats.scala new file mode 100644 index 000000000..9447f9180 --- /dev/null +++ b/protocol/src/main/contraband-scala/sbt/internal/langserver/codec/SbtExecParamsFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.langserver.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait SbtExecParamsFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val SbtExecParamsFormat: JsonFormat[sbt.internal.langserver.SbtExecParams] = new JsonFormat[sbt.internal.langserver.SbtExecParams] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.langserver.SbtExecParams = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val commandLine = unbuilder.readField[String]("commandLine") + unbuilder.endObject() + sbt.internal.langserver.SbtExecParams(commandLine) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.langserver.SbtExecParams, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("commandLine", obj.commandLine) + builder.endObject() + } +} +} diff --git a/protocol/src/main/contraband/lsp.contra b/protocol/src/main/contraband/lsp.contra index cfc43ae69..49853a2f4 100644 --- a/protocol/src/main/contraband/lsp.contra +++ b/protocol/src/main/contraband/lsp.contra @@ -110,3 +110,10 @@ type PublishDiagnosticsParams { ## An array of diagnostic information items. diagnostics: [sbt.internal.langserver.Diagnostic] } + +# sbt extension + +## Command to execute sbt command. +type SbtExecParams { + commandLine: String! +} diff --git a/server.md b/server.md index 20c55f508..a172eb5fd 100644 --- a/server.md +++ b/server.md @@ -1,11 +1,13 @@ +### initialize + +```json +{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "initializationOptions": { "token": "************" } } } +``` ### ExecCommand ```json -{ "type": "ExecCommand", "commandLine": "compile" } +{ "jsonrpc": "2.0", "id": 1, "method": "sbt/exec", "params": { "commandLine": "compile" } } ``` -```json -{ "type": "ExecCommand", "commandLine": "eval Thread.sleep(10000)" } -``` From 1ad9360e3e9446eed325fd7259c41b59541393dc Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Oct 2017 01:45:06 -0400 Subject: [PATCH 23/57] setting query is "sbt/setting" --- .../server/LanguageServerProtocol.scala | 7 ++++++ .../sbt/internal/server/NetworkChannel.scala | 12 ++++++---- .../sbt/internal/server/SettingQuery.scala | 17 +++++++------- server.md | 23 ++++++++++++++++++- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index ba713c631..ad585d6f4 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -5,6 +5,7 @@ package server import sjsonnew.JsonFormat import sjsonnew.support.scalajson.unsafe.Converter import sbt.protocol.Serialization +import sbt.protocol.{ SettingQuery => Q } import sbt.internal.protocol._ import sbt.internal.protocol.codec._ import sbt.internal.langserver._ @@ -24,6 +25,7 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { protected def authOptions: Set[ServerAuthentication] protected def setInitialized(value: Boolean): Unit protected def log: Logger + protected def onSettingQuery(execId: Option[String], req: Q): Unit protected def onRequestMessage(request: JsonRpcRequestMessage): Unit = { @@ -54,6 +56,11 @@ private[sbt] trait LanguageServerProtocol extends CommandChannel { case "sbt/exec" => val param = Converter.fromJson[SbtExecParams](json).get append(Exec(param.commandLine, Some(request.id), Some(CommandSource(name)))) + case "sbt/setting" => { + import sbt.protocol.codec.JsonProtocol._ + val param = Converter.fromJson[Q](json).get + onSettingQuery(Option(request.id), param) + } case _ => () } } diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 12d9b33d8..7044cd9a2 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -9,11 +9,9 @@ import java.net.{ Socket, SocketTimeoutException } import java.util.concurrent.atomic.AtomicBoolean import sjsonnew._ -import sjsonnew.support.scalajson.unsafe.Converter import scala.annotation.tailrec import sbt.protocol._ import sbt.internal.langserver.ErrorCodes -import sbt.internal.protocol.JsonRpcResponseMessage import sbt.internal.util.ObjectEvent import sbt.internal.util.codec.JValueFormats import sbt.util.Logger @@ -283,7 +281,7 @@ final class NetworkChannel(val name: String, def onCommand(command: CommandMessage): Unit = command match { case x: InitCommand => onInitCommand(x) case x: ExecCommand => onExecCommand(x) - case x: SettingQuery => onSettingQuery(x) + case x: SettingQuery => onSettingQuery(None, x) } private def onInitCommand(cmd: InitCommand): Unit = { @@ -312,9 +310,13 @@ final class NetworkChannel(val name: String, } } - private def onSettingQuery(req: SettingQuery) = { + protected def onSettingQuery(execId: Option[String], req: SettingQuery) = { if (initialized) { - StandardMain.exchange publishEventMessage SettingQuery.handleSettingQuery(req, structure) + import sbt.protocol.codec.JsonProtocol._ + SettingQuery.handleSettingQueryEither(req, structure) match { + case Right(x) => langRespond(x, execId) + case Left(s) => langError(execId, ErrorCodes.InvalidParams, s) + } } else { log.warn(s"ignoring query $req before initialization") } diff --git a/main/src/main/scala/sbt/internal/server/SettingQuery.scala b/main/src/main/scala/sbt/internal/server/SettingQuery.scala index e8c585c18..9b3cd3859 100644 --- a/main/src/main/scala/sbt/internal/server/SettingQuery.scala +++ b/main/src/main/scala/sbt/internal/server/SettingQuery.scala @@ -110,18 +110,19 @@ object SettingQuery { toJson(value) }) - def handleSettingQuery(req: SettingQuery, structure: BuildStructure): SettingQueryResponse = { + def handleSettingQueryEither(req: SettingQuery, + structure: BuildStructure): Either[String, SettingQuerySuccess] = { val key = Parser.parse(req.setting, scopedKeyParser(structure)) - val result = - for { - key <- key - json <- getSettingJsonValue(structure, key) - } yield SettingQuerySuccess(json, key.key.manifest.toString) + for { + key <- key + json <- getSettingJsonValue(structure, key) + } yield SettingQuerySuccess(json, key.key.manifest.toString) + } - result match { + def handleSettingQuery(req: SettingQuery, structure: BuildStructure): SettingQueryResponse = + handleSettingQueryEither(req, structure) match { case Right(x) => x case Left(s) => SettingQueryFailure(s) } - } } diff --git a/server.md b/server.md index a172eb5fd..5afbb6f4f 100644 --- a/server.md +++ b/server.md @@ -1,13 +1,34 @@ +$ cat ~/.sbt/1.0/server/0845deda85cb41abdb9f/token.json + ### initialize ```json { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "initializationOptions": { "token": "************" } } } ``` -### ExecCommand +### sbt/exec ```json { "jsonrpc": "2.0", "id": 1, "method": "sbt/exec", "params": { "commandLine": "compile" } } ``` +### sbt/setting + +```json +{ "jsonrpc": "2.0", "id": 1, "method": "sbt/setting", "params": { "setting": "root/name" } } +``` + +Here's an example of a bad query: + +```json +{ "jsonrpc": "2.0", "id": 1, "method": "sbt/setting", "params": { "setting": "name" } } +``` + + +``` +Content-Length: 104 +Content-Type: application/vscode-jsonrpc; charset=utf-8 + +{"jsonrpc":"2.0","id":"1","error":{"code":-32602,"message":"Not a valid project ID: name\nname\n ^"}} +``` From 90c6c611991fff9ac77fc616a6c94111aa3585b2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Oct 2017 18:19:25 -0400 Subject: [PATCH 24/57] Add Scala syntax from daltonjorge/vscode-scala This adds Scala syntax for VS Code. The current plugin was relying on daltonjorge/vscode-scala for detecting that `*.scala` is a Scala source. This change integrates the plugin into this one. daltonjorge/vscode-scala is licensed under MIT license. --- .../client/language-configuration.json | 30 + vscode-sbt-scala/client/package.json | 25 +- .../client/syntaxes/Scala.tmLanguage | 1262 +++++++++++++++++ 3 files changed, 1316 insertions(+), 1 deletion(-) create mode 100644 vscode-sbt-scala/client/language-configuration.json create mode 100644 vscode-sbt-scala/client/syntaxes/Scala.tmLanguage diff --git a/vscode-sbt-scala/client/language-configuration.json b/vscode-sbt-scala/client/language-configuration.json new file mode 100644 index 000000000..aa2571000 --- /dev/null +++ b/vscode-sbt-scala/client/language-configuration.json @@ -0,0 +1,30 @@ +{ + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "//", + // symbols used for start and end a block comment. Remove this entry if your language does not support block comments + "blockComment": [ "/*", "*/" ] + }, + // symbols used as brackets + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that that can be used to surround a selection + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +} \ No newline at end of file diff --git a/vscode-sbt-scala/client/package.json b/vscode-sbt-scala/client/package.json index 7f1760155..fa56b2102 100644 --- a/vscode-sbt-scala/client/package.json +++ b/vscode-sbt-scala/client/package.json @@ -1,7 +1,7 @@ { "name": "vscode-sbt-scala", "displayName": "Scala (sbt)", - "version": "0.0.1", + "version": "0.0.2", "author": "Lightbend, Inc.", "license": "BSD-3-Clause", "publisher": "lightbend", @@ -17,6 +17,29 @@ "categories": [ "Languages" ], + "contributes": { + "languages": [ + { + "id": "scala", + "aliases": [ + "Scala", + "scala" + ], + "extensions": [ + ".scala", + ".sbt" + ], + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "scala", + "scopeName": "source.scala", + "path": "./syntaxes/Scala.tmLanguage" + } + ] + }, "activationEvents": [ "workspaceContains:build.sbt" ], diff --git a/vscode-sbt-scala/client/syntaxes/Scala.tmLanguage b/vscode-sbt-scala/client/syntaxes/Scala.tmLanguage new file mode 100644 index 000000000..2dc4860cd --- /dev/null +++ b/vscode-sbt-scala/client/syntaxes/Scala.tmLanguage @@ -0,0 +1,1262 @@ + + + + + fileTypes + + scala + + firstLineMatch + ^#!/.*\b\w*scala\b + foldingStartMarker + /\*\*|\{\s*$ + foldingStopMarker + \*\*/|^\s*\} + keyEquivalent + ^~S + name + Scala + patterns + + + include + #code + + + repository + + block-comments + + begin + /\* + end + \*/ + name + comment.block.scala + patterns + + + include + #block-comments + + + match + (?x) + (?! /\*) + (?! \*/) + + + + + char-literal + + begin + ' + beginCaptures + + 0 + + name + punctuation.definition.character.begin.scala + + + end + ' + endCaptures + + 0 + + name + punctuation.definition.character.end.scala + + + name + constant.character.literal.scala + patterns + + + match + \\(?:[btnfr\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4}) + name + constant.character.escape.scala + + + match + \\. + name + invalid.illegal.unrecognized-character-escape.scala + + + match + [^']{2,} + name + invalid.illegal.character-literal-too-long + + + match + (?<!')[^'] + name + invalid.illegal.character-literal-too-long + + + + code + + patterns + + + include + #script-header + + + include + #storage-modifiers + + + include + #declarations + + + include + #inheritance + + + include + #imports + + + include + #comments + + + include + #strings + + + include + #initialization + + + include + #xml-literal + + + include + #keywords + + + include + #constants + + + include + #scala-symbol + + + include + #special-identifier + + + include + #char-literal + + + include + #empty-parentheses + + + include + #parameter-list + + + include + #qualifiedClassName + + + include + #meta-brackets + + + include + #meta-bounds + + + include + #meta-colons + + + + comments + + patterns + + + captures + + 0 + + name + punctuation.definition.comment.scala + + + match + /\*\*/ + name + comment.block.empty.scala + + + begin + ^\s*(/\*\*)(?!/) + beginCaptures + + 1 + + name + punctuation.definition.comment.scala + + + end + \*/ + endCaptures + + 0 + + name + punctuation.definition.comment.scala + + + name + comment.block.documentation.scala + patterns + + + captures + + 1 + + name + keyword.other.documentation.scaladoc.scala + + 2 + + name + variable.parameter.scala + + + match + (@param)\s+(\S+) + + + captures + + 1 + + name + keyword.other.documentation.scaladoc.scala + + 2 + + name + entity.name.class + + + match + (@(?:tparam|throws))\s+(\S+) + + + match + @(return|see|note|example|usecase|author|version|since|todo|deprecated|migration|define|inheritdoc)\b + name + keyword.other.documentation.scaladoc.scala + + + captures + + 1 + + name + punctuation.definition.documentation.link.scala + + 2 + + name + entity.other.documentation.link.scala + + 3 + + name + punctuation.definition.documentation.link.scala + + + match + (\[\[)([^\]]+)(\]\]) + + + + + begin + /\* + captures + + 0 + + name + punctuation.definition.comment.scala + + + end + \*/ + name + comment.block.scala + + + begin + (^[ \t]+)?(?=//) + beginCaptures + + 1 + + name + punctuation.whitespace.comment.leading.scala + + + end + (?!\G) + patterns + + + begin + // + beginCaptures + + 0 + + name + punctuation.definition.comment.scala + + + end + \n + name + comment.line.double-slash.scala + + + + + + constants + + patterns + + + match + \b(false|null|true|Nil|None)\b + name + constant.language.scala + + + match + \b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.[0-9]+)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?|[0-9]+)([LlFfDd]|UL|ul)?\b + name + constant.numeric.scala + + + match + \b(this|super|self)\b + name + variable.language.scala + + + match + \b(Unit|Boolean|Byte|Char|Short|Int|Float|Long|Double)\b + name + storage.type.primitive.scala + + + match + \b(String|Symbol)\b + name + storage.type.scala + + + + declarations + + patterns + + + captures + + 1 + + name + keyword.declaration.scala + + 2 + + name + entity.name.function.declaration + + + match + (?x) + \b(def)\s+ + (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w])(?=[(\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+) + + + captures + + 1 + + name + keyword.declaration.scala + + 2 + + name + keyword.declaration.scala + + 3 + + name + entity.name.class.declaration + + + match + (case)?\b(class|trait|object)\s+([^\s\{\(\[]+) + + + captures + + 1 + + name + keyword.declaration.scala + + 2 + + name + entity.name.type.declaration + + + match + \b(type)\s+(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\s])(?=[\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+) + + + captures + + 1 + + name + keyword.declaration.stable.scala + + 2 + + name + constant.other.declaration.scala + + + match + \b(val)\s+(?:([A-Z][_a-zA-Z0-9]*))\b + + + captures + + 1 + + name + keyword.declaration.stable.scala + + 2 + + name + keyword.declaration.volatile.scala + + 3 + + name + variable.other.declaration.scala + + + match + \b(?:(val)|(var))\s+(?:(`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w])(?=[\t ])|[_$a-zA-Z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+)|(?=\()) + + + captures + + 1 + + name + keyword.other.scoping.scala + + 2 + + name + keyword.declaration.scala + + 3 + + name + entity.name.class.declaration + + + match + \b(package)\s+(object)\s+([^\s\{\(\[]+) + + + begin + \b(package)\s+ + beginCaptures + + 1 + + name + keyword.other.import.scala + + + end + (?<=[\n;]) + name + meta.package.scala + patterns + + + include + #comments + + + match + (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) + name + entity.name.package.scala + + + match + \. + name + punctuation.definition.package + + + + + + empty-parentheses + + captures + + 1 + + name + meta.bracket.scala + + + match + (\(\)) + name + meta.parentheses.scala + + imports + + begin + \b(import)\s+ + beginCaptures + + 1 + + name + keyword.other.import.scala + + + end + (?<=[\n;]) + name + meta.import.scala + patterns + + + include + #comments + + + match + (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) + name + entity.name.import.scala + + + match + \. + name + punctuation.definition.import + + + begin + { + beginCaptures + + 0 + + name + meta.bracket.scala + + + end + } + endCaptures + + 0 + + name + meta.bracket.scala + + + name + meta.import.selector.scala + patterns + + + captures + + 1 + + name + entity.name.import.renamed-from.scala + + 2 + + name + keyword.other.arrow.scala + + 3 + + name + entity.name.import.renamed-to.scala + + + match + (?x) \s* + (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \s* + (=>) \s* + (`[^`]+`|[_$a-zA-Z][_$a-zA-Z0-9]*) \s* + + + + match + ([^\s.,}]+) + name + entity.name.import.scala + + + + + + inheritance + + patterns + + + captures + + 1 + + name + keyword.declaration.scala + + 2 + + name + entity.other.inherited-class.scala + + + match + (extends|with)\s+([^\s\{\(\[\]]+) + + + + initialization + + captures + + 1 + + name + keyword.declaration.scala + + 2 + + name + entity.name.class + + + match + \b(new)\s+([^\s,\{\}\(\)\[\]]+) + + keywords + + patterns + + + match + \b(return|throw)\b + name + keyword.control.flow.jump.scala + + + match + \b(classOf|isInstanceOf|asInstanceOf)\b + name + support.function.type-of.scala + + + match + \b(else|if|do|while|for|yield|match|case)\b + name + keyword.control.flow.scala + + + match + \b(catch|finally|try)\b + name + keyword.control.exception.scala + + + match + (==?|!=|<=|>=|<>|<|>) + name + keyword.operator.comparison.scala + + + match + (\-|\+|\*|/(?![/*])|%|~) + name + keyword.operator.arithmetic.scala + + + match + (!|&&|\|\|) + name + keyword.operator.logical.scala + + + match + (<-|←|->|→|=>|⇒|\?|\:+|@|\|)+ + name + keyword.operator.scala + + + + meta-bounds + + comment + For themes: Matching view bounds + match + <%|=:=|<:<|<%<|>:|<: + name + meta.bounds.scala + + meta-brackets + + comment + For themes: Brackets look nice when colored. + patterns + + + comment + The punctuation.section.*.begin is needed for return snippet in source bundle + match + \{ + name + punctuation.section.block.begin.scala + + + comment + The punctuation.section.*.end is needed for return snippet in source bundle + match + \} + name + punctuation.section.block.end.scala + + + match + {|}|\(|\)|\[|\] + name + meta.bracket.scala + + + + meta-colons + + comment + For themes: Matching type colons + patterns + + + match + (?<!:):(?!:) + name + meta.colon.scala + + + + parameter-list + + patterns + + + captures + + 1 + + name + variable.parameter.scala + + 2 + + name + meta.colon.scala + + + comment + We do not match param names that start with a Capitol letter + match + (?<=[^\._$a-zA-Z0-9])(`[^`]+`|[_$a-z][_$a-zA-Z0-9]*(?:_[^\s])(?=[\t ])|[_$a-z][_$a-zA-Z0-9]*|[-?~><^+*%:!#|/@\\]+)\s*(:)\s+ + + + + qualifiedClassName + + captures + + 1 + + name + entity.name.class + + + match + (\b([A-Z][\w]*)) + + scala-symbol + + match + '\w+(?=[^'\w]|$) + name + constant.other.symbol.scala + + script-header + + captures + + 1 + + name + string.unquoted.shebang.scala + + + match + ^#!(.*)$ + name + comment.block.shebang.scala + + special-identifier + + comment + + Match special scala style identifiers that can end with and underscore and + a a not letter such as blank_?. This way the symbol will not be colored + differently. + + match + \b[_$a-zA-Z][_$a-zA-Z0-9]*(?:_[^\t .,;()\[\]{}'"`\w]) + + storage-modifiers + + patterns + + + match + \b(private\[\S+\]|protected\[\S+\]|private|protected)\b + name + storage.modifier.access + + + match + \b(synchronized|@volatile|abstract|final|lazy|sealed|implicit|override|@transient|@native)\b + name + storage.modifier.other + + + + strings + + patterns + + + begin + """ + beginCaptures + + 0 + + name + punctuation.definition.string.begin.scala + + + end + """(?!") + endCaptures + + 0 + + name + punctuation.definition.string.end.scala + + + name + string.quoted.triple.scala + patterns + + + match + \\\\|\\u[0-9A-Fa-f]{4} + name + constant.character.escape.scala + + + + + begin + " + beginCaptures + + 0 + + name + punctuation.definition.string.begin.scala + + + end + " + endCaptures + + 0 + + name + punctuation.definition.string.end.scala + + + name + string.quoted.double.scala + patterns + + + match + \\(?:[btnfr\\"']|[0-7]{1,3}|u[0-9A-Fa-f]{4}) + name + constant.character.escape.scala + + + match + \\. + name + invalid.illegal.unrecognized-string-escape.scala + + + + + + xml-doublequotedString + + begin + " + beginCaptures + + 0 + + name + punctuation.definition.string.begin.xml + + + end + " + endCaptures + + 0 + + name + punctuation.definition.string.end.xml + + + name + string.quoted.double.xml + patterns + + + include + #xml-entity + + + + xml-embedded-content + + patterns + + + begin + { + captures + + 0 + + name + meta.bracket.scala + + + end + } + name + meta.source.embedded.scala + patterns + + + include + #code + + + + + captures + + 1 + + name + entity.other.attribute-name.namespace.xml + + 2 + + name + entity.other.attribute-name.xml + + 3 + + name + punctuation.separator.namespace.xml + + 4 + + name + entity.other.attribute-name.localname.xml + + + match + (?:([-_a-zA-Z0-9]+)((:)))?([_a-zA-Z-]+)= + + + include + #xml-doublequotedString + + + include + #xml-singlequotedString + + + + xml-entity + + captures + + 1 + + name + punctuation.definition.constant.xml + + 3 + + name + punctuation.definition.constant.xml + + + match + (&)([:a-zA-Z_][:a-zA-Z0-9_.-]*|#[0-9]+|#x[0-9a-fA-F]+)(;) + name + constant.character.entity.xml + + xml-literal + + patterns + + + begin + (<)((?:([_a-zA-Z0-9][_a-zA-Z0-9]*)((:)))?([_a-zA-Z0-9][-_a-zA-Z0-9:]*))(?=(\s[^>]*)?></\2>) + beginCaptures + + 1 + + name + punctuation.definition.tag.xml + + 3 + + name + entity.name.tag.namespace.xml + + 4 + + name + entity.name.tag.xml + + 5 + + name + punctuation.separator.namespace.xml + + 6 + + name + entity.name.tag.localname.xml + + + comment + We do not allow a tag name to start with a - since this would + likely conflict with the <- operator. This is not very common + for tag names anyway. Also code such as -- if (val <val2 || val> val3) + will falsly be recognized as an xml tag. The solution is to put a + space on either side of the comparison operator + end + (>(<))/(?:([-_a-zA-Z0-9]+)((:)))?([-_a-zA-Z0-9:]*[_a-zA-Z0-9])(>) + endCaptures + + 1 + + name + punctuation.definition.tag.xml + + 2 + + name + meta.scope.between-tag-pair.xml + + 3 + + name + entity.name.tag.namespace.xml + + 4 + + name + entity.name.tag.xml + + 5 + + name + punctuation.separator.namespace.xml + + 6 + + name + entity.name.tag.localname.xml + + 7 + + name + punctuation.definition.tag.xml + + + name + meta.tag.no-content.xml + patterns + + + include + #xml-embedded-content + + + + + begin + (</?)(?:([_a-zA-Z0-9][-_a-zA-Z0-9]*)((:)))?([_a-zA-Z0-9][-_a-zA-Z0-9:]*)(?=[^>]*?>) + captures + + 1 + + name + punctuation.definition.tag.xml + + 2 + + name + entity.name.tag.namespace.xml + + 3 + + name + entity.name.tag.xml + + 4 + + name + punctuation.separator.namespace.xml + + 5 + + name + entity.name.tag.localname.xml + + + end + (/?>) + name + meta.tag.xml + patterns + + + include + #xml-embedded-content + + + + + include + #xml-entity + + + + xml-singlequotedString + + begin + ' + beginCaptures + + 0 + + name + punctuation.definition.string.begin.xml + + + end + ' + endCaptures + + 0 + + name + punctuation.definition.string.end.xml + + + name + string.quoted.single.xml + patterns + + + include + #xml-entity + + + + + scopeName + source.scala + uuid + 158C0929-299A-40C8-8D89-316BE0C446E8 + + From 10539bcd22dc1da135b3ef4e7929580745b67b70 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Oct 2017 18:22:14 -0400 Subject: [PATCH 25/57] update logo to a white background version --- .../client/images/sbt-logo-455x262.png | Bin 6715 -> 0 bytes .../client/images/sbt-logo-bgwhite-455x262.png | Bin 0 -> 7859 bytes vscode-sbt-scala/client/package.json | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 vscode-sbt-scala/client/images/sbt-logo-455x262.png create mode 100644 vscode-sbt-scala/client/images/sbt-logo-bgwhite-455x262.png diff --git a/vscode-sbt-scala/client/images/sbt-logo-455x262.png b/vscode-sbt-scala/client/images/sbt-logo-455x262.png deleted file mode 100644 index 82f485ef9692ede8f09d296bce9df0ae9c23aa80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6715 zcmZ`;2T)T{m!=z<5(3f!h9q4Xl303slvBhrzkqOs76ph74ip$bxzCQYP>qBKQH zD1sE}2$)c$2-2nQ(|>k$XLdF-nPkrW?)koR?!D)|cOL$VsR26+KMM^F4ZD#c8cRb% z+W~x;Kumyz!_YAw_~E;!Z+p+e@A^G|7n}!;uDhSB2h8ZEi>C+H!^J)DPN#skhkuVkCt5->`O_$;Kt)aVscyWB=|J^N$%wY9AKbp2wt_Zf=JVEYVdrq25e`q>{# zuB~0p{m6CU;KkQCCMNnJs)CcfcWe^5hup&ho<4;f`c<0Lxp(kGzai${X+X*U_i^Su zj)K#S_GusQj0~Ra_cb3LHJ|LBR7kK#ya~_)(@aWr$j&9=kE@C`%fgSBr&UroXmAXM z=7eyq^+cQdE^uQSDu@`#>r}dTn$eC9W)QJB7hrw-^xYnJsZ#B0^^!cj$0T z);R9kHg(5K|Fzu49oA5q>Hf`l-WsqHmTzWf-CgNa!W=OhfB|@g1!mTu>1K|Qt?Odd z=rkHMfhGz=XxbGBy^=l`dBb+pyGE8hto(T&J;ETOp8iX2yY>$dN{{BIved*+t74D+ zlB(IGu8s|5>fm+EmD#Wm_-Kvn@^4T%Mt+| z_517gb~^JvFA=$&|BKpL`($sz$tgt}^F$kdknqn9sTllEz&|NO#6S6%|0@K*04lsL z(HtZYjxaGXM&xrsC^~b5IYNggUhjCF4E{S8VE!uyK!QA)f5&G2)rU?1Qa}bs;C~Yk z0sWW5%2NRSzx@4A_y7i2Xp8>@pfd#Wu6_Xm#N!zDGPw2sJBJaXmD7K-7y-!E_$@tK z{G;{ewB>pF#ejuCwz0#C;k}W4%c!X*@7^Oi=v{I_G^k9Xi*>N*`LLuh#tSJ`Sd8YO%c=I6Pui72W3pr`p8?=uCycCmH$+(hg zWc5}@>)t|g>LY9vfdL}&$FOY`NPqcabZu*t*F7+MetujHg_&-05A=uXt! zxDPMu2Ug@ETYyx2MSK#PBN|qPXnnX@Z7lSVcNdSP){)jql4(>!THHgofh_aR8^vJD z^U6Sv_jp#r+HGf;r8%>kRctKp=V{}c}YX%!3)JQi*~i59;Pb6Va!>T?Jm4deba*3iZ(-D#d~&ZBtN z&%9to-_+uRx7hp?FzTZO7@x2>pP4MUpUtL`e* z=dx7EwmToUuQ1;&UG-b7Q{a8#A(#RMyZMnL)Fryr;~a?dhz`xr8T9f(u%N!ZEWB%} z*I6R!Zi2Yc9&HT{x{`%(T@mC97_tA=4;~N8cf29&Pw!`WHu=%`tlk9NpDD_YiG*;4 zvPrDLvAXt&{3F%7qI^X`6NC2oZ7CD31SBmAjxmlJxFoBIA!v40NpEVuS@l%>oU4;W zd<(6eMPLM^;Sl$;9~UT32PjDnKkYmt6sflLr%%hl$ugqX+)5Q#nx^?2hJUIwQfXlO zdV{_iDreL6>h_i)+FwbArElByX25yv$dB6nXRC^J(i|U1or`Ohpp4c3P8^d+(A5D!u zt}PIA4T0Dl=o2cX3~kGzj5i#3w!!{12Le;!}LUtapN7}W3WFQGY9H`&uH|_F5k$uKMWq8IH=&RI zX_vo@Re@bEx;QT06dD|l;yohvht7g^E8fV$4OIF4m{F3n%Qb%j$LzwEvGKv^K!n2R zM&R77>98hrJQ=L^a%QgcLLHQzw|oP8b}jmlMm-N&ze-A%xt?eqCr8BdvL#-|q))c7 zn5@4q_X(`bw3`SQ*Y2yG_+{QCtG-r(NzqEX=9b8d=dZu`7V2)5e|tip!u4qc+21y$ zPbw<+)g`9*TC?&kb^AZk2ESV=H;!xiStO}9oM7Poy9uH%E9}~RSzJ?a`!hdOEsm~C-cT;ZN9(sjiV{4hGv64yB zTTKOq+COgUe$9ol_er`feyvX`_y46aAIe1yxbV0_#?W#r?sA%<)PB3oL7XA+z34|; z4RQ^+d0MEFoobB--{DVA-ex(l4CjgEn3Xk6UI zO)`9?HJldpS$S5w88FYGD8qHF#aiD*Jo{%6NNsC@#A-fV!hNXi#nr_T*02uqh)MuzBq zJH?Y~D|nmdgJn=gkmk2E+lvhc$_s5|Vl`Asx1x)%p1CCEv!$cEjYg1BN+5~u-yQMI zTvP-3Z$vj^zS}W}w=zQ5Es5yF2xwXFb91V3CLIpxgC-Kvy`ub3KAyIxY?<8NO+_E- zaCx7h0GClYE#3Ke`WbZ`TWIA|)D9faPjXv|Ov!pAp>(Qgu8yri0~wprNbZxag?G?1 zh3yDXxTqQ*T^;)e*t*RJ$3{qOWX2>k0i9sPf`d9YPk-&YVL)hsS3l%4I?Zs90K)0u zeArO%4hphU@D&>13)8J$i-9((94{L(+OZFJV~NwqJJIED@6D0J+_oa2q^xLYy|Yl@ z`-J;+mBVoibp)C7C{Cp!VZ%HFs^Qk?y$3&U$#U-LDgHdOBLFU7L=EJU+<1B%?D;Gq z*&H_%Gu{2FLj&y@QAG%HyuBWwNubd|N5kxmgGgpdW9Ny>m{OB2{;0ixp>seIw^GpW zgw*P;kgX3Jlv;`r|D1*}ce9T~6UbGA;<5Cl6Udw~Q*>Zg4ik=HFcMm|5e2RHSsx+L z*Y4`4;HJJ~`plXNA-CkhX6bO3&4_$T|Hg5zCQ)ri&I`#KC23CDqG5={u}?8a?MTLd zly5#Y-}Q#Bd3D?7cj@W>QT|kDQ--7B78Ds#FEB*65%yzt`kwy0l$h!dH(;snQm&@D z=_apSBffu_*wTc+t=ycsNHln0Du~QW2R3UZf^3Y4Le&G+%W|(d?a?t0<{J%uoyz zalKfiS57|>8qGmXRSx33Kdvw$F8?N@!U|PAZK%$N?E?0%6>(&4^BF~1FxQ;w?VOuY z4F2UYQ@9KM>oJY0-XUN1y0?MNB_s6+19GO*2b7zDuxWN3w}MeBZ`>*t;OEc%A+v=m zQw`OH0r^D?5*?b3?^oNJeM`%@-%orW@v$OW1Dgo3%0SGwGwR~TRu{;)MOC{Pv^ zw)=CC$l4SV=0Dj#jv-nTdTa%^M*YwP;JCj*&ar&B^QQ-jSMMNpcc<`e#qht%KS+@F zrNiBT8QI-x6wh^1lH@e+`i}GzIX53dMxWXdcvuXU-jHsWE%f6^U&vFYF>IoSf1EuJvJ5DcuyXW>!bJL)G`Ft|1Uw@U_;wulO$fAc(T9oKRndY#8 z_z@B&nG;pmbf|W2F%MT3<@jmcnSMur7PTXL38fw=!K^vA$(pyao5c8!m*~b@-B9k) zG%wRwIMT4N*uU{S8o1Mk8H_^At&Ly9yHW@-TYQ@K|B3Jbrpt=bGfAm8K%bTQBMjlOutA+ciWB7hZP=R2SGQ)cUXBhe?vZ9vLy3O!An4R!Lv-`!|F~bJ zL+KftJ1z;n{+8s+7T-<&^@h^?dC7xqMdk0^{i1o&w#W!C5@mAlD?;r;|E43ZkYX52O;8J!(n6Y+^>(DYTu5F((19PYJ4 zYOGX5_k^0M#+jfM6}=dUII!_vycEZ(g@d}wGk#AmKsaTH2#A;tfu42a(y55r?L|3Z zl#F6EBXw`E0PhZ^f{s`=%DOsmtw~s_Dpoh=t6Fr_5k`lwek7^p8I1on0plhc`!f>3{Mc-*T*5bcbuD?6YIpXoR zMLAs*oJ@P6Zkn6~)T~BGgQ&u~>DHcvHHxWvItGU4_m?QjGi)%Hnw!)b(N*LIOp z=#3t#j#y^UEs_GBqo|{0yqn`EA|;#Wiet~&_SkP%Ej(p(lm*FaqGXhwL5XfJu^JM& zeYZ}o&U?;jAGCagJVv`7JA$ew+`ATF7Jc*nnCh& zS%HYCRKxpd^&EC718%q3Oxc%4pNi7HWd3gCaL+S;Qh3zPjw_hfUM+snd`qG|b_u?y z&B+&01U?-kx2ggsE9SAKS@QKAcAK}=t!uz82^&}UdbcVpSa?cVB#t2>FV|*gSqO&h z>yxj#InEX172^n6W#k7E9lG$TxGbPV`ch+H5E3P}-m+2N%#jdO7yjKs%)Tw9ztlY6 z0}nG`81p#LzVjf>3eSI(6wTkGu{~7h@7MT~9}h2!A5I6evBmKQ>(c?(IQfcV5<2S^ z2p8fjV$irfZ`|iPslsst{;^W<0Hs$>*U2f!#^L^Sm6`>hmfo$f`X!UxZaTlKgknWj zLO>om^44LARTu(Do)#rj9Q#XD=!IanFS6ro^g;dgq9lzP4e@Wi5l?W2XHm*L$Y9$< zGtTo{QTlvJjuwciv^$28A>+^GZ0HY07yb8}&e_Ewa|Hz0dgD!{8@lBBkJ>}2AH>eQ z6}xh`G*3l0jLk)VP8{X4VGJfeS1Hv`Iu~s^*`KZ+&iV$T9N6LBt{MTO_ZCAZXzreR zr+LR&En{O$E~=i@-$ZMK_7WUsH*dew&!-sFwau&)JFcj)tK`B~hcL8Bn-hp_$pRiM z4?I`i25&qLYMXq8Hsj==Tk@uqL^9G27OF{63Qw zpoO*0 zbRa8tSd6S*8K&BVix&FDnN&$huiii;Yd%{eUl9^=d=Ldn@>3=xmE>{It?dNRM8EkjPK3 z-u2-uF|9CWBemIHnb0rAO7?bFg^=BA``tNxp=UqBaGrD!^7f6hURgviy_#L-m6MLm zo{s4X<8qvf3J>F>i@#hF_H~C|8)ayG@+o0;$5CxvTjL%x4;Wj0^cSlx2%R4uR zMq~#-j~3-jh=vGip2hS%=~WkYSJp%Q4mY0&A5aS_p^?-5xoC#`o62;U8X); z&7H>X@MD6q0Hg2C1r@Hg?9@}^yF}b17+J%uuJF@nWTAn&+l@_&#Zhmi(?vTPsag)d z2Yhca&v428T79PS#*ZFXE}0+Vh#IbsF8Z3Wb$>eBJk3wU&bS6GHh$KcKK0X!WVJL( z3%6TZm+ncLE^DMlgjndINKnS_fjjf1e!chKf8|p53tps1e>d;$gqpA<#rF(FP3*E} zUm$q#(05lU!(^cEl(&@PdM^fgWAqC#ct?E%58hE9?rK z?{!n3C^X&}JZnDJ@UyXM+|-7!N>jF~dB&U5>rHs}B3f~{YV^2zNt1hX{AORe+}<0? z!PT?yaJ=szYwbi+u6*H92C>y}BVoE}`%_y+{MjO?uR{8JgmESFV+_Uy|6tK#cQ2UP z;HJd^80mVsSo=KOcVV{cj+msXKXL`yGX5v<#Px=`hbF!C`p&#RgLh;qB_jOXk=N`G zyX)*ugxapa5|TT{VoE?Fr=}0LE;DpR+D zT0)X|8CUol<#xB^Z>egH{ zZ^t6xFglL@ z7q*zo&V?3ut5Au&3-3IK&8k^D4fHf6&6^(l7Sh*?1zN|?Q;|+}6BD_vPPl8uT%9_M zKqvlG+=itHU$VH3WE&%18327u7gyl_>KjwVeE;~CJjfJ0AA;Iv3oPXCfRVl_x-l3|bMO6ZXZxJKJcBcYAL?D=#~ks;#@V-8n5+D+fCRJ1g4&&mOxwFxXi@>%J<= ze_}aXPutLVx=WGENN+>pVaA-RQPK^5r(Y~Krs!2iajDLZQHhw7Y!mlH1?dV(pZ)1# zyS%S28n22QiyEXyc-yPDbhB6ooStru)4f?!$g%Kc_wX0x_^Fw#t*y7y^0d7Z=RdOA z^!--K*;8s-U#(9RQK^F{9B=n4hr?jaAoPrfC@1{m2h9kBVR&FLO8|N)hl?wod{QYk z=@xqZ*+V+$n@jGd%T%XH^dVA^`IYHGxFwLVdS9Kflr;>XD{svRJ)B(%)v~_SFt%{% zWE(xSQ6)jD=xf_gjwAjvywFMM^PZv8wxKyYIkK##^98GUh%!DtPG}%l^~200bvVE3 zh*sF8=C;Wcd0h(HbGtoU9r({mOpCTYrNU|*h_I|$yvEO3O<-AWFU@x%?I#}yqJ5TKuV)7KIGvxS)i8wR zpNMir(Xlh38Mll9%jwW-hj%&oL?CL6DUAf``pgdo43A?s_?{3qK!U`>iE{l>*cB;F z4@pVEgh!Ppc%kMi8=gMb3BAd51J&^o6woxPvjQwR#6fyUr1O#RI1rkf`EM>HRmUVi zAN7w;E^dGhqW`Zdk2(O&(;>#?vOxRa?gpWS7@l7zpk>YA-JRUHd^j|(2(6A}g!U1z z1)zllmW}&peag(9AGGB;+(eHjS9(C0r?-bF&ELI$E4p8s!)yO3p| z8KqS9|8a5-_m98QT--mhlm0P7_t2IHIKd6Hw9pC*J4T=*6>(#txCr-iOE)<1^g)(oO z$EA06RI)exA5@Kw5H|d~Km3s@AjGYxK=Z{$yq#o}WV3V!z8t~tu{OB!BerJ z5xzy~)2qyyrb4d@(P?w6Kpu{TJ8GyO-djv7C7a>orE}63ibg{MLq3gcR{mrPByX^O z+B?j(K%)KVjCsU+{X|rr+73_ay-e^(TO>QiR6lC)`I=6|ij-uCHISTtSdhU^+08)y z--f%zO?HbJbrtF6skhzR=carnsk)3d>t)T&0TjlJo8`g(waxd<93| z&O2s!aWwZ5V93>*-#kji1oVwcf~F<}a6yyPnzg2q|8y4yM~BGB+!GjH)Y?A(CTn@M zz#?v#e75NnWJ)+I0P%!dUu46(1f#BWdYBWtx-$Kga_)UE3z%NQlA_^lmg@D$ouKnD zXXR3MWgKOtZxqv8x8kT#0?9pN+hDk{!T&+U9Gd0x z=FH_Yyv!AFZ0y#bfZr!eH2>xn$BP0#o0H%an43CKm%QLm)Kg4YnBjkgJ$oXg@#U06 ztNbTTsc8^NHDBNw;U3pCyq3y|e@~$9Sr=2YfB!~VX9o8+l^KppMEvl*`0Xra4M^18?4K?k&3D56IlE%!zV~Il&8^=E48FfwE$f@0>?pR( zP1kPBgE-*z*7?BE&c4Fn95wjaUv(f#Vv?*xzam+?jC( zwA2BrmCwEd+vWTwi9t0TVEGjKK4|dQ#MWHoxgnm!MlnUc9oP zV9TxyTRR+&ql&+pEg*&~99F7^Y2$|v)^dwa@{J0V@M}a)b%U+$uV5q@nK z18aS%^g;Xe-jX_T9%DeXGhgwevs&0W{7sd7Uc?m^ZUEaB;L6Nt z3%sy2$(7-pt9`-~0dHryXv(8Xp=TRPBkdU7p~a}_^H?)t4TlfG9?~hdrbJIzv}BXs zbCT?y#=>vir;NlN!xz28(RvQC@o#M1AfX*G-8S&XLqf=wLLAUxmn?Z%KXrJwT;>c| zx|ShNa8+9OmCTyL^dUbLt%{PREK5<`z{hQVBKGE8))haA$XWxxYmD|nY6J^|$18VFS!Mx0=dV-{z%?Is)-PT!%Flm^UwaAJ zmA6ychRI9VM~jkn_~nOQJWDG9r8hse-VDfP9)I331ouiJbfApfrrrfMxa{>Ti^1XI zr&yIk4mGz{6=xIg&1h&!P^wH(9Y`L-iMF4l*{VZyDuuqs&uCqV_E-PYQhb%4?Vs0J zp9qvb*xq$f?iEMvBfr}b4fMCmU=JRL%N~!u&zlZ!Fuy4ma;1OZE#YW9nv%Q4Kb`H%y&mQhB|01&Z=TQZ6GDP-PX1fx3 z54Zf=gR_%Md_Po9jy`GM_L%EyWm*KA0~SVH|9=@|wZ*{C>BiEaO#UN-=;B z1y+BQ=LtjBkYvt?zJBV=98-x2wFtamH^+j$QV%d%NXOAa534$Ug2F54`4mLc$H8|Z z?^nOS*6_0_sa@zo6H>~G)6xP;2O`;i)h4DPxU21NY3KCr{^712j`5m?%Y{ng&Q z6>Y%gWXwMEQ(Q1#PBBJh&Z|wyte28$37Dg?orz+%BEX>*8k1U{M?ra>$2)5XML*9n z#Uu>FQVG;v5jo5X0DQb3n@fGLN5 zF(EvU&v~_5c=RjL-R0G|g_WHDrgBz?l~6h8qdey&*F*6=!wYDcCSw$LmIj-ukLM^i zomu^ESZ*(lE@abz!>rRL&ti_1ha~Z-rs^?Gi?Bww>h$A(P9o?uCVmNhNX*LMa3T;V zB)#j3cgn^M8EgBF5+BL;%FkAUq()3omlF%i7~1%K7D4RR)WA{(nKM7%IMrIh=MU5A z9@(RvvY{5EHU1tVcNi5eDP;ouI5jkzdJ_@3AFhP`R_Iu&aSW@MR6GmgdjB+G@MUw z`89h~0B72A!#B>BVv-O6S0i2S((o|CKcf4St=uz<`bzua612VVLDP9QmY-yRqWA<{ z;vyBD9&u!3G4&xw9XnH%G`B4tg+`gkGXZbR)q!a1gQPyJ;rMx^9X>jpZPvi?cY;~G z>{~U}W>#^~NdkS@1`SBb-bXisn+ZDFaWIQ+>&GOe;InRa>45Vl8yMV<_!7~UJ!otG zED-H8|MTokHfxWiyj&be!WiBfsc8eMo!&?Jh|wxdJ%yq+a;d|0xLyQ7oCvy75M|_W zGKP)3b^k)s{)Uay!U>HBDrOJ>-{e_({)oM;n#D8~X(#sBMr!HaKuOT&ujLaE^la$J z)cC3W7!N;XL{sjB4Eha&gUR5Syi8p_4s5`Tl*oJcaaY5KJ$Gq3~=&{-j%|`R{5=g)uzpuqq<)M0;o%IJh$jl$Z$`;;CqoJO%O<(+jczP@XCA> zuSaAV1m(<(KVT%pEm7zIJUXz!uT$)O?NyDyOAUw1JLkW7tb7@dIZMN(*qwUXY0?xG(y7Y3ByZONR-b@jJ^q_1-$?Bdq~t}6Js0)GR&1D zN322FaJ}7fE%DfM_xI=Z36mc$J_m?TXfw~Y*kU&jixiAu?%46=({bRhLy?PUy7`+a z=uHwR8Ja}kIvuAU1auP(ocOAsK?r({K%OQBUk)1AWG|Vzp*$sJ04w#H9fR7Ay5w-c zhvcM65crH~njh;r2ys~=Lg}2hSZ+qo=_Q2IAx>=DHU-r`F zI)oS&6{~Y`y=fK7e;~I|(>h^7$$j#tkpWNV?LfPK;WVC39IU8zk{9t8#4zVJ00~ab zP>g~+6f^_E+*%oa5Gb&zq_S6lT#%E}s}l&`4L+BAXK_uA>LvJ|v?6QHfJlOwC;jud0G^t~mDDLEU>$ti{A28{iV`u3aK98+fr zPRPYgcI6P|%)rIB1#M zeCNjVPD0{shp2_3=6jL8Og(KCK|zTi0Z3SqkVE>F*9QJ@qK5+6KPP(7xDmYpVPvX8 z$EK>Dk#UzK5(VXp5%Qh;2mcTQAO9HVv8kxVTH}Fe=^&fWMdsI*M&0n9U|f&eu{f|B z9FAvzqS0l#227Bj!+x^N$njt2^&9PsepFJm5}(%zIGS{Woi@!a4z_|q^7{Jv)8pO{{W+noC8eLe+5ri5Ae2)LV1{<# zJrf9!<*w(XS1XkwGE3qJPNjlSR!aa8fzojd@Q(u(N~QU@ID$!3vKoeRb?f7R0rsY4 z&?9yI)GMuVpzc>6E;Ns7)$03ueJlpCk9{J+lj?xIDwMg-6Iss;`J79h`|vd^;dx~~ zu9x3R9Z*5rLPJH3q{l9YsrtN@+gslpDt)s%M4xi`b3?grI2W<5Ose@4@o^TRE+QXp zbpIo&;~i@`h!n^0yV(I;4~p$6PUIkkEXU^Mv;Jp@5x{&6Wjs8oM~J(^YLP)l9Q3lk zaKY`uNov|mL>uV!he^$_?2S7stEYeU8}nnB4sBq}82D5i*#mJOe6>>%vLh_tF@#H)?#r3wvo$=7>Hvmk`KnK<0n2!=$)vsd5A$x(#90lb(krA5*Ht+} zuPn*D*2nZuyg@#xNUZkZ`SW81b?5%+_}pNJ|MTrd^cVs^OuHA2k^ff>u>u&GW#hly zXf`<&)>bXdxzr+pYtDBPf3ec^5)GxwLywVilfhawK)hRcFnf9==F)M1uZY9>F$Hq< zP!zn%^l`k#3g>-{1AHoOu0_~-6N#aPD$vJ67FuVVnxb$Npcmw|1VuZgt7+deU`rjJ zfm-3~Oe91PnCCGY%OchLsRJB+`h)G~Lerhg7v+^F0;_c+i>i8`7F$IJomV3qzZVat z8)6fHl6mBwJW^@&{ngR8CN266b_3NeaUdtYJvVNpNg0jRyixU5?J|RYWU)y3frovv zvD$_tuRK%OdY&*RzC0gfs6U!qkqjarBub=_4)#yypL_2`^>-aOy3bM^3-sSA13Q0?R~-?eTdtUFe%q|p+IyNn!FG(@75=(N$Bn}F zqlg>+wN<7u6#5OtIDTDEd!%%_p7y$yJ(^JGx0qsvbd)Y)^2i!N=;X_eb?&DbU~yD! zQe41y`6q9wC$Etn7k3z^3cz9qeX%Rf_ESvlcRg7f!lQu7gDK|8!ijw{wrE;tqL zBc9WP8%?zZ)Nau4-s}_~gA`wzpfkQ|8pvn~%&R+3#6$F66LR&Ge+LCmp(2;eDsU&@ z&^K8~o$vqhm}# zzSu5N*C0{4iK5Q*g?}NWHq7UO%FJTOb=3C}S&vXv6zt(?vvTkW~CTF9_JoUQGPLe3|?NP{L8Kpy@jJk5L#_FHueV1a_5u z3+)g&DNeJg`DL%q>RtS%FXC3Qrkh_Qt8yzFp}l@0WMNQvqTANniFM;(rR{_*aEx*~ zuTi?AW#aDj$w^WFo-hB(K&X2qOd7S(3%sG{99ch*^`!2Gq+|?- zgF{f(D+!++K7-2EErUg&GuHkRx-m-9ZLE8l`ygJ9A;}6+1rNopL_N}q&7I7<>p`2I zd*PP+?>bIXHPiqm}TYCzYGbpb0Nf8%z21z3i2qyw782hL*r@L5CI%K7wea zFeqP6(C#F?(O?0jmDjoKY#9N>h^V69kB+*^1|74Y>UFhWyVJry%{@yu0<{kC598Tg zIyC!@q}}Xd0E{!g_Qm+cq~2OP2_3O6jSVhIpFatnVs1arg@hcWrf=!(FcJn{E6OdX4L$>xXUc9Py3lY<{D}jD7i-D#D{$AH~VwlA0B;Fqb-5 zrVmBsA$gA`F@aP2RBVio(mG@f1#XRXi?J(QRUeUgH3%ia;sG-y`$Nt1V>gF5T}hvc zUjry2Tl5PRWJTI=lO%!=m0AFL|KX_r8~z>g|6cA{?;6YD?QoNlu~%;<3A?o|tWX{4 z)X~|O+)FF^Hai9q>z>8=yNButwtw@6m#{HPJ)0Q1;}2hgU=c1FL^oa>yxTbi>jMTS1cgFyw-*e>Y#EQ z|Dr2ZwYIo)^vGYI=JsZom>kjZ8ZTj0BF$U!+Q95@9B4syWkH^HD1429V9&4mP6TxG zaTwjH=R?GBATg})&)#s>?0)sWHM<#UXtd8DrOuSDyH`GP>}dXSDkG(0YC+8h_oVqr znToRy%%-SvOQ_npiht~uyM&Znv9)!)foq1)1?-FM1(l+-8 zBOHtSCZ=w@xi@T)_zoMXmt)Z~Bd;kDtDNp7HC?nM;@0?oan(P}r_B7ii5{pOaM2Q{)-pvS|2&Ljqihn$hxb(*Lo~83V}T1?~t6W-PC&IbzL^ zrbNkka7nDx^qmj5y44==SIn^#xH$oQ;nPP3hr(7nCWNw##q%NDkhOlh&6?w6o<-Nb zJ>$kAREPb80ZL6ToDDqgr+Hyty`>dA4wbIi?{G_TyDbaVl(jduE-)7-9HcPAwL zo@(s_qwe0Gd}27OPk4QHkn)4}U|z^FLHKV%BH=&v@h`2@45YIs%uJm~3ObwD=1Xl% zW#$}#$kdJvsN_5lM@-SXu*ROyXT>f0XlDvVJXpOrw&HkyuhNnTT?)v-MHtXppAhys zCKT7DmGaP6YNX|5@&nzl=BDD4+_7ZE53}~i`&s0Y@{hx^c};44Ty=CMQ|u|NQ3aDG zE9zBCzu1YA!Z4SLsPZ)Pe@FmZIbI5syfzJBh>@a!7X zy^Ds$I>DrdC(m62oEcQH3A%WR~YoXU4CZ%W+PtjqgdZmt=MIUT<}Giv zDJ%;9mSR?6#N#~G8KI_Gv=)UBY`K!c5DtXf`c{))&lZeUj<}FuK07_dzfQD(ux@WW zVb;WzRx*6@4b(pK#-I3;^B5}nV0gqk0~fB;0(t79Y(u<%C8D>X;hM_pvROsfN&|`D zn)Ge*vw|yU66v9SmO&X5?AW6|Loqa@CN?;(MI35@3CA%=K8(ljU_~Psq%MshZ4AXH znKS)tQDXBqK-0K*(Rr~m)} literal 0 HcmV?d00001 diff --git a/vscode-sbt-scala/client/package.json b/vscode-sbt-scala/client/package.json index fa56b2102..d42177c0a 100644 --- a/vscode-sbt-scala/client/package.json +++ b/vscode-sbt-scala/client/package.json @@ -10,7 +10,7 @@ "url": "https://github.com/sbt/sbt" }, "description": "Scala language support using sbt", - "icon": "images/sbt-logo-455x262.png", + "icon": "images/sbt-logo-bgwhite-455x262.png", "engines": { "vscode": "^1.16.0" }, From 9e855ffb555ef0a4a68f2a628df694bd49ab79f9 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 3 Oct 2017 18:07:42 +0100 Subject: [PATCH 26/57] Resolve some TODOs by creating a private copy2 in Project --- main/src/main/scala/sbt/Project.scala | 59 ++++++++------------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 6ad6e9d45..d284e64c4 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -111,7 +111,6 @@ sealed trait ProjectDefinition[PR <: ProjectReference] { } sealed trait Project extends ProjectDefinition[ProjectReference] { - // TODO: add parameters for plugins in 0.14.0 (not reasonable to do in a binary compatible way in 0.13) private[sbt] def copy( id: String = id, base: File = base, @@ -119,6 +118,19 @@ sealed trait Project extends ProjectDefinition[ProjectReference] { dependencies: Seq[ClasspathDep[ProjectReference]] = dependencies, settings: Seq[Setting[_]] = settings, configurations: Seq[Configuration] = configurations + ): Project = + copy2(id, base, aggregate, dependencies, settings, configurations) + + private[this] def copy2( + id: String = id, + base: File = base, + aggregate: Seq[ProjectReference] = aggregate, + dependencies: Seq[ClasspathDep[ProjectReference]] = dependencies, + settings: Seq[Setting[_]] = settings, + configurations: Seq[Configuration] = configurations, + plugins: Plugins = plugins, + autoPlugins: Seq[AutoPlugin] = autoPlugins, + projectOrigin: ProjectOrigin = projectOrigin, ): Project = unresolved( id, @@ -217,52 +229,13 @@ sealed trait Project extends ProjectDefinition[ProjectReference] { def disablePlugins(ps: AutoPlugin*): Project = setPlugins(Plugins.and(plugins, Plugins.And(ps.map(p => Plugins.Exclude(p)).toList))) - private[this] def setPlugins(ns: Plugins): Project = { - // TODO: for 0.14.0, use copy when it has the additional `plugins` parameter - unresolved( - id, - base, - aggregate = aggregate, - dependencies = dependencies, - settings, - configurations, - ns, - autoPlugins, - projectOrigin - ) - } + private[this] def setPlugins(ns: Plugins): Project = copy2(plugins = ns) /** Definitively set the [[AutoPlugin]]s for this project. */ - private[sbt] def setAutoPlugins(autos: Seq[AutoPlugin]): Project = { - // TODO: for 0.14.0, use copy when it has the additional `autoPlugins` parameter - unresolved( - id, - base, - aggregate = aggregate, - dependencies = dependencies, - settings, - configurations, - plugins, - autos, - projectOrigin - ) - } + private[sbt] def setAutoPlugins(autos: Seq[AutoPlugin]): Project = copy2(autoPlugins = autos) /** Definitively set the [[ProjectOrigin]] for this project. */ - private[sbt] def setProjectOrigin(origin: ProjectOrigin): Project = { - // TODO: for 1.0.x, use withProjectOrigin. - unresolved( - id, - base, - aggregate = aggregate, - dependencies = dependencies, - settings, - configurations, - plugins, - autoPlugins, - origin - ) - } + private[sbt] def setProjectOrigin(origin: ProjectOrigin): Project = copy2(projectOrigin = origin) } sealed trait ResolvedProject extends ProjectDefinition[ProjectRef] { From ceb0f0228a8af1f9abf27f7ebe56ad4a85b04365 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 3 Oct 2017 18:09:20 +0100 Subject: [PATCH 27/57] Use copy2 in resolveBuild --- main/src/main/scala/sbt/Project.scala | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index d284e64c4..ef780663f 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -167,17 +167,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference] { def resolveDeps(ds: Seq[ClasspathDep[ProjectReference]]) = ds map resolveDep def resolveDep(d: ClasspathDep[ProjectReference]) = ClasspathDependency(resolveRef(d.project), d.configuration) - unresolved( - id, - base, - aggregate = resolveRefs(aggregate), - dependencies = resolveDeps(dependencies), - settings, - configurations, - plugins, - autoPlugins, - projectOrigin - ) + copy2(aggregate = resolveRefs(aggregate), dependencies = resolveDeps(dependencies)) } /** From 1685dae1d93662308d48ce4c4edf70da4a238000 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 3 Oct 2017 18:10:37 +0100 Subject: [PATCH 28/57] Oneline Project.apply --- main/src/main/scala/sbt/Project.scala | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index ef780663f..8b091f45f 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -262,17 +262,7 @@ object Project extends ProjectExtra { } def apply(id: String, base: File): Project = - unresolved( - id, - base, - Nil, - Nil, - Nil, - Nil, - Plugins.empty, - Nil, - ProjectOrigin.Organic - ) + unresolved(id, base, Nil, Nil, Nil, Nil, Plugins.empty, Nil, ProjectOrigin.Organic) // TODO: add parameter for plugins and projectOrigin in 1.0 // TODO: Modify default settings to be the core settings, and automatically add the IvyModule + JvmPlugins. From ccdd77a94f529dfcc46a2dc0fd48519f1205f64c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 3 Oct 2017 18:13:57 +0100 Subject: [PATCH 29/57] Remove old, commented out Project.apply --- main/src/main/scala/sbt/Project.scala | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 8b091f45f..251e812f0 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -258,18 +258,13 @@ object Project extends ProjectExtra { val autoPlugins: Seq[AutoPlugin], val projectOrigin: ProjectOrigin ) extends ProjectDefinition[PR] { - Dag.topologicalSort(configurations)(_.extendsConfigs) // checks for cyclic references here instead of having to do it in Scope.delegates + // checks for cyclic references here instead of having to do it in Scope.delegates + Dag.topologicalSort(configurations)(_.extendsConfigs) } def apply(id: String, base: File): Project = unresolved(id, base, Nil, Nil, Nil, Nil, Plugins.empty, Nil, ProjectOrigin.Organic) - // TODO: add parameter for plugins and projectOrigin in 1.0 - // TODO: Modify default settings to be the core settings, and automatically add the IvyModule + JvmPlugins. - // def apply(id: String, base: File, aggregate: => Seq[ProjectReference] = Nil, dependencies: => Seq[ClasspathDep[ProjectReference]] = Nil, - // delegates: => Seq[ProjectReference] = Nil, settings: => Seq[Def.Setting[_]] = Nil, configurations: Seq[Configuration] = Nil): Project = - // unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil) // Note: JvmModule/IvyModule auto included... - def showContextKey(state: State): Show[ScopedKey[_]] = showContextKey(state, None) From d997fe80433385f2452e6a2a9d6a0f8dfc7ae1b5 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 4 Oct 2017 13:38:25 +0100 Subject: [PATCH 30/57] Oneline mkGeneratedRoot --- main/src/main/scala/sbt/Project.scala | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 251e812f0..21956b4f7 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -296,17 +296,10 @@ object Project extends ProjectExtra { aggregate: Seq[ProjectReference] ): Project = { validProjectID(id).foreach(errMsg => sys.error(s"Invalid project ID: $errMsg")) - new ProjectDef[ProjectReference]( - id, - base, - aggregate, - Nil, - Nil, - Nil, - Plugins.empty, - Nil, - ProjectOrigin.GenericRoot - ) with Project with GeneratedRootProject + val plugins = Plugins.empty + val origin = ProjectOrigin.GenericRoot + new ProjectDef(id, base, aggregate, Nil, Nil, Nil, plugins, Nil, origin) with Project + with GeneratedRootProject } /** Returns None if `id` is a valid Project ID or Some containing the parser error message if it is not.*/ From 530c405b2f9ba5fdde45801ceafd62921587402d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 4 Oct 2017 13:41:46 +0100 Subject: [PATCH 31/57] Implement Project#withId --- main/src/main/scala/sbt/Project.scala | 2 ++ notes/1.1.0/project-id.md | 11 +++++++++++ 2 files changed, 13 insertions(+) create mode 100644 notes/1.1.0/project-id.md diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 21956b4f7..0a92c1eab 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -177,6 +177,8 @@ sealed trait Project extends ProjectDefinition[ProjectReference] { */ def configure(transforms: (Project => Project)*): Project = Function.chain(transforms)(this) + def withId(id: String) = copy(id = id) + /** Sets the base directory for this project.*/ def in(dir: File): Project = copy(base = dir) diff --git a/notes/1.1.0/project-id.md b/notes/1.1.0/project-id.md new file mode 100644 index 000000000..fb408b1f8 --- /dev/null +++ b/notes/1.1.0/project-id.md @@ -0,0 +1,11 @@ +[@dwijnand]: https://github.com/dwijnand + +[#3601]: https://github.com/sbt/sbt/pull/3601 + +### Fixes with compatibility implications + +### Improvements + +- Adds `Project#withId` to change a project's id. [#3601][] by [@dwijnand][] + +### Bug fixes From 53bbb996171e22475efb33604ffe25c4c6769462 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 5 Oct 2017 02:43:50 -0400 Subject: [PATCH 32/57] Fixes Zero / Zero / Zero / name handling Prior to this change `Zero / Zero / Zero / name` broke as folllows: ``` scala> Zero / Zero / Zero / name Zero / Zero / Zero / name :18: error: inferred type arguments [sbt.Zero.type] do not conform to method /'s type parameter bounds [K <: sbt.SlashSyntax.Key[K]] Zero / Zero / Zero / name ^ ``` --- main/src/main/scala/sbt/SlashSyntax.scala | 8 +++++++- sbt/src/sbt-test/project/unified/build.sbt | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index 14d6d476c..634a86b75 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -1,6 +1,7 @@ package sbt import sbt.librarymanagement.Configuration +import sbt.internal.util.AttributeKey /** * SlashSyntax implements the slash syntax to scope keys for build.sbt DSL. @@ -57,7 +58,12 @@ object SlashSyntax { } /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ - final class RichConfiguration(protected val scope: Scope) extends RichScopeLike + final class RichConfiguration(protected val scope: Scope) extends RichScopeLike { + + // This is for handling `Zero / Zero / Zero / name`. + def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope = + new RichScope(scope.copy(task = taskAxis)) + } /** Both `Scoped.ScopingSetting` and `Scoped` are parents of `SettingKey`, `TaskKey` and * `InputKey`. We'll need both, so this is a convenient type alias. */ diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt index 935e32855..7f9835fea 100644 --- a/sbt/src/sbt-test/project/unified/build.sbt +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -10,6 +10,7 @@ lazy val root = (project in file(".")) Compile / console / scalacOptions += "-Ywarn-numeric-widen", projA / Compile / console / scalacOptions += "-feature", Zero / Zero / name := "foo", + Zero / Zero / Zero / name := "foo", libraryDependencies += uTest % Test, testFrameworks += new TestFramework("utest.runner.Framework"), From 60f2498c0a9c9f097a65c560eb724dd4b7bf9b13 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 5 Oct 2017 02:46:09 -0400 Subject: [PATCH 33/57] Implement toString for keys toString added for REPL testing: ``` scala> Zero / Zero / Zero / name res0: sbt.SlashSyntax.ScopeAndKey[sbt.SettingKey[String]] = Zero / Zero / Zero / name ``` --- main-settings/src/main/scala/sbt/Scope.scala | 5 +++++ main-settings/src/main/scala/sbt/Structure.scala | 6 ++++++ main/src/main/scala/sbt/SlashSyntax.scala | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 80661eb6b..4ca49b94d 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -24,6 +24,11 @@ final case class Scope(project: ScopeAxis[Reference], def in(project: Reference): Scope = copy(project = Select(project)) def in(config: ConfigKey): Scope = copy(config = Select(config)) def in(task: AttributeKey[_]): Scope = copy(task = Select(task)) + + override def toString: String = { + if (extra == This) s"$project / $config / $task" + else s"Scope($project, $config, $task, $extra)" + } } object Scope { val ThisScope: Scope = Scope(This, This, This, This) diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 247b776d4..da963325e 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -34,6 +34,8 @@ sealed abstract class SettingKey[T] val key: AttributeKey[T] + override def toString: String = s"SettingKey($scope / $key)" + final def toTask: Initialize[Task[T]] = this apply inlineTask final def scopedKey: ScopedKey[T] = ScopedKey(scope, key) @@ -105,6 +107,8 @@ sealed abstract class TaskKey[T] val key: AttributeKey[Task[T]] + override def toString: String = s"TaskKey($scope / $key)" + def toTask: Initialize[Task[T]] = this def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key) @@ -172,6 +176,8 @@ sealed trait InputKey[T] val key: AttributeKey[InputTask[T]] + override def toString: String = s"InputKey($scope / $key)" + def scopedKey: ScopedKey[InputTask[T]] = ScopedKey(scope, key) def in(scope: Scope): InputKey[T] = diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index 634a86b75..bf353f0ae 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -97,6 +97,10 @@ object SlashSyntax { final class ScopeAndKey[K <: Key[K]](scope: Scope, key: K) { private[sbt] def materialize: K = key in scope private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key) + + override def toString: String = { + s"$scope / ${key.key}" + } } } From a41727fb17bb923036f90ca2ca62897def1a893e Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 4 Oct 2017 18:01:06 +0100 Subject: [PATCH 34/57] Add, configure & enforce file headers --- .travis.yml | 2 +- LICENSE | 43 ++++++++++--------- NOTICE | 6 +-- build.sbt | 7 +++ .../internal/util/appmacro/ContextUtil.scala | 7 +++ .../sbt/internal/util/appmacro/Convert.scala | 7 +++ .../sbt/internal/util/appmacro/Instance.scala | 7 +++ .../internal/util/appmacro/KListBuilder.scala | 7 +++ .../internal/util/appmacro/LinterDSL.scala | 7 +++ .../internal/util/appmacro/MixedBuilder.scala | 7 +++ .../internal/util/appmacro/TupleBuilder.scala | 7 +++ .../util/appmacro/TupleNBuilder.scala | 7 +++ internal/util-collection/NOTICE | 7 +-- .../main/scala/sbt/internal/util/AList.scala | 7 +++ .../scala/sbt/internal/util/Attributes.scala | 8 +++- .../scala/sbt/internal/util/Classes.scala | 7 +++ .../main/scala/sbt/internal/util/Dag.scala | 8 +++- .../main/scala/sbt/internal/util/HList.scala | 8 +++- .../sbt/internal/util/HListFormats.scala | 7 +++ .../main/scala/sbt/internal/util/IDSet.scala | 8 +++- .../main/scala/sbt/internal/util/INode.scala | 7 +++ .../main/scala/sbt/internal/util/KList.scala | 7 +++ .../main/scala/sbt/internal/util/PMap.scala | 8 +++- .../main/scala/sbt/internal/util/Param.scala | 8 +++- .../scala/sbt/internal/util/Settings.scala | 8 +++- .../main/scala/sbt/internal/util/Signal.scala | 7 +++ .../sbt/internal/util/TypeFunctions.scala | 8 +++- .../main/scala/sbt/internal/util/Types.scala | 8 +++- .../main/scala/sbt/internal/util/Util.scala | 8 +++- .../main/scala/sbt/util/OptJsonWriter.scala | 7 +++ .../src/main/scala/sbt/util/Show.scala | 7 +++ .../src/test/scala/DagSpecification.scala | 8 +++- .../src/test/scala/HListFormatSpec.scala | 7 +++ .../src/test/scala/KeyTest.scala | 7 +++ .../src/test/scala/LiteralTest.scala | 8 +++- .../src/test/scala/PMapTest.scala | 8 +++- .../src/test/scala/SettingsExample.scala | 7 +++ .../src/test/scala/SettingsTest.scala | 7 +++ .../src/test/scala/UnitSpec.scala | 7 +++ internal/util-complete/NOTICE | 7 +-- .../scala/sbt/internal/util/LineReader.scala | 8 +++- .../internal/util/complete/Completions.scala | 8 +++- .../internal/util/complete/EditDistance.scala | 7 +++ .../util/complete/ExampleSource.scala | 7 +++ .../sbt/internal/util/complete/History.scala | 8 +++- .../util/complete/HistoryCommands.scala | 8 +++- .../util/complete/JLineCompletion.scala | 8 +++- .../sbt/internal/util/complete/Parser.scala | 8 +++- .../sbt/internal/util/complete/Parsers.scala | 8 +++- .../internal/util/complete/ProcessError.scala | 7 +++ .../util/complete/TokenCompletions.scala | 7 +++ .../internal/util/complete/TypeString.scala | 7 +++ .../internal/util/complete/UpperBound.scala | 8 +++- .../src/test/scala/ParserTest.scala | 7 +++ .../src/test/scala/UnitSpec.scala | 7 +++ .../scala/sbt/complete/FileExamplesTest.scala | 7 +++ .../sbt/complete/FixedSetExamplesTest.scala | 7 +++ .../sbt/complete/ParserWithExamplesTest.scala | 7 +++ .../scala/sbt/internal/util/logic/Logic.scala | 7 +++ .../src/test/scala/sbt/logic/Test.scala | 7 +++ launch/NOTICE | 7 +-- main-actions/src/main/scala/sbt/Console.scala | 8 +++- main-actions/src/main/scala/sbt/Doc.scala | 8 +++- .../src/main/scala/sbt/DotGraph.scala | 8 +++- .../src/main/scala/sbt/ForkTests.scala | 8 +++- main-actions/src/main/scala/sbt/Package.scala | 8 +++- .../src/main/scala/sbt/RawCompileLike.scala | 8 +++- main-actions/src/main/scala/sbt/Sync.scala | 8 +++- .../src/main/scala/sbt/TestResultLogger.scala | 7 +++ main-actions/src/main/scala/sbt/Tests.scala | 8 +++- .../src/main/scala/sbt/compiler/Eval.scala | 7 +++ .../src/test/scala/sbt/CacheIvyTest.scala | 7 +++ .../test/scala/sbt/compiler/EvalTest.scala | 7 +++ .../main/scala/sbt/BasicCommandStrings.scala | 8 +++- .../src/main/scala/sbt/BasicCommands.scala | 7 +++ .../src/main/scala/sbt/BasicKeys.scala | 7 +++ main-command/src/main/scala/sbt/Command.scala | 8 +++- .../src/main/scala/sbt/CommandUtil.scala | 7 +++ .../main/scala/sbt/ExceptionCategory.scala | 7 +++ .../src/main/scala/sbt/Highlight.scala | 7 +++ .../src/main/scala/sbt/MainControl.scala | 8 +++- main-command/src/main/scala/sbt/State.scala | 8 +++- main-command/src/main/scala/sbt/Watched.scala | 8 +++- .../scala/sbt/internal/CommandChannel.scala | 7 +++ .../scala/sbt/internal/ConsoleChannel.scala | 7 +++ .../sbt/internal/client/NetworkClient.scala | 6 ++- .../internal/client/ServerConnection.scala | 6 ++- .../scala/sbt/internal/server/Server.scala | 6 ++- main-command/src/main/scala/xsbt/IPC.scala | 8 +++- main-settings/src/main/scala/sbt/Append.scala | 7 +++ .../src/main/scala/sbt/ConfigKey.scala | 7 +++ main-settings/src/main/scala/sbt/Def.scala | 7 +++ .../src/main/scala/sbt/DelegateIndex.scala | 7 +++ .../src/main/scala/sbt/InputTask.scala | 7 +++ .../src/main/scala/sbt/KeyRanks.scala | 7 +++ .../src/main/scala/sbt/Previous.scala | 7 +++ .../src/main/scala/sbt/Reference.scala | 8 +++- main-settings/src/main/scala/sbt/Remove.scala | 7 +++ main-settings/src/main/scala/sbt/Scope.scala | 8 +++- .../src/main/scala/sbt/ScopeAxis.scala | 7 +++ .../src/main/scala/sbt/ScopeMask.scala | 7 +++ .../src/main/scala/sbt/Structure.scala | 8 +++- .../src/main/scala/sbt/std/InputConvert.scala | 7 +++ .../src/main/scala/sbt/std/InputWrapper.scala | 7 +++ .../src/main/scala/sbt/std/KeyMacro.scala | 7 +++ .../src/main/scala/sbt/std/SettingMacro.scala | 7 +++ .../main/scala/sbt/std/TaskLinterDSL.scala | 7 +++ .../src/main/scala/sbt/std/TaskMacro.scala | 7 +++ .../src/main/scala/sbt/unchecked.scala | 7 +++ .../src/test/scala/sbt/std/TaskPosSpec.scala | 7 +++ .../src/test/scala/sbt/std/TestUtil.scala | 6 ++- .../src/test/scala/sbt/std/UsageTest.scala | 7 +++ .../test/scala/sbt/std/neg/TaskNegSpec.scala | 7 +++ main/NOTICE | 7 +-- .../main/scala/sbt/BackgroundJobService.scala | 7 +++ main/src/main/scala/sbt/BuildPaths.scala | 8 +++- main/src/main/scala/sbt/BuildSyntax.scala | 7 +++ .../main/scala/sbt/CommandLineUIService.scala | 7 +++ main/src/main/scala/sbt/Cross.scala | 8 +++- main/src/main/scala/sbt/Defaults.scala | 8 +++- main/src/main/scala/sbt/EvaluateTask.scala | 8 +++- main/src/main/scala/sbt/Extracted.scala | 7 +++ .../main/scala/sbt/InteractionService.scala | 7 +++ main/src/main/scala/sbt/Keys.scala | 8 +++- main/src/main/scala/sbt/Main.scala | 8 +++- main/src/main/scala/sbt/MainLoop.scala | 8 +++- main/src/main/scala/sbt/OptionSyntax.scala | 7 +++ main/src/main/scala/sbt/Opts.scala | 8 +++- main/src/main/scala/sbt/PluginCross.scala | 12 +++--- main/src/main/scala/sbt/Plugins.scala | 7 +++ main/src/main/scala/sbt/Project.scala | 8 +++- main/src/main/scala/sbt/Resolvers.scala | 7 ++- main/src/main/scala/sbt/RichURI.scala | 7 ++- main/src/main/scala/sbt/ScopeFilter.scala | 7 +++ main/src/main/scala/sbt/ScopedKeyData.scala | 7 +++ main/src/main/scala/sbt/SessionVar.scala | 7 +++ main/src/main/scala/sbt/SlashSyntax.scala | 7 +++ main/src/main/scala/sbt/Tags.scala | 7 +++ main/src/main/scala/sbt/TemplateCommand.scala | 7 +++ .../main/scala/sbt/internal/APIMappings.scala | 7 +++ main/src/main/scala/sbt/internal/Act.scala | 8 +++- .../main/scala/sbt/internal/AddSettings.scala | 7 +++ .../main/scala/sbt/internal/Aggregation.scala | 8 +++- .../main/scala/sbt/internal/BuildDef.scala | 8 +++- .../sbt/internal/BuildDependencies.scala | 7 +++ .../main/scala/sbt/internal/BuildLoader.scala | 8 +++- .../scala/sbt/internal/BuildStructure.scala | 8 +++- .../main/scala/sbt/internal/BuildUtil.scala | 7 +++ .../scala/sbt/internal/CommandExchange.scala | 7 +++ .../scala/sbt/internal/CommandStrings.scala | 8 +++- .../scala/sbt/internal/ConsoleProject.scala | 8 +++- .../DefaultBackgroundJobService.scala | 7 +++ main/src/main/scala/sbt/internal/DslAst.scala | 7 +++ .../sbt/internal/EvaluateConfigurations.scala | 8 +++- main/src/main/scala/sbt/internal/GCUtil.scala | 7 +++ .../scala/sbt/internal/GlobalPlugin.scala | 7 +++ .../sbt/internal/GroupedAutoPlugins.scala | 7 +++ .../src/main/scala/sbt/internal/Inspect.scala | 7 +++ .../main/scala/sbt/internal/IvyConsole.scala | 8 +++- .../main/scala/sbt/internal/KeyIndex.scala | 8 +++- .../sbt/internal/LibraryManagement.scala | 7 +++ main/src/main/scala/sbt/internal/Load.scala | 8 +++- .../scala/sbt/internal/LoadedSbtFile.scala | 7 +++ .../main/scala/sbt/internal/LogManager.scala | 8 +++- main/src/main/scala/sbt/internal/Output.scala | 8 +++- .../scala/sbt/internal/PluginDiscovery.scala | 7 +++ .../scala/sbt/internal/PluginManagement.scala | 7 +++ .../scala/sbt/internal/PluginsDebug.scala | 7 +++ .../sbt/internal/ProjectNavigation.scala | 8 +++- .../scala/sbt/internal/RelayAppender.scala | 7 +++ .../src/main/scala/sbt/internal/Resolve.scala | 7 +++ .../scala/sbt/internal/RetrieveUnit.scala | 8 +++- main/src/main/scala/sbt/internal/Script.scala | 8 +++- .../scala/sbt/internal/SessionSettings.scala | 8 +++- .../sbt/internal/SettingCompletions.scala | 7 +++ .../scala/sbt/internal/SettingGraph.scala | 8 +++- .../main/scala/sbt/internal/TaskName.scala | 7 +++ .../scala/sbt/internal/TaskSequential.scala | 7 +++ .../main/scala/sbt/internal/TaskTimings.scala | 7 +++ .../librarymanagement/FakeRawRepository.scala | 7 +++ .../scala/sbt/internal/parser/SbtParser.scala | 7 +++ .../sbt/internal/parser/SbtRefactorings.scala | 7 +++ .../server/LanguageServerProtocol.scala | 7 +++ .../server/LanguageServerReporter.scala | 7 +++ .../sbt/internal/server/NetworkChannel.scala | 6 ++- .../sbt/internal/server/SettingQuery.scala | 6 ++- .../main/scala/sbt/plugins/CorePlugin.scala | 7 +++ .../sbt/plugins/Giter8ResolverPlugin.scala | 7 +++ .../main/scala/sbt/plugins/IvyPlugin.scala | 7 +++ .../sbt/plugins/JUnitXmlReportPlugin.scala | 7 +++ .../main/scala/sbt/plugins/JvmPlugin.scala | 7 +++ main/src/test/scala/DefaultsTest.scala | 7 +++ main/src/test/scala/Delegates.scala | 7 +++ main/src/test/scala/ParseKey.scala | 7 +++ main/src/test/scala/PluginCommandTest.scala | 7 +++ main/src/test/scala/PluginsTest.scala | 7 +++ main/src/test/scala/ProjectMacro.scala | 7 +++ main/src/test/scala/ProjectSpec.scala | 7 +++ main/src/test/scala/TagsTest.scala | 7 +++ .../test/scala/sbt/internal/TestBuild.scala | 7 +++ .../sbt/internal/parser/AbstractSpec.scala | 7 +++ .../internal/parser/CheckIfParsedSpec.scala | 7 +++ .../internal/parser/CommentedXmlSpec.scala | 7 +++ .../sbt/internal/parser/EmbeddedXmlSpec.scala | 7 +++ .../scala/sbt/internal/parser/ErrorSpec.scala | 7 +++ .../sbt/internal/parser/NewFormatSpec.scala | 7 +++ .../internal/parser/SessionSettingsSpec.scala | 7 +++ .../internal/parser/SplitExpressions.scala | 7 +++ .../parser/SplitExpressionsBehavior.scala | 7 +++ .../parser/SplitExpressionsTest.scala | 7 +++ .../internal/server/SettingQueryTest.scala | 7 +++ project/plugins.sbt | 1 + .../langserver/DiagnosticSeverity.scala | 7 +++ .../sbt/internal/langserver/ErrorCodes.scala | 7 +++ .../protocol/codec/JsonRPCProtocol.scala | 8 +++- .../JsonRpcNotificationMessageFormats.scala | 8 +++- .../codec/JsonRpcRequestMessageFormats.scala | 8 +++- .../codec/JsonRpcResponseErrorFormats.scala | 8 +++- .../codec/JsonRpcResponseMessageFormats.scala | 8 +++- .../scala/sbt/protocol/Serialization.scala | 6 ++- run/NOTICE | 17 ++++---- run/src/main/scala/sbt/Fork.scala | 8 +++- run/src/main/scala/sbt/OutputStrategy.scala | 7 +++ run/src/main/scala/sbt/Run.scala | 8 +++- run/src/main/scala/sbt/SelectMainClass.scala | 8 +++- run/src/main/scala/sbt/TrapExit.scala | 12 +++--- .../scala/sbt/TrapExitSecurityException.scala | 7 +++ run/src/test/scala/sbt/ForkTest.scala | 7 +++ run/src/test/scala/sbt/TestLogger.scala | 7 +++ sbt/src/main/scala/AllSyntax.scala | 7 +++ sbt/src/main/scala/Import.scala | 7 +++ sbt/src/main/scala/package.scala | 10 +++-- .../src/main/scala/sbt/ScriptedPlugin.scala | 8 +++- scripted/sbt/NOTICE | 7 +-- .../scala/sbt/test/BatchScriptRunner.scala | 7 +++ .../src/main/scala/sbt/test/SbtHandler.scala | 8 +++- .../main/scala/sbt/test/ScriptedTests.scala | 7 ++- tasks-standard/NOTICE | 7 +-- .../src/main/scala/sbt/Action.scala | 8 +++- .../src/main/scala/sbt/std/Streams.scala | 8 +++- .../src/main/scala/sbt/std/System.scala | 8 +++- .../src/main/scala/sbt/std/TaskExtra.scala | 8 +++- tasks-standard/src/test/scala/Execute.scala | 8 +++- tasks-standard/src/test/scala/TaskGen.scala | 8 +++- .../src/test/scala/TaskRunnerCircular.scala | 7 +++ .../src/test/scala/TaskRunnerFork.scala | 7 +++ .../src/test/scala/TaskSerial.scala | 7 +++ tasks-standard/src/test/scala/Test.scala | 8 +++- .../src/test/scala/TestRunnerCall.scala | 7 +++ .../src/test/scala/TestRunnerSort.scala | 8 +++- .../src/test/scala/checkResult.scala | 8 +++- tasks/NOTICE | 7 +-- .../main/scala/sbt/CompletionService.scala | 8 +++- .../scala/sbt/ConcurrentRestrictions.scala | 7 +++ tasks/src/main/scala/sbt/Execute.scala | 8 +++- .../src/main/scala/sbt/ExecuteProgress.scala | 7 +++ tasks/src/main/scala/sbt/Incomplete.scala | 8 +++- tasks/src/main/scala/sbt/Node.scala | 8 +++- tasks/src/main/scala/sbt/Result.scala | 8 +++- testing/NOTICE | 7 +-- .../src/main/java/sbt/ForkConfiguration.java | 7 +++ testing/agent/src/main/java/sbt/ForkMain.java | 8 +++- testing/agent/src/main/java/sbt/ForkTags.java | 8 +++- .../src/main/java/sbt/FrameworkWrapper.java | 7 +++ .../scala/sbt/JUnitXmlTestsListener.scala | 7 +++ .../src/main/scala/sbt/TestFramework.scala | 8 +++- .../main/scala/sbt/TestReportListener.scala | 7 ++- .../main/scala/sbt/TestStatusReporter.scala | 8 +++- .../sbt/internal/testing/StatusFormats.scala | 7 +++ .../sbt/internal/testing/TestLogger.scala | 7 +++ 270 files changed, 1750 insertions(+), 273 deletions(-) diff --git a/.travis.yml b/.travis.yml index 32110046e..4d33b9c23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ matrix: env: matrix: - - SBT_CMD=";mimaReportBinaryIssues ;scalafmt::test ;test:scalafmt::test ;sbt:scalafmt::test ;test:compile ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests" + - SBT_CMD=";mimaReportBinaryIssues ;scalafmt::test ;test:scalafmt::test ;sbt:scalafmt::test ;headerCheck ;test:headerCheck ;test:compile ;mainSettingsProj/test ;safeUnitTests ;otherUnitTests" - SBT_CMD="scripted actions/*" - SBT_CMD="scripted apiinfo/* compiler-project/* ivy-deps-management/*" - SBT_CMD="scripted dependency-management/*1of4" diff --git a/LICENSE b/LICENSE index d70192438..3a92f3a7c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,25 +1,28 @@ -Copyright (c) 2008-2014 Typesafe Inc, Mark Harrah, Grzegorz Kossakowski, Josh Suereth, Indrajit Raychaudhuri, Eugene Yokota, and other contributors. +Copyright (c) 2011 - 2017, Lightbend, Inc. +Copyright (c) 2008 - 2010, Mark Harrah All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. +modification, are permitted provided that the following conditions are met: -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NOTICE b/NOTICE index 55efecac8..01ea358e4 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,7 @@ sbt -Copyright (c) 2008-2014 Typesafe Inc, Mark Harrah, Grzegorz Kossakowski, Josh Suereth, Indrajit Raychaudhuri, Eugene Yokota, and other contributors. -Licensed under BSD-style license (see LICENSE) +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) Portions based on code from the Scala compiler. Portions of the Scala library are distributed with the launcher. @@ -33,4 +34,3 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - \ No newline at end of file diff --git a/build.sbt b/build.sbt index e59cc8169..2f2cb6553 100644 --- a/build.sbt +++ b/build.sbt @@ -39,6 +39,13 @@ def buildLevelSettings: Seq[Setting[_]] = def commonSettings: Seq[Setting[_]] = Seq[SettingsDefinition]( + headerLicense := Some(HeaderLicense.Custom( + """|sbt + |Copyright 2011 - 2017, Lightbend, Inc. + |Copyright 2008 - 2010, Mark Harrah + |Licensed under BSD-3-Clause license (see LICENSE) + |""".stripMargin + )), scalaVersion := baseScalaVersion, componentID := None, resolvers += Resolver.typesafeIvyRepo("releases"), diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala index 5d4cdf1b1..b70461e53 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/ContextUtil.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Convert.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Convert.scala index edb13f54c..2aae74f3b 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Convert.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Convert.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala index 7917d5255..a14637e05 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/KListBuilder.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/KListBuilder.scala index 4a2428912..99a210a0c 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/KListBuilder.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/KListBuilder.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/LinterDSL.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/LinterDSL.scala index 0ac846e9e..3c4587739 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/LinterDSL.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/LinterDSL.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util.appmacro import scala.reflect.macros.blackbox diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/MixedBuilder.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/MixedBuilder.scala index 8688d7376..472a0446b 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/MixedBuilder.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/MixedBuilder.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleBuilder.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleBuilder.scala index 0ca8b3ab3..0cd12ba44 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleBuilder.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleBuilder.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleNBuilder.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleNBuilder.scala index bb005a537..fab552157 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleNBuilder.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/TupleNBuilder.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package appmacro diff --git a/internal/util-collection/NOTICE b/internal/util-collection/NOTICE index 428020987..db1ba7e33 100644 --- a/internal/util-collection/NOTICE +++ b/internal/util-collection/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Collection Component -Copyright 2010 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Collection Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala b/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala index bbb20800d..3ab98f72e 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import Classes.Applicative diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index 80de459b2..a521a5de5 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import Types._ diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Classes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Classes.scala index bfef90b3e..d2cc6f13b 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Classes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Classes.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util object Classes { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Dag.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Dag.scala index b9d58a0bd..aa0f4a399 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Dag.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Dag.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 David MacIver, Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util trait Dag[Node <: Dag[Node]] { self: Node => diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/HList.scala b/internal/util-collection/src/main/scala/sbt/internal/util/HList.scala index 384c4c0d2..9fca8fada 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/HList.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/HList.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import Types._ diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/HListFormats.scala b/internal/util-collection/src/main/scala/sbt/internal/util/HListFormats.scala index e8173f554..eb5847930 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/HListFormats.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/HListFormats.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package util diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/IDSet.scala b/internal/util-collection/src/main/scala/sbt/internal/util/IDSet.scala index df5b1dedc..d952a508b 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/IDSet.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/IDSet.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util /** A mutable set interface that uses object identity to test for set membership.*/ diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala b/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala index 6f1661cf5..90e004efa 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import java.lang.Runnable diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala b/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala index 5e470c413..42ad69bb9 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import Types._ diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala b/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala index 4fe6f51ca..a488fb32f 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import collection.mutable diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala index dbded9292..201663b4e 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util // Used to emulate ~> literals diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala index 2be4f4b88..42cc4c8e3 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import scala.language.existentials diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Signal.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Signal.scala index bb339865b..c6818239f 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Signal.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Signal.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util object Signals { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala b/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala index 63c822103..c0875046c 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util trait TypeFunctions { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Types.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Types.scala index 9b6eb0733..ba472f8de 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Types.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Types.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util object Types extends Types diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala index 5736f57c2..8b3f7bd6d 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Util.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import java.util.Locale diff --git a/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala b/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala index e840bc689..a1733927d 100644 --- a/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala +++ b/internal/util-collection/src/main/scala/sbt/util/OptJsonWriter.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.util import sjsonnew.JsonWriter diff --git a/internal/util-collection/src/main/scala/sbt/util/Show.scala b/internal/util-collection/src/main/scala/sbt/util/Show.scala index 20ac0565d..d910b5319 100644 --- a/internal/util-collection/src/main/scala/sbt/util/Show.scala +++ b/internal/util-collection/src/main/scala/sbt/util/Show.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.util trait Show[A] { diff --git a/internal/util-collection/src/test/scala/DagSpecification.scala b/internal/util-collection/src/test/scala/DagSpecification.scala index a52401fa6..7047784a8 100644 --- a/internal/util-collection/src/test/scala/DagSpecification.scala +++ b/internal/util-collection/src/test/scala/DagSpecification.scala @@ -1,5 +1,9 @@ -/* sbt -- Simple Build Tool - * Copyright 2008 Mark Harrah */ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ package sbt.internal.util diff --git a/internal/util-collection/src/test/scala/HListFormatSpec.scala b/internal/util-collection/src/test/scala/HListFormatSpec.scala index 6b9040f2e..0b7ae08e4 100644 --- a/internal/util-collection/src/test/scala/HListFormatSpec.scala +++ b/internal/util-collection/src/test/scala/HListFormatSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package util diff --git a/internal/util-collection/src/test/scala/KeyTest.scala b/internal/util-collection/src/test/scala/KeyTest.scala index 32479e6fd..40a5b7e76 100644 --- a/internal/util-collection/src/test/scala/KeyTest.scala +++ b/internal/util-collection/src/test/scala/KeyTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import org.scalacheck._ diff --git a/internal/util-collection/src/test/scala/LiteralTest.scala b/internal/util-collection/src/test/scala/LiteralTest.scala index f38dc3d31..b479752f7 100644 --- a/internal/util-collection/src/test/scala/LiteralTest.scala +++ b/internal/util-collection/src/test/scala/LiteralTest.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util // compilation test diff --git a/internal/util-collection/src/test/scala/PMapTest.scala b/internal/util-collection/src/test/scala/PMapTest.scala index d81bf3a3c..f07fde20e 100644 --- a/internal/util-collection/src/test/scala/PMapTest.scala +++ b/internal/util-collection/src/test/scala/PMapTest.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import Types._ diff --git a/internal/util-collection/src/test/scala/SettingsExample.scala b/internal/util-collection/src/test/scala/SettingsExample.scala index 21b009cd1..b31a7adaa 100644 --- a/internal/util-collection/src/test/scala/SettingsExample.scala +++ b/internal/util-collection/src/test/scala/SettingsExample.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import sbt.util.Show diff --git a/internal/util-collection/src/test/scala/SettingsTest.scala b/internal/util-collection/src/test/scala/SettingsTest.scala index 65878a59c..235cf5508 100644 --- a/internal/util-collection/src/test/scala/SettingsTest.scala +++ b/internal/util-collection/src/test/scala/SettingsTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import org.scalacheck._ diff --git a/internal/util-collection/src/test/scala/UnitSpec.scala b/internal/util-collection/src/test/scala/UnitSpec.scala index 99ad43c2d..fe1c4196e 100644 --- a/internal/util-collection/src/test/scala/UnitSpec.scala +++ b/internal/util-collection/src/test/scala/UnitSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import org.scalatest._ diff --git a/internal/util-complete/NOTICE b/internal/util-complete/NOTICE index a6f2c1de4..d5827b9c2 100644 --- a/internal/util-complete/NOTICE +++ b/internal/util-complete/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Completion Component -Copyright 2010 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Completion Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala index 971f57620..b5e9d53d2 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util import jline.console.ConsoleReader diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Completions.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Completions.scala index 64f6f1618..fd3df80c1 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Completions.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Completions.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/EditDistance.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/EditDistance.scala index e9536f0e1..5a8efe1be 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/EditDistance.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/EditDistance.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/ExampleSource.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/ExampleSource.scala index 54ac83a4e..6def5167d 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/ExampleSource.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/ExampleSource.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/History.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/History.scala index 23d60d411..1b3baa25e 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/History.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/History.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/HistoryCommands.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/HistoryCommands.scala index bf34ea047..827b9f544 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/HistoryCommands.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/HistoryCommands.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/JLineCompletion.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/JLineCompletion.scala index b779ace36..11ea1db4b 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/JLineCompletion.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/JLineCompletion.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala index 3ed65c2ee..19cb9770e 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parser.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2010, 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala index 3e15f3a14..b04b61127 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/Parsers.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/ProcessError.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/ProcessError.scala index 6f8efff7e..5eaf44357 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/ProcessError.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/ProcessError.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/TokenCompletions.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/TokenCompletions.scala index ca4768953..af62ddf95 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/TokenCompletions.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/TokenCompletions.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/TypeString.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/TypeString.scala index fa16073c0..9f512ed16 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/TypeString.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/TypeString.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/complete/UpperBound.scala b/internal/util-complete/src/main/scala/sbt/internal/util/complete/UpperBound.scala index e76d3b102..0c2a7de41 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/complete/UpperBound.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/complete/UpperBound.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008,2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/test/scala/ParserTest.scala b/internal/util-complete/src/test/scala/ParserTest.scala index f3abdbe50..df318d323 100644 --- a/internal/util-complete/src/test/scala/ParserTest.scala +++ b/internal/util-complete/src/test/scala/ParserTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/test/scala/UnitSpec.scala b/internal/util-complete/src/test/scala/UnitSpec.scala index 99ad43c2d..fe1c4196e 100644 --- a/internal/util-complete/src/test/scala/UnitSpec.scala +++ b/internal/util-complete/src/test/scala/UnitSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util import org.scalatest._ diff --git a/internal/util-complete/src/test/scala/sbt/complete/FileExamplesTest.scala b/internal/util-complete/src/test/scala/sbt/complete/FileExamplesTest.scala index 30a633459..61c6e53b1 100644 --- a/internal/util-complete/src/test/scala/sbt/complete/FileExamplesTest.scala +++ b/internal/util-complete/src/test/scala/sbt/complete/FileExamplesTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/test/scala/sbt/complete/FixedSetExamplesTest.scala b/internal/util-complete/src/test/scala/sbt/complete/FixedSetExamplesTest.scala index b1149fe88..08c9fd8cf 100644 --- a/internal/util-complete/src/test/scala/sbt/complete/FixedSetExamplesTest.scala +++ b/internal/util-complete/src/test/scala/sbt/complete/FixedSetExamplesTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-complete/src/test/scala/sbt/complete/ParserWithExamplesTest.scala b/internal/util-complete/src/test/scala/sbt/complete/ParserWithExamplesTest.scala index 93486dd54..e142e4a66 100644 --- a/internal/util-complete/src/test/scala/sbt/complete/ParserWithExamplesTest.scala +++ b/internal/util-complete/src/test/scala/sbt/complete/ParserWithExamplesTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package complete diff --git a/internal/util-logic/src/main/scala/sbt/internal/util/logic/Logic.scala b/internal/util-logic/src/main/scala/sbt/internal/util/logic/Logic.scala index f273d795e..5034ea25f 100644 --- a/internal/util-logic/src/main/scala/sbt/internal/util/logic/Logic.scala +++ b/internal/util-logic/src/main/scala/sbt/internal/util/logic/Logic.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package logic diff --git a/internal/util-logic/src/test/scala/sbt/logic/Test.scala b/internal/util-logic/src/test/scala/sbt/logic/Test.scala index 91ded0e69..51d2f2f67 100644 --- a/internal/util-logic/src/test/scala/sbt/logic/Test.scala +++ b/internal/util-logic/src/test/scala/sbt/logic/Test.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.util package logic diff --git a/launch/NOTICE b/launch/NOTICE index d0158f707..8abf4ed53 100644 --- a/launch/NOTICE +++ b/launch/NOTICE @@ -1,6 +1,7 @@ -Simple Build Tool Launcher -Copyright 2008, 2009, 2010 Mark Harrah, David MacIver -Licensed under BSD-style license (see LICENSE) +sbt Launcher +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah, David MacIver +Licensed under BSD-3-Clause license (see LICENSE) Classes from the Scala library are distributed with the launcher. Copyright 2002-2013 EPFL, Lausanne diff --git a/main-actions/src/main/scala/sbt/Console.scala b/main-actions/src/main/scala/sbt/Console.scala index c8ddf6544..c2792d595 100644 --- a/main-actions/src/main/scala/sbt/Console.scala +++ b/main-actions/src/main/scala/sbt/Console.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-actions/src/main/scala/sbt/Doc.scala b/main-actions/src/main/scala/sbt/Doc.scala index 2b0b662f9..db8a70db9 100644 --- a/main-actions/src/main/scala/sbt/Doc.scala +++ b/main-actions/src/main/scala/sbt/Doc.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010, 2011 Mark Harrah, Indrajit Raychaudhuri +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-actions/src/main/scala/sbt/DotGraph.scala b/main-actions/src/main/scala/sbt/DotGraph.scala index 96fb50743..d0be921be 100644 --- a/main-actions/src/main/scala/sbt/DotGraph.scala +++ b/main-actions/src/main/scala/sbt/DotGraph.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-actions/src/main/scala/sbt/ForkTests.scala b/main-actions/src/main/scala/sbt/ForkTests.scala index 3a0fb85f2..5beec08d3 100755 --- a/main-actions/src/main/scala/sbt/ForkTests.scala +++ b/main-actions/src/main/scala/sbt/ForkTests.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2012 Eugene Vigdorchik +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.collection.mutable diff --git a/main-actions/src/main/scala/sbt/Package.scala b/main-actions/src/main/scala/sbt/Package.scala index 3e48bee13..76333963e 100644 --- a/main-actions/src/main/scala/sbt/Package.scala +++ b/main-actions/src/main/scala/sbt/Package.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.Predef.{ conforms => _, _ } diff --git a/main-actions/src/main/scala/sbt/RawCompileLike.scala b/main-actions/src/main/scala/sbt/RawCompileLike.scala index 06b05100a..f06e7e3a8 100644 --- a/main-actions/src/main/scala/sbt/RawCompileLike.scala +++ b/main-actions/src/main/scala/sbt/RawCompileLike.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010, 2011 Mark Harrah, Indrajit Raychaudhuri +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-actions/src/main/scala/sbt/Sync.scala b/main-actions/src/main/scala/sbt/Sync.scala index 1660bef6b..feaca69c8 100644 --- a/main-actions/src/main/scala/sbt/Sync.scala +++ b/main-actions/src/main/scala/sbt/Sync.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.{ File, IOException } diff --git a/main-actions/src/main/scala/sbt/TestResultLogger.scala b/main-actions/src/main/scala/sbt/TestResultLogger.scala index 0992937d5..d2b8b5b30 100644 --- a/main-actions/src/main/scala/sbt/TestResultLogger.scala +++ b/main-actions/src/main/scala/sbt/TestResultLogger.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.Tests.{ Output, Summary } diff --git a/main-actions/src/main/scala/sbt/Tests.scala b/main-actions/src/main/scala/sbt/Tests.scala index e0dbbffa9..6030af1b0 100644 --- a/main-actions/src/main/scala/sbt/Tests.scala +++ b/main-actions/src/main/scala/sbt/Tests.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import std._ diff --git a/main-actions/src/main/scala/sbt/compiler/Eval.scala b/main-actions/src/main/scala/sbt/compiler/Eval.scala index b0cdd17da..3bd69b09a 100644 --- a/main-actions/src/main/scala/sbt/compiler/Eval.scala +++ b/main-actions/src/main/scala/sbt/compiler/Eval.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package compiler diff --git a/main-actions/src/test/scala/sbt/CacheIvyTest.scala b/main-actions/src/test/scala/sbt/CacheIvyTest.scala index 689a86a14..1827bc5db 100644 --- a/main-actions/src/test/scala/sbt/CacheIvyTest.scala +++ b/main-actions/src/test/scala/sbt/CacheIvyTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.scalacheck._ diff --git a/main-actions/src/test/scala/sbt/compiler/EvalTest.scala b/main-actions/src/test/scala/sbt/compiler/EvalTest.scala index 31eaceb60..10600a9a8 100644 --- a/main-actions/src/test/scala/sbt/compiler/EvalTest.scala +++ b/main-actions/src/test/scala/sbt/compiler/EvalTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package compiler diff --git a/main-command/src/main/scala/sbt/BasicCommandStrings.scala b/main-command/src/main/scala/sbt/BasicCommandStrings.scala index efa853903..7d5f120d7 100644 --- a/main-command/src/main/scala/sbt/BasicCommandStrings.scala +++ b/main-command/src/main/scala/sbt/BasicCommandStrings.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.util.Level diff --git a/main-command/src/main/scala/sbt/BasicCommands.scala b/main-command/src/main/scala/sbt/BasicCommands.scala index fb4112194..2ae3e6431 100644 --- a/main-command/src/main/scala/sbt/BasicCommands.scala +++ b/main-command/src/main/scala/sbt/BasicCommands.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.util.Level diff --git a/main-command/src/main/scala/sbt/BasicKeys.scala b/main-command/src/main/scala/sbt/BasicKeys.scala index f59f3f605..ef6bb00cd 100644 --- a/main-command/src/main/scala/sbt/BasicKeys.scala +++ b/main-command/src/main/scala/sbt/BasicKeys.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io.File diff --git a/main-command/src/main/scala/sbt/Command.scala b/main-command/src/main/scala/sbt/Command.scala index d5625436e..f90aedc8e 100644 --- a/main-command/src/main/scala/sbt/Command.scala +++ b/main-command/src/main/scala/sbt/Command.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.inc.ReflectUtilities diff --git a/main-command/src/main/scala/sbt/CommandUtil.scala b/main-command/src/main/scala/sbt/CommandUtil.scala index 00dd6c8b6..4087b5932 100644 --- a/main-command/src/main/scala/sbt/CommandUtil.scala +++ b/main-command/src/main/scala/sbt/CommandUtil.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io.File diff --git a/main-command/src/main/scala/sbt/ExceptionCategory.scala b/main-command/src/main/scala/sbt/ExceptionCategory.scala index 247cf7af3..f78d31ba2 100644 --- a/main-command/src/main/scala/sbt/ExceptionCategory.scala +++ b/main-command/src/main/scala/sbt/ExceptionCategory.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.lang.reflect.InvocationTargetException diff --git a/main-command/src/main/scala/sbt/Highlight.scala b/main-command/src/main/scala/sbt/Highlight.scala index 811efabfb..8eae20119 100644 --- a/main-command/src/main/scala/sbt/Highlight.scala +++ b/main-command/src/main/scala/sbt/Highlight.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.util.regex.Pattern diff --git a/main-command/src/main/scala/sbt/MainControl.scala b/main-command/src/main/scala/sbt/MainControl.scala index 12492babe..e728dd765 100644 --- a/main-command/src/main/scala/sbt/MainControl.scala +++ b/main-command/src/main/scala/sbt/MainControl.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-command/src/main/scala/sbt/State.scala b/main-command/src/main/scala/sbt/State.scala index 16608986b..6259a02a9 100644 --- a/main-command/src/main/scala/sbt/State.scala +++ b/main-command/src/main/scala/sbt/State.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-command/src/main/scala/sbt/Watched.scala b/main-command/src/main/scala/sbt/Watched.scala index 08a1c5838..0d24e18c4 100644 --- a/main-command/src/main/scala/sbt/Watched.scala +++ b/main-command/src/main/scala/sbt/Watched.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mikko Peltonen, Stuart Roebuck, Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import BasicCommandStrings.ClearOnFailure diff --git a/main-command/src/main/scala/sbt/internal/CommandChannel.scala b/main-command/src/main/scala/sbt/internal/CommandChannel.scala index ec46a0738..4fbb9a299 100644 --- a/main-command/src/main/scala/sbt/internal/CommandChannel.scala +++ b/main-command/src/main/scala/sbt/internal/CommandChannel.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala b/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala index eff9abf9e..6c2134050 100644 --- a/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala +++ b/main-command/src/main/scala/sbt/internal/ConsoleChannel.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala index 03fc3177d..303a08f2b 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal package client diff --git a/main-command/src/main/scala/sbt/internal/client/ServerConnection.scala b/main-command/src/main/scala/sbt/internal/client/ServerConnection.scala index c551613ae..530e117e1 100644 --- a/main-command/src/main/scala/sbt/internal/client/ServerConnection.scala +++ b/main-command/src/main/scala/sbt/internal/client/ServerConnection.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal package client diff --git a/main-command/src/main/scala/sbt/internal/server/Server.scala b/main-command/src/main/scala/sbt/internal/server/Server.scala index 9c8d3ee95..3a7c2785b 100644 --- a/main-command/src/main/scala/sbt/internal/server/Server.scala +++ b/main-command/src/main/scala/sbt/internal/server/Server.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal package server diff --git a/main-command/src/main/scala/xsbt/IPC.scala b/main-command/src/main/scala/xsbt/IPC.scala index 771a27197..db3be18a3 100644 --- a/main-command/src/main/scala/xsbt/IPC.scala +++ b/main-command/src/main/scala/xsbt/IPC.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package xsbt import java.io.{ BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter } diff --git a/main-settings/src/main/scala/sbt/Append.scala b/main-settings/src/main/scala/sbt/Append.scala index bb50f52fa..c9116de97 100644 --- a/main-settings/src/main/scala/sbt/Append.scala +++ b/main-settings/src/main/scala/sbt/Append.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io.File diff --git a/main-settings/src/main/scala/sbt/ConfigKey.scala b/main-settings/src/main/scala/sbt/ConfigKey.scala index 9bca80e6e..e9313ed15 100644 --- a/main-settings/src/main/scala/sbt/ConfigKey.scala +++ b/main-settings/src/main/scala/sbt/ConfigKey.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt final case class ConfigKey(name: String) diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index 70e8c460d..cfde273f9 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.Types.const diff --git a/main-settings/src/main/scala/sbt/DelegateIndex.scala b/main-settings/src/main/scala/sbt/DelegateIndex.scala index f270068d9..a5a6f64c7 100644 --- a/main-settings/src/main/scala/sbt/DelegateIndex.scala +++ b/main-settings/src/main/scala/sbt/DelegateIndex.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt sealed trait DelegateIndex { diff --git a/main-settings/src/main/scala/sbt/InputTask.scala b/main-settings/src/main/scala/sbt/InputTask.scala index e2d623f92..fbdb4a221 100644 --- a/main-settings/src/main/scala/sbt/InputTask.scala +++ b/main-settings/src/main/scala/sbt/InputTask.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.complete.Parser diff --git a/main-settings/src/main/scala/sbt/KeyRanks.scala b/main-settings/src/main/scala/sbt/KeyRanks.scala index 327fd2bc6..18a3758dc 100644 --- a/main-settings/src/main/scala/sbt/KeyRanks.scala +++ b/main-settings/src/main/scala/sbt/KeyRanks.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt object KeyRanks { diff --git a/main-settings/src/main/scala/sbt/Previous.scala b/main-settings/src/main/scala/sbt/Previous.scala index 35acdd87e..a40db6649 100644 --- a/main-settings/src/main/scala/sbt/Previous.scala +++ b/main-settings/src/main/scala/sbt/Previous.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import Def.{ Initialize, ScopedKey } diff --git a/main-settings/src/main/scala/sbt/Reference.scala b/main-settings/src/main/scala/sbt/Reference.scala index 07a4b268a..a605e16f5 100644 --- a/main-settings/src/main/scala/sbt/Reference.scala +++ b/main-settings/src/main/scala/sbt/Reference.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main-settings/src/main/scala/sbt/Remove.scala b/main-settings/src/main/scala/sbt/Remove.scala index 542e7d290..ad2a4a0fe 100644 --- a/main-settings/src/main/scala/sbt/Remove.scala +++ b/main-settings/src/main/scala/sbt/Remove.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import scala.annotation.implicitNotFound diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index 4ca49b94d..edfeb4826 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.net.URI diff --git a/main-settings/src/main/scala/sbt/ScopeAxis.scala b/main-settings/src/main/scala/sbt/ScopeAxis.scala index 95b380852..7ae24d62c 100644 --- a/main-settings/src/main/scala/sbt/ScopeAxis.scala +++ b/main-settings/src/main/scala/sbt/ScopeAxis.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.Types.some diff --git a/main-settings/src/main/scala/sbt/ScopeMask.scala b/main-settings/src/main/scala/sbt/ScopeMask.scala index 65b7acb80..27524facc 100644 --- a/main-settings/src/main/scala/sbt/ScopeMask.scala +++ b/main-settings/src/main/scala/sbt/ScopeMask.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt /** Specifies the Scope axes that should be used for an operation. `true` indicates an axis should be used. */ diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index da963325e..54a421cfe 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.language.experimental.macros diff --git a/main-settings/src/main/scala/sbt/std/InputConvert.scala b/main-settings/src/main/scala/sbt/std/InputConvert.scala index 45ab17e60..3437af145 100644 --- a/main-settings/src/main/scala/sbt/std/InputConvert.scala +++ b/main-settings/src/main/scala/sbt/std/InputConvert.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/main-settings/src/main/scala/sbt/std/InputWrapper.scala b/main-settings/src/main/scala/sbt/std/InputWrapper.scala index 29c4aadb8..b6dcc7b46 100644 --- a/main-settings/src/main/scala/sbt/std/InputWrapper.scala +++ b/main-settings/src/main/scala/sbt/std/InputWrapper.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/main-settings/src/main/scala/sbt/std/KeyMacro.scala b/main-settings/src/main/scala/sbt/std/KeyMacro.scala index 4f06cbd3b..aa08c14e6 100644 --- a/main-settings/src/main/scala/sbt/std/KeyMacro.scala +++ b/main-settings/src/main/scala/sbt/std/KeyMacro.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/main-settings/src/main/scala/sbt/std/SettingMacro.scala b/main-settings/src/main/scala/sbt/std/SettingMacro.scala index 43097cb19..23b9e51e0 100644 --- a/main-settings/src/main/scala/sbt/std/SettingMacro.scala +++ b/main-settings/src/main/scala/sbt/std/SettingMacro.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala b/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala index 0fa3a630d..ec6b04288 100644 --- a/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala +++ b/main-settings/src/main/scala/sbt/std/TaskLinterDSL.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.std import sbt.SettingKey diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index 9639a20ea..efeff7877 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/main-settings/src/main/scala/sbt/unchecked.scala b/main-settings/src/main/scala/sbt/unchecked.scala index 072150f8b..5cbb50f78 100644 --- a/main-settings/src/main/scala/sbt/unchecked.scala +++ b/main-settings/src/main/scala/sbt/unchecked.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import scala.annotation.Annotation diff --git a/main-settings/src/test/scala/sbt/std/TaskPosSpec.scala b/main-settings/src/test/scala/sbt/std/TaskPosSpec.scala index eb52dbdc4..68d8f9cdf 100644 --- a/main-settings/src/test/scala/sbt/std/TaskPosSpec.scala +++ b/main-settings/src/test/scala/sbt/std/TaskPosSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.std class TaskPosSpec { diff --git a/main-settings/src/test/scala/sbt/std/TestUtil.scala b/main-settings/src/test/scala/sbt/std/TestUtil.scala index 34b6a1b3b..ed6f15530 100644 --- a/main-settings/src/test/scala/sbt/std/TestUtil.scala +++ b/main-settings/src/test/scala/sbt/std/TestUtil.scala @@ -1,6 +1,8 @@ /* - * This file has been copy-pasted from spores. - * https://github.com/scalacenter/spores/blob/master/core/src/test/scala/scala/spores/TestUtil.scala + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ package sbt.std diff --git a/main-settings/src/test/scala/sbt/std/UsageTest.scala b/main-settings/src/test/scala/sbt/std/UsageTest.scala index 106ff6e4e..36e7750f9 100644 --- a/main-settings/src/test/scala/sbt/std/UsageTest.scala +++ b/main-settings/src/test/scala/sbt/std/UsageTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.std import sbt.internal.util.complete diff --git a/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala b/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala index ff9447502..75549783e 100644 --- a/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala +++ b/main-settings/src/test/scala/sbt/std/neg/TaskNegSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.std.neg import org.scalatest.FunSuite diff --git a/main/NOTICE b/main/NOTICE index de7e8ba8c..0fab58e02 100644 --- a/main/NOTICE +++ b/main/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Main integration component -Copyright 2010 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Main integration component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/main/src/main/scala/sbt/BackgroundJobService.scala b/main/src/main/scala/sbt/BackgroundJobService.scala index 7b7b30955..5af16058e 100644 --- a/main/src/main/scala/sbt/BackgroundJobService.scala +++ b/main/src/main/scala/sbt/BackgroundJobService.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io.Closeable diff --git a/main/src/main/scala/sbt/BuildPaths.scala b/main/src/main/scala/sbt/BuildPaths.scala index 89b5a1105..b83fe2311 100644 --- a/main/src/main/scala/sbt/BuildPaths.scala +++ b/main/src/main/scala/sbt/BuildPaths.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main/src/main/scala/sbt/BuildSyntax.scala b/main/src/main/scala/sbt/BuildSyntax.scala index 6c265118d..a2ef2c2cd 100644 --- a/main/src/main/scala/sbt/BuildSyntax.scala +++ b/main/src/main/scala/sbt/BuildSyntax.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.DslEntry diff --git a/main/src/main/scala/sbt/CommandLineUIService.scala b/main/src/main/scala/sbt/CommandLineUIService.scala index 24f143317..f4d97f26b 100644 --- a/main/src/main/scala/sbt/CommandLineUIService.scala +++ b/main/src/main/scala/sbt/CommandLineUIService.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.{ JLine, SimpleReader } diff --git a/main/src/main/scala/sbt/Cross.scala b/main/src/main/scala/sbt/Cross.scala index 4b2380d70..745206a27 100644 --- a/main/src/main/scala/sbt/Cross.scala +++ b/main/src/main/scala/sbt/Cross.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index f4d64983d..6fa48bcd9 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import Def.{ Initialize, ScopedKey, Setting, SettingsDefinition } diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index e14af7571..2400b2163 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.{ Load, BuildStructure, TaskTimings, TaskName, GCUtil } diff --git a/main/src/main/scala/sbt/Extracted.scala b/main/src/main/scala/sbt/Extracted.scala index aa8ad3052..5ccf71160 100644 --- a/main/src/main/scala/sbt/Extracted.scala +++ b/main/src/main/scala/sbt/Extracted.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.{ Load, BuildStructure, Act, Aggregation, SessionSettings } diff --git a/main/src/main/scala/sbt/InteractionService.scala b/main/src/main/scala/sbt/InteractionService.scala index 021ede221..dd5e76f50 100644 --- a/main/src/main/scala/sbt/InteractionService.scala +++ b/main/src/main/scala/sbt/InteractionService.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt /** diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 66c06b82e..2572e6cce 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 47a67a0fd..0896a7152 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010, 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.{ diff --git a/main/src/main/scala/sbt/MainLoop.scala b/main/src/main/scala/sbt/MainLoop.scala index 36e66a3bd..11f2c0fb3 100644 --- a/main/src/main/scala/sbt/MainLoop.scala +++ b/main/src/main/scala/sbt/MainLoop.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010, 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.annotation.tailrec diff --git a/main/src/main/scala/sbt/OptionSyntax.scala b/main/src/main/scala/sbt/OptionSyntax.scala index d25fc54f1..57d2743a6 100644 --- a/main/src/main/scala/sbt/OptionSyntax.scala +++ b/main/src/main/scala/sbt/OptionSyntax.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.util.Optional diff --git a/main/src/main/scala/sbt/Opts.scala b/main/src/main/scala/sbt/Opts.scala index a3100d883..2d6ac2c6c 100644 --- a/main/src/main/scala/sbt/Opts.scala +++ b/main/src/main/scala/sbt/Opts.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah, Indrajit Raychaudhuri +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.librarymanagement.{ MavenRepository, Resolver } diff --git a/main/src/main/scala/sbt/PluginCross.scala b/main/src/main/scala/sbt/PluginCross.scala index 93b788c3d..0e9e1462d 100644 --- a/main/src/main/scala/sbt/PluginCross.scala +++ b/main/src/main/scala/sbt/PluginCross.scala @@ -1,10 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah - * Copyright 2012 Johannes Rudolph - * - * This was basically copied from the sbt source code and then adapted to use - * `sbtVersion in pluginCrossBuild`. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.complete.{ Parser, DefaultParsers } diff --git a/main/src/main/scala/sbt/Plugins.scala b/main/src/main/scala/sbt/Plugins.scala index 21f219a47..0b65c6aea 100644 --- a/main/src/main/scala/sbt/Plugins.scala +++ b/main/src/main/scala/sbt/Plugins.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt /* TODO: diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 0a92c1eab..0c42d86b3 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/main/src/main/scala/sbt/Resolvers.scala b/main/src/main/scala/sbt/Resolvers.scala index 6f45f935c..c574c55aa 100644 --- a/main/src/main/scala/sbt/Resolvers.scala +++ b/main/src/main/scala/sbt/Resolvers.scala @@ -1,5 +1,8 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Sanjin Sehic +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ package sbt diff --git a/main/src/main/scala/sbt/RichURI.scala b/main/src/main/scala/sbt/RichURI.scala index c7090ac78..78a06372d 100644 --- a/main/src/main/scala/sbt/RichURI.scala +++ b/main/src/main/scala/sbt/RichURI.scala @@ -1,5 +1,8 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Sanjin Sehic +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ package sbt diff --git a/main/src/main/scala/sbt/ScopeFilter.scala b/main/src/main/scala/sbt/ScopeFilter.scala index 8db2bb44c..a303ca09a 100644 --- a/main/src/main/scala/sbt/ScopeFilter.scala +++ b/main/src/main/scala/sbt/ScopeFilter.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.{ Load, LoadedBuildUnit } diff --git a/main/src/main/scala/sbt/ScopedKeyData.scala b/main/src/main/scala/sbt/ScopedKeyData.scala index 2723f3d6c..3574f455d 100644 --- a/main/src/main/scala/sbt/ScopedKeyData.scala +++ b/main/src/main/scala/sbt/ScopedKeyData.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import Def.ScopedKey diff --git a/main/src/main/scala/sbt/SessionVar.scala b/main/src/main/scala/sbt/SessionVar.scala index e7754e12a..adbda41a5 100644 --- a/main/src/main/scala/sbt/SessionVar.scala +++ b/main/src/main/scala/sbt/SessionVar.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import scala.util.control.NonFatal diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main/src/main/scala/sbt/SlashSyntax.scala index bf353f0ae..b614cc3f8 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main/src/main/scala/sbt/SlashSyntax.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.librarymanagement.Configuration diff --git a/main/src/main/scala/sbt/Tags.scala b/main/src/main/scala/sbt/Tags.scala index e1cbafcd1..240e2c580 100644 --- a/main/src/main/scala/sbt/Tags.scala +++ b/main/src/main/scala/sbt/Tags.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import annotation.tailrec diff --git a/main/src/main/scala/sbt/TemplateCommand.scala b/main/src/main/scala/sbt/TemplateCommand.scala index 7d12acd66..2da6dcb33 100644 --- a/main/src/main/scala/sbt/TemplateCommand.scala +++ b/main/src/main/scala/sbt/TemplateCommand.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.lang.reflect.InvocationTargetException diff --git a/main/src/main/scala/sbt/internal/APIMappings.scala b/main/src/main/scala/sbt/internal/APIMappings.scala index 75323c121..defae6041 100644 --- a/main/src/main/scala/sbt/internal/APIMappings.scala +++ b/main/src/main/scala/sbt/internal/APIMappings.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Act.scala b/main/src/main/scala/sbt/internal/Act.scala index c72e89dda..91051f3ec 100644 --- a/main/src/main/scala/sbt/internal/Act.scala +++ b/main/src/main/scala/sbt/internal/Act.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/AddSettings.scala b/main/src/main/scala/sbt/internal/AddSettings.scala index f61720ae9..9019f460d 100644 --- a/main/src/main/scala/sbt/internal/AddSettings.scala +++ b/main/src/main/scala/sbt/internal/AddSettings.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Aggregation.scala b/main/src/main/scala/sbt/internal/Aggregation.scala index 525e73524..0d2da79d8 100644 --- a/main/src/main/scala/sbt/internal/Aggregation.scala +++ b/main/src/main/scala/sbt/internal/Aggregation.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/BuildDef.scala b/main/src/main/scala/sbt/internal/BuildDef.scala index baa1c7fd8..96c4641f6 100644 --- a/main/src/main/scala/sbt/internal/BuildDef.scala +++ b/main/src/main/scala/sbt/internal/BuildDef.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/BuildDependencies.scala b/main/src/main/scala/sbt/internal/BuildDependencies.scala index 4d0dbb083..6b6709610 100644 --- a/main/src/main/scala/sbt/internal/BuildDependencies.scala +++ b/main/src/main/scala/sbt/internal/BuildDependencies.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/BuildLoader.scala b/main/src/main/scala/sbt/internal/BuildLoader.scala index 1d69e1552..11d024337 100644 --- a/main/src/main/scala/sbt/internal/BuildLoader.scala +++ b/main/src/main/scala/sbt/internal/BuildLoader.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/BuildStructure.scala b/main/src/main/scala/sbt/internal/BuildStructure.scala index 3fd86d4cd..9b02e9dfd 100644 --- a/main/src/main/scala/sbt/internal/BuildStructure.scala +++ b/main/src/main/scala/sbt/internal/BuildStructure.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/BuildUtil.scala b/main/src/main/scala/sbt/internal/BuildUtil.scala index 85f6de333..0d1ac38e5 100644 --- a/main/src/main/scala/sbt/internal/BuildUtil.scala +++ b/main/src/main/scala/sbt/internal/BuildUtil.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 6daf56ab0..9605558a4 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/CommandStrings.scala b/main/src/main/scala/sbt/internal/CommandStrings.scala index ef1d5988c..dc070a468 100644 --- a/main/src/main/scala/sbt/internal/CommandStrings.scala +++ b/main/src/main/scala/sbt/internal/CommandStrings.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/ConsoleProject.scala b/main/src/main/scala/sbt/internal/ConsoleProject.scala index 4823c095e..bc3756460 100644 --- a/main/src/main/scala/sbt/internal/ConsoleProject.scala +++ b/main/src/main/scala/sbt/internal/ConsoleProject.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala index 308ce2047..dc73c66fd 100644 --- a/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala +++ b/main/src/main/scala/sbt/internal/DefaultBackgroundJobService.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/DslAst.scala b/main/src/main/scala/sbt/internal/DslAst.scala index abdcf0c5b..88f31c77c 100644 --- a/main/src/main/scala/sbt/internal/DslAst.scala +++ b/main/src/main/scala/sbt/internal/DslAst.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/EvaluateConfigurations.scala b/main/src/main/scala/sbt/internal/EvaluateConfigurations.scala index be9800db2..6b4e77f91 100644 --- a/main/src/main/scala/sbt/internal/EvaluateConfigurations.scala +++ b/main/src/main/scala/sbt/internal/EvaluateConfigurations.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/GCUtil.scala b/main/src/main/scala/sbt/internal/GCUtil.scala index 01f29162f..ba4ba8e1e 100644 --- a/main/src/main/scala/sbt/internal/GCUtil.scala +++ b/main/src/main/scala/sbt/internal/GCUtil.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/GlobalPlugin.scala b/main/src/main/scala/sbt/internal/GlobalPlugin.scala index 3dc96f5bb..e71b8ee24 100644 --- a/main/src/main/scala/sbt/internal/GlobalPlugin.scala +++ b/main/src/main/scala/sbt/internal/GlobalPlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/GroupedAutoPlugins.scala b/main/src/main/scala/sbt/internal/GroupedAutoPlugins.scala index ce6f838a8..c43b5a50b 100644 --- a/main/src/main/scala/sbt/internal/GroupedAutoPlugins.scala +++ b/main/src/main/scala/sbt/internal/GroupedAutoPlugins.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Inspect.scala b/main/src/main/scala/sbt/internal/Inspect.scala index 51867b797..405da6c78 100644 --- a/main/src/main/scala/sbt/internal/Inspect.scala +++ b/main/src/main/scala/sbt/internal/Inspect.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/IvyConsole.scala b/main/src/main/scala/sbt/internal/IvyConsole.scala index e7170776a..79f6344bc 100644 --- a/main/src/main/scala/sbt/internal/IvyConsole.scala +++ b/main/src/main/scala/sbt/internal/IvyConsole.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/KeyIndex.scala b/main/src/main/scala/sbt/internal/KeyIndex.scala index ebbf80ca8..78183984e 100644 --- a/main/src/main/scala/sbt/internal/KeyIndex.scala +++ b/main/src/main/scala/sbt/internal/KeyIndex.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/LibraryManagement.scala b/main/src/main/scala/sbt/internal/LibraryManagement.scala index d0a12767a..a245344dc 100644 --- a/main/src/main/scala/sbt/internal/LibraryManagement.scala +++ b/main/src/main/scala/sbt/internal/LibraryManagement.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal import java.io.File diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 133d7b39f..e0ac0b6f8 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/LoadedSbtFile.scala b/main/src/main/scala/sbt/internal/LoadedSbtFile.scala index aa2247985..dbf961472 100644 --- a/main/src/main/scala/sbt/internal/LoadedSbtFile.scala +++ b/main/src/main/scala/sbt/internal/LoadedSbtFile.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index b29f745c5..7183caefb 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Output.scala b/main/src/main/scala/sbt/internal/Output.scala index 207bc5598..0886280cd 100644 --- a/main/src/main/scala/sbt/internal/Output.scala +++ b/main/src/main/scala/sbt/internal/Output.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/PluginDiscovery.scala b/main/src/main/scala/sbt/internal/PluginDiscovery.scala index 3d21ad6e2..fb82ea5e1 100644 --- a/main/src/main/scala/sbt/internal/PluginDiscovery.scala +++ b/main/src/main/scala/sbt/internal/PluginDiscovery.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/PluginManagement.scala b/main/src/main/scala/sbt/internal/PluginManagement.scala index a701e6c41..e35964040 100644 --- a/main/src/main/scala/sbt/internal/PluginManagement.scala +++ b/main/src/main/scala/sbt/internal/PluginManagement.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/PluginsDebug.scala b/main/src/main/scala/sbt/internal/PluginsDebug.scala index 1a9409680..676a4caff 100644 --- a/main/src/main/scala/sbt/internal/PluginsDebug.scala +++ b/main/src/main/scala/sbt/internal/PluginsDebug.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/ProjectNavigation.scala b/main/src/main/scala/sbt/internal/ProjectNavigation.scala index 326225ebf..305967d06 100644 --- a/main/src/main/scala/sbt/internal/ProjectNavigation.scala +++ b/main/src/main/scala/sbt/internal/ProjectNavigation.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010, 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/RelayAppender.scala b/main/src/main/scala/sbt/internal/RelayAppender.scala index 7509ecbae..3e0daf474 100644 --- a/main/src/main/scala/sbt/internal/RelayAppender.scala +++ b/main/src/main/scala/sbt/internal/RelayAppender.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Resolve.scala b/main/src/main/scala/sbt/internal/Resolve.scala index a421775ff..9797bbab8 100644 --- a/main/src/main/scala/sbt/internal/Resolve.scala +++ b/main/src/main/scala/sbt/internal/Resolve.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/RetrieveUnit.scala b/main/src/main/scala/sbt/internal/RetrieveUnit.scala index bb3c0433a..655f4de72 100644 --- a/main/src/main/scala/sbt/internal/RetrieveUnit.scala +++ b/main/src/main/scala/sbt/internal/RetrieveUnit.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/Script.scala b/main/src/main/scala/sbt/internal/Script.scala index ac11105b6..addf7d4ed 100644 --- a/main/src/main/scala/sbt/internal/Script.scala +++ b/main/src/main/scala/sbt/internal/Script.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/SessionSettings.scala b/main/src/main/scala/sbt/internal/SessionSettings.scala index 368975c9a..30911a384 100755 --- a/main/src/main/scala/sbt/internal/SessionSettings.scala +++ b/main/src/main/scala/sbt/internal/SessionSettings.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/SettingCompletions.scala b/main/src/main/scala/sbt/internal/SettingCompletions.scala index bb499037b..d9bbafbff 100644 --- a/main/src/main/scala/sbt/internal/SettingCompletions.scala +++ b/main/src/main/scala/sbt/internal/SettingCompletions.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/SettingGraph.scala b/main/src/main/scala/sbt/internal/SettingGraph.scala index 59add7340..33f1b9a5c 100644 --- a/main/src/main/scala/sbt/internal/SettingGraph.scala +++ b/main/src/main/scala/sbt/internal/SettingGraph.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah, Eugene Yokota +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/TaskName.scala b/main/src/main/scala/sbt/internal/TaskName.scala index 524a88c8c..e5710281b 100644 --- a/main/src/main/scala/sbt/internal/TaskName.scala +++ b/main/src/main/scala/sbt/internal/TaskName.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/TaskSequential.scala b/main/src/main/scala/sbt/internal/TaskSequential.scala index dbdb6959a..8fbab839e 100644 --- a/main/src/main/scala/sbt/internal/TaskSequential.scala +++ b/main/src/main/scala/sbt/internal/TaskSequential.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/TaskTimings.scala b/main/src/main/scala/sbt/internal/TaskTimings.scala index f99d45bd6..2c39ffc43 100644 --- a/main/src/main/scala/sbt/internal/TaskTimings.scala +++ b/main/src/main/scala/sbt/internal/TaskTimings.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/main/scala/sbt/internal/librarymanagement/FakeRawRepository.scala b/main/src/main/scala/sbt/internal/librarymanagement/FakeRawRepository.scala index f1859d11c..7cc8d98a4 100644 --- a/main/src/main/scala/sbt/internal/librarymanagement/FakeRawRepository.scala +++ b/main/src/main/scala/sbt/internal/librarymanagement/FakeRawRepository.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package librarymanagement diff --git a/main/src/main/scala/sbt/internal/parser/SbtParser.scala b/main/src/main/scala/sbt/internal/parser/SbtParser.scala index 0e87b2a87..a3b9b321b 100644 --- a/main/src/main/scala/sbt/internal/parser/SbtParser.scala +++ b/main/src/main/scala/sbt/internal/parser/SbtParser.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/main/scala/sbt/internal/parser/SbtRefactorings.scala b/main/src/main/scala/sbt/internal/parser/SbtRefactorings.scala index c4e94ca21..14e09e2bd 100644 --- a/main/src/main/scala/sbt/internal/parser/SbtRefactorings.scala +++ b/main/src/main/scala/sbt/internal/parser/SbtRefactorings.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala index ad585d6f4..4fb90f3a9 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerProtocol.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package server diff --git a/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala b/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala index 5d550c41f..b4b3da950 100644 --- a/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala +++ b/main/src/main/scala/sbt/internal/server/LanguageServerReporter.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package server diff --git a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala index 7044cd9a2..cee95034f 100644 --- a/main/src/main/scala/sbt/internal/server/NetworkChannel.scala +++ b/main/src/main/scala/sbt/internal/server/NetworkChannel.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal package server diff --git a/main/src/main/scala/sbt/internal/server/SettingQuery.scala b/main/src/main/scala/sbt/internal/server/SettingQuery.scala index 9b3cd3859..25dd1b66a 100644 --- a/main/src/main/scala/sbt/internal/server/SettingQuery.scala +++ b/main/src/main/scala/sbt/internal/server/SettingQuery.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016-2017 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package internal package server diff --git a/main/src/main/scala/sbt/plugins/CorePlugin.scala b/main/src/main/scala/sbt/plugins/CorePlugin.scala index f543653ac..df66eb438 100644 --- a/main/src/main/scala/sbt/plugins/CorePlugin.scala +++ b/main/src/main/scala/sbt/plugins/CorePlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package plugins diff --git a/main/src/main/scala/sbt/plugins/Giter8ResolverPlugin.scala b/main/src/main/scala/sbt/plugins/Giter8ResolverPlugin.scala index 88bd32e38..a36652079 100644 --- a/main/src/main/scala/sbt/plugins/Giter8ResolverPlugin.scala +++ b/main/src/main/scala/sbt/plugins/Giter8ResolverPlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package plugins diff --git a/main/src/main/scala/sbt/plugins/IvyPlugin.scala b/main/src/main/scala/sbt/plugins/IvyPlugin.scala index 21158865d..9c9257b2a 100644 --- a/main/src/main/scala/sbt/plugins/IvyPlugin.scala +++ b/main/src/main/scala/sbt/plugins/IvyPlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package plugins diff --git a/main/src/main/scala/sbt/plugins/JUnitXmlReportPlugin.scala b/main/src/main/scala/sbt/plugins/JUnitXmlReportPlugin.scala index 1205a3a28..b65324be7 100644 --- a/main/src/main/scala/sbt/plugins/JUnitXmlReportPlugin.scala +++ b/main/src/main/scala/sbt/plugins/JUnitXmlReportPlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package plugins diff --git a/main/src/main/scala/sbt/plugins/JvmPlugin.scala b/main/src/main/scala/sbt/plugins/JvmPlugin.scala index bac761f11..b8cc3493a 100644 --- a/main/src/main/scala/sbt/plugins/JvmPlugin.scala +++ b/main/src/main/scala/sbt/plugins/JvmPlugin.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package plugins diff --git a/main/src/test/scala/DefaultsTest.scala b/main/src/test/scala/DefaultsTest.scala index b03222b46..b029123fc 100644 --- a/main/src/test/scala/DefaultsTest.scala +++ b/main/src/test/scala/DefaultsTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.specs2.mutable.Specification diff --git a/main/src/test/scala/Delegates.scala b/main/src/test/scala/Delegates.scala index df2dec96b..492cdcdd9 100644 --- a/main/src/test/scala/Delegates.scala +++ b/main/src/test/scala/Delegates.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import Project._ diff --git a/main/src/test/scala/ParseKey.scala b/main/src/test/scala/ParseKey.scala index a0b62d8c3..2d6991af7 100644 --- a/main/src/test/scala/ParseKey.scala +++ b/main/src/test/scala/ParseKey.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import Def.{ displayFull, displayMasked, ScopedKey } diff --git a/main/src/test/scala/PluginCommandTest.scala b/main/src/test/scala/PluginCommandTest.scala index 2ab7be056..8262326ae 100644 --- a/main/src/test/scala/PluginCommandTest.scala +++ b/main/src/test/scala/PluginCommandTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io._ diff --git a/main/src/test/scala/PluginsTest.scala b/main/src/test/scala/PluginsTest.scala index 632f60fd3..0062a7782 100644 --- a/main/src/test/scala/PluginsTest.scala +++ b/main/src/test/scala/PluginsTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.specs2._ diff --git a/main/src/test/scala/ProjectMacro.scala b/main/src/test/scala/ProjectMacro.scala index e586514e4..4c8936a71 100644 --- a/main/src/test/scala/ProjectMacro.scala +++ b/main/src/test/scala/ProjectMacro.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import scala.util.control.NonFatal diff --git a/main/src/test/scala/ProjectSpec.scala b/main/src/test/scala/ProjectSpec.scala index f3c381385..5b5a3e114 100644 --- a/main/src/test/scala/ProjectSpec.scala +++ b/main/src/test/scala/ProjectSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.specs2.Specification diff --git a/main/src/test/scala/TagsTest.scala b/main/src/test/scala/TagsTest.scala index 9154a197b..ed6282078 100644 --- a/main/src/test/scala/TagsTest.scala +++ b/main/src/test/scala/TagsTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.scalacheck._ diff --git a/main/src/test/scala/sbt/internal/TestBuild.scala b/main/src/test/scala/sbt/internal/TestBuild.scala index 47874cb7e..7b8a70db5 100644 --- a/main/src/test/scala/sbt/internal/TestBuild.scala +++ b/main/src/test/scala/sbt/internal/TestBuild.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/main/src/test/scala/sbt/internal/parser/AbstractSpec.scala b/main/src/test/scala/sbt/internal/parser/AbstractSpec.scala index f169829ee..708f36290 100644 --- a/main/src/test/scala/sbt/internal/parser/AbstractSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/AbstractSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.parser import org.specs2.mutable._ diff --git a/main/src/test/scala/sbt/internal/parser/CheckIfParsedSpec.scala b/main/src/test/scala/sbt/internal/parser/CheckIfParsedSpec.scala index df1ddec74..c230f8a68 100644 --- a/main/src/test/scala/sbt/internal/parser/CheckIfParsedSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/CheckIfParsedSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/CommentedXmlSpec.scala b/main/src/test/scala/sbt/internal/parser/CommentedXmlSpec.scala index 116fb0d5a..a3cb444a7 100644 --- a/main/src/test/scala/sbt/internal/parser/CommentedXmlSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/CommentedXmlSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.parser class CommentedXmlSpec extends CheckIfParsedSpec { diff --git a/main/src/test/scala/sbt/internal/parser/EmbeddedXmlSpec.scala b/main/src/test/scala/sbt/internal/parser/EmbeddedXmlSpec.scala index 542e2c05d..d939d5e8c 100644 --- a/main/src/test/scala/sbt/internal/parser/EmbeddedXmlSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/EmbeddedXmlSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.parser import sbt.internal.util.MessageOnlyException diff --git a/main/src/test/scala/sbt/internal/parser/ErrorSpec.scala b/main/src/test/scala/sbt/internal/parser/ErrorSpec.scala index 03ac2d657..6d7cc7b42 100644 --- a/main/src/test/scala/sbt/internal/parser/ErrorSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/ErrorSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/NewFormatSpec.scala b/main/src/test/scala/sbt/internal/parser/NewFormatSpec.scala index d8927b7f3..797f05356 100644 --- a/main/src/test/scala/sbt/internal/parser/NewFormatSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/NewFormatSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/SessionSettingsSpec.scala b/main/src/test/scala/sbt/internal/parser/SessionSettingsSpec.scala index 5d212e79b..3eb364ed9 100644 --- a/main/src/test/scala/sbt/internal/parser/SessionSettingsSpec.scala +++ b/main/src/test/scala/sbt/internal/parser/SessionSettingsSpec.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/SplitExpressions.scala b/main/src/test/scala/sbt/internal/parser/SplitExpressions.scala index 75b31f312..a03207ff4 100644 --- a/main/src/test/scala/sbt/internal/parser/SplitExpressions.scala +++ b/main/src/test/scala/sbt/internal/parser/SplitExpressions.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/SplitExpressionsBehavior.scala b/main/src/test/scala/sbt/internal/parser/SplitExpressionsBehavior.scala index 56e31425e..17167e024 100644 --- a/main/src/test/scala/sbt/internal/parser/SplitExpressionsBehavior.scala +++ b/main/src/test/scala/sbt/internal/parser/SplitExpressionsBehavior.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/parser/SplitExpressionsTest.scala b/main/src/test/scala/sbt/internal/parser/SplitExpressionsTest.scala index b3667c685..5e6c78038 100644 --- a/main/src/test/scala/sbt/internal/parser/SplitExpressionsTest.scala +++ b/main/src/test/scala/sbt/internal/parser/SplitExpressionsTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package parser diff --git a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala index c77d38ed7..27c7e7238 100644 --- a/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala +++ b/main/src/test/scala/sbt/internal/server/SettingQueryTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package server diff --git a/project/plugins.sbt b/project/plugins.sbt index f9064f32f..2ebca3cac 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -11,3 +11,4 @@ addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.1") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.1") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0-M1") addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.10") +addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2") diff --git a/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala b/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala index 7f208114e..6594d9050 100644 --- a/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala +++ b/protocol/src/main/scala/sbt/internal/langserver/DiagnosticSeverity.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package langserver diff --git a/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala b/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala index b6483d032..952cf7896 100644 --- a/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala +++ b/protocol/src/main/scala/sbt/internal/langserver/ErrorCodes.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal package langserver diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala index 5a8a96aaa..95374a2ba 100644 --- a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRPCProtocol.scala @@ -1,6 +1,10 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.protocol.codec trait JsonRPCProtocol extends sbt.internal.util.codec.JValueFormats diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala index 387a45e03..b00ae5d07 100644 --- a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcNotificationMessageFormats.scala @@ -1,6 +1,10 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.protocol.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala index 5ef60b221..8dcac3fa3 100644 --- a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcRequestMessageFormats.scala @@ -1,6 +1,10 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.protocol.codec import sjsonnew.shaded.scalajson.ast.unsafe.JValue diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala index 6db41174f..110a6cae2 100644 --- a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseErrorFormats.scala @@ -1,6 +1,10 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.protocol.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } diff --git a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala index b786d7f2a..56e773bd3 100644 --- a/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala +++ b/protocol/src/main/scala/sbt/internal/protocol/codec/JsonRpcResponseMessageFormats.scala @@ -1,6 +1,10 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt.internal.protocol.codec import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } diff --git a/protocol/src/main/scala/sbt/protocol/Serialization.scala b/protocol/src/main/scala/sbt/protocol/Serialization.scala index d363b31ec..2a6e174b4 100644 --- a/protocol/src/main/scala/sbt/protocol/Serialization.scala +++ b/protocol/src/main/scala/sbt/protocol/Serialization.scala @@ -1,6 +1,10 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package protocol diff --git a/run/NOTICE b/run/NOTICE index 27f7f6161..40d55bd9b 100644 --- a/run/NOTICE +++ b/run/NOTICE @@ -1,11 +1,12 @@ -/* sbt -- Simple Build Tool - * Copyright 2008 Mark Harrah - * - * Partially based on exit trapping in Nailgun by Pete Kirkham, - * copyright 2004, Martian Software, Inc - * licensed under Apache 2.0 License. - */ +sbt: Run Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) + +Partially based on exit trapping in Nailgun by Pete Kirkham, +copyright 2004, Martian Software, Inc +licensed under Apache 2.0 License. Portions based on code by Pete Kirkham in Nailgun Copyright 2004, Martian Software, Inc -Licensed under the Apache License, Version 2.0 (see licenses/LICENSE_Apache) \ No newline at end of file +Licensed under the Apache License, Version 2.0 (see licenses/LICENSE_Apache) diff --git a/run/src/main/scala/sbt/Fork.scala b/run/src/main/scala/sbt/Fork.scala index 80839181e..7058e3a31 100644 --- a/run/src/main/scala/sbt/Fork.scala +++ b/run/src/main/scala/sbt/Fork.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah, Vesa Vilhonen +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/run/src/main/scala/sbt/OutputStrategy.scala b/run/src/main/scala/sbt/OutputStrategy.scala index 1afbc4f0b..be1031e30 100644 --- a/run/src/main/scala/sbt/OutputStrategy.scala +++ b/run/src/main/scala/sbt/OutputStrategy.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.util.Logger diff --git a/run/src/main/scala/sbt/Run.scala b/run/src/main/scala/sbt/Run.scala index 121448a31..a0a64346d 100644 --- a/run/src/main/scala/sbt/Run.scala +++ b/run/src/main/scala/sbt/Run.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah, Vesa Vilhonen +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/run/src/main/scala/sbt/SelectMainClass.scala b/run/src/main/scala/sbt/SelectMainClass.scala index 9499dfc73..b840bf839 100644 --- a/run/src/main/scala/sbt/SelectMainClass.scala +++ b/run/src/main/scala/sbt/SelectMainClass.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt object SelectMainClass { diff --git a/run/src/main/scala/sbt/TrapExit.scala b/run/src/main/scala/sbt/TrapExit.scala index 8cc944351..94a3f60f5 100644 --- a/run/src/main/scala/sbt/TrapExit.scala +++ b/run/src/main/scala/sbt/TrapExit.scala @@ -1,10 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008 Mark Harrah - * - * Partially based on exit trapping in Nailgun by Pete Kirkham, - * copyright 2004, Martian Software, Inc - * licensed under Apache 2.0 License. +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.reflect.Manifest diff --git a/run/src/main/scala/sbt/TrapExitSecurityException.scala b/run/src/main/scala/sbt/TrapExitSecurityException.scala index dc5792e66..bad5cf67f 100644 --- a/run/src/main/scala/sbt/TrapExitSecurityException.scala +++ b/run/src/main/scala/sbt/TrapExitSecurityException.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt /** diff --git a/run/src/test/scala/sbt/ForkTest.scala b/run/src/test/scala/sbt/ForkTest.scala index 6b715a7b1..645e54598 100644 --- a/run/src/test/scala/sbt/ForkTest.scala +++ b/run/src/test/scala/sbt/ForkTest.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.scalacheck._ diff --git a/run/src/test/scala/sbt/TestLogger.scala b/run/src/test/scala/sbt/TestLogger.scala index e526792a2..fabd9df87 100644 --- a/run/src/test/scala/sbt/TestLogger.scala +++ b/run/src/test/scala/sbt/TestLogger.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal diff --git a/sbt/src/main/scala/AllSyntax.scala b/sbt/src/main/scala/AllSyntax.scala index 2eac995c2..ccd5bff85 100644 --- a/sbt/src/main/scala/AllSyntax.scala +++ b/sbt/src/main/scala/AllSyntax.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt // Todo share this this io.syntax diff --git a/sbt/src/main/scala/Import.scala b/sbt/src/main/scala/Import.scala index b3ab3b9e1..2e318663d 100644 --- a/sbt/src/main/scala/Import.scala +++ b/sbt/src/main/scala/Import.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt trait Import { diff --git a/sbt/src/main/scala/package.scala b/sbt/src/main/scala/package.scala index 0954f8306..671f23892 100644 --- a/sbt/src/main/scala/package.scala +++ b/sbt/src/main/scala/package.scala @@ -1,8 +1,12 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + import scala.language.experimental.macros -/* sbt -- Simple Build Tool - * Copyright 2010, 2011 Mark Harrah - */ package object sbt extends sbt.IOSyntax0 with sbt.std.TaskExtra diff --git a/scripted/plugin/src/main/scala/sbt/ScriptedPlugin.scala b/scripted/plugin/src/main/scala/sbt/ScriptedPlugin.scala index f3df071ae..3e38a26ac 100644 --- a/scripted/plugin/src/main/scala/sbt/ScriptedPlugin.scala +++ b/scripted/plugin/src/main/scala/sbt/ScriptedPlugin.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Artyom Olshevskiy +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import Def.Initialize diff --git a/scripted/sbt/NOTICE b/scripted/sbt/NOTICE index 05434b284..89cb6a81c 100644 --- a/scripted/sbt/NOTICE +++ b/scripted/sbt/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Scripted Testing -Copyright 2008, 2009, 2010 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Scripted Testing +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/scripted/sbt/src/main/scala/sbt/test/BatchScriptRunner.scala b/scripted/sbt/src/main/scala/sbt/test/BatchScriptRunner.scala index d181a2ac1..ccf9d5148 100644 --- a/scripted/sbt/src/main/scala/sbt/test/BatchScriptRunner.scala +++ b/scripted/sbt/src/main/scala/sbt/test/BatchScriptRunner.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package test diff --git a/scripted/sbt/src/main/scala/sbt/test/SbtHandler.scala b/scripted/sbt/src/main/scala/sbt/test/SbtHandler.scala index 353cfb1d0..ed1c2ac5b 100644 --- a/scripted/sbt/src/main/scala/sbt/test/SbtHandler.scala +++ b/scripted/sbt/src/main/scala/sbt/test/SbtHandler.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package test diff --git a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala index 00781be92..29b4f2258 100644 --- a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala +++ b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala @@ -1,5 +1,8 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ package sbt diff --git a/tasks-standard/NOTICE b/tasks-standard/NOTICE index 5761647e7..3f12e2eda 100644 --- a/tasks-standard/NOTICE +++ b/tasks-standard/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Standard Tasks Component -Copyright 2009 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Standard Tasks Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/tasks-standard/src/main/scala/sbt/Action.scala b/tasks-standard/src/main/scala/sbt/Action.scala index 003d74c8c..0be3a8ae5 100644 --- a/tasks-standard/src/main/scala/sbt/Action.scala +++ b/tasks-standard/src/main/scala/sbt/Action.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.Types._ diff --git a/tasks-standard/src/main/scala/sbt/std/Streams.scala b/tasks-standard/src/main/scala/sbt/std/Streams.scala index 574c071fb..6206b9271 100644 --- a/tasks-standard/src/main/scala/sbt/std/Streams.scala +++ b/tasks-standard/src/main/scala/sbt/std/Streams.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package std diff --git a/tasks-standard/src/main/scala/sbt/std/System.scala b/tasks-standard/src/main/scala/sbt/std/System.scala index f34ce0b17..7e7673a33 100644 --- a/tasks-standard/src/main/scala/sbt/std/System.scala +++ b/tasks-standard/src/main/scala/sbt/std/System.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package std diff --git a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala index e60c4b94f..2872d3ced 100644 --- a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala +++ b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt package std diff --git a/tasks-standard/src/test/scala/Execute.scala b/tasks-standard/src/test/scala/Execute.scala index afd1a4368..a4852567d 100644 --- a/tasks-standard/src/test/scala/Execute.scala +++ b/tasks-standard/src/test/scala/Execute.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/TaskGen.scala b/tasks-standard/src/test/scala/TaskGen.scala index 26b1509f8..8fdace35d 100644 --- a/tasks-standard/src/test/scala/TaskGen.scala +++ b/tasks-standard/src/test/scala/TaskGen.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/TaskRunnerCircular.scala b/tasks-standard/src/test/scala/TaskRunnerCircular.scala index c5c5255f8..1350a22b0 100644 --- a/tasks-standard/src/test/scala/TaskRunnerCircular.scala +++ b/tasks-standard/src/test/scala/TaskRunnerCircular.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/TaskRunnerFork.scala b/tasks-standard/src/test/scala/TaskRunnerFork.scala index e897fff66..b469dc38e 100644 --- a/tasks-standard/src/test/scala/TaskRunnerFork.scala +++ b/tasks-standard/src/test/scala/TaskRunnerFork.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + import sbt._ import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/TaskSerial.scala b/tasks-standard/src/test/scala/TaskSerial.scala index ace3ba7fc..43aeea41f 100644 --- a/tasks-standard/src/test/scala/TaskSerial.scala +++ b/tasks-standard/src/test/scala/TaskSerial.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package std diff --git a/tasks-standard/src/test/scala/Test.scala b/tasks-standard/src/test/scala/Test.scala index 6722bf1f2..07a6c11b6 100644 --- a/tasks-standard/src/test/scala/Test.scala +++ b/tasks-standard/src/test/scala/Test.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.AList diff --git a/tasks-standard/src/test/scala/TestRunnerCall.scala b/tasks-standard/src/test/scala/TestRunnerCall.scala index 219908036..9f03e4e4f 100644 --- a/tasks-standard/src/test/scala/TestRunnerCall.scala +++ b/tasks-standard/src/test/scala/TestRunnerCall.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + import sbt._ import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/TestRunnerSort.scala b/tasks-standard/src/test/scala/TestRunnerSort.scala index dadb852b9..e0f5792d8 100644 --- a/tasks-standard/src/test/scala/TestRunnerSort.scala +++ b/tasks-standard/src/test/scala/TestRunnerSort.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import org.scalacheck._ diff --git a/tasks-standard/src/test/scala/checkResult.scala b/tasks-standard/src/test/scala/checkResult.scala index be4e956ad..276367064 100644 --- a/tasks-standard/src/test/scala/checkResult.scala +++ b/tasks-standard/src/test/scala/checkResult.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.util.control.NonFatal diff --git a/tasks/NOTICE b/tasks/NOTICE index 640aae060..e3f56a307 100644 --- a/tasks/NOTICE +++ b/tasks/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Task Engine Component -Copyright 2009, 2010 Mark Harrah -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Task Engine Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/tasks/src/main/scala/sbt/CompletionService.scala b/tasks/src/main/scala/sbt/CompletionService.scala index 0113558f4..f6fc3a957 100644 --- a/tasks/src/main/scala/sbt/CompletionService.scala +++ b/tasks/src/main/scala/sbt/CompletionService.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt trait CompletionService[A, R] { diff --git a/tasks/src/main/scala/sbt/ConcurrentRestrictions.scala b/tasks/src/main/scala/sbt/ConcurrentRestrictions.scala index 60e415904..40a15d4fd 100644 --- a/tasks/src/main/scala/sbt/ConcurrentRestrictions.scala +++ b/tasks/src/main/scala/sbt/ConcurrentRestrictions.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.AttributeKey diff --git a/tasks/src/main/scala/sbt/Execute.scala b/tasks/src/main/scala/sbt/Execute.scala index 2fe6d7b4e..5a60ce706 100644 --- a/tasks/src/main/scala/sbt/Execute.scala +++ b/tasks/src/main/scala/sbt/Execute.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.ErrorHandling.wideConvert diff --git a/tasks/src/main/scala/sbt/ExecuteProgress.scala b/tasks/src/main/scala/sbt/ExecuteProgress.scala index 51a7f9bea..34a19d206 100644 --- a/tasks/src/main/scala/sbt/ExecuteProgress.scala +++ b/tasks/src/main/scala/sbt/ExecuteProgress.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import sbt.internal.util.RMap diff --git a/tasks/src/main/scala/sbt/Incomplete.scala b/tasks/src/main/scala/sbt/Incomplete.scala index 09dc78b5c..ad8296196 100644 --- a/tasks/src/main/scala/sbt/Incomplete.scala +++ b/tasks/src/main/scala/sbt/Incomplete.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import scala.collection.mutable.ListBuffer diff --git a/tasks/src/main/scala/sbt/Node.scala b/tasks/src/main/scala/sbt/Node.scala index e3892bb07..b579f3f28 100644 --- a/tasks/src/main/scala/sbt/Node.scala +++ b/tasks/src/main/scala/sbt/Node.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.AList diff --git a/tasks/src/main/scala/sbt/Result.scala b/tasks/src/main/scala/sbt/Result.scala index 9fd7283cf..691a54f00 100644 --- a/tasks/src/main/scala/sbt/Result.scala +++ b/tasks/src/main/scala/sbt/Result.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2010 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import sbt.internal.util.~> diff --git a/testing/NOTICE b/testing/NOTICE index 2853703b9..36daa88f1 100644 --- a/testing/NOTICE +++ b/testing/NOTICE @@ -1,3 +1,4 @@ -Simple Build Tool: Testing Component -Copyright 2008, 2009, 2010 Steven Blundy, Mark Harrah, Josh Cough -Licensed under BSD-style license (see LICENSE) \ No newline at end of file +sbt: Testing Component +Copyright 2011 - 2017, Lightbend, Inc. +Copyright 2008 - 2010, Mark Harrah, Steven Blundy, Josh Cough +Licensed under BSD-3-Clause license (see LICENSE) diff --git a/testing/agent/src/main/java/sbt/ForkConfiguration.java b/testing/agent/src/main/java/sbt/ForkConfiguration.java index 9f51e9c69..22f82b8c5 100644 --- a/testing/agent/src/main/java/sbt/ForkConfiguration.java +++ b/testing/agent/src/main/java/sbt/ForkConfiguration.java @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt; import java.io.Serializable; diff --git a/testing/agent/src/main/java/sbt/ForkMain.java b/testing/agent/src/main/java/sbt/ForkMain.java index 7ce45cf45..24acaf52b 100644 --- a/testing/agent/src/main/java/sbt/ForkMain.java +++ b/testing/agent/src/main/java/sbt/ForkMain.java @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2012 Eugene Vigdorchik +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt; import sbt.testing.*; diff --git a/testing/agent/src/main/java/sbt/ForkTags.java b/testing/agent/src/main/java/sbt/ForkTags.java index 4318555ee..e18074cbf 100644 --- a/testing/agent/src/main/java/sbt/ForkTags.java +++ b/testing/agent/src/main/java/sbt/ForkTags.java @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2012 Eugene Vigdorchik +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt; public enum ForkTags { diff --git a/testing/agent/src/main/java/sbt/FrameworkWrapper.java b/testing/agent/src/main/java/sbt/FrameworkWrapper.java index dd606ab54..23eea7b95 100644 --- a/testing/agent/src/main/java/sbt/FrameworkWrapper.java +++ b/testing/agent/src/main/java/sbt/FrameworkWrapper.java @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt; import sbt.testing.*; diff --git a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala index 0d83f3ce0..05fd86832 100644 --- a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala +++ b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt import java.io.{ File, IOException, PrintWriter, StringWriter } diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index 3dca237e2..ffd7ef36d 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009 Steven Blundy, Mark Harrah, Josh Cough +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/testing/src/main/scala/sbt/TestReportListener.scala b/testing/src/main/scala/sbt/TestReportListener.scala index 336b3fd2c..090ddc7ef 100644 --- a/testing/src/main/scala/sbt/TestReportListener.scala +++ b/testing/src/main/scala/sbt/TestReportListener.scala @@ -1,5 +1,8 @@ -/* sbt -- Simple Build Tool - * Copyright 2008, 2009 Steven Blundy, Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ package sbt diff --git a/testing/src/main/scala/sbt/TestStatusReporter.scala b/testing/src/main/scala/sbt/TestStatusReporter.scala index 4f62aa169..732e3257c 100644 --- a/testing/src/main/scala/sbt/TestStatusReporter.scala +++ b/testing/src/main/scala/sbt/TestStatusReporter.scala @@ -1,6 +1,10 @@ -/* sbt -- Simple Build Tool - * Copyright 2009, 2010, 2011, 2012 Mark Harrah +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) */ + package sbt import java.io.File diff --git a/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala b/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala index d5ecfdaff..e655b0021 100644 --- a/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala +++ b/testing/src/main/scala/sbt/internal/testing/StatusFormats.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt.internal.testing import sbt.testing.Status diff --git a/testing/src/main/scala/sbt/internal/testing/TestLogger.scala b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala index dfa526c0c..1cd5ff4b4 100644 --- a/testing/src/main/scala/sbt/internal/testing/TestLogger.scala +++ b/testing/src/main/scala/sbt/internal/testing/TestLogger.scala @@ -1,3 +1,10 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + package sbt package internal.testing From 68129e67821fa892d2344c4708292519056e00eb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Oct 2017 09:14:01 +0100 Subject: [PATCH 35/57] Dedup DefaultCommands and allBasicCommands The command component's BasicCommands.allBasicCommands is a subset of main component's BuiltinCommands.DefaultCommands, so I deduplicated. --- main/src/main/scala/sbt/Main.scala | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 47a67a0fd..248d0fc6f 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -161,9 +161,6 @@ object BuiltinCommands { def DefaultCommands: Seq[Command] = Seq( - ignore, - help, - completionsCommand, about, tasks, settingsCommand, @@ -171,9 +168,6 @@ object BuiltinCommands { templateCommand, projects, project, - reboot, - read, - history, set, sessionCommand, inspect, @@ -184,36 +178,21 @@ object BuiltinCommands { PluginCross.pluginCross, PluginCross.pluginSwitch, Cross.crossRestoreSession, - setOnFailure, - clearOnFailure, - stashOnFailure, - popOnFailure, setLogLevel, plugin, plugins, writeSbtVersion, notifyUsersAboutShell, - ifLast, - multi, shell, - oldshell, startServer, - BasicCommands.client, - continuous, eval, - alias, - append, last, lastGrep, export, boot, - nop, - call, - exit, - early, initialize, act - ) ++ compatCommands + ) ++ allBasicCommands def DefaultBootCommands: Seq[String] = WriteSbtVersion :: LoadProject :: NotifyUsersAboutShell :: s"$IfLast $Shell" :: Nil From f4b2fc422868ccb170dbcc19e3832b81d69a8f9f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Oct 2017 17:53:31 +0100 Subject: [PATCH 36/57] Correct handling of resolving ThisProject In ca71b4b9026d973b9fd2b55032144e6c7d5cd57a I went about fixing the inexhaustive matching in Scope's resolveProjectBuild and resolveProjectRef. Looking back the change was wrong. For resolveProjectBuild the new implementation is less wrong, but still not great, seeing as it doesn't actually do any build resolving. For resolveProjectRef the new implementation now blows up instead of lies. Which means it's less leneant, more "fail-fast". isProjectThis is unused; remnant of the pre-AutoPlugin days when build settings where defined in Plugin.settings. --- build.sbt | 2 ++ main-settings/src/main/scala/sbt/Scope.scala | 13 +++++-------- main/src/main/scala/sbt/internal/Load.scala | 6 ------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/build.sbt b/build.sbt index 2f2cb6553..2a16a7065 100644 --- a/build.sbt +++ b/build.sbt @@ -391,6 +391,8 @@ lazy val mainProj = (project in file("main")) exclude[DirectMissingMethodProblem]("sbt.internal.KeyIndex.*"), // Removed unused val. internal. exclude[DirectMissingMethodProblem]("sbt.internal.RelayAppender.jsonFormat"), + // Removed unused def. internal. + exclude[DirectMissingMethodProblem]("sbt.internal.Load.isProjectThis"), ) ) .configure( diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index edfeb4826..34815405a 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -97,8 +97,7 @@ object Scope { case LocalProject(id) => ProjectRef(current, id) case RootProject(uri) => RootProject(resolveBuild(current, uri)) case ProjectRef(uri, id) => ProjectRef(resolveBuild(current, uri), id) - case ThisProject => - RootProject(current) // Is this right? It was an inexhaustive match before.. + case ThisProject => ThisProject // haven't exactly "resolved" anything.. } def resolveBuild(current: URI, uri: URI): URI = if (!uri.isAbsolute && current.isOpaque && uri.getSchemeSpecificPart == ".") @@ -118,13 +117,11 @@ object Scope { rootProject: URI => String, ref: ProjectReference): ProjectRef = ref match { - case LocalRootProject => ProjectRef(current, rootProject(current)) - case LocalProject(id) => ProjectRef(current, id) - case RootProject(uri) => - val res = resolveBuild(current, uri); ProjectRef(res, rootProject(res)) + case LocalRootProject => ProjectRef(current, rootProject(current)) + case LocalProject(id) => ProjectRef(current, id) + case RootProject(uri) => val u = resolveBuild(current, uri); ProjectRef(u, rootProject(u)) case ProjectRef(uri, id) => ProjectRef(resolveBuild(current, uri), id) - case ThisProject => - ProjectRef(current, rootProject(current)) // Is this right? It was an inexhaustive match before.. + case ThisProject => sys.error("Cannot resolve ThisProject w/o the current project") } def resolveBuildRef(current: URI, ref: BuildReference): BuildRef = ref match { diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index e0ac0b6f8..b10235eac 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -363,12 +363,6 @@ private[sbt] object Load { ) } - def isProjectThis(s: Setting[_]): Boolean = - s.key.scope.project match { - case This | Select(ThisProject) => true - case _ => false - } - def buildConfigurations( loaded: LoadedBuild, rootProject: URI => String, From 2a5ba9475da587a10c3d19b7883806a4803b4744 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Oct 2017 20:21:38 +0100 Subject: [PATCH 37/57] Handle Global in Scope#toString Print "Global" instead of "Zero / Zero / Zero". --- main-settings/src/main/scala/sbt/Scope.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index edfeb4826..020d86a31 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -29,9 +29,10 @@ final case class Scope(project: ScopeAxis[Reference], def in(config: ConfigKey): Scope = copy(config = Select(config)) def in(task: AttributeKey[_]): Scope = copy(task = Select(task)) - override def toString: String = { - if (extra == This) s"$project / $config / $task" - else s"Scope($project, $config, $task, $extra)" + override def toString: String = this match { + case Scope(Zero, Zero, Zero, Zero) => "Global" + case Scope(_, _, _, This) => s"$project / $config / $task" + case _ => s"Scope($project, $config, $task, $extra)" } } object Scope { From 96b476f1364f1a632460ffe756f6ef6e77bc4116 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Fri, 6 Oct 2017 02:26:59 +0200 Subject: [PATCH 38/57] Print npm output, handle exit code in case of errors --- build.sbt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 2a16a7065..93f3e3576 100644 --- a/build.sbt +++ b/build.sbt @@ -427,19 +427,23 @@ lazy val vscodePlugin = (project in file("vscode-sbt-scala")) skip in publish := true, compile in Compile := { val u = update.value + val log = streams.value.log import sbt.internal.inc.Analysis import scala.sys.process._ - Process(s"npm run compile", Option(baseDirectory.value)).! + val exitCode = Process(s"npm run compile", Option(baseDirectory.value)) ! log + if (exitCode != 0) throw new Exception("Process returned exit code: " + exitCode) Analysis.empty }, update := { val old = update.value val t = target.value / "updated" val base = baseDirectory.value + val log = streams.value.log if (t.exists) () else { import scala.sys.process._ - Process("npm install", Option(base)).! + val exitCode = Process("npm install", Option(base)) ! log + if (exitCode != 0) throw new Exception("Process returned exit code: " + exitCode) IO.touch(t) } old From f22843f91c1a5c1860b20c735c373a18be54940a Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Oct 2017 09:44:05 +0100 Subject: [PATCH 39/57] Move SlashSyntax to the settings component --- .../src/main/scala/sbt/SlashSyntax.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename {main => main-settings}/src/main/scala/sbt/SlashSyntax.scala (95%) diff --git a/main/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala similarity index 95% rename from main/src/main/scala/sbt/SlashSyntax.scala rename to main-settings/src/main/scala/sbt/SlashSyntax.scala index b614cc3f8..7678907ba 100644 --- a/main/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -34,7 +34,8 @@ trait SlashSyntax { new RichReference(Scope(a, This, This, This)) implicit def sbtSlashSyntaxRichReference(r: Reference): RichReference = Select(r) - implicit def sbtSlashSyntaxRichProject(p: Project): RichReference = (p: Reference) + implicit def sbtSlashSyntaxRichProject[A](p: A)(implicit x: A => Reference): RichReference = + (p: Reference) implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration = new RichConfiguration(Scope(This, Select(c), This, This)) @@ -105,9 +106,7 @@ object SlashSyntax { private[sbt] def materialize: K = key in scope private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key) - override def toString: String = { - s"$scope / ${key.key}" - } + override def toString: String = s"$scope / ${key.key}" } } From 97ddc1ffb79540de8ecf4b3b761b18c442dd8abd Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Oct 2017 10:08:13 +0100 Subject: [PATCH 40/57] Copy the non-runtime parts of project/unified to SlashSyntaxTest --- .../src/test/scala/sbt/SlashSyntaxTest.scala | 41 +++++++++++++++++++ sbt/src/main/scala/package.scala | 10 ----- sbt/src/sbt-test/project/unified/build.sbt | 3 +- .../unified/project/Dependencies.scala | 5 --- 4 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 main-settings/src/test/scala/sbt/SlashSyntaxTest.scala delete mode 100644 sbt/src/sbt-test/project/unified/project/Dependencies.scala diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala b/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala new file mode 100644 index 000000000..f7a1ae065 --- /dev/null +++ b/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala @@ -0,0 +1,41 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + +package sbt.test + +import sbt.Def.{ Setting, settingKey, taskKey } +import sbt.Scope.Global +import sbt.librarymanagement.ModuleID +import sbt.librarymanagement.syntax._ +import sbt.{ LocalProject, ProjectReference, ThisBuild, Zero } + +object SlashSyntaxTest extends sbt.SlashSyntax { + final case class Proj(id: String) + implicit def projToRef(p: Proj): ProjectReference = LocalProject(p.id) + + val projA = Proj("a") + + val cancelable = settingKey[Boolean]("") + val console = taskKey[Unit]("") + val libraryDependencies = settingKey[Seq[ModuleID]]("") + val name = settingKey[String]("") + val scalaVersion = settingKey[String]("") + val scalacOptions = taskKey[Seq[String]]("") + + val uTest = "com.lihaoyi" %% "utest" % "0.5.3" + + Seq[Setting[_]]( + Global / cancelable := true, + ThisBuild / scalaVersion := "2.12.3", + console / scalacOptions += "-deprecation", + Compile / console / scalacOptions += "-Ywarn-numeric-widen", + projA / Compile / console / scalacOptions += "-feature", + Zero / Zero / name := "foo", + Zero / Zero / Zero / name := "foo", + libraryDependencies += uTest % Test, + ) +} diff --git a/sbt/src/main/scala/package.scala b/sbt/src/main/scala/package.scala index 671f23892..3e067e0de 100644 --- a/sbt/src/main/scala/package.scala +++ b/sbt/src/main/scala/package.scala @@ -43,16 +43,6 @@ package object sbt final val Global = Scope.Global final val GlobalScope = Scope.GlobalScope - // import sbt.{ Configurations => C } - // final val Compile = C.Compile - // final val Test = C.Test - // final val Runtime = C.Runtime - // final val IntegrationTest = C.IntegrationTest - // final val Default = C.Default - // final val Provided = C.Provided - // java.lang.System is more important, so don't alias this one - // final val System = C.System - // final val Optional = C.Optional def config(name: String): Configuration = macro sbt.librarymanagement.ConfigurationMacro.configMacroImpl } diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt index 7f9835fea..91f772197 100644 --- a/sbt/src/sbt-test/project/unified/build.sbt +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -1,7 +1,8 @@ -import Dependencies._ import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } import sbt.internal.Inspect +val uTest = "com.lihaoyi" %% "utest" % "0.5.3" + lazy val root = (project in file(".")) .settings( Global / cancelable := true, diff --git a/sbt/src/sbt-test/project/unified/project/Dependencies.scala b/sbt/src/sbt-test/project/unified/project/Dependencies.scala deleted file mode 100644 index 0d84ec7d4..000000000 --- a/sbt/src/sbt-test/project/unified/project/Dependencies.scala +++ /dev/null @@ -1,5 +0,0 @@ -import sbt._ - -object Dependencies { - val uTest = "com.lihaoyi" %% "utest" % "0.5.3" -} From db87e4c8717cf4aa868d421be1a9b30b59c4dd74 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 6 Oct 2017 15:05:38 +0100 Subject: [PATCH 41/57] Add SlashSyntaxSpec to validate syntax parity --- .../src/main/scala/sbt/SlashSyntax.scala | 1 + .../src/test/scala/sbt/SlashSyntaxSpec.scala | 238 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index 7678907ba..fc98cfc39 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -58,6 +58,7 @@ object SlashSyntax { /** RichReference wraps a reference to provide the `/` operator for scoping. */ final class RichReference(protected val scope: Scope) extends RichScopeLike { + def /(c: ConfigKey): RichConfiguration = new RichConfiguration(scope in c) def /(c: Configuration): RichConfiguration = new RichConfiguration(scope in c) // This is for handling `Zero / Zero / name`. diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala new file mode 100644 index 000000000..936a027db --- /dev/null +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -0,0 +1,238 @@ +/* + * sbt + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under BSD-3-Clause license (see LICENSE) + */ + +package sbt.test + +import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._, Prop._ + +import java.io.File +import sbt.io.IO +import sbt.SlashSyntax, SlashSyntax.Key +import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero }, Scope.{ Global, ThisScope } +import sbt.{ BuildRef, LocalProject, LocalRootProject, ProjectRef, Reference, RootProject, ThisBuild, ThisProject } +import sbt.ConfigKey +import sbt.librarymanagement.syntax._ +import sbt.{ InputKey, SettingKey, TaskKey } +import sbt.internal.util.{ AttributeKey, AttributeMap } + +object BuildDSLInstances { + val genFile: Gen[File] = Gen.oneOf(new File("."), new File("/tmp")) // for now.. + + implicit val arbBuildRef: Arbitrary[BuildRef] = Arbitrary(genFile map (f => BuildRef(IO toURI f))) + + implicit val arbProjectRef: Arbitrary[ProjectRef] = + Arbitrary(for (f <- genFile; id <- Gen.identifier) yield ProjectRef(f, id)) + + implicit val arbLocalProject: Arbitrary[LocalProject] = + Arbitrary(arbitrary[String] map LocalProject) + + implicit val arbRootProject: Arbitrary[RootProject] = Arbitrary(genFile map (RootProject(_))) + + implicit val arbReference: Arbitrary[Reference] = Arbitrary { + Gen.frequency( + 1 -> arbitrary[BuildRef], // 96 + 100 -> ThisBuild, // 10,271 + 3 -> LocalRootProject, // 325 + 23 -> arbitrary[ProjectRef], // 2,283 + 3 -> ThisProject, // 299 + 4 -> arbitrary[LocalProject], // 436 + 11 -> arbitrary[RootProject], // 1,133 + ) + } + + implicit def arbConfigKey: Arbitrary[ConfigKey] = Arbitrary { + Gen.frequency( + 2 -> const[ConfigKey](Compile), + 2 -> const[ConfigKey](Test), + 1 -> const[ConfigKey](Runtime), + 1 -> const[ConfigKey](IntegrationTest), + 1 -> const[ConfigKey](Provided), + ) + } + + implicit def arbAttrKey[A: Manifest]: Arbitrary[AttributeKey[_]] = + Arbitrary(Gen.identifier map (AttributeKey[A](_))) + + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = + Arbitrary(Gen.identifier map (InputKey[A](_))) + + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = + Arbitrary(Gen.identifier map (SettingKey[A](_))) + + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = + Arbitrary(Gen.identifier map (TaskKey[A](_))) + + implicit def arbKey[A: Manifest]: Arbitrary[Key[_]] = Arbitrary { + Gen.frequency[Key[_]]( + 15 -> arbitrary[InputKey[A]], // 15,431 + 20 -> arbitrary[SettingKey[A]], // 19,645 + 23 -> arbitrary[TaskKey[A]], // 22,867 + ) + } + + implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] = + Arbitrary(Gen.oneOf[ScopeAxis[A]](This, Zero, arbitrary[A] map (Select(_)))) + + implicit val arbAttributeMap: Arbitrary[AttributeMap] = Arbitrary { + Gen.frequency( + 20 -> AttributeMap.empty, + 1 -> (for (name <- Gen.identifier; isModule <- arbitrary[Boolean]) + yield AttributeMap.empty + .put(AttributeKey[String]("name"), name) + .put(AttributeKey[Boolean]("isModule"), isModule) + ) + ) + } + + implicit def arbScope: Arbitrary[Scope] = Arbitrary( + for { + r <- arbitrary[ScopeAxis[Reference]] + c <- arbitrary[ScopeAxis[ConfigKey]] + t <- arbitrary[ScopeAxis[AttributeKey[_]]] + e <- arbitrary[ScopeAxis[AttributeMap]] + } yield Scope(r, c, t, e) + ) +} +import BuildDSLInstances._ + +object CustomEquality { + trait Eq[A] { + def equal(x: A, y: A): Boolean + } + + // Avoid reimplementing equality for other standard classes. + trait EqualLowPriority { + implicit def universal[A] = (x: A, y: A) => x == y + } + + object Eq extends EqualLowPriority { + def apply[A: Eq]: Eq[A] = implicitly + + implicit def eqScoped[A <: Scoped]: Eq[A] = (x, y) => x.scope == y.scope && x.key == y.key + } + + implicit class AnyWith_===[A](private val x: A) extends AnyVal { + def ===(y: A)(implicit z: Eq[A]): Boolean = z.equal(x, y) + def =?(y: A)(implicit z: Eq[A]): Prop = { + if (x === y) proved else falsified :| s"Expected $x but got $y" + } + } + + def expectValue[A: Eq](expected: A)(x: A) = x.toString |: (expected =? x) +} +import CustomEquality._ + +object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { + property("Global / key == key in Global") = { + def check[K <: Key[K]: Arbitrary] = forAll((k: K) => expectValue(k in Global)(Global / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Reference / key == key in Reference") = { + def check[K <: Key[K]: Arbitrary] = forAll((r: Reference, k: K) => expectValue(k in r)(r / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Reference / Config / key == key in Reference in Config") = { + def check[K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, k: K) => expectValue(k in r in c)(r / c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Reference / task / key == key in Reference in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Reference / Config / task / key == key in Reference in Config in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Config / key == key in Config") = { + def check[K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, k: K) => expectValue(k in c)(c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Config / task / key == key in Config in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("task / key == key in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((t: K, k: K) => expectValue(k in t)(t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Scope / key == key in Scope") = { + def check[K <: Key[K]: Arbitrary] = forAll((s: Scope, k: K) => expectValue(k in s)(s / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Reference? / key == key in ThisScope.copy(..)") = { + def check[K <: Key[K]: Arbitrary] = + forAll((r: ScopeAxis[Reference], k: K) => + expectValue(k in ThisScope.copy(project = r))(r / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } + property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { + def check[K <: Key[K]: Arbitrary] = + forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: K) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } +// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { +// def check[K <: Key[K]: Arbitrary] = +// forAll( +// (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: K) => +// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k)) +// check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] +// } + property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = { + def check[K <: Key[K]: Arbitrary] = + forAll( + (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: K) => + expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + } +} From 9b526f54bf12d6a65dc219de724fd67a08dd5503 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 6 Oct 2017 15:40:31 +0100 Subject: [PATCH 42/57] Rarely include custom scopes in key generators --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 936a027db..929d48b93 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -57,14 +57,29 @@ object BuildDSLInstances { implicit def arbAttrKey[A: Manifest]: Arbitrary[AttributeKey[_]] = Arbitrary(Gen.identifier map (AttributeKey[A](_))) - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = - Arbitrary(Gen.identifier map (InputKey[A](_))) + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = Arbitrary { + val keyGen = Gen.identifier map (InputKey[A](_)) + Gen.frequency( + 50 -> keyGen, + 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) + ) + } - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = - Arbitrary(Gen.identifier map (SettingKey[A](_))) + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = Arbitrary { + val keyGen = Gen.identifier map (SettingKey[A](_)) + Gen.frequency( + 50 -> keyGen, + 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) + ) + } - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = - Arbitrary(Gen.identifier map (TaskKey[A](_))) + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = Arbitrary { + val keyGen = Gen.identifier map (TaskKey[A](_)) + Gen.frequency( + 50 -> keyGen, + 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) + ) + } implicit def arbKey[A: Manifest]: Arbitrary[Key[_]] = Arbitrary { Gen.frequency[Key[_]]( From 5b03379693d0a9df6dace69d28751383be5ac418 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 6 Oct 2017 17:41:06 +0100 Subject: [PATCH 43/57] Extract withScope --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 929d48b93..8432a3f54 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -57,29 +57,20 @@ object BuildDSLInstances { implicit def arbAttrKey[A: Manifest]: Arbitrary[AttributeKey[_]] = Arbitrary(Gen.identifier map (AttributeKey[A](_))) - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = Arbitrary { - val keyGen = Gen.identifier map (InputKey[A](_)) - Gen.frequency( + def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Arbitrary[K] = + Arbitrary(Gen.frequency( 50 -> keyGen, 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) - ) - } + )) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = Arbitrary { - val keyGen = Gen.identifier map (SettingKey[A](_)) - Gen.frequency( - 50 -> keyGen, - 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) - ) - } + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = + withScope(Gen.identifier map (InputKey[A](_))) - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = Arbitrary { - val keyGen = Gen.identifier map (TaskKey[A](_)) - Gen.frequency( - 50 -> keyGen, - 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) - ) - } + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = + withScope(Gen.identifier map (SettingKey[A](_))) + + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = + withScope(Gen.identifier map (TaskKey[A](_))) implicit def arbKey[A: Manifest]: Arbitrary[Key[_]] = Arbitrary { Gen.frequency[Key[_]]( From 2a6385fd941c0b95ace351648522ac641aa64874 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 6 Oct 2017 15:47:46 -0400 Subject: [PATCH 44/57] Remove thunk for slash syntax Ref #3606, #3611, and #3613 This removes unnecessary thunk for slash syntax. The semantics using this approach is strictly better than the previous `in (ref, config, task)`. By removing the thunk, we retain `(a / b) / c == a / b / c`. See the following example: ```scala scala> import sbt._, Keys._ scala> val t: TaskKey[Unit] = (test in Test) t: sbt.TaskKey[Unit] = TaskKey(This / Select(ConfigKey(test)) / This / test) scala> ThisBuild / t ThisBuild / t res1: sbt.TaskKey[Unit] = TaskKey(Select(ThisBuild) / Select(ConfigKey(test)) / This / test) scala> ThisBuild / t / name ThisBuild / t / name res2: sbt.SettingKey[String] = SettingKey(Select(ThisBuild) / Select(ConfigKey(test)) / Select(test) / name) ``` so far so good? Now look at this: ``` scala> scala> name in (ThisBuild, t) name in (ThisBuild, t) res3: sbt.SettingKey[String] = SettingKey(Select(ThisBuild) / This / Select(test) / name) ``` `Test` configuration knowledge is lost! For `in (..)` maybe it was ok because mostly we don't use unscoped keys, but that's the difference between `in (..)` and `/`. Fixes #3605 --- .../src/main/scala/sbt/SlashSyntax.scala | 70 +++---- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 193 +++++++++--------- sbt/src/sbt-test/project/unified/build.sbt | 21 ++ 3 files changed, 147 insertions(+), 137 deletions(-) diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index fc98cfc39..9b1898a05 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -39,23 +39,31 @@ trait SlashSyntax { implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration = new RichConfiguration(Scope(This, Select(c), This, This)) - - implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = (c: ConfigKey) - - implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope = - new RichScope(Scope(This, This, Select(t.key), This)) + implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = + sbtSlashSyntaxRichConfigKey(c: ConfigKey) implicit def sbtSlashSyntaxRichScope(s: Scope): RichScope = new RichScope(s) - implicit def sbtSlashSyntaxScopeAndKeyRescope(scopeAndKey: ScopeAndKey[_]): TerminalScope = - scopeAndKey.rescope + /** + * This handles task scoping an existing scoped key (such as `Compile / test`) + * into a task scoping in `(Compile / test) / name`. + */ + implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope = + new RichScope(t.scope.copy(task = Select(t.key))) - implicit def sbtSlashSyntaxScopeAndKeyMaterialize[K <: Key[K]](scopeAndKey: ScopeAndKey[K]): K = - scopeAndKey.materialize + implicit val sbtSlashSyntaxSettingKeyCanScope: CanScope[SettingKey] = new SettingKeyCanScope() + implicit val sbtSlashSyntaxTaskKeyCanScope: CanScope[TaskKey] = new TaskKeyCanScope() + implicit val sbtSlashSyntaxInputKeyCanScope: CanScope[InputKey] = new InputKeyCanScope() } object SlashSyntax { + /** RichScopeLike wraps a general scope to provide the `/` operator for key scoping. */ + sealed trait RichScopeLike { + protected def scope: Scope + def /[A, F[_]: CanScope](key: F[A]): F[A] = implicitly[CanScope[F]].inScope(key, scope) + } + /** RichReference wraps a reference to provide the `/` operator for scoping. */ final class RichReference(protected val scope: Scope) extends RichScopeLike { def /(c: ConfigKey): RichConfiguration = new RichConfiguration(scope in c) @@ -68,46 +76,28 @@ object SlashSyntax { /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ final class RichConfiguration(protected val scope: Scope) extends RichScopeLike { - // This is for handling `Zero / Zero / Zero / name`. def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope = new RichScope(scope.copy(task = taskAxis)) } - /** Both `Scoped.ScopingSetting` and `Scoped` are parents of `SettingKey`, `TaskKey` and - * `InputKey`. We'll need both, so this is a convenient type alias. */ - type Key[K] = Scoped.ScopingSetting[K] with Scoped - - sealed trait RichScopeLike { - protected def scope: Scope - - // We don't know what the key is for yet, so just capture for now. - def /[K <: Key[K]](key: K): ScopeAndKey[K] = new ScopeAndKey(scope, key) - } - /** RichScope wraps a general scope to provide the `/` operator for scoping. */ - final class RichScope(protected val scope: Scope) extends RichScopeLike - - /** TerminalScope provides the last `/` for scoping. */ - final class TerminalScope(scope: Scope) { - def /[K <: Key[K]](key: K): K = key in scope - } + final class RichScope(protected val scope: Scope) extends RichScopeLike {} /** - * ScopeAndKey is a synthetic DSL construct necessary to capture both the built-up scope with a - * given key, while we're not sure if the given key is terminal or task-scoping. The "materialize" - * method will be used if it's terminal, returning the scoped key, while "rescope" will be used - * if we're task-scoping. - * - * @param scope the built-up scope - * @param key a given key - * @tparam K the type of the given key, necessary to type "materialize" + * A typeclass that represents scoping. */ - final class ScopeAndKey[K <: Key[K]](scope: Scope, key: K) { - private[sbt] def materialize: K = key in scope - private[sbt] def rescope: TerminalScope = new TerminalScope(scope in key.key) - - override def toString: String = s"$scope / ${key.key}" + sealed trait CanScope[F[A]] { + def inScope[A](key: F[A], scope: Scope): F[A] } + final class SettingKeyCanScope extends CanScope[SettingKey] { + def inScope[A](key: SettingKey[A], scope: Scope): SettingKey[A] = key in scope + } + final class TaskKeyCanScope extends CanScope[TaskKey] { + def inScope[A](key: TaskKey[A], scope: Scope): TaskKey[A] = key in scope + } + final class InputKeyCanScope extends CanScope[InputKey] { + def inScope[A](key: InputKey[A], scope: Scope): InputKey[A] = key in scope + } } diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 8432a3f54..34f6b55d2 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -11,7 +11,7 @@ import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._, Prop._ import java.io.File import sbt.io.IO -import sbt.SlashSyntax, SlashSyntax.Key +import sbt.SlashSyntax import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero }, Scope.{ Global, ThisScope } import sbt.{ BuildRef, LocalProject, LocalRootProject, ProjectRef, Reference, RootProject, ThisBuild, ThisProject } import sbt.ConfigKey @@ -63,21 +63,26 @@ object BuildDSLInstances { 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) )) - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = - withScope(Gen.identifier map (InputKey[A](_))) + object WithScope { + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = + withScope(Gen.identifier map (InputKey[A](_))) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = - withScope(Gen.identifier map (SettingKey[A](_))) + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = + withScope(Gen.identifier map (SettingKey[A](_))) - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = - withScope(Gen.identifier map (TaskKey[A](_))) + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = + withScope(Gen.identifier map (TaskKey[A](_))) + } - implicit def arbKey[A: Manifest]: Arbitrary[Key[_]] = Arbitrary { - Gen.frequency[Key[_]]( - 15 -> arbitrary[InputKey[A]], // 15,431 - 20 -> arbitrary[SettingKey[A]], // 19,645 - 23 -> arbitrary[TaskKey[A]], // 22,867 - ) + object WithoutScope { + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = + Arbitrary(Gen.identifier map (InputKey[A](_))) + + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = + Arbitrary(Gen.identifier map (SettingKey[A](_))) + + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = + Arbitrary(Gen.identifier map (TaskKey[A](_))) } implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] = @@ -134,111 +139,105 @@ import CustomEquality._ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Global / key == key in Global") = { - def check[K <: Key[K]: Arbitrary] = forAll((k: K) => expectValue(k in Global)(Global / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (k: SettingKey[String]) => expectValue(k in Global)(Global / k) } + && forAll { (k: TaskKey[String]) => expectValue(k in Global)(Global / k) } + && forAll { (k: InputKey[String]) => expectValue(k in Global)(Global / k) }) } + property("Reference / key == key in Reference") = { - def check[K <: Key[K]: Arbitrary] = forAll((r: Reference, k: K) => expectValue(k in r)(r / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (r: Reference, k: SettingKey[String]) => expectValue(k in r)(r / k) } + && forAll { (r: Reference, k: TaskKey[String]) => expectValue(k in r)(r / k) } + && forAll { (r: Reference, k: InputKey[String]) => expectValue(k in r)(r / k) }) } + property("Reference / Config / key == key in Reference in Config") = { - def check[K <: Key[K]: Arbitrary] = - forAll((r: Reference, c: ConfigKey, k: K) => expectValue(k in r in c)(r / c / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (r: Reference, c: ConfigKey, k: SettingKey[String]) => expectValue(k in r in c)(r / c / k) } + && forAll { (r: Reference, c: ConfigKey, k: TaskKey[String]) => expectValue(k in r in c)(r / c / k) } + && forAll { (r: Reference, c: ConfigKey, k: InputKey[String]) => expectValue(k in r in c)(r / c / k) }) } + property("Reference / task / key == key in Reference in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + import WithoutScope._ + (forAll { (r: Reference, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, t))(r / t / k) } + && forAll { (r: Reference, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, t))(r / t / k) } + && forAll { (r: Reference, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, t))(r / t / k) }) } + property("Reference / Config / task / key == key in Reference in Config in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + import WithoutScope._ + (forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) } + && forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) } + && forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) }) } + property("Config / key == key in Config") = { - def check[K <: Key[K]: Arbitrary] = - forAll((c: ConfigKey, k: K) => expectValue(k in c)(c / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (c: ConfigKey, k: SettingKey[String]) => expectValue(k in c)(c / k) } + && forAll { (c: ConfigKey, k: TaskKey[String]) => expectValue(k in c)(c / k) } + && forAll { (c: ConfigKey, k: InputKey[String]) => expectValue(k in c)(c / k) }) } + property("Config / task / key == key in Config in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + import WithoutScope._ + (forAll { (c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in c in t)(c / t / k) } + && forAll { (c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in c in t)(c / t / k) } + && forAll { (c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in c in t)(c / t / k) }) } + property("task / key == key in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((t: K, k: K) => expectValue(k in t)(t / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + import WithoutScope._ + (forAll { (t: TaskKey[String], k: SettingKey[String]) => expectValue(k in t)(t / k) } + && forAll { (t: TaskKey[String], k: TaskKey[String]) => expectValue(k in t)(t / k) } + && forAll { (t: TaskKey[String], k: InputKey[String]) => expectValue(k in t)(t / k) }) } + property("Scope / key == key in Scope") = { - def check[K <: Key[K]: Arbitrary] = forAll((s: Scope, k: K) => expectValue(k in s)(s / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (s: Scope, k: SettingKey[String]) => expectValue(k in s)(s / k) } + && forAll { (s: Scope, k: TaskKey[String]) => expectValue(k in s)(s / k) } + && forAll { (s: Scope, k: InputKey[String]) => expectValue(k in s)(s / k) }) } + property("Reference? / key == key in ThisScope.copy(..)") = { - def check[K <: Key[K]: Arbitrary] = - forAll((r: ScopeAxis[Reference], k: K) => - expectValue(k in ThisScope.copy(project = r))(r / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (r: ScopeAxis[Reference], k: SettingKey[String]) => + expectValue(k in ThisScope.copy(project = r))(r / k) } && + forAll { (r: ScopeAxis[Reference], k: TaskKey[String]) => + expectValue(k in ThisScope.copy(project = r))(r / k) } && + forAll { (r: ScopeAxis[Reference], k: InputKey[String]) => + expectValue(k in ThisScope.copy(project = r))(r / k) }) } + property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { - def check[K <: Key[K]: Arbitrary] = - forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: K) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: SettingKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } && + forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: TaskKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } && + forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: InputKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) }) } -// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { -// def check[K <: Key[K]: Arbitrary] = -// forAll( -// (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: K) => -// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k)) -// check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] -// } + + // property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { + // import WithScope._ + // (forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => + // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } && + // forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => + // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } && + // forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) => + // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } + // } + property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = { - def check[K <: Key[K]: Arbitrary] = - forAll( - (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: K) => - expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k)) - check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] + import WithScope._ + (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } && + forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } && + forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) => + expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) }) } } diff --git a/sbt/src/sbt-test/project/unified/build.sbt b/sbt/src/sbt-test/project/unified/build.sbt index 91f772197..7f456b66c 100644 --- a/sbt/src/sbt-test/project/unified/build.sbt +++ b/sbt/src/sbt-test/project/unified/build.sbt @@ -1,8 +1,14 @@ import sbt.internal.CommandStrings.{ inspectBrief, inspectDetailed } import sbt.internal.Inspect +import sjsonnew._, BasicJsonProtocol._ val uTest = "com.lihaoyi" %% "utest" % "0.5.3" +val foo = taskKey[Int]("") +val bar = taskKey[Int]("") +val baz = inputKey[Unit]("") +val buildInfo = taskKey[Seq[File]]("The task that generates the build info.") + lazy val root = (project in file(".")) .settings( Global / cancelable := true, @@ -10,9 +16,24 @@ lazy val root = (project in file(".")) console / scalacOptions += "-deprecation", Compile / console / scalacOptions += "-Ywarn-numeric-widen", projA / Compile / console / scalacOptions += "-feature", + Zero / name := "foo", Zero / Zero / name := "foo", Zero / Zero / Zero / name := "foo", + Test / bar := 1, + Test / foo := (Test / bar).value + 1, + Compile / foo := { + (Compile / bar).previous.getOrElse(1) + }, + Compile / bar := { + (Compile / foo).previous.getOrElse(2) + }, + Test / buildInfo := Nil, + baz := { + val x = (Test / buildInfo).taskValue + (Compile / run).evaluated + }, + libraryDependencies += uTest % Test, testFrameworks += new TestFramework("utest.runner.Framework"), From e5898111fedca21be2088804ad891d0ac37c2207 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:07:19 +0100 Subject: [PATCH 45/57] Replace CanScope with Scoped.ScopingSetting --- .../src/main/scala/sbt/SlashSyntax.scala | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index 9b1898a05..a88dbc828 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -50,10 +50,6 @@ trait SlashSyntax { */ implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope = new RichScope(t.scope.copy(task = Select(t.key))) - - implicit val sbtSlashSyntaxSettingKeyCanScope: CanScope[SettingKey] = new SettingKeyCanScope() - implicit val sbtSlashSyntaxTaskKeyCanScope: CanScope[TaskKey] = new TaskKeyCanScope() - implicit val sbtSlashSyntaxInputKeyCanScope: CanScope[InputKey] = new InputKeyCanScope() } object SlashSyntax { @@ -61,7 +57,7 @@ object SlashSyntax { /** RichScopeLike wraps a general scope to provide the `/` operator for key scoping. */ sealed trait RichScopeLike { protected def scope: Scope - def /[A, F[_]: CanScope](key: F[A]): F[A] = implicitly[CanScope[F]].inScope(key, scope) + final def /[K](key: Scoped.ScopingSetting[K]): K = key in scope } /** RichReference wraps a reference to provide the `/` operator for scoping. */ @@ -83,21 +79,4 @@ object SlashSyntax { /** RichScope wraps a general scope to provide the `/` operator for scoping. */ final class RichScope(protected val scope: Scope) extends RichScopeLike {} - - /** - * A typeclass that represents scoping. - */ - sealed trait CanScope[F[A]] { - def inScope[A](key: F[A], scope: Scope): F[A] - } - - final class SettingKeyCanScope extends CanScope[SettingKey] { - def inScope[A](key: SettingKey[A], scope: Scope): SettingKey[A] = key in scope - } - final class TaskKeyCanScope extends CanScope[TaskKey] { - def inScope[A](key: TaskKey[A], scope: Scope): TaskKey[A] = key in scope - } - final class InputKeyCanScope extends CanScope[InputKey] { - def inScope[A](key: InputKey[A], scope: Scope): InputKey[A] = key in scope - } } From 0bcd7c3b6d23aed2e4532bf155fb568e3d027f19 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:08:32 +0100 Subject: [PATCH 46/57] Remove boilerplate around sbtSlashSyntaxRichConfiguration --- main-settings/src/main/scala/sbt/SlashSyntax.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index a88dbc828..0e512c487 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -39,8 +39,8 @@ trait SlashSyntax { implicit def sbtSlashSyntaxRichConfigKey(c: ConfigKey): RichConfiguration = new RichConfiguration(Scope(This, Select(c), This, This)) - implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = - sbtSlashSyntaxRichConfigKey(c: ConfigKey) + + implicit def sbtSlashSyntaxRichConfiguration(c: Configuration): RichConfiguration = (c: ConfigKey) implicit def sbtSlashSyntaxRichScope(s: Scope): RichScope = new RichScope(s) From 18d615701f6a90dc6f1314dbb4d12efedbb1b758 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:11:11 +0100 Subject: [PATCH 47/57] Remove WithScope wrapping --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 34f6b55d2..fd60ea06c 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -63,16 +63,14 @@ object BuildDSLInstances { 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) )) - object WithScope { - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = - withScope(Gen.identifier map (InputKey[A](_))) + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = + withScope(Gen.identifier map (InputKey[A](_))) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = - withScope(Gen.identifier map (SettingKey[A](_))) + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = + withScope(Gen.identifier map (SettingKey[A](_))) - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = - withScope(Gen.identifier map (TaskKey[A](_))) - } + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = + withScope(Gen.identifier map (TaskKey[A](_))) object WithoutScope { implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = @@ -139,21 +137,18 @@ import CustomEquality._ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Global / key == key in Global") = { - import WithScope._ (forAll { (k: SettingKey[String]) => expectValue(k in Global)(Global / k) } && forAll { (k: TaskKey[String]) => expectValue(k in Global)(Global / k) } && forAll { (k: InputKey[String]) => expectValue(k in Global)(Global / k) }) } property("Reference / key == key in Reference") = { - import WithScope._ (forAll { (r: Reference, k: SettingKey[String]) => expectValue(k in r)(r / k) } && forAll { (r: Reference, k: TaskKey[String]) => expectValue(k in r)(r / k) } && forAll { (r: Reference, k: InputKey[String]) => expectValue(k in r)(r / k) }) } property("Reference / Config / key == key in Reference in Config") = { - import WithScope._ (forAll { (r: Reference, c: ConfigKey, k: SettingKey[String]) => expectValue(k in r in c)(r / c / k) } && forAll { (r: Reference, c: ConfigKey, k: TaskKey[String]) => expectValue(k in r in c)(r / c / k) } && forAll { (r: Reference, c: ConfigKey, k: InputKey[String]) => expectValue(k in r in c)(r / c / k) }) @@ -174,7 +169,6 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Config / key == key in Config") = { - import WithScope._ (forAll { (c: ConfigKey, k: SettingKey[String]) => expectValue(k in c)(c / k) } && forAll { (c: ConfigKey, k: TaskKey[String]) => expectValue(k in c)(c / k) } && forAll { (c: ConfigKey, k: InputKey[String]) => expectValue(k in c)(c / k) }) @@ -195,14 +189,12 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Scope / key == key in Scope") = { - import WithScope._ (forAll { (s: Scope, k: SettingKey[String]) => expectValue(k in s)(s / k) } && forAll { (s: Scope, k: TaskKey[String]) => expectValue(k in s)(s / k) } && forAll { (s: Scope, k: InputKey[String]) => expectValue(k in s)(s / k) }) } property("Reference? / key == key in ThisScope.copy(..)") = { - import WithScope._ (forAll { (r: ScopeAxis[Reference], k: SettingKey[String]) => expectValue(k in ThisScope.copy(project = r))(r / k) } && forAll { (r: ScopeAxis[Reference], k: TaskKey[String]) => @@ -212,7 +204,6 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { - import WithScope._ (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: SettingKey[String]) => expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } && forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: TaskKey[String]) => @@ -222,7 +213,6 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } // property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { - // import WithScope._ // (forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } && // forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => @@ -232,7 +222,6 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { // } property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = { - import WithScope._ (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } && forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => From 165dc794ca8f830ef47a18e8fd70d0f3cf11cbe0 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:14:36 +0100 Subject: [PATCH 48/57] Extract gen{Input,Setting,Task}Key --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index fd60ea06c..5abbea8f4 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -63,24 +63,18 @@ object BuildDSLInstances { 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) )) - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = - withScope(Gen.identifier map (InputKey[A](_))) + def genInputKey[A: Manifest]: Gen[InputKey[A]] = Gen.identifier map (InputKey[A](_)) + def genSettingKey[A: Manifest]: Gen[SettingKey[A]] = Gen.identifier map (SettingKey[A](_)) + def genTaskKey[A: Manifest]: Gen[TaskKey[A]] = Gen.identifier map (TaskKey[A](_)) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = - withScope(Gen.identifier map (SettingKey[A](_))) - - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = - withScope(Gen.identifier map (TaskKey[A](_))) + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = withScope(genInputKey[A]) + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = withScope(genSettingKey[A]) + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = withScope(genTaskKey[A]) object WithoutScope { - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = - Arbitrary(Gen.identifier map (InputKey[A](_))) - - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = - Arbitrary(Gen.identifier map (SettingKey[A](_))) - - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = - Arbitrary(Gen.identifier map (TaskKey[A](_))) + implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = Arbitrary(genInputKey[A]) + implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = Arbitrary(genSettingKey[A]) + implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = Arbitrary(genTaskKey[A]) } implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] = From 025075efd0d9d417357f470dc766aa4641837eb0 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:25:04 +0100 Subject: [PATCH 49/57] Dedup, cleanup & cover all key types --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 139 +++++++++++------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 5abbea8f4..473d288a6 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -130,97 +130,130 @@ object CustomEquality { import CustomEquality._ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { + type Key[K] = Scoped.ScopingSetting[K] with Scoped + property("Global / key == key in Global") = { - (forAll { (k: SettingKey[String]) => expectValue(k in Global)(Global / k) } - && forAll { (k: TaskKey[String]) => expectValue(k in Global)(Global / k) } - && forAll { (k: InputKey[String]) => expectValue(k in Global)(Global / k) }) + def check[K <: Key[K]: Arbitrary] = forAll((k: K) => expectValue(k in Global)(Global / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference / key == key in Reference") = { - (forAll { (r: Reference, k: SettingKey[String]) => expectValue(k in r)(r / k) } - && forAll { (r: Reference, k: TaskKey[String]) => expectValue(k in r)(r / k) } - && forAll { (r: Reference, k: InputKey[String]) => expectValue(k in r)(r / k) }) + def check[K <: Key[K]: Arbitrary] = forAll((r: Reference, k: K) => expectValue(k in r)(r / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference / Config / key == key in Reference in Config") = { - (forAll { (r: Reference, c: ConfigKey, k: SettingKey[String]) => expectValue(k in r in c)(r / c / k) } - && forAll { (r: Reference, c: ConfigKey, k: TaskKey[String]) => expectValue(k in r in c)(r / c / k) } - && forAll { (r: Reference, c: ConfigKey, k: InputKey[String]) => expectValue(k in r in c)(r / c / k) }) + def check[K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, k: K) => expectValue(k in r in c)(r / c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference / task / key == key in Reference in task") = { import WithoutScope._ - (forAll { (r: Reference, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, t))(r / t / k) } - && forAll { (r: Reference, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, t))(r / t / k) } - && forAll { (r: Reference, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, t))(r / t / k) }) + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) } property("Reference / Config / task / key == key in Reference in Config in task") = { import WithoutScope._ - (forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) } - && forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) } - && forAll { (r: Reference, c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in (r, c, t))(r / c / t / k) }) + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) } property("Config / key == key in Config") = { - (forAll { (c: ConfigKey, k: SettingKey[String]) => expectValue(k in c)(c / k) } - && forAll { (c: ConfigKey, k: TaskKey[String]) => expectValue(k in c)(c / k) } - && forAll { (c: ConfigKey, k: InputKey[String]) => expectValue(k in c)(c / k) }) + def check[K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, k: K) => expectValue(k in c)(c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Config / task / key == key in Config in task") = { import WithoutScope._ - (forAll { (c: ConfigKey, t: TaskKey[String], k: SettingKey[String]) => expectValue(k in c in t)(c / t / k) } - && forAll { (c: ConfigKey, t: TaskKey[String], k: TaskKey[String]) => expectValue(k in c in t)(c / t / k) } - && forAll { (c: ConfigKey, t: TaskKey[String], k: InputKey[String]) => expectValue(k in c in t)(c / t / k) }) + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) } property("task / key == key in task") = { import WithoutScope._ - (forAll { (t: TaskKey[String], k: SettingKey[String]) => expectValue(k in t)(t / k) } - && forAll { (t: TaskKey[String], k: TaskKey[String]) => expectValue(k in t)(t / k) } - && forAll { (t: TaskKey[String], k: InputKey[String]) => expectValue(k in t)(t / k) }) + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((t: K, k: K) => expectValue(k in t)(t / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) } property("Scope / key == key in Scope") = { - (forAll { (s: Scope, k: SettingKey[String]) => expectValue(k in s)(s / k) } - && forAll { (s: Scope, k: TaskKey[String]) => expectValue(k in s)(s / k) } - && forAll { (s: Scope, k: InputKey[String]) => expectValue(k in s)(s / k) }) + def check[K <: Key[K]: Arbitrary] = forAll((s: Scope, k: K) => expectValue(k in s)(s / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference? / key == key in ThisScope.copy(..)") = { - (forAll { (r: ScopeAxis[Reference], k: SettingKey[String]) => - expectValue(k in ThisScope.copy(project = r))(r / k) } && - forAll { (r: ScopeAxis[Reference], k: TaskKey[String]) => - expectValue(k in ThisScope.copy(project = r))(r / k) } && - forAll { (r: ScopeAxis[Reference], k: InputKey[String]) => - expectValue(k in ThisScope.copy(project = r))(r / k) }) + def check[K <: Key[K]: Arbitrary] = + forAll((r: ScopeAxis[Reference], k: K) => + expectValue(k in ThisScope.copy(project = r))(r / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { - (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: SettingKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } && - forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: TaskKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) } && - forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: InputKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) }) + def check[K <: Key[K]: Arbitrary] = + forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: K) => + expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } - // property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { - // (forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => - // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } && - // forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => - // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } && - // forAll { (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) => - // expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k) } - // } +// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { +// def check[K <: Key[K]: Arbitrary] = +// forAll( +// (r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: K) => +// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k)) +// check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] +// } property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = { - (forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: SettingKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } && - forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: TaskKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) } && - forAll { (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: InputKey[String]) => - expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) }) + def check[K <: Key[K]: Arbitrary] = + forAll( + (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: K) => + expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } } From 74ac7d9e07214457a70fdc01f0c7f2b26a750c28 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:30:54 +0100 Subject: [PATCH 50/57] Drop redudant label in expectValue --- main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 473d288a6..c4b13b27b 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -125,7 +125,7 @@ object CustomEquality { } } - def expectValue[A: Eq](expected: A)(x: A) = x.toString |: (expected =? x) + def expectValue[A: Eq](expected: A)(x: A) = expected =? x } import CustomEquality._ From fb28c201c8315aefa60285f1ed6346ad8aa46e90 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:32:25 +0100 Subject: [PATCH 51/57] Make scoped keys more frequent --- main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index c4b13b27b..b0505ac86 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -59,7 +59,7 @@ object BuildDSLInstances { def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Arbitrary[K] = Arbitrary(Gen.frequency( - 50 -> keyGen, + 5 -> keyGen, 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) )) From 8af3110c0047d41164ad31bcb98932529cf06977 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:35:06 +0100 Subject: [PATCH 52/57] Add .previous tests to SlashSyntaxTest --- .../src/test/scala/sbt/SlashSyntaxTest.scala | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala b/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala index f7a1ae065..31235f79d 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxTest.scala @@ -7,7 +7,9 @@ package sbt.test -import sbt.Def.{ Setting, settingKey, taskKey } +import java.io.File +import sjsonnew._, BasicJsonProtocol._ +import sbt.Def.{ Setting, inputKey, settingKey, taskKey } import sbt.Scope.Global import sbt.librarymanagement.ModuleID import sbt.librarymanagement.syntax._ @@ -23,9 +25,15 @@ object SlashSyntaxTest extends sbt.SlashSyntax { val console = taskKey[Unit]("") val libraryDependencies = settingKey[Seq[ModuleID]]("") val name = settingKey[String]("") + val run = inputKey[Unit]("") val scalaVersion = settingKey[String]("") val scalacOptions = taskKey[Seq[String]]("") + val foo = taskKey[Int]("") + val bar = taskKey[Int]("") + val baz = inputKey[Unit]("") + val buildInfo = taskKey[Seq[File]]("") + val uTest = "com.lihaoyi" %% "utest" % "0.5.3" Seq[Setting[_]]( @@ -34,8 +42,23 @@ object SlashSyntaxTest extends sbt.SlashSyntax { console / scalacOptions += "-deprecation", Compile / console / scalacOptions += "-Ywarn-numeric-widen", projA / Compile / console / scalacOptions += "-feature", + Zero / name := "foo", Zero / Zero / name := "foo", Zero / Zero / Zero / name := "foo", + Test / bar := 1, + Test / foo := (Test / bar).value + 1, + Compile / foo := { + (Compile / bar).previous.getOrElse(1) + }, + Compile / bar := { + (Compile / foo).previous.getOrElse(2) + }, + Test / buildInfo := Nil, + baz := { + val _ = (Test / buildInfo).taskValue + (Compile / run).evaluated + }, + foo := (Test / bar).value + 1, libraryDependencies += uTest % Test, ) } From d19c350687094c28ccd1647d6aecf88f9bfc501b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:36:28 +0100 Subject: [PATCH 53/57] Correct name of WithoutScope properties --- main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index b0505ac86..8a267f81a 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -148,7 +148,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } - property("Reference / task / key == key in Reference in task") = { + property("Reference / task / key ~= key in Reference in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k)) @@ -165,7 +165,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { ) } - property("Reference / Config / task / key == key in Reference in Config in task") = { + property("Reference / Config / task / key ~= key in Reference in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) @@ -188,7 +188,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } - property("Config / task / key == key in Config in task") = { + property("Config / task / key ~= key in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k)) @@ -205,7 +205,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { ) } - property("task / key == key in task") = { + property("task / key ~= key in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = forAll((t: K, k: K) => expectValue(k in t)(t / k)) From ef4828cfc2169126b90730b050a0f51cd1f8abcf Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 12:09:31 +0100 Subject: [PATCH 54/57] Add slash syntax for AttrKey that parity with "in" syntax --- .../src/main/scala/sbt/SlashSyntax.scala | 18 ++++-- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 64 +++++++++++++++++++ 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/main-settings/src/main/scala/sbt/SlashSyntax.scala b/main-settings/src/main/scala/sbt/SlashSyntax.scala index 0e512c487..93d31b1aa 100644 --- a/main-settings/src/main/scala/sbt/SlashSyntax.scala +++ b/main-settings/src/main/scala/sbt/SlashSyntax.scala @@ -50,18 +50,25 @@ trait SlashSyntax { */ implicit def sbtSlashSyntaxRichScopeFromScoped(t: Scoped): RichScope = new RichScope(t.scope.copy(task = Select(t.key))) + + implicit def sbtSlashSyntaxRichScopeFromAttributeKey(a: AttributeKey[_]): RichScope = + Scope(This, This, Select(a), This) + } object SlashSyntax { - /** RichScopeLike wraps a general scope to provide the `/` operator for key scoping. */ - sealed trait RichScopeLike { + sealed trait HasSlashKey { protected def scope: Scope final def /[K](key: Scoped.ScopingSetting[K]): K = key in scope } + sealed trait HasSlashKeyOrAttrKey extends HasSlashKey { + final def /(key: AttributeKey[_]): RichScope = new RichScope(scope in key) + } + /** RichReference wraps a reference to provide the `/` operator for scoping. */ - final class RichReference(protected val scope: Scope) extends RichScopeLike { + final class RichReference(protected val scope: Scope) extends HasSlashKeyOrAttrKey { def /(c: ConfigKey): RichConfiguration = new RichConfiguration(scope in c) def /(c: Configuration): RichConfiguration = new RichConfiguration(scope in c) @@ -71,12 +78,13 @@ object SlashSyntax { } /** RichConfiguration wraps a configuration to provide the `/` operator for scoping. */ - final class RichConfiguration(protected val scope: Scope) extends RichScopeLike { + final class RichConfiguration(protected val scope: Scope) extends HasSlashKeyOrAttrKey { // This is for handling `Zero / Zero / Zero / name`. def /(taskAxis: ScopeAxis[AttributeKey[_]]): RichScope = new RichScope(scope.copy(task = taskAxis)) } /** RichScope wraps a general scope to provide the `/` operator for scoping. */ - final class RichScope(protected val scope: Scope) extends RichScopeLike {} + final class RichScope(protected val scope: Scope) extends HasSlashKey + } diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 8a267f81a..93a2e77bb 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -148,6 +148,22 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } + property("Reference / task.key / key == key in Reference in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t.key / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Reference / task / key ~= key in Reference in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = @@ -165,6 +181,22 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { ) } + property("Reference / Config / task.key / key == key in Reference in Config in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t.key / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Reference / Config / task / key ~= key in Reference in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = @@ -188,6 +220,22 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } + property("Config / task.key / key == key in Config in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t.key / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("Config / task / key ~= key in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = @@ -205,6 +253,22 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { ) } + property("task / key == key in task") = { + def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = + forAll((t: K, k: K) => expectValue(k in t)(t.key / k)) + (true + && check[InputKey[String], InputKey[String]] + && check[InputKey[String], SettingKey[String]] + && check[InputKey[String], TaskKey[String]] + && check[SettingKey[String], InputKey[String]] + && check[SettingKey[String], SettingKey[String]] + && check[SettingKey[String], TaskKey[String]] + && check[TaskKey[String], InputKey[String]] + && check[TaskKey[String], SettingKey[String]] + && check[TaskKey[String], TaskKey[String]] + ) + } + property("task / key ~= key in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = From 5e0b080f516510161be78eebaf9d83e8c998d103 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 7 Oct 2017 18:42:26 +0100 Subject: [PATCH 55/57] Fix some minor errors --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index 93a2e77bb..d439809f3 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -150,7 +150,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Reference / task.key / key == key in Reference in task") = { def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t.key / k)) + forAll((r: Reference, t: T, k: K) => expectValue(k in (r, t))(r / t.key / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -167,7 +167,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Reference / task / key ~= key in Reference in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, t: K, k: K) => expectValue(k in (r, t))(r / t / k)) + forAll((r: Reference, t: T, k: K) => expectValue(k in (r, t))(r / t / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -183,7 +183,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Reference / Config / task.key / key == key in Reference in Config in task") = { def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t.key / k)) + forAll((r: Reference, c: ConfigKey, t: T, k: K) => expectValue(k in (r, c, t))(r / c / t.key / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -200,7 +200,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Reference / Config / task / key ~= key in Reference in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, c: ConfigKey, t: K, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) + forAll((r: Reference, c: ConfigKey, t: T, k: K) => expectValue(k in (r, c, t))(r / c / t / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -222,7 +222,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Config / task.key / key == key in Config in task") = { def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t.key / k)) + forAll((c: ConfigKey, t: T, k: K) => expectValue(k in c in t)(c / t.key / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -239,7 +239,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("Config / task / key ~= key in Config in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((c: ConfigKey, t: K, k: K) => expectValue(k in c in t)(c / t / k)) + forAll((c: ConfigKey, t: T, k: K) => expectValue(k in c in t)(c / t / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -253,9 +253,9 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { ) } - property("task / key == key in task") = { + property("task.key / key == key in task") = { def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((t: K, k: K) => expectValue(k in t)(t.key / k)) + forAll((t: T, k: K) => expectValue(k in t)(t.key / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] @@ -272,7 +272,7 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { property("task / key ~= key in task") = { import WithoutScope._ def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((t: K, k: K) => expectValue(k in t)(t / k)) + forAll((t: T, k: K) => expectValue(k in t)(t / k)) (true && check[InputKey[String], InputKey[String]] && check[InputKey[String], SettingKey[String]] From 668ace98eed2308239d4a77c0d62ab67f46f17e3 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 8 Oct 2017 16:39:46 +0100 Subject: [PATCH 56/57] Remove some duplication when only Scoped is required --- .../src/test/scala/sbt/SlashSyntaxSpec.scala | 77 ++++++------------- 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index d439809f3..a4c802934 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -71,6 +71,18 @@ object BuildDSLInstances { implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = withScope(genSettingKey[A]) implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = withScope(genTaskKey[A]) + implicit def arbScoped[A: Manifest](implicit + arbInputKey: Arbitrary[InputKey[A]], + arbSettingKey: Arbitrary[SettingKey[A]], + arbTaskKey: Arbitrary[TaskKey[A]], + ): Arbitrary[Scoped] = { + Arbitrary(Gen.frequency( + 15 -> arbitrary[InputKey[A]], // 15,431 + 20 -> arbitrary[SettingKey[A]], // 19,645 + 23 -> arbitrary[TaskKey[A]], // 22,867 + )) + } + object WithoutScope { implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = Arbitrary(genInputKey[A]) implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = Arbitrary(genSettingKey[A]) @@ -149,19 +161,9 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Reference / task.key / key == key in Reference in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, t: T, k: K) => expectValue(k in (r, t))(r / t.key / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + def check[K <: Key[K]: Arbitrary] = + forAll((r: Reference, t: Scoped, k: K) => expectValue(k in (r, t))(r / t.key / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference / task / key ~= key in Reference in task") = { @@ -182,19 +184,10 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Reference / Config / task.key / key == key in Reference in Config in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((r: Reference, c: ConfigKey, t: T, k: K) => expectValue(k in (r, c, t))(r / c / t.key / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + def check[K <: Key[K]: Arbitrary] = + forAll((r: Reference, c: ConfigKey, t: Scoped, k: K) => + expectValue(k in (r, c, t))(r / c / t.key / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Reference / Config / task / key ~= key in Reference in Config in task") = { @@ -221,19 +214,9 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("Config / task.key / key == key in Config in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((c: ConfigKey, t: T, k: K) => expectValue(k in c in t)(c / t.key / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + def check[K <: Key[K]: Arbitrary] = + forAll((c: ConfigKey, t: Scoped, k: K) => expectValue(k in c in t)(c / t.key / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("Config / task / key ~= key in Config in task") = { @@ -254,19 +237,9 @@ object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { } property("task.key / key == key in task") = { - def check[T <: Key[T]: Arbitrary, K <: Key[K]: Arbitrary] = - forAll((t: T, k: K) => expectValue(k in t)(t.key / k)) - (true - && check[InputKey[String], InputKey[String]] - && check[InputKey[String], SettingKey[String]] - && check[InputKey[String], TaskKey[String]] - && check[SettingKey[String], InputKey[String]] - && check[SettingKey[String], SettingKey[String]] - && check[SettingKey[String], TaskKey[String]] - && check[TaskKey[String], InputKey[String]] - && check[TaskKey[String], SettingKey[String]] - && check[TaskKey[String], TaskKey[String]] - ) + def check[K <: Key[K]: Arbitrary] = + forAll((t: Scoped, k: K) => expectValue(k in t)(t.key / k)) + check[InputKey[String]] && check[SettingKey[String]] && check[TaskKey[String]] } property("task / key ~= key in task") = { From a3c34c6c0a76948fe56ecf990e9defb18dfbf6d6 Mon Sep 17 00:00:00 2001 From: Michael Stringer Date: Tue, 3 Oct 2017 10:30:06 +0100 Subject: [PATCH 57/57] Add system property to revert to old polling fs watcher This adds a sbt.watch.mode system property that if set to 'polling' will use PollingWatchService instead of WatchServiceAdapter (nio). On macOS this will default to 'polling' and on all others 'nio'. This is a temporary workaround for users affected by #3527 --- main-command/src/main/scala/sbt/Watched.scala | 29 ++++++++++++++----- main/src/main/scala/sbt/Defaults.scala | 3 +- notes/1.0.3/watch.md | 26 +++++++++++++++++ 3 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 notes/1.0.3/watch.md diff --git a/main-command/src/main/scala/sbt/Watched.scala b/main-command/src/main/scala/sbt/Watched.scala index 0d24e18c4..fa1dee03f 100644 --- a/main-command/src/main/scala/sbt/Watched.scala +++ b/main-command/src/main/scala/sbt/Watched.scala @@ -7,18 +7,19 @@ package sbt -import BasicCommandStrings.ClearOnFailure -import State.FailureWall -import annotation.tailrec import java.io.File import java.nio.file.FileSystems -import scala.concurrent.duration._ - -import sbt.io.{ AllPassFilter, NothingFilter, FileFilter, WatchService } +import sbt.BasicCommandStrings.ClearOnFailure +import sbt.State.FailureWall import sbt.internal.io.{ Source, SourceModificationWatch, WatchState } import sbt.internal.util.AttributeKey import sbt.internal.util.Types.const +import sbt.io._ + +import scala.annotation.tailrec +import scala.concurrent.duration._ +import scala.util.Properties trait Watched { @@ -39,7 +40,7 @@ trait Watched { private[sbt] def triggeredMessage(s: WatchState): String = Watched.defaultTriggeredMessage(s) /** The `WatchService` to use to monitor the file system. */ - private[sbt] def watchService(): WatchService = FileSystems.getDefault.newWatchService() + private[sbt] def watchService(): WatchService = Watched.createWatchService() } object Watched { @@ -125,4 +126,18 @@ object Watched { AttributeKey[WatchState]("watch state", "Internal: tracks state for continuous execution.") val Configuration = AttributeKey[Watched]("watched-configuration", "Configures continuous execution.") + + def createWatchService(): WatchService = { + sys.props.get("sbt.watch.mode") match { + case Some("polling") => + new PollingWatchService(PollDelay) + case Some("nio") => + FileSystems.getDefault.newWatchService() + case _ if Properties.isMac => + // WatchService is slow on macOS - use old polling mode + new PollingWatchService(PollDelay) + case _ => + FileSystems.getDefault.newWatchService() + } + } } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 6fa48bcd9..16122e720 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -9,7 +9,6 @@ package sbt import Def.{ Initialize, ScopedKey, Setting, SettingsDefinition } import java.io.{ File, PrintWriter } -import java.nio.file.FileSystems import java.net.{ URI, URL } import java.util.Optional import java.util.concurrent.{ TimeUnit, Callable } @@ -251,7 +250,7 @@ object Defaults extends BuildCommon { parallelExecution :== true, pollInterval :== new FiniteDuration(500, TimeUnit.MILLISECONDS), watchService :== { () => - FileSystems.getDefault.newWatchService + Watched.createWatchService() }, logBuffered :== false, commands :== Nil, diff --git a/notes/1.0.3/watch.md b/notes/1.0.3/watch.md new file mode 100644 index 000000000..ff751fdf9 --- /dev/null +++ b/notes/1.0.3/watch.md @@ -0,0 +1,26 @@ +### Fixes with compatibility implications + +### Improvements + +- Add `sbt.watch.mode` system property to allow switching back to old polling behaviour for watch. See below for more details. [#3597][3597] by [@stringbean][@stringbean] + +### Bug fixes + +#### Alternative watch mode + +sbt 1.0.0 introduced a new mechanism for watching for source changes based on the NIO `WatchService` in Java 1.7. On +some platforms (namely macOS) this has led to long delays before changes are picked up. An alternative `WatchService` +for these platforms is planned for sbt 1.1.0 ([#3527][3527]), in the meantime an option to select which watch service +has been added. + +The new `sbt.watch.mode` JVM flag has been added with the following supported values: + +- `polling`: (default for macOS) poll the filesystem for changes (mechanism used in sbt 0.13). +- `nio` (default for other platforms): use the NIO based `WatchService`. + +If you are experiencing long delays on a non-macOS machine then try adding `-Dsbt.watch.mode=polling` to your sbt +options. + +[@stringbean]: https://github.com/stringbean +[3527]: https://github.com/sbt/sbt/issues/3527 +[3597]: https://github.com/sbt/sbt/pull/3597