From 419575a643fc2d797a1cf91d1e5ceb9432e41acb Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:27:41 -0500 Subject: [PATCH 01/18] Bump sbt to 1.10.2, add crossbuilds --- build.sbt | 11 +++++++++++ project/build.properties | 2 +- sbt-web-tester/project/build.properties | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 0f3d7ec..3ea6b55 100644 --- a/build.sbt +++ b/build.sbt @@ -11,6 +11,10 @@ developers += Developer( url("https://github.com/playframework") ) +lazy val scala212 = "2.12.20" +lazy val scala3 = "3.3.4" +ThisBuild / crossScalaVersions := Seq(scala212, scala3) + libraryDependencies ++= Seq( "org.webjars" % "webjars-locator-core" % "0.59", "org.specs2" %% "specs2-core" % "4.20.8" % "test", @@ -26,3 +30,10 @@ Global / onLoad := (Global / onLoad).value.andThen { s => dynverAssertTagVersion.value s } + +(pluginCrossBuild / sbtVersion) := { + scalaBinaryVersion.value match { + case "2.12" => "1.10.2" + case _ => "2.0.0-M2" + } +} \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index ee4c672..0b699c3 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.1 +sbt.version=1.10.2 diff --git a/sbt-web-tester/project/build.properties b/sbt-web-tester/project/build.properties index ee4c672..0b699c3 100644 --- a/sbt-web-tester/project/build.properties +++ b/sbt-web-tester/project/build.properties @@ -1 +1 @@ -sbt.version=1.10.1 +sbt.version=1.10.2 From 7620bb01d1b0b73647ed95cfafd89e9bab083107 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:04:27 -0500 Subject: [PATCH 02/18] Fix several Scala 3 compatibility issues/warnings --- .../com/typesafe/sbt/web/incremental/Bytes.scala | 8 ++++---- .../com/typesafe/sbt/web/incremental/OpCache.scala | 9 ++++----- .../com/typesafe/sbt/web/incremental/OpCacheIO.scala | 12 ++++++------ .../typesafe/sbt/web/incremental/OpInputHash.scala | 2 +- .../com/typesafe/sbt/web/incremental/OpResult.scala | 2 +- .../com/typesafe/sbt/web/incremental/package.scala | 12 ++++++------ 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/Bytes.scala b/src/main/scala/com/typesafe/sbt/web/incremental/Bytes.scala index c021dff..e88aeee 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/Bytes.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/Bytes.scala @@ -3,19 +3,19 @@ */ package com.typesafe.sbt.web.incremental -import java.util.Arrays +import java.util /** * Wraps a byte array to ensure immutability. */ class Bytes(private[incremental] val arr: Array[Byte]) { - override def toString = Arrays.toString(arr) + override def toString: String = util.Arrays.toString(arr) override def equals(that: Any): Boolean = that match { case null => false - case other: Bytes => Arrays.equals(arr, other.arr) + case other: Bytes => util.Arrays.equals(arr, other.arr) case _ => false } - override def hashCode: Int = Arrays.hashCode(arr) + override def hashCode: Int = util.Arrays.hashCode(arr) } /** diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala index 8e0dbaa..8adce6e 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala @@ -5,14 +5,13 @@ package com.typesafe.sbt.web.incremental import java.io.File import sbt.Hash -import scala.collection.immutable.Set /** * Cache for recording which operations have successfully completed. Associates a hash of the operations' inputs * (OpInputHash) with a record of the files that were accessed by the operation. */ private[incremental] class OpCache(var content: Map[OpInputHash, OpCache.Record] = Map.empty) { - import OpCache._ + import OpCache.* def allOpInputHashes: Set[OpInputHash] = content.keySet def contains(oih: OpInputHash): Boolean = { content.contains(oih) @@ -20,10 +19,10 @@ private[incremental] class OpCache(var content: Map[OpInputHash, OpCache.Record] def getRecord(oih: OpInputHash): Option[Record] = { content.get(oih) } - def putRecord(oih: OpInputHash, record: Record) = { + def putRecord(oih: OpInputHash, record: Record): Unit = { content = content + ((oih, record)) } - def removeRecord(oih: OpInputHash) = { + def removeRecord(oih: OpInputHash): Unit = { content = content - oih } } @@ -74,7 +73,7 @@ private[incremental] object OpCache { * Remove all operations from the cache that aren't in the given set of operations. */ def vacuumExcept[Op](cache: OpCache, opsToKeep: Seq[Op])(implicit opInputHasher: OpInputHasher[Op]): Unit = { - val oihSet: Set[OpInputHash] = opsToKeep.map(opInputHasher.hash).to[Set] + val oihSet: Set[OpInputHash] = opsToKeep.map(opInputHasher.hash).to(Set) for (oih <- cache.allOpInputHashes) yield { if (!oihSet.contains(oih)) { cache.removeRecord(oih) diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala index 1a3f5da..15bbf6a 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala @@ -31,17 +31,17 @@ private[incremental] object OpCacheIO { */ private[incremental] object OpCacheProtocol { - import sjsonnew._ - import BasicJsonProtocol._ + import sjsonnew.* + import BasicJsonProtocol.* import OpCache.{ FileHash, Record } - implicit val fileFormat: JsonFormat[File] = projectFormat[File, String](_.getAbsolutePath, new File(_)) - implicit val bytesFormat: JsonFormat[Bytes] = projectFormat[Bytes, String]( + implicit val fileFormat: JsonFormat[File] = BasicJsonProtocol.projectFormat[File, String](_.getAbsolutePath, new File(_)) + implicit val bytesFormat: JsonFormat[Bytes] = BasicJsonProtocol.projectFormat[Bytes, String]( bytes => Base64.getEncoder.encodeToString(bytes.arr), bytes => new Bytes(Base64.getDecoder.decode(bytes)) ) - implicit val opInputHashKeyFormat = JsonKeyFormat[OpInputHash]( + implicit val opInputHashKeyFormat: JsonKeyFormat[OpInputHash] = JsonKeyFormat[OpInputHash]( hash => Base64.getEncoder.encodeToString(hash.bytes.arr), hashBytes => OpInputHash(Bytes(Base64.getDecoder.decode(hashBytes))) ) @@ -87,6 +87,6 @@ private[incremental] object OpCacheProtocol { } implicit val opCacheFormat: JsonFormat[OpCache] = { - projectFormat[OpCache, Map[OpInputHash, Record]](_.content, new OpCache(_)) + BasicJsonProtocol.projectFormat[OpCache, Map[OpInputHash, Record]](_.content, new OpCache(_)) } } diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpInputHash.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpInputHash.scala index e664a03..32fca58 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpInputHash.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpInputHash.scala @@ -42,6 +42,6 @@ object OpInputHasher { * Construct an OpInputHash that uses the given hashing logic. */ def apply[Op](f: Op => OpInputHash): OpInputHasher[Op] = new OpInputHasher[Op] { - def hash(op: Op) = f(op) + def hash(op: Op): OpInputHash = f(op) } } diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpResult.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpResult.scala index 8f53b49..d0a38ca 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpResult.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpResult.scala @@ -20,4 +20,4 @@ final case class OpSuccess(filesRead: Set[File], filesWritten: Set[File]) extend /** * An operation that failed. */ -final case object OpFailure extends OpResult +case object OpFailure extends OpResult diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala index 3b962b5..37063d0 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala @@ -99,7 +99,7 @@ package object incremental { val cache: OpCache = OpCacheIO.fromFile(cacheFile) // Before vacuuming the cache, find out what the old cache had produced - val allOldProducts = cache.content.values.to[Set].flatMap(_.products) + val allOldProducts = cache.content.values.to(Set).flatMap(_.products) // Clear out any unknown operations from the existing cache OpCache.vacuumExcept(cache, ops) @@ -109,17 +109,17 @@ package object incremental { val (results: Map[Op, OpResult], finalResult) = runOps(prunedOps) // Check returned results are all within the set of given ops - val prunedOpsSet: Set[Op] = prunedOps.to[Set] + val prunedOpsSet: Set[Op] = prunedOps.to(Set) val resultOpsSet: Set[Op] = results.keySet val unexpectedOps: Set[Op] = resultOpsSet -- prunedOpsSet - if (!unexpectedOps.isEmpty) { + if (unexpectedOps.nonEmpty) { throw new IllegalArgumentException(s"runOps function returned results for unknown ops: $unexpectedOps") } // Work out what the current valid products are - val opsSet: Set[Op] = ops.to[Set] + val opsSet: Set[Op] = ops.to(Set) val oldProductsToKeep = OpCache.productsForOps(cache, opsSet -- prunedOpsSet) - val newProducts = results.values.to[Set].flatMap { + val newProducts = results.values.to(Set).flatMap { case OpFailure => Set.empty[File] case OpSuccess(_, products) => products } @@ -147,6 +147,6 @@ package object incremental { * } * }}} */ - implicit def toStringInputHasher[Op] = OpInputHasher[Op](op => OpInputHash.hashString(op.toString)) + implicit def toStringInputHasher[Op]: OpInputHasher[Op] = OpInputHasher[Op](op => OpInputHash.hashString(op.toString)) } From 74434c2a4a2b63899a065ef1052aa8c41d99924c Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:27:11 -0500 Subject: [PATCH 03/18] Add compatibility shim, resolve several classpath errors --- .../com/typesafe/sbt/web/PluginCompat.scala | 19 ++++++++++++ .../com/typesafe/sbt/web/PluginCompat.scala | 19 ++++++++++++ .../scala/com/typesafe/sbt/web/SbtWeb.scala | 29 ++++++++++--------- .../sbt/web/incremental/OpCache.scala | 2 +- 4 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala create mode 100644 src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala new file mode 100644 index 0000000..f23b1f8 --- /dev/null +++ b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala @@ -0,0 +1,19 @@ +package com.typesafe.sbt.web + +import java.nio.file.{ Path => NioPath } +import sbt.* +import xsbti.FileConverter + +private[web] object PluginCompat { + type FileRef = java.io.File + type Out = java.io.File + + def toNioPath(a: Attributed[File])(implicit conv: FileConverter): NioPath = + a.data.toPath + def toFile(a: Attributed[File])(implicit conv: FileConverter): File = + a.data + def toNioPaths(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[NioPath] = + cp.map(_.data.toPath()).toVector + def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = + cp.map(_.data).toVector +} diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala new file mode 100644 index 0000000..636738f --- /dev/null +++ b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala @@ -0,0 +1,19 @@ +package com.typesafe.sbt.web + +import java.nio.file.{ Path => NioPath } +import sbt.* +import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile } + +private[web] object PluginCompat: + type FileRef = HashedVirtualFileRef + type Out = VirtualFile + + def toNioPath(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): NioPath = + conv.toPath(a.data) + inline def toFile(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): File = + toNioPath(a).toFile() + def toNioPaths(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[NioPath] = + cp.map(toNioPath).toVector + inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = + toNioPaths(cp).map(_.toFile()) +end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 3b012e4..818ecb5 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -1,16 +1,19 @@ package com.typesafe.sbt.web -import sbt._ +import sbt.{ given, * } import sbt.internal.inc.Analysis import sbt.internal.io.Source -import sbt.Keys._ +import sbt.Keys.* import sbt.Defaults.relativeMappings +import scala.language.implicitConversions import org.webjars.WebJarExtractor import org.webjars.WebJarAssetLocator.WEBJARS_PATH_PREFIX import com.typesafe.sbt.web.pipeline.Pipeline -import com.typesafe.sbt.web.incremental.{ OpResult, OpSuccess } +import com.typesafe.sbt.web.incremental.{ toStringInputHasher, OpResult, OpSuccess } import xsbti.Reporter +import PluginCompat.* + object Import { val Assets = config("web-assets") @@ -178,12 +181,12 @@ object SbtWeb extends AutoPlugin { override def requires = sbt.plugins.JvmPlugin - import autoImport._ - import WebKeys._ + import autoImport.* + import WebKeys.* - override def projectConfigurations = super.projectConfigurations ++ Seq(Assets, TestAssets, Plugin) + override def projectConfigurations: Seq[Configuration] = super.projectConfigurations ++ Seq(Assets, TestAssets, Plugin) - override def buildSettings: Seq[Def.Setting[_]] = Seq( + override def buildSettings: Seq[Def.Setting[?]] = Seq( (Plugin / nodeModuleDirectory) := (Plugin / target).value / "node-modules", (Plugin / nodeModules / webJarsCache) := (Plugin / target).value / "webjars-plugin.cache", (Plugin / webJarsClassLoader) := SbtWeb.getClass.getClassLoader, @@ -199,7 +202,7 @@ object SbtWeb extends AutoPlugin { ) ) ++ inConfig(Plugin)(nodeModulesSettings) - override def projectSettings: Seq[Setting[_]] = Seq( + override def projectSettings: Seq[Setting[?]] = Seq( reporter := new CompileProblems.LoggerReporter(5, streams.value.log), webTarget := target.value / "web", (Assets / sourceDirectory) := (Compile / sourceDirectory).value / "assets", @@ -278,7 +281,7 @@ object SbtWeb extends AutoPlugin { inConfig(TestAssets)(unscopedAssetSettings) ++ inConfig(TestAssets)(nodeModulesSettings) ++ packageSettings - val unscopedAssetSettings: Seq[Setting[_]] = Seq( + val unscopedAssetSettings: Seq[Setting[?]] = Seq( includeFilter := GlobFilter("*"), sourceGenerators := Nil, managedSourceDirectories := Nil, @@ -286,7 +289,7 @@ object SbtWeb extends AutoPlugin { unmanagedSourceDirectories := Seq(sourceDirectory.value), unmanagedSources := unmanagedSourceDirectories.value .descendantsExcept(includeFilter.value, excludeFilter.value) - .get, + .get(), sourceDirectories := managedSourceDirectories.value ++ unmanagedSourceDirectories.value, sources := managedSources.value ++ unmanagedSources.value, (sources / mappings) := relativeMappings(sources, sourceDirectories).value, @@ -296,7 +299,7 @@ object SbtWeb extends AutoPlugin { unmanagedResourceDirectories := Seq(resourceDirectory.value), unmanagedResources := unmanagedResourceDirectories.value .descendantsExcept(includeFilter.value, excludeFilter.value) - .get, + .get(), resourceDirectories := managedResourceDirectories.value ++ unmanagedResourceDirectories.value, resources := managedResources.value ++ unmanagedResources.value, (resources / mappings) := relativeMappings(resources, resourceDirectories).value, @@ -503,14 +506,14 @@ object SbtWeb extends AutoPlugin { private def generateNodeWebJars(target: File, cache: File, classLoader: ClassLoader): Seq[File] = { withWebJarExtractor(target, cache, classLoader) { (e, to) => e.extractAllNodeModulesTo(to) - }.**(AllPassFilter).get + }.**(AllPassFilter).get() } private def generateWebJars(target: File, lib: String, cache: File, classLoader: ClassLoader): Seq[File] = { withWebJarExtractor(target / lib, cache, classLoader) { (e, to) => e.extractAllWebJarsTo(to) } - target.**(AllPassFilter).get + target.**(AllPassFilter).get() } // Mapping deduplication diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala index 8adce6e..455f6e9 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala @@ -128,6 +128,6 @@ private[incremental] object OpCache { ops.flatMap { op => val record = cache.getRecord(opInputHasher.hash(op)) record.fold(Set.empty[File])(_.products) - }.toSet + } } } From bf669a6179c95628f391817b4bd6b5202577a768 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:26:47 -0500 Subject: [PATCH 04/18] Compatibility shim for to[Set] --- build.sbt | 2 +- .../scala-2.12/com/typesafe/sbt/web/PluginCompat.scala | 1 + src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala | 1 + .../scala/com/typesafe/sbt/web/incremental/OpCache.scala | 3 ++- .../scala/com/typesafe/sbt/web/incremental/package.scala | 9 +++++---- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index 3ea6b55..b835481 100644 --- a/build.sbt +++ b/build.sbt @@ -36,4 +36,4 @@ Global / onLoad := (Global / onLoad).value.andThen { s => case "2.12" => "1.10.2" case _ => "2.0.0-M2" } -} \ No newline at end of file +} diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala index f23b1f8..4911a91 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala @@ -16,4 +16,5 @@ private[web] object PluginCompat { cp.map(_.data.toPath()).toVector def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = cp.map(_.data).toVector + def toCompatSet[A]( iterable: Iterable[A] ): Set[A] = iterable.to[Set] } diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala index 636738f..2bfc25b 100644 --- a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala @@ -16,4 +16,5 @@ private[web] object PluginCompat: cp.map(toNioPath).toVector inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = toNioPaths(cp).map(_.toFile()) + def toCompatSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala index 455f6e9..253e5d9 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala @@ -3,6 +3,7 @@ */ package com.typesafe.sbt.web.incremental +import com.typesafe.sbt.web.PluginCompat.toCompatSet import java.io.File import sbt.Hash @@ -73,7 +74,7 @@ private[incremental] object OpCache { * Remove all operations from the cache that aren't in the given set of operations. */ def vacuumExcept[Op](cache: OpCache, opsToKeep: Seq[Op])(implicit opInputHasher: OpInputHasher[Op]): Unit = { - val oihSet: Set[OpInputHash] = opsToKeep.map(opInputHasher.hash).to(Set) + val oihSet: Set[OpInputHash] = toCompatSet(opsToKeep.map(opInputHasher.hash)) for (oih <- cache.allOpInputHashes) yield { if (!oihSet.contains(oih)) { cache.removeRecord(oih) diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala index 37063d0..f3c4123 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala @@ -4,6 +4,7 @@ package com.typesafe.sbt.web import java.io.File +import PluginCompat.toCompatSet /** * The incremental task API lets tasks run more quickly when they are called more than once. The idea is to do less work @@ -99,7 +100,7 @@ package object incremental { val cache: OpCache = OpCacheIO.fromFile(cacheFile) // Before vacuuming the cache, find out what the old cache had produced - val allOldProducts = cache.content.values.to(Set).flatMap(_.products) + val allOldProducts = toCompatSet(cache.content.values).flatMap(_.products) // Clear out any unknown operations from the existing cache OpCache.vacuumExcept(cache, ops) @@ -109,7 +110,7 @@ package object incremental { val (results: Map[Op, OpResult], finalResult) = runOps(prunedOps) // Check returned results are all within the set of given ops - val prunedOpsSet: Set[Op] = prunedOps.to(Set) + val prunedOpsSet: Set[Op] = toCompatSet(prunedOps) val resultOpsSet: Set[Op] = results.keySet val unexpectedOps: Set[Op] = resultOpsSet -- prunedOpsSet if (unexpectedOps.nonEmpty) { @@ -117,9 +118,9 @@ package object incremental { } // Work out what the current valid products are - val opsSet: Set[Op] = ops.to(Set) + val opsSet: Set[Op] = toCompatSet(ops) val oldProductsToKeep = OpCache.productsForOps(cache, opsSet -- prunedOpsSet) - val newProducts = results.values.to(Set).flatMap { + val newProducts = toCompatSet(results.values).flatMap { case OpFailure => Set.empty[File] case OpSuccess(_, products) => products } From 2a309c65a612f0daae0fc2856a121615c113b34e Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:29:48 -0500 Subject: [PATCH 05/18] Better name for compatibility method --- .../scala-2.12/com/typesafe/sbt/web/PluginCompat.scala | 2 +- .../scala-3/com/typesafe/sbt/web/PluginCompat.scala | 3 ++- .../com/typesafe/sbt/web/incremental/OpCache.scala | 4 ++-- .../com/typesafe/sbt/web/incremental/package.scala | 10 +++++----- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala index 4911a91..1aaeade 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala @@ -16,5 +16,5 @@ private[web] object PluginCompat { cp.map(_.data.toPath()).toVector def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = cp.map(_.data).toVector - def toCompatSet[A]( iterable: Iterable[A] ): Set[A] = iterable.to[Set] + def toSet[A](iterable: Iterable[A] ): Set[A] = iterable.to[Set] } diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala index 2bfc25b..5d22cd5 100644 --- a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala @@ -1,6 +1,7 @@ package com.typesafe.sbt.web import java.nio.file.{ Path => NioPath } +import java.io.{ File => IoFile } import sbt.* import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile } @@ -16,5 +17,5 @@ private[web] object PluginCompat: cp.map(toNioPath).toVector inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = toNioPaths(cp).map(_.toFile()) - def toCompatSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) + def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala index 253e5d9..4a46595 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala @@ -3,7 +3,7 @@ */ package com.typesafe.sbt.web.incremental -import com.typesafe.sbt.web.PluginCompat.toCompatSet +import com.typesafe.sbt.web.PluginCompat.toSet import java.io.File import sbt.Hash @@ -74,7 +74,7 @@ private[incremental] object OpCache { * Remove all operations from the cache that aren't in the given set of operations. */ def vacuumExcept[Op](cache: OpCache, opsToKeep: Seq[Op])(implicit opInputHasher: OpInputHasher[Op]): Unit = { - val oihSet: Set[OpInputHash] = toCompatSet(opsToKeep.map(opInputHasher.hash)) + val oihSet: Set[OpInputHash] = toSet(opsToKeep.map(opInputHasher.hash)) for (oih <- cache.allOpInputHashes) yield { if (!oihSet.contains(oih)) { cache.removeRecord(oih) diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala index f3c4123..476e502 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala @@ -4,7 +4,7 @@ package com.typesafe.sbt.web import java.io.File -import PluginCompat.toCompatSet +import PluginCompat.toSet /** * The incremental task API lets tasks run more quickly when they are called more than once. The idea is to do less work @@ -100,7 +100,7 @@ package object incremental { val cache: OpCache = OpCacheIO.fromFile(cacheFile) // Before vacuuming the cache, find out what the old cache had produced - val allOldProducts = toCompatSet(cache.content.values).flatMap(_.products) + val allOldProducts = toSet(cache.content.values).flatMap(_.products) // Clear out any unknown operations from the existing cache OpCache.vacuumExcept(cache, ops) @@ -110,7 +110,7 @@ package object incremental { val (results: Map[Op, OpResult], finalResult) = runOps(prunedOps) // Check returned results are all within the set of given ops - val prunedOpsSet: Set[Op] = toCompatSet(prunedOps) + val prunedOpsSet: Set[Op] = toSet(prunedOps) val resultOpsSet: Set[Op] = results.keySet val unexpectedOps: Set[Op] = resultOpsSet -- prunedOpsSet if (unexpectedOps.nonEmpty) { @@ -118,9 +118,9 @@ package object incremental { } // Work out what the current valid products are - val opsSet: Set[Op] = toCompatSet(ops) + val opsSet: Set[Op] = toSet(ops) val oldProductsToKeep = OpCache.productsForOps(cache, opsSet -- prunedOpsSet) - val newProducts = toCompatSet(results.values).flatMap { + val newProducts = toSet(results.values).flatMap { case OpFailure => Set.empty[File] case OpSuccess(_, products) => products } From e736497c46a06c8ba7d97ffe99603f28a96b4bd5 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:57:22 -0500 Subject: [PATCH 06/18] Scala 3 dialect for shims --- .scalafmt.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.scalafmt.conf b/.scalafmt.conf index dc3ec7d..b947232 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -24,3 +24,8 @@ align.tokens."+" = [ ] } ] +fileOverride { + "glob:**/scala-3/**" { + runner.dialect = scala3 + } +} From e431a6a76af7e0f53e17f67d60c4717085830365 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:44:41 -0500 Subject: [PATCH 07/18] Fix classpath.files sbt2 compatibility error --- src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala | 4 +++- src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala | 2 ++ src/main/scala/com/typesafe/sbt/web/SbtWeb.scala | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala index 1aaeade..e344054 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala @@ -2,6 +2,7 @@ package com.typesafe.sbt.web import java.nio.file.{ Path => NioPath } import sbt.* +import sbt.Keys.Classpath import xsbti.FileConverter private[web] object PluginCompat { @@ -16,5 +17,6 @@ private[web] object PluginCompat { cp.map(_.data.toPath()).toVector def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = cp.map(_.data).toVector - def toSet[A](iterable: Iterable[A] ): Set[A] = iterable.to[Set] + def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to[Set] + def classpathToFiles( classpath: Classpath): Seq[FileRef] = classpath.files } diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala index 5d22cd5..632048d 100644 --- a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala @@ -3,6 +3,7 @@ package com.typesafe.sbt.web import java.nio.file.{ Path => NioPath } import java.io.{ File => IoFile } import sbt.* +import sbt.Keys.Classpath import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile } private[web] object PluginCompat: @@ -18,4 +19,5 @@ private[web] object PluginCompat: inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = toNioPaths(cp).map(_.toFile()) def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) + def classpathToFiles( classpath: Classpath): Seq[File] = toFiles(classpath) end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 818ecb5..b15f0fc 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -493,7 +493,7 @@ object SbtWeb extends AutoPlugin { } private def classLoader(classpath: Classpath): ClassLoader = - new java.net.URLClassLoader(Path.toURLs(classpath.files), null) + new java.net.URLClassLoader(Path.toURLs(classpathToFiles(classpath)), null) private def withWebJarExtractor(to: File, cacheFile: File, classLoader: ClassLoader)( block: (WebJarExtractor, File) => Unit From 327a19678b67c9d44ec5087b0bde5bd02d5816b7 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:49:34 -0500 Subject: [PATCH 08/18] Fix CI errors --- .github/workflows/build-test.yml | 2 +- .github/workflows/format.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 6e7ec32..3be3c12 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -20,7 +20,7 @@ jobs: java: 17, 11, 8 scala: 2.12.20 cmd: | - sbt ++$MATRIX_SCALA test ^scripted + sbt ++$MATRIX_SCALA test +scripted finish: name: Finish diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 9a21f0f..69cedc4 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -18,6 +18,6 @@ jobs: persist-credentials: false - name: Check project is formatted - uses: jrouly/scalafmt-native-action@v3 + uses: jrouly/scalafmt-native-action@v4 with: arguments: '--list --mode diff-ref=origin/main' From 809da5baa6760de809559cdd635ecba187eaef9c Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:58:51 -0500 Subject: [PATCH 09/18] fOrMaTtInG --- .../com/typesafe/sbt/web/PluginCompat.scala | 2 +- .../scala-3/com/typesafe/sbt/web/PluginCompat.scala | 2 +- src/main/scala/com/typesafe/sbt/web/SbtWeb.scala | 11 ++++++----- .../com/typesafe/sbt/web/incremental/OpCacheIO.scala | 3 ++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala index e344054..47f84cd 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala @@ -18,5 +18,5 @@ private[web] object PluginCompat { def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = cp.map(_.data).toVector def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to[Set] - def classpathToFiles( classpath: Classpath): Seq[FileRef] = classpath.files + def classpathToFiles(classpath: Classpath): Seq[FileRef] = classpath.files } diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala index 632048d..5b179cb 100644 --- a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala @@ -19,5 +19,5 @@ private[web] object PluginCompat: inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = toNioPaths(cp).map(_.toFile()) def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) - def classpathToFiles( classpath: Classpath): Seq[File] = toFiles(classpath) + def classpathToFiles(classpath: Classpath): Seq[File] = toFiles(classpath) end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index b15f0fc..355d5c1 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -1,6 +1,6 @@ package com.typesafe.sbt.web -import sbt.{ given, * } +import sbt.{ Def, *, given } import sbt.internal.inc.Analysis import sbt.internal.io.Source import sbt.Keys.* @@ -9,7 +9,7 @@ import scala.language.implicitConversions import org.webjars.WebJarExtractor import org.webjars.WebJarAssetLocator.WEBJARS_PATH_PREFIX import com.typesafe.sbt.web.pipeline.Pipeline -import com.typesafe.sbt.web.incremental.{ toStringInputHasher, OpResult, OpSuccess } +import com.typesafe.sbt.web.incremental.{ OpResult, OpSuccess, toStringInputHasher } import xsbti.Reporter import PluginCompat.* @@ -184,7 +184,8 @@ object SbtWeb extends AutoPlugin { import autoImport.* import WebKeys.* - override def projectConfigurations: Seq[Configuration] = super.projectConfigurations ++ Seq(Assets, TestAssets, Plugin) + override def projectConfigurations: Seq[Configuration] = + super.projectConfigurations ++ Seq(Assets, TestAssets, Plugin) override def buildSettings: Seq[Def.Setting[?]] = Seq( (Plugin / nodeModuleDirectory) := (Plugin / target).value / "node-modules", @@ -444,7 +445,7 @@ object SbtWeb extends AutoPlugin { /** * Create package mappings for all assets, adding the optional prefix. */ - def packageAssetsMappings = Def.task { + def packageAssetsMappings: Def.Initialize[Task[Seq[(FileRef, String)]]] = Def.task { val prefix = packagePrefix.value (Defaults.ConfigGlobal / pipeline).value map { case (file, path) => file -> (prefix + path) @@ -454,7 +455,7 @@ object SbtWeb extends AutoPlugin { /** * Get module names for all internal web module dependencies on the classpath. */ - def getInternalWebModules(conf: Configuration) = Def.task { + def getInternalWebModules(conf: Configuration): Def.Initialize[Task[Seq[String]]] = Def.task { (conf / internalDependencyClasspath).value.flatMap(_.get(WebKeys.webModulesLib.key)) } diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala index 15bbf6a..5f47103 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCacheIO.scala @@ -36,7 +36,8 @@ private[incremental] object OpCacheProtocol { import OpCache.{ FileHash, Record } - implicit val fileFormat: JsonFormat[File] = BasicJsonProtocol.projectFormat[File, String](_.getAbsolutePath, new File(_)) + implicit val fileFormat: JsonFormat[File] = + BasicJsonProtocol.projectFormat[File, String](_.getAbsolutePath, new File(_)) implicit val bytesFormat: JsonFormat[Bytes] = BasicJsonProtocol.projectFormat[Bytes, String]( bytes => Base64.getEncoder.encodeToString(bytes.arr), bytes => new Bytes(Base64.getDecoder.decode(bytes)) From bfe241ea5454ebb84e3a7cde1a6da0dbad9a2810 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Sat, 12 Oct 2024 08:00:57 -0500 Subject: [PATCH 10/18] Add 3.3.4 to matrix, remove cross-script, add -Xsource:3 --- .github/workflows/build-test.yml | 4 ++-- build.sbt | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 3be3c12..c902d90 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -18,9 +18,9 @@ jobs: uses: playframework/.github/.github/workflows/cmd.yml@v3 with: java: 17, 11, 8 - scala: 2.12.20 + scala: 2.12.20, 3.3.4 cmd: | - sbt ++$MATRIX_SCALA test +scripted + sbt ++$MATRIX_SCALA test scripted finish: name: Finish diff --git a/build.sbt b/build.sbt index b835481..fb35549 100644 --- a/build.sbt +++ b/build.sbt @@ -37,3 +37,10 @@ Global / onLoad := (Global / onLoad).value.andThen { s => case _ => "2.0.0-M2" } } + +scalacOptions := { + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, major)) => Seq("-Xsource:3") + case _ => Seq.empty + } +} \ No newline at end of file From 03419ce375523cc2797faa34915750853e1053ed Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Sat, 12 Oct 2024 08:02:44 -0500 Subject: [PATCH 11/18] Move PluginCompat to give access to package.scala --- .../com/typesafe/sbt/{web => }/PluginCompat.scala | 7 ++++--- .../scala-3/com/typesafe/sbt/{web => }/PluginCompat.scala | 4 ++-- .../scala/com/typesafe/sbt/web/incremental/OpCache.scala | 2 +- .../scala/com/typesafe/sbt/web/incremental/package.scala | 2 +- src/main/scala/com/typesafe/sbt/web/package.scala | 4 +++- 5 files changed, 11 insertions(+), 8 deletions(-) rename src/main/scala-2.12/com/typesafe/sbt/{web => }/PluginCompat.scala (86%) rename src/main/scala-3/com/typesafe/sbt/{web => }/PluginCompat.scala (93%) diff --git a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala similarity index 86% rename from src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala rename to src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala index 47f84cd..7d60e01 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala @@ -1,11 +1,12 @@ -package com.typesafe.sbt.web +package com.typesafe.sbt -import java.nio.file.{ Path => NioPath } import sbt.* import sbt.Keys.Classpath import xsbti.FileConverter -private[web] object PluginCompat { +import java.nio.file.Path as NioPath + +private[sbt] object PluginCompat { type FileRef = java.io.File type Out = java.io.File diff --git a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala similarity index 93% rename from src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala rename to src/main/scala-3/com/typesafe/sbt/PluginCompat.scala index 5b179cb..7a58f40 100644 --- a/src/main/scala-3/com/typesafe/sbt/web/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala @@ -1,4 +1,4 @@ -package com.typesafe.sbt.web +package com.typesafe.sbt import java.nio.file.{ Path => NioPath } import java.io.{ File => IoFile } @@ -6,7 +6,7 @@ import sbt.* import sbt.Keys.Classpath import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFile } -private[web] object PluginCompat: +private[sbt] object PluginCompat: type FileRef = HashedVirtualFileRef type Out = VirtualFile diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala index 4a46595..b5d3003 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/OpCache.scala @@ -3,7 +3,7 @@ */ package com.typesafe.sbt.web.incremental -import com.typesafe.sbt.web.PluginCompat.toSet +import com.typesafe.sbt.PluginCompat.toSet import java.io.File import sbt.Hash diff --git a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala index 476e502..4da2feb 100644 --- a/src/main/scala/com/typesafe/sbt/web/incremental/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/incremental/package.scala @@ -4,7 +4,7 @@ package com.typesafe.sbt.web import java.io.File -import PluginCompat.toSet +import com.typesafe.sbt.PluginCompat.toSet /** * The incremental task API lets tasks run more quickly when they are called more than once. The idea is to do less work diff --git a/src/main/scala/com/typesafe/sbt/web/package.scala b/src/main/scala/com/typesafe/sbt/web/package.scala index 1dc1402..831efc9 100644 --- a/src/main/scala/com/typesafe/sbt/web/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/package.scala @@ -1,5 +1,7 @@ package com.typesafe.sbt +import PluginCompat.FileRef + import java.io.File package object web { @@ -12,5 +14,5 @@ package object web { /** * A function for possibly selecting a single file from a sequence. */ - type Deduplicator = Seq[File] => Option[File] + type Deduplicator = Seq[FileRef] => Option[FileRef] } From 8158c602446b249a50c1fb0c878fb818090d447e Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Sat, 12 Oct 2024 08:05:05 -0500 Subject: [PATCH 12/18] Change type of PathMapping, add key converter for StringAttributeKey --- .../com/typesafe/sbt/PluginCompat.scala | 7 +++- .../com/typesafe/sbt/PluginCompat.scala | 8 +++- .../scala/com/typesafe/sbt/web/SbtWeb.scala | 41 +++++++++++-------- .../scala/com/typesafe/sbt/web/package.scala | 2 +- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala index 7d60e01..8645c72 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala @@ -19,5 +19,10 @@ private[sbt] object PluginCompat { def toFiles(cp: Seq[Attributed[File]])(implicit conv: FileConverter): Vector[File] = cp.map(_.data).toVector def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to[Set] - def classpathToFiles(classpath: Classpath): Seq[FileRef] = classpath.files + def classpathToFiles(classpath: Classpath)(implicit conv: FileConverter): Seq[FileRef] = + classpath.files + def toKey( settingKey: SettingKey[String] ): AttributeKey[String] = settingKey.key + def toNioPath(f: File)(implicit conv: FileConverter): NioPath = + f.toPath + def toFile(f: File)(implicit conv: FileConverter): File = f } diff --git a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala index 7a58f40..d9b5028 100644 --- a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala @@ -19,5 +19,11 @@ private[sbt] object PluginCompat: inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = toNioPaths(cp).map(_.toFile()) def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) - def classpathToFiles(classpath: Classpath): Seq[File] = toFiles(classpath) + inline def classpathToFiles(classpath: Classpath)(using conv: FileConverter): Seq[File] = + toFiles(classpath.to(Seq)) + inline def toKey( settingKey: SettingKey[String] ): StringAttributeKey = StringAttributeKey(settingKey.key.label) + def toNioPath(hvf: HashedVirtualFileRef)(using conv: FileConverter): NioPath = + conv.toPath(hvf) + def toFile(hvf: HashedVirtualFileRef)(using conv: FileConverter): File = + toNioPath(hvf).toFile() end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 355d5c1..78f13af 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -1,6 +1,6 @@ package com.typesafe.sbt.web -import sbt.{ Def, *, given } +import sbt.{Def, given, *} import sbt.internal.inc.Analysis import sbt.internal.io.Source import sbt.Keys.* @@ -10,9 +10,9 @@ import org.webjars.WebJarExtractor import org.webjars.WebJarAssetLocator.WEBJARS_PATH_PREFIX import com.typesafe.sbt.web.pipeline.Pipeline import com.typesafe.sbt.web.incremental.{ OpResult, OpSuccess, toStringInputHasher } -import xsbti.Reporter +import xsbti.{ Reporter, FileConverter } -import PluginCompat.* +import com.typesafe.sbt.PluginCompat.* object Import { @@ -234,8 +234,8 @@ object SbtWeb extends AutoPlugin { (TestAssets / webJars / webJarsCache) := webTarget.value / "web-modules" / "webjars-test.cache", (Assets / nodeModules / webJarsCache) := webTarget.value / "node-modules" / "webjars-main.cache", (TestAssets / nodeModules / webJarsCache) := webTarget.value / "node-modules" / "webjars-test.cache", - (Assets / webJarsClassLoader) := classLoader((Compile / dependencyClasspath).value), - (TestAssets / webJarsClassLoader) := classLoader((Test / dependencyClasspath).value), + (Assets / webJarsClassLoader) := classLoader((Compile / dependencyClasspath).value, fileConverter.value), + (TestAssets / webJarsClassLoader) := classLoader((Test / dependencyClasspath).value, fileConverter.value), assets := (Assets / assets).value, (Compile / packageBin / mappings) ++= { if ((Assets / addExportedMappingsToPackageBinMappings).value) { @@ -270,12 +270,13 @@ object SbtWeb extends AutoPlugin { allPipelineStages := Pipeline.chain(pipelineStages).value, pipeline := allPipelineStages.value((Assets / mappings).value), deduplicators := Nil, - pipeline := deduplicateMappings(pipeline.value, deduplicators.value), + pipeline := deduplicateMappings(pipeline.value, deduplicators.value, fileConverter.value), stagingDirectory := webTarget.value / "stage", stage := syncMappings( streams.value.cacheStoreFactory.make("sync-stage"), pipeline.value, - stagingDirectory.value + stagingDirectory.value, + fileConverter.value ) ) ++ inConfig(Assets)(unscopedAssetSettings) ++ inConfig(Assets)(nodeModulesSettings) ++ @@ -327,11 +328,12 @@ object SbtWeb extends AutoPlugin { allPipelineStages := Pipeline.chain(pipelineStages).value, mappings := allPipelineStages.value(mappings.value), deduplicators := Nil, - mappings := deduplicateMappings(mappings.value, deduplicators.value), + mappings := deduplicateMappings(mappings.value, deduplicators.value, fileConverter.value), assets := syncMappings( streams.value.cacheStoreFactory.make(s"sync-assets-" + configuration.value.name), mappings.value, - public.value + public.value, + fileConverter.value ), exportedMappings := createWebJarMappings.value, addExportedMappingsToPackageBinMappings := true, @@ -388,7 +390,8 @@ object SbtWeb extends AutoPlugin { syncMappings( streams.value.cacheStoreFactory.make("sync-exported-assets-" + configuration.value.name), exportedMappings.value, - syncTargetDir + syncTargetDir, + fileConverter.value ) } else @@ -431,7 +434,7 @@ object SbtWeb extends AutoPlugin { if (state.value.get(disableExportedProducts).getOrElse(false)) { Seq.empty } else { - Seq(Attributed.blank(exportTask.value).put(webModulesLib.key, moduleName.value)) + Seq(Attributed.blank(exportTask.value).put(toKey(webModulesLib), moduleName.value)) } } @@ -456,14 +459,14 @@ object SbtWeb extends AutoPlugin { * Get module names for all internal web module dependencies on the classpath. */ def getInternalWebModules(conf: Configuration): Def.Initialize[Task[Seq[String]]] = Def.task { - (conf / internalDependencyClasspath).value.flatMap(_.get(WebKeys.webModulesLib.key)) + (conf / internalDependencyClasspath).value.flatMap(_.get(toKey(WebKeys.webModulesLib))) } /** * Remove web module dependencies from a classpath. This is a helper method for Play 2.3 transitions. */ def classpathWithoutAssets(classpath: Classpath): Classpath = { - classpath.filter(_.get(WebKeys.webModulesLib.key).isEmpty) + classpath.filter(_.get(toKey(WebKeys.webModulesLib)).isEmpty) } def flattenDirectWebModules = Def.task { @@ -493,8 +496,10 @@ object SbtWeb extends AutoPlugin { prefixes.find(s.startsWith).fold(s)(s.stripPrefix) } - private def classLoader(classpath: Classpath): ClassLoader = + private def classLoader(classpath: Classpath, conv: FileConverter): ClassLoader = { + implicit val fc: FileConverter = conv new java.net.URLClassLoader(Path.toURLs(classpathToFiles(classpath)), null) + } private def withWebJarExtractor(to: File, cacheFile: File, classLoader: ClassLoader)( block: (WebJarExtractor, File) => Unit @@ -533,7 +538,8 @@ object SbtWeb extends AutoPlugin { * @return * the (possibly) deduplicated mappings */ - def deduplicateMappings(mappings: Seq[PathMapping], deduplicators: Seq[Deduplicator]): Seq[PathMapping] = { + def deduplicateMappings(mappings: Seq[PathMapping], deduplicators: Seq[Deduplicator], conv: FileConverter): Seq[PathMapping] = { + implicit val fc: FileConverter = conv if (deduplicators.isEmpty) { mappings } else { @@ -608,9 +614,10 @@ object SbtWeb extends AutoPlugin { * @return * the target value */ - def syncMappings(cacheStore: sbt.util.CacheStore, mappings: Seq[PathMapping], target: File): File = { + def syncMappings(cacheStore: sbt.util.CacheStore, mappings: Seq[PathMapping], target: File, conv: FileConverter): File = { + implicit val fc: FileConverter = conv val copies = mappings map { case (file, path) => - file -> (target / path) + toFile(file) -> (target / path) } Sync.sync(cacheStore)(copies) target diff --git a/src/main/scala/com/typesafe/sbt/web/package.scala b/src/main/scala/com/typesafe/sbt/web/package.scala index 831efc9..ac89093 100644 --- a/src/main/scala/com/typesafe/sbt/web/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/package.scala @@ -9,7 +9,7 @@ package object web { /** * Describes a string path relative to a base directory. */ - type PathMapping = (File, String) + type PathMapping = (FileRef, String) /** * A function for possibly selecting a single file from a sequence. From e80bc74fba54bf999686f579adfda6e2567522cd Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:24:01 -0500 Subject: [PATCH 13/18] No more type errors, yay! --- .../com/typesafe/sbt/PluginCompat.scala | 5 ++++ .../com/typesafe/sbt/PluginCompat.scala | 12 +++++++--- .../scala/com/typesafe/sbt/web/SbtWeb.scala | 24 ++++++------------- .../scala/com/typesafe/sbt/web/package.scala | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala index 8645c72..0179f19 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala @@ -25,4 +25,9 @@ private[sbt] object PluginCompat { def toNioPath(f: File)(implicit conv: FileConverter): NioPath = f.toPath def toFile(f: File)(implicit conv: FileConverter): File = f + + def toFileRef(f: File)(implicit conv: FileConverter): FileRef = f + + def selectFirstPredicate: Seq[FileRef] => Boolean = files => + files.forall(_.isFile) && files.map(_.hashString).distinct.size == 1 } diff --git a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala index d9b5028..bb348a3 100644 --- a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala @@ -13,11 +13,11 @@ private[sbt] object PluginCompat: def toNioPath(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): NioPath = conv.toPath(a.data) inline def toFile(a: Attributed[HashedVirtualFileRef])(using conv: FileConverter): File = - toNioPath(a).toFile() + toNioPath(a).toFile def toNioPaths(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[NioPath] = cp.map(toNioPath).toVector inline def toFiles(cp: Seq[Attributed[HashedVirtualFileRef]])(using conv: FileConverter): Vector[File] = - toNioPaths(cp).map(_.toFile()) + toNioPaths(cp).map(_.toFile) def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) inline def classpathToFiles(classpath: Classpath)(using conv: FileConverter): Seq[File] = toFiles(classpath.to(Seq)) @@ -25,5 +25,11 @@ private[sbt] object PluginCompat: def toNioPath(hvf: HashedVirtualFileRef)(using conv: FileConverter): NioPath = conv.toPath(hvf) def toFile(hvf: HashedVirtualFileRef)(using conv: FileConverter): File = - toNioPath(hvf).toFile() + toNioPath(hvf).toFile + + def toFileRef(file: File)(using conv: FileConverter): FileRef = + conv.toVirtualFile(file.toPath) + + inline def selectFirstPredicate(using conv: FileConverter): Seq[FileRef] => Boolean = files => + files.forall(toFile(_).isFile) && files.map(_.contentHashStr).distinct.size == 1 end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 78f13af..2ff70fc 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -402,10 +402,11 @@ object SbtWeb extends AutoPlugin { * Create package mappings for assets in the webjar format. Use the webjars path prefix and exclude all web module * assets. */ - def createWebJarMappings: Def.Initialize[Task[Seq[(File, String)]]] = Def.task { + def createWebJarMappings: Def.Initialize[Task[Seq[(FileRef, String)]]] = Def.task { def webModule(file: File) = webModuleDirectories.value.exists(dir => IO.relativize(dir, file).isDefined) + implicit val fc: FileConverter = fileConverter.value mappings.value flatMap { - case (file, path) if webModule(file) => None + case (file, path) if webModule(toFile(file)) => None case (file, path) => Some(file -> (webJarsPathPrefix.value + path)) } } @@ -434,7 +435,8 @@ object SbtWeb extends AutoPlugin { if (state.value.get(disableExportedProducts).getOrElse(false)) { Seq.empty } else { - Seq(Attributed.blank(exportTask.value).put(toKey(webModulesLib), moduleName.value)) + implicit val fc: FileConverter = fileConverter.value + Seq(Attributed.blank(toFileRef(exportTask.value)).put(toKey(webModulesLib), moduleName.value)) } } @@ -546,9 +548,9 @@ object SbtWeb extends AutoPlugin { mappings.groupBy(_._2 /*path*/ ).toSeq flatMap { grouped => val (path, group) = grouped if (group.size > 1) { - val files = group.map(_._1) + val files = group.map(mapping => toFile(mapping._1)) val deduplicated = firstResult(deduplicators)(files) - deduplicated.fold(group)(file => Seq((file, path))) + deduplicated.fold(group)(file => Seq((toFileRef(file), path))) } else { group } @@ -563,18 +565,6 @@ object SbtWeb extends AutoPlugin { (fs.toStream flatMap { f => f(a).toSeq }).headOption } - /** - * Deduplicator that selects the first file contained in the base directory. - * - * @param base - * the base directory to check against - * @return - * a deduplicator function that prefers files in the base directory - */ - def selectFileFrom(base: File): Deduplicator = { (files: Seq[File]) => - files.find(_.relativeTo(base).isDefined) - } - /** * Deduplicator that checks whether all duplicates are directories and if so will simply select the first one. * diff --git a/src/main/scala/com/typesafe/sbt/web/package.scala b/src/main/scala/com/typesafe/sbt/web/package.scala index ac89093..63ac456 100644 --- a/src/main/scala/com/typesafe/sbt/web/package.scala +++ b/src/main/scala/com/typesafe/sbt/web/package.scala @@ -14,5 +14,5 @@ package object web { /** * A function for possibly selecting a single file from a sequence. */ - type Deduplicator = Seq[FileRef] => Option[FileRef] + type Deduplicator = Seq[File] => Option[File] } From 487ac15419c7fa063b71fd264dd30dd7cd198d0e Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:27:36 -0500 Subject: [PATCH 14/18] Fix test compilation errors --- .../sbt/web/incremental/IncrementalSpec.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala b/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala index 0a394a4..3426543 100644 --- a/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala +++ b/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala @@ -269,7 +269,7 @@ class IncrementalSpec extends Specification { IO.write(file2, "x") var hashPrefix = "" - implicit val hasher = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) + implicit val hasher: OpInputHasher[String] = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) // Cache ops with an initial hash prefix @@ -580,7 +580,7 @@ class IncrementalSpec extends Specification { IO.write(file2, "x") var hashPrefix = "" - implicit val hasher = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) + implicit val hasher: OpInputHasher[String] = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) // Cache ops with an initial hash prefix @@ -641,7 +641,7 @@ class IncrementalSpec extends Specification { "op1" -> OpSuccess(Set.empty, Set(file1)), "op2" -> OpSuccess(Set.empty, Set(file2)) ), - Unit + () ) } val (outputFiles, _) = syncIncremental(tmpDir, List("op1")) { prunedOps => @@ -673,7 +673,7 @@ class IncrementalSpec extends Specification { Map[String, OpResult]( "op1" -> OpSuccess(Set(infile), Set(file1, file2)) ), - Unit + () ) } @@ -709,7 +709,7 @@ class IncrementalSpec extends Specification { "op1" -> OpSuccess(Set(infile), Set(file1)), "op2" -> OpSuccess(Set.empty, Set(file2)) ), - Unit + () ) } @@ -721,7 +721,7 @@ class IncrementalSpec extends Specification { "op1" -> OpSuccess(Set(infile), Set.empty), "op3" -> OpSuccess(Set.empty, Set(file1, file2)) ), - Unit + () ) } From e60b33a68484898d2d2662f51758d986ec9c2369 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:50:38 -0500 Subject: [PATCH 15/18] Formatting fixes --- .../com/typesafe/sbt/PluginCompat.scala | 6 ++---- .../scala-3/com/typesafe/sbt/PluginCompat.scala | 6 ++---- .../scala/com/typesafe/sbt/web/SbtWeb.scala | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala index 0179f19..e1ac30f 100644 --- a/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-2.12/com/typesafe/sbt/PluginCompat.scala @@ -4,7 +4,7 @@ import sbt.* import sbt.Keys.Classpath import xsbti.FileConverter -import java.nio.file.Path as NioPath +import java.nio.file.{ Path => NioPath } private[sbt] object PluginCompat { type FileRef = java.io.File @@ -21,13 +21,11 @@ private[sbt] object PluginCompat { def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to[Set] def classpathToFiles(classpath: Classpath)(implicit conv: FileConverter): Seq[FileRef] = classpath.files - def toKey( settingKey: SettingKey[String] ): AttributeKey[String] = settingKey.key + def toKey(settingKey: SettingKey[String]): AttributeKey[String] = settingKey.key def toNioPath(f: File)(implicit conv: FileConverter): NioPath = f.toPath def toFile(f: File)(implicit conv: FileConverter): File = f - def toFileRef(f: File)(implicit conv: FileConverter): FileRef = f - def selectFirstPredicate: Seq[FileRef] => Boolean = files => files.forall(_.isFile) && files.map(_.hashString).distinct.size == 1 } diff --git a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala index bb348a3..6205cdf 100644 --- a/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala +++ b/src/main/scala-3/com/typesafe/sbt/PluginCompat.scala @@ -21,15 +21,13 @@ private[sbt] object PluginCompat: def toSet[A](iterable: Iterable[A]): Set[A] = iterable.to(Set) inline def classpathToFiles(classpath: Classpath)(using conv: FileConverter): Seq[File] = toFiles(classpath.to(Seq)) - inline def toKey( settingKey: SettingKey[String] ): StringAttributeKey = StringAttributeKey(settingKey.key.label) + inline def toKey(settingKey: SettingKey[String]): StringAttributeKey = StringAttributeKey(settingKey.key.label) def toNioPath(hvf: HashedVirtualFileRef)(using conv: FileConverter): NioPath = conv.toPath(hvf) def toFile(hvf: HashedVirtualFileRef)(using conv: FileConverter): File = toNioPath(hvf).toFile - - def toFileRef(file: File)(using conv: FileConverter): FileRef = + inline def toFileRef(file: File)(using conv: FileConverter): FileRef = conv.toVirtualFile(file.toPath) - inline def selectFirstPredicate(using conv: FileConverter): Seq[FileRef] => Boolean = files => files.forall(toFile(_).isFile) && files.map(_.contentHashStr).distinct.size == 1 end PluginCompat diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 2ff70fc..7378258 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -1,6 +1,6 @@ package com.typesafe.sbt.web -import sbt.{Def, given, *} +import sbt.{ Def, given, * } import sbt.internal.inc.Analysis import sbt.internal.io.Source import sbt.Keys.* @@ -407,7 +407,7 @@ object SbtWeb extends AutoPlugin { implicit val fc: FileConverter = fileConverter.value mappings.value flatMap { case (file, path) if webModule(toFile(file)) => None - case (file, path) => Some(file -> (webJarsPathPrefix.value + path)) + case (file, path) => Some(file -> (webJarsPathPrefix.value + path)) } } @@ -540,7 +540,11 @@ object SbtWeb extends AutoPlugin { * @return * the (possibly) deduplicated mappings */ - def deduplicateMappings(mappings: Seq[PathMapping], deduplicators: Seq[Deduplicator], conv: FileConverter): Seq[PathMapping] = { + def deduplicateMappings( + mappings: Seq[PathMapping], + deduplicators: Seq[Deduplicator], + conv: FileConverter + ): Seq[PathMapping] = { implicit val fc: FileConverter = conv if (deduplicators.isEmpty) { mappings @@ -604,7 +608,12 @@ object SbtWeb extends AutoPlugin { * @return * the target value */ - def syncMappings(cacheStore: sbt.util.CacheStore, mappings: Seq[PathMapping], target: File, conv: FileConverter): File = { + def syncMappings( + cacheStore: sbt.util.CacheStore, + mappings: Seq[PathMapping], + target: File, + conv: FileConverter + ): File = { implicit val fc: FileConverter = conv val copies = mappings map { case (file, path) => toFile(file) -> (target / path) From 22fd8c7608b892c751fb80d4a9a7e41a8e5f6394 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:53:30 -0500 Subject: [PATCH 16/18] Formatting fixes, part 2 --- build.sbt | 4 ++-- .../com/typesafe/sbt/web/incremental/IncrementalSpec.scala | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index fb35549..79f6171 100644 --- a/build.sbt +++ b/build.sbt @@ -41,6 +41,6 @@ Global / onLoad := (Global / onLoad).value.andThen { s => scalacOptions := { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, major)) => Seq("-Xsource:3") - case _ => Seq.empty + case _ => Seq.empty } -} \ No newline at end of file +} diff --git a/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala b/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala index 3426543..49dcb72 100644 --- a/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala +++ b/src/test/scala/com/typesafe/sbt/web/incremental/IncrementalSpec.scala @@ -269,7 +269,8 @@ class IncrementalSpec extends Specification { IO.write(file2, "x") var hashPrefix = "" - implicit val hasher: OpInputHasher[String] = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) + implicit val hasher: OpInputHasher[String] = + OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) // Cache ops with an initial hash prefix @@ -580,7 +581,8 @@ class IncrementalSpec extends Specification { IO.write(file2, "x") var hashPrefix = "" - implicit val hasher: OpInputHasher[String] = OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) + implicit val hasher: OpInputHasher[String] = + OpInputHasher[String](op => OpInputHash.hashString(hashPrefix + op)) // Cache ops with an initial hash prefix From cbee7d82af77de94ade575d9414e4a7da18fd785 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:12:10 -0500 Subject: [PATCH 17/18] Amend slash format, scala 2.12 scripted tests --- .../scala/com/typesafe/sbt/web/SbtWeb.scala | 20 +++++++++++++++---- src/sbt-test/sbt-web/asset-pipeline/build.sbt | 6 +++--- src/sbt-test/sbt-web/deduplicate/build.sbt | 2 +- src/sbt-test/sbt-web/dev-pipeline/build.sbt | 2 +- src/sbt-test/sbt-web/multi-module/build.sbt | 2 +- src/sbt-test/sbt-web/multi-module/test | 2 +- src/sbt-test/sbt-web/package/test | 2 +- 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 7378258..864db9e 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -128,16 +128,16 @@ object Import { * {{{ * + src * --+ main - * ----+ assets .....(sourceDirectory in Assets) + * ----+ assets .....(Assets / sourceDirectory) * ------+ js - * ----+ public .....(resourceDirectory in Assets) + * ----+ public .....(Assets / resourceDirectory) * ------+ css * ------+ images * ------+ js * --+ test - * ----+ assets .....(sourceDirectory in TestAssets) + * ----+ assets .....(TestAssets / sourceDirectory) * ------+ js - * ----+ public .....(resourceDirectory in TestAssets) + * ----+ public .....(TestAssets / resourceDirectory) * ------+ css * ------+ images * ------+ js @@ -569,6 +569,18 @@ object SbtWeb extends AutoPlugin { (fs.toStream flatMap { f => f(a).toSeq }).headOption } + /** + * Deduplicator that selects the first file contained in the base directory. + * + * @param base + * the base directory to check against + * @return + * a deduplicator function that prefers files in the base directory + */ + def selectFileFrom(base: File): Deduplicator = { (files: Seq[File]) => + files.find(_.relativeTo(base).isDefined) + } + /** * Deduplicator that checks whether all duplicates are directories and if so will simply select the first one. * diff --git a/src/sbt-test/sbt-web/asset-pipeline/build.sbt b/src/sbt-test/sbt-web/asset-pipeline/build.sbt index 3e48e43..cf6262f 100644 --- a/src/sbt-test/sbt-web/asset-pipeline/build.sbt +++ b/src/sbt-test/sbt-web/asset-pipeline/build.sbt @@ -8,17 +8,17 @@ val coffee = taskKey[Seq[File]]("mock coffeescript processing") coffee := { // translate .coffee files into .js files - val sourceDir = (sourceDirectory in Assets).value + val sourceDir = (Assets / sourceDirectory).value val targetDir = target.value / "cs-plugin" val sources = sourceDir ** "*.coffee" val mappings = sources pair Path.relativeTo(sourceDir) val renamed = mappings map { case (file, path) => file -> path.replaceAll("coffee", "js") } - val copies = renamed map { case (file, path) => file -> (resourceManaged in Assets).value / path } + val copies = renamed map { case (file, path) => file -> (Assets / resourceManaged).value / path } IO.copy(copies) copies map (_._2) } -sourceGenerators in Assets += coffee.taskValue +Assets / sourceGenerators += coffee.taskValue val jsmin = taskKey[Pipeline.Stage]("mock js minifier") diff --git a/src/sbt-test/sbt-web/deduplicate/build.sbt b/src/sbt-test/sbt-web/deduplicate/build.sbt index 4d46ea4..49f83e3 100644 --- a/src/sbt-test/sbt-web/deduplicate/build.sbt +++ b/src/sbt-test/sbt-web/deduplicate/build.sbt @@ -1,3 +1,3 @@ lazy val root = (project in file(".")).enablePlugins(SbtWeb) -WebKeys.deduplicators in Assets += SbtWeb.selectFileFrom((sourceDirectory in Assets).value) +Assets / WebKeys.deduplicators += SbtWeb.selectFileFrom((Assets / sourceDirectory).value) diff --git a/src/sbt-test/sbt-web/dev-pipeline/build.sbt b/src/sbt-test/sbt-web/dev-pipeline/build.sbt index c492e74..fdcc2cf 100644 --- a/src/sbt-test/sbt-web/dev-pipeline/build.sbt +++ b/src/sbt-test/sbt-web/dev-pipeline/build.sbt @@ -22,4 +22,4 @@ transform := { } } -pipelineStages in Assets := Seq(transform) +Assets / pipelineStages := Seq(transform) diff --git a/src/sbt-test/sbt-web/multi-module/build.sbt b/src/sbt-test/sbt-web/multi-module/build.sbt index f76e512..e1b06df 100644 --- a/src/sbt-test/sbt-web/multi-module/build.sbt +++ b/src/sbt-test/sbt-web/multi-module/build.sbt @@ -6,7 +6,7 @@ lazy val b = (project in file("modules/b")) .enablePlugins(SbtWeb) .dependsOn(c % "compile;test->test", d % "compile;test->test") .settings( - WebKeys.directWebModules in TestAssets := Nil + TestAssets / WebKeys.directWebModules := Nil ) lazy val c = (project in file("modules/c")) diff --git a/src/sbt-test/sbt-web/multi-module/test b/src/sbt-test/sbt-web/multi-module/test index b5f53c2..f70d68b 100644 --- a/src/sbt-test/sbt-web/multi-module/test +++ b/src/sbt-test/sbt-web/multi-module/test @@ -71,7 +71,7 @@ $ exists modules/e/target/web/public/test/lib/jquery/jquery.js # Let's optimize the syncing -> set trackInternalDependencies in ThisBuild := TrackLevel.TrackIfMissing +> set ThisBuild / trackInternalDependencies := TrackLevel.TrackIfMissing > a/assets diff --git a/src/sbt-test/sbt-web/package/test b/src/sbt-test/sbt-web/package/test index 96a6afe..689d52a 100644 --- a/src/sbt-test/sbt-web/package/test +++ b/src/sbt-test/sbt-web/package/test @@ -5,7 +5,7 @@ $ exists target/web-project-0.1-web-assets.jar $ exists extracted/js/a.js $ exists extracted/lib/jquery/jquery.js -> 'set WebKeys.packagePrefix in Assets := "public/"' +> 'set Assets / WebKeys.packagePrefix := "public/"' > web-assets:package $ delete extracted From 2e0bd4db54ab6f51d6a99d1966cd8e77de7b41f9 Mon Sep 17 00:00:00 2001 From: Billy Autrey <40704452+BillyAutrey@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:13:21 -0500 Subject: [PATCH 18/18] Formatting, the third --- src/main/scala/com/typesafe/sbt/web/SbtWeb.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala index 864db9e..94beb8c 100644 --- a/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala +++ b/src/main/scala/com/typesafe/sbt/web/SbtWeb.scala @@ -573,9 +573,9 @@ object SbtWeb extends AutoPlugin { * Deduplicator that selects the first file contained in the base directory. * * @param base - * the base directory to check against + * the base directory to check against * @return - * a deduplicator function that prefers files in the base directory + * a deduplicator function that prefers files in the base directory */ def selectFileFrom(base: File): Deduplicator = { (files: Seq[File]) => files.find(_.relativeTo(base).isDefined)