From 57e1044f5bcb52a30c5146fc09a7e40350fcfd81 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 18 Dec 2021 15:05:05 -0500 Subject: [PATCH 01/19] log4j 2.17.0 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 06bf9bbaf..23972722c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -124,7 +124,7 @@ object Dependencies { val scalaPar = "org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.0" // specify all of log4j modules to prevent misalignment - def log4jModule = (n: String) => "org.apache.logging.log4j" % n % "2.16.0" + def log4jModule = (n: String) => "org.apache.logging.log4j" % n % "2.17.0" val log4jApi = log4jModule("log4j-api") val log4jCore = log4jModule("log4j-core") val log4jSlf4jImpl = log4jModule("log4j-slf4j-impl") From df46c08051e9f8c887087d58482ef2905d796d11 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 18 Dec 2021 18:11:10 -0500 Subject: [PATCH 02/19] sbt 1.6.0-RC2 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index 218f45141..ea4654a73 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.0-RC1" +declare builtin_sbt_version="1.6.0-RC2" declare -a residual_args declare -a java_args declare -a scalac_args From 645cebccac46f49dd35e6c8ff583f11c8d398773 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Dec 2021 00:28:09 -0500 Subject: [PATCH 03/19] IO 1.6.0 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 23972722c..85dfa1ee2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,7 +12,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") // sbt modules - private val ioVersion = nightlyVersion.getOrElse("1.6.0-M2") + private val ioVersion = nightlyVersion.getOrElse("1.6.0") private val lmVersion = sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.6.0-M2") val zincVersion = nightlyVersion.getOrElse("1.6.0-M2") From 0f8ac0f543d812d7bea53b12011153130353fd73 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Dec 2021 01:44:00 -0500 Subject: [PATCH 04/19] Zinc 1.6.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 85dfa1ee2..d2a166720 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -14,8 +14,8 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.6.0") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.6.0-M2") - val zincVersion = nightlyVersion.getOrElse("1.6.0-M2") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.6.0") + val zincVersion = nightlyVersion.getOrElse("1.6.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 990fa9530f2f4cfe499f4fc54cc2cb4f179a78e3 Mon Sep 17 00:00:00 2001 From: gontard Date: Fri, 24 Dec 2021 16:12:37 +0100 Subject: [PATCH 05/19] Ensure sbtConfig argv does not need sbt in PATH Before, the BSP config .bsp/sbt.json generated by `sbt bspConfig` contained a command line which required the sbt binary in the PATH. This fix changes the nature of the -Dsbt.script option. It was an argument of the main class xsbt.boot.Boot, it's now a system property and thus it's used to launch the sbt server. Fixes https://github.com/sbt/sbt/issues/6760 --- .../scala/sbt/internal/bsp/BuildServerConnection.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala index 66ac7bdf0..fa7fce354 100644 --- a/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala +++ b/protocol/src/main/scala/sbt/internal/bsp/BuildServerConnection.scala @@ -49,9 +49,11 @@ object BuildServerConnection { "-Xmx100m", "-classpath", classPath, - "xsbt.boot.Boot", - "-bsp" - ) ++ sbtScript.orElse(sbtLaunchJar) + ) ++ + sbtScript ++ + Vector("xsbt.boot.Boot", "-bsp") ++ + (if (sbtScript.isEmpty) sbtLaunchJar else None) + val details = BspConnectionDetails(name, sbtVersion, bspVersion, languages, argv) val json = Converter.toJson(details).get IO.write(bspConnectionFile, CompactPrinter(json), append = false) From 544a935534975603cf698381ea5196364d234e98 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Dec 2021 01:48:14 -0500 Subject: [PATCH 06/19] Update banner --- main/src/main/scala/sbt/internal/Banner.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/Banner.scala b/main/src/main/scala/sbt/internal/Banner.scala index b43f811ad..0b5a25e71 100644 --- a/main/src/main/scala/sbt/internal/Banner.scala +++ b/main/src/main/scala/sbt/internal/Banner.scala @@ -16,7 +16,7 @@ private[sbt] object Banner { | - Improved JDK 17 support | - Improved Build Server Protocol (BSP) support | - Tab completion of global keys - |See https://eed3si9n.com/sbt-1.6.0-beta for full release notes. + |See https://eed3si9n.com/sbt-1.6.0 for full release notes. |Hide the banner for this release by running `skipBanner`. |""".stripMargin.linesIterator.mkString("\n")) case v if v.startsWith("1.4.0") => From 43088834d2e936f42830faf5b68c441b026ddb18 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Dec 2021 13:44:22 -0500 Subject: [PATCH 07/19] sbt 1.6.0 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index ea4654a73..e1219c287 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.0-RC2" +declare builtin_sbt_version="1.6.0" declare -a residual_args declare -a java_args declare -a scalac_args From d71a1fbdacd84a5609c17685c444dea9ee653bdd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 28 Dec 2021 23:07:39 -0500 Subject: [PATCH 08/19] log4j 2.17.1 Fixes CVE-2021-44832 https://logging.apache.org/log4j/2.x/security.html --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d2a166720..125d56457 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -124,7 +124,7 @@ object Dependencies { val scalaPar = "org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.0" // specify all of log4j modules to prevent misalignment - def log4jModule = (n: String) => "org.apache.logging.log4j" % n % "2.17.0" + def log4jModule = (n: String) => "org.apache.logging.log4j" % n % "2.17.1" val log4jApi = log4jModule("log4j-api") val log4jCore = log4jModule("log4j-core") val log4jSlf4jImpl = log4jModule("log4j-slf4j-impl") From 515993498d80eab063c39d37a6927a46040d93e1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 28 Dec 2021 23:45:04 -0500 Subject: [PATCH 09/19] Use lazy val --- main/src/main/scala/sbt/internal/SysProp.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index fbf0942b2..737b0b368 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -218,6 +218,6 @@ object SysProp { baseCache.getAbsoluteFile / "v1" } - val sbtCredentialsEnv: Option[Credentials] = + lazy val sbtCredentialsEnv: Option[Credentials] = sys.env.get("SBT_CREDENTIALS").map(raw => new FileCredentials(new File(raw))) } From a3610377d46b1ff09b1c44a1019dac71d8c8e113 Mon Sep 17 00:00:00 2001 From: Amina Adewusi Date: Fri, 21 Jan 2022 14:51:11 +0000 Subject: [PATCH 10/19] Remove scalacoption -S-X Fixes https://github.com/sbt/sbt/issues/6785. --- sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/sbt b/sbt index e1219c287..6d153b336 100755 --- a/sbt +++ b/sbt @@ -580,7 +580,6 @@ Usage: `basename "$0"` [options] -Dkey=val pass -Dkey=val directly to the java runtime -J-X pass option -X directly to the java runtime (-J is stripped) - -S-X add -X to sbt's scalacOptions (-S is stripped) In the case of duplicated or conflicting options, the order above shows precedence: JAVA_OPTS lowest, command line options highest. From f5fb537c6d565642cd65e0845f93466ddef212d4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 29 Dec 2021 00:18:51 -0500 Subject: [PATCH 11/19] sbt 1.6.1 --- sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt b/sbt index 6d153b336..07e3c0409 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.0" +declare builtin_sbt_version="1.6.1" declare -a residual_args declare -a java_args declare -a scalac_args From a549e79c1d2c80a443d544581eb52e4985a909bf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 31 Jan 2022 16:37:38 -0500 Subject: [PATCH 12/19] Throw when test framework cannot be loaded due to MatchError or NoClassDefFoundError Problem ------- In some situations like Dotty Community Build, sbt version is mechanically upgraded on an old commit without humans checking the log. For reasons we're not completely sure (likely change in ClassLoader structure) sbt 1.6.x started to fail to load test frameworks during tests, but since the failure of the test framework loading doesn't fail the task, this silently succeeded the builds. Solution -------- On MatchError and NoClassDefFound Error, rethrow the exception. Note that ClassNotFoundException is considered ok since we have predefined test frameworks listed in sbt, which often are not included in the users' classpath. --- build.sbt | 2 +- .../src/main/scala/sbt/TestFramework.scala | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/build.sbt b/build.sbt index e8c0a5d3b..edb4d4340 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.6.0-SNAPSHOT" + val v = "1.6.2-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index d7e057ac5..fe3f76196 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -49,12 +49,14 @@ final class TestFramework(val implClassNames: String*) extends Serializable { ): Option[Framework] = { def logError(e: Throwable): Option[Framework] = { log.error( - s"Error loading test framework ($e). This usually means that you are" - + " using a layered class loader that cannot reach the sbt.testing.Framework class." - + " The most likely cause is that your project has a runtime dependency on your" - + " test framework, e.g. scalatest. To fix this, you can try to set\n" - + "Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary\nor\n" - + "Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat" + s"""Error loading test framework ($e). + |This often means that you are using a layered class loader that cannot reach the sbt.testing.Framework class. + |The most likely cause is that your project has a runtime dependency on your + |test framework, e.g. ScalaTest. To fix this, you can try to set + | + | Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary + |or + | Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat""".stripMargin ) None } @@ -66,8 +68,12 @@ final class TestFramework(val implClassNames: String*) extends Serializable { case oldFramework: OldFramework => new FrameworkWrapper(oldFramework) }) } catch { - case e: NoClassDefFoundError => logError(e) - case e: MatchError => logError(e) + case e: NoClassDefFoundError => + logError(e) + throw e + case e: MatchError => + logError(e) + throw e case _: ClassNotFoundException => log.debug("Framework implementation '" + head + "' not present.") createFramework(loader, log, tail) From 4f9fe2af6446d75aeb94f88c2738360e773c8aea Mon Sep 17 00:00:00 2001 From: tpetillot Date: Wed, 26 Jan 2022 16:19:15 +0100 Subject: [PATCH 13/19] fix: propagate `InterruptedException` from JLine.readLine Motivation: Cannot exit from InteractionService.readLine Modification: Remove try/catch of InterruptedException mapped to None in JLine.readLine --- .../src/main/scala/sbt/internal/util/LineReader.scala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) 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 d52903d87..fbc86b725 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 @@ -178,13 +178,7 @@ abstract class JLine extends LineReader { protected[this] lazy val in: InputStream = Terminal.wrappedSystemIn override def readLine(prompt: String, mask: Option[Char] = None): Option[String] = - try { - unsynchronizedReadLine(prompt, mask) - } catch { - case _: InterruptedException => - // println("readLine: InterruptedException") - Option("") - } + unsynchronizedReadLine(prompt, mask) private[this] def unsynchronizedReadLine(prompt: String, mask: Option[Char]): Option[String] = readLineWithHistory(prompt, mask) map { x => From 761ad142673ce45a5768eb077118bcb1c752da83 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 31 Jan 2022 22:00:54 -0500 Subject: [PATCH 14/19] Make License object available Fixes #1937 Ref https://github.com/sbt/librarymanagement/pull/395 --- project/Dependencies.scala | 2 +- sbt-app/src/main/scala/sbt/Import.scala | 1 + sbt-app/src/sbt-test/dependency-management/artifact/build.sbt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 125d56457..84413f9d7 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -14,7 +14,7 @@ object Dependencies { // sbt modules private val ioVersion = nightlyVersion.getOrElse("1.6.0") private val lmVersion = - sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.6.0") + sys.props.get("sbt.build.lm.version").orElse(nightlyVersion).getOrElse("1.6.1") val zincVersion = nightlyVersion.getOrElse("1.6.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/sbt-app/src/main/scala/sbt/Import.scala b/sbt-app/src/main/scala/sbt/Import.scala index b71e855df..548e571a4 100644 --- a/sbt-app/src/main/scala/sbt/Import.scala +++ b/sbt-app/src/main/scala/sbt/Import.scala @@ -297,6 +297,7 @@ trait Import { type IvyScala = sbt.librarymanagement.ScalaModuleInfo val JCenterRepository = sbt.librarymanagement.Resolver.JCenterRepository val JavaNet2Repository = sbt.librarymanagement.Resolver.JavaNet2Repository + val License = sbt.librarymanagement.License type LogicalClock = sbt.librarymanagement.LogicalClock val LogicalClock = sbt.librarymanagement.LogicalClock type MakePomConfiguration = sbt.librarymanagement.MakePomConfiguration diff --git a/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt b/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt index d0d5afc46..e4ffeae52 100644 --- a/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt +++ b/sbt-app/src/sbt-test/dependency-management/artifact/build.sbt @@ -11,6 +11,7 @@ ThisBuild / version := "0.1.0-SNAPSHOT" ThisBuild / organization := "com.example" ThisBuild / organizationName := "example" ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache" +ThisBuild / licenses := List(License.Apache2) lazy val Dev = config("dev").extend(Compile) .describedAs("Dependencies required for development environments") From ed022a70ace736b645e375a8dfd261d342a3f4f3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 31 Jan 2022 23:25:20 -0500 Subject: [PATCH 15/19] sbt 1.6.2 --- build.sbt | 2 +- sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index edb4d4340..a33ac73ae 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ import scala.util.Try // ThisBuild settings take lower precedence, // but can be shared across the multi projects. ThisBuild / version := { - val v = "1.6.2-SNAPSHOT" + val v = "1.6.3-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / version2_13 := "2.0.0-SNAPSHOT" diff --git a/sbt b/sbt index 07e3c0409..c7c45a3a2 100755 --- a/sbt +++ b/sbt @@ -1,7 +1,7 @@ #!/usr/bin/env bash set +e -declare builtin_sbt_version="1.6.1" +declare builtin_sbt_version="1.6.2" declare -a residual_args declare -a java_args declare -a scalac_args From ca8fd354bd7da44bc86260e444a1cd4a041a1350 Mon Sep 17 00:00:00 2001 From: Amina Adewusi Date: Fri, 4 Feb 2022 17:52:39 +0000 Subject: [PATCH 16/19] Fixes parsing command args quote problem Fixes #6802. --- .../main/scala/sbt/internal/util/complete/Parsers.scala | 7 ++++++- internal/util-complete/src/test/scala/ParserTest.scala | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) 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 884aecc9a..15a1f2dcb 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 @@ -202,7 +202,7 @@ trait Parsers { * Parses a potentially quoted String value. The value may be verbatim quoted ([[StringVerbatim]]), * quoted with interpreted escapes ([[StringEscapable]]), or unquoted ([[NotQuoted]]). */ - lazy val StringBasic = StringVerbatim | StringEscapable | NotQuoted + lazy val StringBasic = StringVerbatim | StringEscapable | NotQuoted | NotQuotedThenQuoted /** * Parses a verbatim quoted String value, discarding the quotes in the result. This kind of quoted text starts with triple quotes `"""` @@ -270,6 +270,11 @@ trait Parsers { /** Parses an unquoted, non-empty String value that cannot start with a double quote and cannot contain whitespace.*/ lazy val NotQuoted = (NotDQuoteSpaceClass ~ OptNotSpace) map { case (c, s) => c.toString + s } + /** Parses a non-empty String value that cannot start with a double quote, but includes double quotes.*/ + lazy val NotQuotedThenQuoted = (NotQuoted ~ StringEscapable) map { + case (s1, s2) => s"""$s1\"$s2\"""" + } + /** * Applies `rep` zero or more times, separated by `sep`. * The result is the (possibly empty) sequence of results from the multiple `rep` applications. The `sep` results are discarded. diff --git a/internal/util-complete/src/test/scala/ParserTest.scala b/internal/util-complete/src/test/scala/ParserTest.scala index 49f99056f..4694f974a 100644 --- a/internal/util-complete/src/test/scala/ParserTest.scala +++ b/internal/util-complete/src/test/scala/ParserTest.scala @@ -119,6 +119,8 @@ object ParserTest extends Properties("Completing Parser") { property("repeatDep requires at least one token") = !matches(repeat, "") property("repeatDep accepts one token") = matches(repeat, colors.toSeq.head) property("repeatDep accepts two tokens") = matches(repeat, colors.toSeq.take(2).mkString(" ")) + property("parses string that doesn't start with quotes, but includes quotes within it") = + matches(StringBasic, "-Dsilicon:z3ConfigArgs=\"model=true model_validate=true\"") } object ParserExample { val ws = charClass(_.isWhitespace, "whitespace").+ From 23b50688ba7b50861544bc09a07a2f278f23ac19 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Fri, 4 Mar 2022 10:53:25 +0100 Subject: [PATCH 17/19] feat: add optional framework field to the bsp --- main/src/main/scala/sbt/Keys.scala | 2 +- .../internal/server/BuildServerProtocol.scala | 35 +++++++++++++------ .../internal/bsp/ScalaTestClassesItem.scala | 23 ++++++++---- .../codec/ScalaTestClassesItemFormats.scala | 4 ++- protocol/src/main/contraband/bsp.contra | 3 ++ 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 1a248b1df..2270ee573 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -419,7 +419,7 @@ object Keys { val bspBuildTargetScalacOptions = inputKey[Unit]("").withRank(DTask) val bspBuildTargetScalacOptionsItem = taskKey[ScalacOptionsItem]("").withRank(DTask) val bspScalaTestClasses = inputKey[Unit]("Corresponds to buildTarget/scalaTestClasses request").withRank(DTask) - val bspScalaTestClassesItem = taskKey[ScalaTestClassesItem]("").withRank(DTask) + val bspScalaTestClassesItem = taskKey[Seq[ScalaTestClassesItem]]("").withRank(DTask) val bspScalaMainClasses = inputKey[Unit]("Corresponds to buildTarget/scalaMainClasses request").withRank(DTask) val bspScalaMainClassesItem = taskKey[ScalaMainClassesItem]("").withRank(DTask) val bspReporter = taskKey[BuildServerReporter]("").withRank(DTask) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index b5006aabb..d289884bf 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -242,7 +242,7 @@ object BuildServerProtocol { val filter = ScopeFilter.in(workspace.scopes.values.toList) Def.task { val items = bspScalaTestClassesItem.result.all(filter).value - val successfulItems = anyOrThrow(items) + val successfulItems = anyOrThrow(items).flatten.toVector val result = ScalaTestClassesResult(successfulItems.toVector, None) s.respondEvent(result) } @@ -840,15 +840,30 @@ object BuildServerProtocol { } } - private def scalaTestClassesTask: Initialize[Task[ScalaTestClassesItem]] = Def.task { - val testClasses = Keys.definedTests.?.value - .getOrElse(Seq.empty) - .map(_.name) - .toVector - ScalaTestClassesItem( - bspTargetIdentifier.value, - testClasses - ) + private def scalaTestClassesTask: Initialize[Task[Seq[ScalaTestClassesItem]]] = Def.task { + Keys.definedTests.?.value match { + case None => Vector.empty + case Some(definitions) => + val fingerprints = Keys.loadedTestFrameworks.?.value + .getOrElse(Map.empty) + .values + .flatMap { framework => + framework.fingerprints().map(fingerprint => (fingerprint, framework)) + } + .toMap + + definitions + .groupBy(defn => fingerprints.get(defn.fingerprint)) + .map { + case (framework, definitions) => + ScalaTestClassesItem( + bspTargetIdentifier.value, + definitions.map(_.name).toVector, + framework.map(_.name()) + ) + } + .toSeq + } } private def scalaMainClassesTask: Initialize[Task[ScalaMainClassesItem]] = Def.task { diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaTestClassesItem.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaTestClassesItem.scala index 210e8cc30..e274fda16 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaTestClassesItem.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/ScalaTestClassesItem.scala @@ -7,25 +7,27 @@ package sbt.internal.bsp /** * @param target The build target that contains the test classes. * @param classes The fully qualified names of the test classes in this target + * @param framework The name of the test framework used in test classes. */ final class ScalaTestClassesItem private ( val target: sbt.internal.bsp.BuildTargetIdentifier, - val classes: Vector[String]) extends Serializable { + val classes: Vector[String], + val framework: Option[String]) extends Serializable { override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: ScalaTestClassesItem => (this.target == x.target) && (this.classes == x.classes) + case x: ScalaTestClassesItem => (this.target == x.target) && (this.classes == x.classes) && (this.framework == x.framework) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaTestClassesItem".##) + target.##) + classes.##) + 37 * (37 * (37 * (37 * (17 + "sbt.internal.bsp.ScalaTestClassesItem".##) + target.##) + classes.##) + framework.##) } override def toString: String = { - "ScalaTestClassesItem(" + target + ", " + classes + ")" + "ScalaTestClassesItem(" + target + ", " + classes + ", " + framework + ")" } - private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, classes: Vector[String] = classes): ScalaTestClassesItem = { - new ScalaTestClassesItem(target, classes) + private[this] def copy(target: sbt.internal.bsp.BuildTargetIdentifier = target, classes: Vector[String] = classes, framework: Option[String] = framework): ScalaTestClassesItem = { + new ScalaTestClassesItem(target, classes, framework) } def withTarget(target: sbt.internal.bsp.BuildTargetIdentifier): ScalaTestClassesItem = { copy(target = target) @@ -33,8 +35,15 @@ final class ScalaTestClassesItem private ( def withClasses(classes: Vector[String]): ScalaTestClassesItem = { copy(classes = classes) } + def withFramework(framework: Option[String]): ScalaTestClassesItem = { + copy(framework = framework) + } + def withFramework(framework: String): ScalaTestClassesItem = { + copy(framework = Option(framework)) + } } object ScalaTestClassesItem { - def apply(target: sbt.internal.bsp.BuildTargetIdentifier, classes: Vector[String]): ScalaTestClassesItem = new ScalaTestClassesItem(target, classes) + def apply(target: sbt.internal.bsp.BuildTargetIdentifier, classes: Vector[String], framework: Option[String]): ScalaTestClassesItem = new ScalaTestClassesItem(target, classes, framework) + def apply(target: sbt.internal.bsp.BuildTargetIdentifier, classes: Vector[String], framework: String): ScalaTestClassesItem = new ScalaTestClassesItem(target, classes, Option(framework)) } diff --git a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesItemFormats.scala b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesItemFormats.scala index a079301b3..1353a0b41 100644 --- a/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesItemFormats.scala +++ b/protocol/src/main/contraband-scala/sbt/internal/bsp/codec/ScalaTestClassesItemFormats.scala @@ -13,8 +13,9 @@ implicit lazy val ScalaTestClassesItemFormat: JsonFormat[sbt.internal.bsp.ScalaT unbuilder.beginObject(__js) val target = unbuilder.readField[sbt.internal.bsp.BuildTargetIdentifier]("target") val classes = unbuilder.readField[Vector[String]]("classes") + val framework = unbuilder.readField[Option[String]]("framework") unbuilder.endObject() - sbt.internal.bsp.ScalaTestClassesItem(target, classes) + sbt.internal.bsp.ScalaTestClassesItem(target, classes, framework) case None => deserializationError("Expected JsObject but found None") } @@ -23,6 +24,7 @@ implicit lazy val ScalaTestClassesItemFormat: JsonFormat[sbt.internal.bsp.ScalaT builder.beginObject() builder.addField("target", obj.target) builder.addField("classes", obj.classes) + builder.addField("framework", obj.framework) builder.endObject() } } diff --git a/protocol/src/main/contraband/bsp.contra b/protocol/src/main/contraband/bsp.contra index 01b3a450f..62438cff0 100644 --- a/protocol/src/main/contraband/bsp.contra +++ b/protocol/src/main/contraband/bsp.contra @@ -636,6 +636,9 @@ type ScalaTestClassesItem { ## The fully qualified names of the test classes in this target classes: [String] + + ## The name of the test framework used in test classes. + framework: String } ## Scala Main Class Request From 1396e1605d04dc53b91e41c1cc1be2f339e310ec Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 8 Mar 2022 18:19:20 +0100 Subject: [PATCH 18/19] Try fix CI: Build and test (6) --- project/Dependencies.scala | 14 +++++++------- project/plugins.sbt | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 84413f9d7..ae0d47987 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -69,13 +69,13 @@ object Dependencies { def addSbtLmIvy = addSbtModule(sbtLmPath, "lmIvy", libraryManagementIvy) def addSbtLmIvyTest = addSbtModule(sbtLmPath, "lmIvy", libraryManagementIvy, Some(Test)) - def addSbtCompilerInterface = addSbtModule(sbtZincPath, "compilerInterfaceJVM", compilerInterface) - def addSbtCompilerClasspath = addSbtModule(sbtZincPath, "zincClasspathJVM2_12", compilerClasspath) - def addSbtCompilerApiInfo = addSbtModule(sbtZincPath, "zincApiInfoJVM2_12", compilerApiInfo) - def addSbtCompilerBridge = addSbtModule(sbtZincPath, "compilerBridgeJVM2_12", compilerBridge) - def addSbtZinc = addSbtModule(sbtZincPath, "zincJVM2_12", zinc) - def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompileJVM2_12", zincCompile) - def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCoreJVM2_12", zincCompileCore) + def addSbtCompilerInterface = addSbtModule(sbtZincPath, "compilerInterface", compilerInterface) + def addSbtCompilerClasspath = addSbtModule(sbtZincPath, "zincClasspath", compilerClasspath) + def addSbtCompilerApiInfo = addSbtModule(sbtZincPath, "zincApiInfo", compilerApiInfo) + def addSbtCompilerBridge = addSbtModule(sbtZincPath, "compilerBridge2_12", compilerBridge) + def addSbtZinc = addSbtModule(sbtZincPath, "zinc", zinc) + def addSbtZincCompile = addSbtModule(sbtZincPath, "zincCompile", zincCompile) + def addSbtZincCompileCore = addSbtModule(sbtZincPath, "zincCompileCore", zincCompileCore) val lmCoursierShaded = "io.get-coursier" %% "lm-coursier-shaded" % "2.0.10" diff --git a/project/plugins.sbt b/project/plugins.sbt index 7f7e8fa9a..00c24984e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,9 +6,9 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.3.0") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") -addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2") +addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.5") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("com.swoval" % "sbt-java-format" % "0.3.1") addDependencyTreePlugin From ce978a19ed39bc69e7b0c3debeb2330f639011f8 Mon Sep 17 00:00:00 2001 From: Kamil Podsiadlo Date: Thu, 10 Mar 2022 19:56:49 +0100 Subject: [PATCH 19/19] tests: add test case for framework field in scala test classes request --- .../internal/server/BuildServerProtocol.scala | 32 ++++++++----------- .../test/scala/testpkg/BuildServerTest.scala | 3 +- .../src/main/scala/sbt/TestFramework.scala | 9 ++++-- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index d289884bf..0c6655e2d 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -39,6 +39,7 @@ import scala.collection.mutable import scala.util.control.NonFatal import scala.util.{ Failure, Success, Try } import scala.annotation.nowarn +import sbt.testing.Framework object BuildServerProtocol { import sbt.internal.bsp.codec.JsonProtocol._ @@ -844,25 +845,20 @@ object BuildServerProtocol { Keys.definedTests.?.value match { case None => Vector.empty case Some(definitions) => - val fingerprints = Keys.loadedTestFrameworks.?.value - .getOrElse(Map.empty) - .values - .flatMap { framework => - framework.fingerprints().map(fingerprint => (fingerprint, framework)) - } - .toMap + val frameworks: Seq[Framework] = Keys.loadedTestFrameworks.?.value + .map(_.values.toSeq) + .getOrElse(Seq.empty) - definitions - .groupBy(defn => fingerprints.get(defn.fingerprint)) - .map { - case (framework, definitions) => - ScalaTestClassesItem( - bspTargetIdentifier.value, - definitions.map(_.name).toVector, - framework.map(_.name()) - ) - } - .toSeq + val grouped = TestFramework.testMap(frameworks, definitions) + + grouped.map { + case (framework, definitions) => + ScalaTestClassesItem( + bspTargetIdentifier.value, + definitions.map(_.name).toVector, + framework.name() + ) + }.toSeq } } diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index 5aa231752..9cbe43980 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -308,7 +308,8 @@ object BuildServerTest extends AbstractServerTest { assert(svr.waitForString(10.seconds) { s => (s contains """"id":"72"""") && (s contains """"tests.FailingTest"""") && - (s contains """"tests.PassingTest"""") + (s contains """"tests.PassingTest"""") && + (s contains """"framework":"ScalaTest"""") }) } diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index fe3f76196..cb89dd5f4 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -231,21 +231,26 @@ object TestFramework { ): Vector[(String, TestFunction)] = for (d <- inputs; act <- mapped.get(d.name)) yield (d.name, act) - private[this] def testMap( + def testMap( frameworks: Seq[Framework], tests: Seq[TestDefinition] ): Map[Framework, Set[TestDefinition]] = { import scala.collection.mutable.{ HashMap, HashSet, Set } val map = new HashMap[Framework, Set[TestDefinition]] + def assignTest(test: TestDefinition): Unit = { def isTestForFramework(framework: Framework) = getFingerprints(framework).exists { t => matches(t, test.fingerprint) } - for (framework <- frameworks.find(isTestForFramework)) + + frameworks.find(isTestForFramework).foreach { framework => map.getOrElseUpdate(framework, new HashSet[TestDefinition]) += test + } } + if (frameworks.nonEmpty) for (test <- tests) assignTest(test) + map.toMap.mapValues(_.toSet).toMap }