From bc3acd3bffdb6aceffca32c05ee225969d15c3b1 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 14 Nov 2023 11:42:51 +0100 Subject: [PATCH 1/8] Bump sbt-scalafmt to solve classpath corruption --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index f9d07a141..7078f1435 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ scalacOptions ++= Seq("-feature", "-language:postfixOps", "-Ywarn-unused:_,-impo 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.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.3") addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.5") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0") From 73e3b43683df4a80d65b838dbe4c39a925ee9ce7 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 14 Nov 2023 11:43:12 +0100 Subject: [PATCH 2/8] Introduce util-core to cross-compile util-logging --- build.sbt | 18 +++++++-- .../sbt/internal/util/StringTypeTag.scala | 38 +++++++++++++++++++ .../sbt/internal/util}/StringTypeTag.scala | 2 +- .../main/scala/sbt/internal/util/Util.scala | 9 ----- .../sbt/internal/util/ManagedLogger.scala | 8 +--- .../src/main/scala/sbt/util/LogExchange.scala | 22 +++-------- 6 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala rename {core-macros/src/main/scala/sbt/internal/util/appmacro => internal/util-core/src/main/scala-3/sbt/internal/util}/StringTypeTag.scala (96%) rename {util-collection => internal/util-core}/src/main/scala/sbt/internal/util/Util.scala (87%) diff --git a/build.sbt b/build.sbt index d23046faf..90d63ab78 100644 --- a/build.sbt +++ b/build.sbt @@ -257,12 +257,11 @@ lazy val bundledLauncherProj = /* ** subproject declarations ** */ val collectionProj = (project in file("util-collection")) - .dependsOn(utilPosition) + .dependsOn(utilPosition, utilCore) .settings( name := "Collections", testedBaseSettings, utilCommonSettings, - Util.keywordsSettings, libraryDependencies ++= Seq(sjsonNewScalaJson.value), libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, major)) if major <= 12 => Seq() @@ -335,9 +334,22 @@ lazy val utilPosition = (project in file("internal") / "util-position") utilMimaSettings, ) +lazy val utilCore = project.in(file("internal") / "util-core") + .settings( + utilCommonSettings, + name := "Util Core", + libraryDependencies ++= { + if (scalaBinaryVersion.value.startsWith("2")) { + Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value) + } else Seq.empty + }, + Util.keywordsSettings, + utilMimaSettings + ) + lazy val utilLogging = (project in file("internal") / "util-logging") .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(utilInterface, collectionProj, coreMacrosProj) + .dependsOn(utilInterface, utilCore) .settings( utilCommonSettings, name := "Util Logging", diff --git a/internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala b/internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala new file mode 100644 index 000000000..d9abff119 --- /dev/null +++ b/internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala @@ -0,0 +1,38 @@ +/* + * sbt + * Copyright 2023, Scala center + * Copyright 2011 - 2022, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal.util + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox + +/** This is used to carry type information in JSON. */ +final case class StringTypeTag[A](key: String) { + override def toString: String = key +} + +object StringTypeTag { + + /** Generates a StringTypeTag for any type at compile time. */ + implicit def fast[A]: StringTypeTag[A] = macro impl[A] + + def impl[A: c.WeakTypeTag](c: blackbox.Context): c.Tree = { + import c.universe._ + val tpe = weakTypeOf[A] + def typeToString(tpe: Type): String = tpe match { + case TypeRef(_, sym, args) if args.nonEmpty => + val typeCon = tpe.typeSymbol.fullName + val typeArgs = args map typeToString + s"""$typeCon[${typeArgs.mkString(",")}]""" + case _ => tpe.toString + } + + val key = Literal(Constant(typeToString(tpe))) + q"new sbt.internal.util.StringTypeTag[$tpe]($key)" + } +} diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/StringTypeTag.scala b/internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala similarity index 96% rename from core-macros/src/main/scala/sbt/internal/util/appmacro/StringTypeTag.scala rename to internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala index a144923a9..4cc8c2981 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/StringTypeTag.scala +++ b/internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala @@ -5,7 +5,7 @@ * Licensed under Apache License 2.0 (see LICENSE) */ -package sbt.internal.util.appmacro +package sbt.internal.util final class StringTypeTag[A](val key: String): override def toString(): String = key diff --git a/util-collection/src/main/scala/sbt/internal/util/Util.scala b/internal/util-core/src/main/scala/sbt/internal/util/Util.scala similarity index 87% rename from util-collection/src/main/scala/sbt/internal/util/Util.scala rename to internal/util-core/src/main/scala/sbt/internal/util/Util.scala index 643f52ea7..8dbfb60f4 100644 --- a/util-collection/src/main/scala/sbt/internal/util/Util.scala +++ b/internal/util-core/src/main/scala/sbt/internal/util/Util.scala @@ -9,15 +9,9 @@ package sbt.internal.util import java.util.Locale -import scala.reflect.macros.blackbox -import scala.language.experimental.macros - object Util { def makeList[T](size: Int, value: T): List[T] = List.fill(size)(value) - // def separateE[A, B](ps: Seq[Either[A, B]]): (Seq[A], Seq[B]) = - // separate(ps)(Types.idFun) - def separate[T, A, B](ps: Seq[T])(f: T => Either[A, B]): (Seq[A], Seq[B]) = { val (a, b) = ps.foldLeft((Nil: Seq[A], Nil: Seq[B]))((xs, y) => prependEither(xs, f(y))) (a.reverse, b.reverse) @@ -74,7 +68,4 @@ object Util { implicit class AnyOps[A](private val value: A) extends AnyVal { def some: Option[A] = (Some(value): Option[A]) } - // class Macro(val c: blackbox.Context) { - // def ignore(f: c.Tree): c.Expr[Unit] = c.universe.reify({ c.Expr[Any](f).splice; () }) - // } } diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala index fd611e655..3c9d90643 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala @@ -9,9 +9,8 @@ package sbt.internal.util import sbt.internal.util.codec.JsonProtocol._ import sbt.util._ -import scala.reflect.runtime.universe.TypeTag import sjsonnew.JsonFormat -import sbt.internal.util.appmacro.StringTypeTag +import sbt.internal.util.StringTypeTag private[sbt] trait MiniLogger { def log[T](level: Level.Value, message: ObjectEvent[T]): Unit @@ -44,10 +43,7 @@ class ManagedLogger( // send special event for success since it's not a real log level override def success(message: => String): Unit = { if (terminal.fold(true)(_.isSuccessEnabled)) { - infoEvent[SuccessEvent](SuccessEvent(message))( - implicitly[JsonFormat[SuccessEvent]], - StringTypeTag[SuccessEvent], - ) + infoEvent[SuccessEvent](SuccessEvent(message)) } } diff --git a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala index 507b7674a..5d63b2418 100644 --- a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala +++ b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala @@ -12,7 +12,7 @@ import org.apache.logging.log4j.core.layout.PatternLayout import org.apache.logging.log4j.core.{ LoggerContext => XLoggerContext } import org.apache.logging.log4j.{ LogManager => XLogManager } import sbt.internal.util.{ Appender, ManagedLogger, TraceEvent, SuccessEvent, Util } -import sbt.internal.util.appmacro.StringTypeTag +import sbt.internal.util.StringTypeTag import java.util.concurrent.ConcurrentHashMap import scala.collection.concurrent @@ -44,23 +44,14 @@ sealed abstract class LogExchange { () } - // Construct these StringTypeTags manually, because they're used at the very startup of sbt - // and we'll try not to initialize the universe by using the StringTypeTag.apply that requires a TypeTag - // A better long-term solution could be to make StringTypeTag.apply a macro. - lazy val stringTypeTagThrowable = StringTypeTag.manually[Throwable]("java.lang.Throwable") - lazy val stringTypeTagTraceEvent = - StringTypeTag.manually[TraceEvent]("sbt.internal.util.TraceEvent") - lazy val stringTypeTagSuccessEvent = - StringTypeTag.manually[SuccessEvent]("sbt.internal.util.SuccessEvent") - private[sbt] def initStringCodecs(): Unit = { import sbt.internal.util.codec.SuccessEventShowLines._ import sbt.internal.util.codec.ThrowableShowLines._ import sbt.internal.util.codec.TraceEventShowLines._ - registerStringCodecByStringTypeTag(stringTypeTagThrowable) - registerStringCodecByStringTypeTag(stringTypeTagTraceEvent) - registerStringCodecByStringTypeTag(stringTypeTagSuccessEvent) + registerStringCodec[Throwable] + registerStringCodec[TraceEvent] + registerStringCodec[SuccessEvent] } // This is a dummy layout to avoid casting error during PatternLayout.createDefaultLayout() @@ -86,11 +77,8 @@ sealed abstract class LogExchange { stringCodecs.getOrElseUpdate(tag, v).asInstanceOf[ShowLines[A]] private[sbt] def registerStringCodec[A: ShowLines: StringTypeTag]: Unit = { - registerStringCodecByStringTypeTag(implicitly[StringTypeTag[A]]) - } - - private[sbt] def registerStringCodecByStringTypeTag[A: ShowLines](tag: StringTypeTag[A]): Unit = { val ev = implicitly[ShowLines[A]] + val tag = implicitly[StringTypeTag[A]] val _ = getOrElseUpdateStringCodec(tag.key, ev) } From eba41fb3b01be1b4255e6443e321cc5a249f6823 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 14 Nov 2023 11:45:09 +0100 Subject: [PATCH 3/8] Fix util-cache cross-compilation --- util-cache/src/main/scala/sbt/util/FileInfo.scala | 2 +- util-cache/src/main/scala/sbt/util/Input.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/util-cache/src/main/scala/sbt/util/FileInfo.scala b/util-cache/src/main/scala/sbt/util/FileInfo.scala index f4351f031..3fbb8de6f 100644 --- a/util-cache/src/main/scala/sbt/util/FileInfo.scala +++ b/util-cache/src/main/scala/sbt/util/FileInfo.scala @@ -64,7 +64,7 @@ final case class FilesInfo[F <: FileInfo] private[sbt] (files: Set[F]) object FilesInfo { def empty[F <: FileInfo]: FilesInfo[F] = FilesInfo(Set.empty[F]) - given format[F <: FileInfo: JsonFormat]: JsonFormat[FilesInfo[F]] = + implicit def format[F <: FileInfo: JsonFormat]: JsonFormat[FilesInfo[F]] = projectFormat(_.files, (fs: Set[F]) => FilesInfo(fs)) def full: FileInfo.Style = FileInfo.full diff --git a/util-cache/src/main/scala/sbt/util/Input.scala b/util-cache/src/main/scala/sbt/util/Input.scala index 1f447265f..3d7438b9e 100644 --- a/util-cache/src/main/scala/sbt/util/Input.scala +++ b/util-cache/src/main/scala/sbt/util/Input.scala @@ -30,8 +30,9 @@ class PlainInput[J: IsoString](input: InputStream, converter: SupportConverter[J val bufferSize = 1024 val buffer = new Array[Char](bufferSize) var read = 0 - while { read = reader.read(buffer, 0, bufferSize); read != -1 } do + while ({ read = reader.read(buffer, 0, bufferSize); read != -1 }) { builder.appendAll(buffer, 0, read) + } builder.toString() } From 1f33b27b0353e918a8630fcc660e2acdbc728c85 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 14 Nov 2023 12:12:34 +0100 Subject: [PATCH 4/8] Deactivate cross-compilation except for utils Lower util projects are used by LM and Zinc --- build.sbt | 34 ++++++-------- .../util/appmacro}/StringTypeTag.scala | 4 +- .../util/{ => appmacro}/StringTypeTag.scala | 2 +- .../sbt/internal/util/ManagedLogger.scala | 2 +- .../src/main/scala/sbt/util/LogExchange.scala | 2 +- .../src/test/scala/LogExchangeSpec.scala | 44 ------------------- .../src/test/scala/ManagedLoggerSpec.scala | 2 +- 7 files changed, 19 insertions(+), 71 deletions(-) rename internal/util-core/src/main/{scala-2.13/sbt/internal/util => scala-2/sbt/internal/util/appmacro}/StringTypeTag.scala (91%) rename internal/util-core/src/main/scala-3/sbt/internal/util/{ => appmacro}/StringTypeTag.scala (96%) delete mode 100644 internal/util-logging/src/test/scala/LogExchangeSpec.scala diff --git a/build.sbt b/build.sbt index 90d63ab78..e9448bcb4 100644 --- a/build.sbt +++ b/build.sbt @@ -98,7 +98,6 @@ def commonBaseSettings: Seq[Setting[_]] = Def.settings( (Compile / unmanagedSources / inputFileStamps).dependsOn(Compile / javafmtOnCompile).value, Test / unmanagedSources / inputFileStamps := (Test / unmanagedSources / inputFileStamps).dependsOn(Test / javafmtOnCompile).value, - crossScalaVersions := List(scala212, scala213), Test / publishArtifact := false, run / fork := true, ) @@ -112,8 +111,11 @@ def commonSettings: Seq[Setting[_]] = } } } -def utilCommonSettings: Seq[Setting[_]] = - baseSettings :+ (crossScalaVersions := (scala212 :: scala213 :: Nil)) + +def utilCommonSettings: Seq[Setting[_]] = Def.settings( + baseSettings, + crossScalaVersions := Seq(scala212, scala213, scala3) +) def minimalSettings: Seq[Setting[_]] = commonSettings ++ customCommands ++ @@ -261,7 +263,7 @@ val collectionProj = (project in file("util-collection")) .settings( name := "Collections", testedBaseSettings, - utilCommonSettings, + baseSettings, libraryDependencies ++= Seq(sjsonNewScalaJson.value), libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, major)) if major <= 12 => Seq() @@ -308,8 +310,7 @@ val logicProj = (project in file("internal") / "util-logic") // the analysis compiler phases and passed back to sbt. The API structures are defined in a simple // format from which Java sources are generated by the datatype generator Projproject lazy val utilInterface = (project in file("internal") / "util-interface").settings( - utilCommonSettings, - crossScalaVersions := List(scala212), + baseSettings, javaOnlySettings, crossPaths := false, autoScalaLibrary := false, @@ -334,7 +335,8 @@ lazy val utilPosition = (project in file("internal") / "util-position") utilMimaSettings, ) -lazy val utilCore = project.in(file("internal") / "util-core") +lazy val utilCore = project + .in(file("internal") / "util-core") .settings( utilCommonSettings, name := "Util Core", @@ -517,7 +519,6 @@ lazy val testingProj = (project in file("testing")) lazy val testAgentProj = (project in file("testing") / "agent") .settings( minimalSettings, - crossScalaVersions := Seq(baseScalaVersion), crossPaths := false, autoScalaLibrary := false, Compile / doc / javacOptions := Nil, @@ -607,7 +608,6 @@ lazy val scriptedSbtReduxProj = (project in file("scripted-sbt-redux")) .dependsOn(sbtProj % "compile;test->test", commandProj, utilLogging, utilScripted) .settings( baseSettings, - crossScalaVersions := Seq(baseScalaVersion), name := "Scripted sbt Redux", libraryDependencies ++= Seq(launcherInterface % "provided"), mimaSettings, @@ -619,7 +619,6 @@ lazy val scriptedSbtOldProj = (project in file("scripted-sbt-old")) .dependsOn(scriptedSbtReduxProj) .settings( baseSettings, - crossScalaVersions := Seq(baseScalaVersion), name := "Scripted sbt", mimaSettings, mimaBinaryIssueFilters ++= Seq( @@ -647,7 +646,6 @@ lazy val dependencyTreeProj = (project in file("dependency-tree")) .settings( sbtPlugin := true, baseSettings, - crossScalaVersions := Seq(baseScalaVersion), name := "sbt-dependency-tree", publishMavenStyle := true, // mimaSettings, @@ -805,7 +803,7 @@ lazy val commandProj = (project in file("main-command")) lazy val coreMacrosProj = (project in file("core-macros")) .dependsOn(collectionProj) .settings( - testedBaseSettings :+ (crossScalaVersions := (scala212 :: scala213 :: Nil)), + testedBaseSettings, name := "Core Macros", SettingKey[Boolean]("exportPipelining") := false, mimaSettings, @@ -976,7 +974,6 @@ lazy val sbtProj = (project in file("sbt-app")) if (scalaVersion.value == baseScalaVersion) version.value else version2_13.value }, - crossScalaVersions := Seq(baseScalaVersion), crossPaths := false, crossTarget := { target.value / scalaVersion.value }, javaOptions ++= Seq("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"), @@ -1002,7 +999,6 @@ lazy val serverTestProj = (project in file("server-test")) .dependsOn(sbtProj % "compile->test", scriptedSbtReduxProj % "compile->test") .settings( testedBaseSettings, - crossScalaVersions := Seq(baseScalaVersion), bspEnabled := false, publish / skip := true, // make server tests serial @@ -1130,8 +1126,7 @@ lazy val sbtBig = (project in file(".big")) lazy val lowerUtils = (project in (file("internal") / "lower")) .aggregate(lowerUtilProjects.map(p => LocalProject(p.id)): _*) .settings( - publish / skip := true, - crossScalaVersions := Nil, + publish / skip := true ) lazy val upperModules = (project in (file("internal") / "upper")) @@ -1140,8 +1135,7 @@ lazy val upperModules = (project in (file("internal") / "upper")) diff Seq(bundledLauncherProj)).map(p => LocalProject(p.id)): _* ) .settings( - publish / skip := true, - crossScalaVersions := Nil, + publish / skip := true ) lazy val sbtIgnoredProblems = { @@ -1196,7 +1190,6 @@ lazy val vscodePlugin = (project in file("vscode-sbt-scala")) .settings( bspEnabled := false, crossPaths := false, - crossScalaVersions := Seq(baseScalaVersion), publish / skip := true, Compile / compile := { val _ = update.value @@ -1278,8 +1271,7 @@ def allProjects = // These need to be cross published to 2.12 and 2.13 for Zinc lazy val lowerUtilProjects = Seq( - collectionProj, - coreMacrosProj, + utilCore, utilCache, utilControl, utilInterface, diff --git a/internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala b/internal/util-core/src/main/scala-2/sbt/internal/util/appmacro/StringTypeTag.scala similarity index 91% rename from internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala rename to internal/util-core/src/main/scala-2/sbt/internal/util/appmacro/StringTypeTag.scala index d9abff119..ee7547ec7 100644 --- a/internal/util-core/src/main/scala-2.13/sbt/internal/util/StringTypeTag.scala +++ b/internal/util-core/src/main/scala-2/sbt/internal/util/appmacro/StringTypeTag.scala @@ -6,7 +6,7 @@ * Licensed under Apache License 2.0 (see LICENSE) */ -package sbt.internal.util +package sbt.internal.util.appmacro import scala.language.experimental.macros import scala.reflect.macros.blackbox @@ -33,6 +33,6 @@ object StringTypeTag { } val key = Literal(Constant(typeToString(tpe))) - q"new sbt.internal.util.StringTypeTag[$tpe]($key)" + q"new sbt.internal.util.appmacro.StringTypeTag[$tpe]($key)" } } diff --git a/internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala b/internal/util-core/src/main/scala-3/sbt/internal/util/appmacro/StringTypeTag.scala similarity index 96% rename from internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala rename to internal/util-core/src/main/scala-3/sbt/internal/util/appmacro/StringTypeTag.scala index 4cc8c2981..a144923a9 100644 --- a/internal/util-core/src/main/scala-3/sbt/internal/util/StringTypeTag.scala +++ b/internal/util-core/src/main/scala-3/sbt/internal/util/appmacro/StringTypeTag.scala @@ -5,7 +5,7 @@ * Licensed under Apache License 2.0 (see LICENSE) */ -package sbt.internal.util +package sbt.internal.util.appmacro final class StringTypeTag[A](val key: String): override def toString(): String = key diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala index 3c9d90643..e0ca75aed 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ManagedLogger.scala @@ -10,7 +10,7 @@ package sbt.internal.util import sbt.internal.util.codec.JsonProtocol._ import sbt.util._ import sjsonnew.JsonFormat -import sbt.internal.util.StringTypeTag +import sbt.internal.util.appmacro.StringTypeTag private[sbt] trait MiniLogger { def log[T](level: Level.Value, message: ObjectEvent[T]): Unit diff --git a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala index 5d63b2418..7edd4d3ec 100644 --- a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala +++ b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala @@ -12,7 +12,7 @@ import org.apache.logging.log4j.core.layout.PatternLayout import org.apache.logging.log4j.core.{ LoggerContext => XLoggerContext } import org.apache.logging.log4j.{ LogManager => XLogManager } import sbt.internal.util.{ Appender, ManagedLogger, TraceEvent, SuccessEvent, Util } -import sbt.internal.util.StringTypeTag +import sbt.internal.util.appmacro.StringTypeTag import java.util.concurrent.ConcurrentHashMap import scala.collection.concurrent diff --git a/internal/util-logging/src/test/scala/LogExchangeSpec.scala b/internal/util-logging/src/test/scala/LogExchangeSpec.scala deleted file mode 100644 index 57dfbe03c..000000000 --- a/internal/util-logging/src/test/scala/LogExchangeSpec.scala +++ /dev/null @@ -1,44 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ - -package sbt.util - -import sbt.internal.util._ -import sbt.internal.util.appmacro.StringTypeTag -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers - -class LogExchangeSpec extends AnyFlatSpec with Matchers { - import LogExchange._ - - checkTypeTag("stringTypeTagThrowable", stringTypeTagThrowable, StringTypeTag[Throwable]) - - checkTypeTag( - "stringTypeTagTraceEvent", - stringTypeTagTraceEvent, - StringTypeTag[TraceEvent] - ) - checkTypeTag( - "stringTypeTagSuccessEvent", - stringTypeTagSuccessEvent, - StringTypeTag[SuccessEvent] - ) - - private def checkTypeTag[A](name: String, inc: StringTypeTag[A], exp: StringTypeTag[A]): Unit = - s"LogExchange.$name" should s"match real StringTypeTag[$exp]" in { - val incomingString = inc.key - val expectedString = exp.key - if ((incomingString startsWith "scala.") || (expectedString startsWith "scala.")) { - // > historically [Scala] has been inconsistent whether `scala.` is included, or not - // > would it be hard to make the test accept either result? - // https://github.com/scala/community-builds/pull/758#issuecomment-409760633 - assert((incomingString stripPrefix "scala.") == (expectedString stripPrefix "scala.")) - } else { - assert(incomingString == expectedString) - } - } -} diff --git a/internal/util-logging/src/test/scala/ManagedLoggerSpec.scala b/internal/util-logging/src/test/scala/ManagedLoggerSpec.scala index b995b8621..4cc44fb29 100644 --- a/internal/util-logging/src/test/scala/ManagedLoggerSpec.scala +++ b/internal/util-logging/src/test/scala/ManagedLoggerSpec.scala @@ -92,7 +92,7 @@ class ManagedLoggerSpec extends AnyFlatSpec with Matchers { } { pool.submit(new Runnable { def run(): Unit = { - val stringTypeTag = StringTypeTag[List[Int]] + val stringTypeTag = implicitly[StringTypeTag[List[Int]]] val log = newLogger(s"foo$i") context.addAppender(s"foo$i", asyncStdout -> Level.Info) if (i % 100 == 0) { From f241fc415857ed927302b8a2f04d639da62f0ea7 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 14 Nov 2023 13:07:04 +0100 Subject: [PATCH 5/8] Run util test on all Scala 2 versions --- .github/workflows/ci.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb9dbce49..09186d676 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -126,8 +126,10 @@ jobs: # ./sbt -v --client "serverTestProj/test" # ./sbt -v --client doc ./sbt -v --client "all $UTIL_TESTS" - # ./sbt -v --client ++$SCALA_213 - # ./sbt -v --client "all $UTIL_TESTS" + ./sbt -v --client ++$SCALA_213 + ./sbt -v --client "all $UTIL_TESTS" + ./sbt -v --client ++$SCALA_212 + ./sbt -v --client "all $UTIL_TESTS" - name: Build and test (2) if: ${{ matrix.jobtype == 2 }} shell: bash @@ -149,11 +151,13 @@ jobs: # ./sbt -v "repoOverrideTest:scripted dependency-management/*" ./sbt -v "scripted source-dependencies/*" # ./sbt -v "scripted project/*" - # - name: Build and test (5) - # if: ${{ matrix.jobtype == 5 }} - # shell: bash - # run: | - # ./sbt -v "++$SCALA_213!; test; ++$SCALA_3!; all utilControl/test utilRelation/test utilPosition/test" + - name: Build and test (5) + if: ${{ matrix.jobtype == 5 }} + shell: bash + run: | + ./sbt -v --client test + ./sbt -v --client "++$SCALA_213; all $UTIL_TESTS" + ./sbt -v --client "++$SCALA_212; all $UTIL_TESTS" # - name: Build and test (6) # if: ${{ matrix.jobtype == 6 }} # shell: bash From b6510a1c1cc9b42769479e682c07bc5da7fecbae Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 16 Nov 2023 13:15:50 +0100 Subject: [PATCH 6/8] scripted run/fork-loader is not pending anymore --- sbt-app/src/sbt-test/run/fork-loader/{pending => test} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sbt-app/src/sbt-test/run/fork-loader/{pending => test} (100%) diff --git a/sbt-app/src/sbt-test/run/fork-loader/pending b/sbt-app/src/sbt-test/run/fork-loader/test similarity index 100% rename from sbt-app/src/sbt-test/run/fork-loader/pending rename to sbt-app/src/sbt-test/run/fork-loader/test From 99385881f0a6ffaeb7a365067e1807f178ad4c78 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 16 Nov 2023 17:00:05 +0100 Subject: [PATCH 7/8] ignore discarded Unit --- .../util-core/src/main/scala/sbt/internal/util/Util.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/util-core/src/main/scala/sbt/internal/util/Util.scala b/internal/util-core/src/main/scala/sbt/internal/util/Util.scala index 8dbfb60f4..e5e987a96 100644 --- a/internal/util-core/src/main/scala/sbt/internal/util/Util.scala +++ b/internal/util-core/src/main/scala/sbt/internal/util/Util.scala @@ -39,8 +39,10 @@ object Util { def quoteIfKeyword(s: String): String = if (ScalaKeywords.values(s)) s"`${s}`" else s - def ignoreResult[A](f: => A): Unit = - f; () + def ignoreResult[A](f: => A): Unit = { + val _ = f + () + } lazy val isMac: Boolean = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("mac") From ba6daf1521a761bae031fcebd6daa2f2ad406a7a Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 22 Nov 2023 15:51:28 +0100 Subject: [PATCH 8/8] Fix deadlock in Terminal init --- .../scala/sbt/internal/util/Terminal.scala | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala index 4d69ab357..af6ebe567 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala @@ -604,6 +604,9 @@ object Terminal { private[sbt] def withPrintStream[T](f: PrintStream => T): T = console.withPrintStream(f) private[this] val attached = new AtomicBoolean(true) + private[sbt] val NullTerminal = new DefaultTerminal(nullInputStream, _ => (), _ => ()) + private[sbt] val SimpleTerminal = new DefaultTerminal(originalIn, originalOut, originalErr) + /** * A wrapped instance of a jline.Terminal2 instance. It should only ever be changed when the * backgrounds sbt with ctrl+z and then foregrounds sbt which causes a call to reset. The @@ -1029,7 +1032,11 @@ object Terminal { catch { case _: InterruptedException => } -1 } - private[sbt] class DefaultTerminal extends Terminal { + private[sbt] class DefaultTerminal( + val inputStream: InputStream, + val outputStream: OutputStream, + val errorStream: OutputStream + ) extends Terminal { override def close(): Unit = {} override private[sbt] def progressState: ProgressState = new ProgressState(1) override private[sbt] def enterRawMode(): Unit = {} @@ -1042,15 +1049,12 @@ object Terminal { override def getNumericCapability(capability: String): Integer = null override def getStringCapability(capability: String): String = null override def getWidth: Int = 0 - override def inputStream: InputStream = nullInputStream override def isAnsiSupported: Boolean = Terminal.isAnsiSupported override def isColorEnabled: Boolean = isColorEnabledProp.getOrElse(Terminal.isColorEnabled) override def isEchoEnabled: Boolean = false override def isSuccessEnabled: Boolean = true override def isSupershellEnabled: Boolean = false override def setEchoEnabled(toggle: Boolean): Unit = {} - override def outputStream: OutputStream = _ => {} - override def errorStream: OutputStream = _ => {} override private[sbt] def getAttributes: Map[String, String] = Map.empty override private[sbt] def setAttributes(attributes: Map[String, String]): Unit = {} override private[sbt] def setSize(width: Int, height: Int): Unit = {} @@ -1061,10 +1065,4 @@ object Terminal { override private[sbt] def write(bytes: Int*): Unit = {} override private[sbt] def withRawOutput[R](f: => R): R = f } - private[sbt] object NullTerminal extends DefaultTerminal - private[sbt] object SimpleTerminal extends DefaultTerminal { - override lazy val inputStream: InputStream = originalIn - override lazy val outputStream: OutputStream = originalOut - override lazy val errorStream: OutputStream = originalErr - } }