diff --git a/.github/workflows/client-test.yml b/.github/workflows/client-test.yml index b7aa93927..2b36eb49a 100644 --- a/.github/workflows/client-test.yml +++ b/.github/workflows/client-test.yml @@ -54,11 +54,11 @@ jobs: # test building sbtn on Linux (sbtw native-image dropped: scopt lazy vals break under Graal) sbt "-Dsbt.io.virtual=false" nativeImage # smoke test native Image - ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt about - ./client/target/bin/sbtn --sbt-script=$(pwd)/sbt shutdown + ./target/out/jvm/u/sbt-client/bin/sbtn --sbt-script=$(pwd)/sbt about + ./target/out/jvm/u/sbt-client/bin/sbtn --sbt-script=$(pwd)/sbt shutdown # test launcher script echo build using JDK 17 test using JDK 17 and JDK 25 - sbt -Dsbt.build.version=$TEST_SBT_VER launcherPackage/Rpm/packageBin launcherPackage/Debian/packageBin + sbt --server -Dsbt.build.version=$TEST_SBT_VER launcherPackage/Rpm/packageBin launcherPackage/Debian/packageBin sbt -Dsbt.build.version=$TEST_SBT_VER launcherPackageIntegrationTest/test cd launcher-package/citest && ./test.sh JAVA_HOME="$JAVA_HOME_25_X64" @@ -91,8 +91,8 @@ jobs: shell: bash run: | # smoke test native Image (sbtn) - ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat about - ./client/target/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat shutdown + ./target/out/jvm/u/sbt-client/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat about + ./target/out/jvm/u/sbt-client/bin/sbtn --sbt-script=$(pwd)/launcher-package/src/universal/bin/sbt.bat shutdown # test launcher script echo build using JDK 17 test using JDK 17 and JDK 25 launcher-package/bin/coursier.bat resolve diff --git a/.scalafmt.conf b/.scalafmt.conf index 74cd92451..f7bafc352 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -29,11 +29,11 @@ rewrite.scala3.newSyntax.control = false fileOverride { "glob:**/project/**" { - runner.dialect = scala212source3 + runner.dialect = scala3 runner.dialectOverride.allowAsForImportRename = false } "glob:**/*.sbt" { - runner.dialect = scala212source3 + runner.dialect = scala3 runner.dialectOverride.allowAsForImportRename = false } } diff --git a/build.sbt b/build.sbt index 3da599f28..877aea82d 100644 --- a/build.sbt +++ b/build.sbt @@ -91,7 +91,7 @@ def commonSettings: Seq[Setting[?]] = Def.settings( import scala.sys.process.* val devnull = ProcessLogger(_ => ()) val tagOrSha = - ("git describe --exact-match" #|| "git rev-parse HEAD").lineStream(devnull).head + ("git describe --exact-match" #|| "git rev-parse HEAD").lazyLines(devnull).head Seq( "-source-links:github://sbt/sbt", "-revision", @@ -214,7 +214,7 @@ lazy val sbtRoot: Project = (project in file(".")) } } val base = baseDirectory.value.toPath - val exec = (sbtClientProj / nativeImage).value.toPath + val exec = fileConverter.value.toPath((sbtClientProj / nativeImage).value) streams.value.log.info(s"installing thin client ${base.relativize(exec)} to ${target}") Files.copy(exec, target, java.nio.file.StandardCopyOption.REPLACE_EXISTING) } @@ -447,6 +447,7 @@ lazy val workerProj = (project in file("worker")) .dependsOn(exampleWorkProj % Test) .settings( name := "worker", + Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Raw, testedBaseSettings, Compile / doc / javacOptions := Nil, crossPaths := false, @@ -693,6 +694,7 @@ lazy val buildFileProj = (project in file("buildfile")) mainSettingsProj, ) .settings( + exportJars := false, testedBaseSettings, name := "build file", libraryDependencies ++= Seq(scalaCompiler), @@ -843,7 +845,11 @@ lazy val serverTestProj = (project in file("server-test")) Test / run / fork := true, Test / sourceGenerators += Def.task { val rawClasspath = - (Compile / fullClasspathAsJars).value.map(_.data).mkString(java.io.File.pathSeparator) + (Compile / fullClasspathAsJars).value + .map(_.data) + .map(fileConverter.value.toPath) + .map(_.toFile.getAbsolutePath) + .mkString(java.io.File.pathSeparator) val cp = if (scala.util.Properties.isWin) rawClasspath.replace("\\", "\\\\") else rawClasspath @@ -861,7 +867,7 @@ lazy val serverTestProj = (project in file("server-test")) val file = (Test / target).value / "generated" / "src" / "test" / "scala" / "testpkg" / "TestProperties.scala" IO.write(file, content) - file :: Nil + Seq(file) }, ) @@ -897,7 +903,7 @@ lazy val sbtClientProj = (project in file("client")) if (!Files.exists(outputDir)) { Files.createDirectories(outputDir) } - outputDir.resolve("sbtn").toFile + fileConverter.value.toVirtualFile(outputDir.resolve("sbtn")) }, nativeImageCommand := { val orig = nativeImageCommand.value @@ -1003,6 +1009,7 @@ lazy val sbtIgnoredProblems = { def scriptedTask(launch: Boolean): Def.Initialize[InputTask[Unit]] = Def.inputTask { val _ = publishLocalBinAll.value val launchJar = s"-Dsbt.launch.jar=${(bundledLauncherProj / Compile / packageBin).value}" + val converter = fileConverter.value Scripted.doScripted( (scriptedSbtProj / scalaInstance).value, scriptedSource.value, @@ -1014,10 +1021,12 @@ def scriptedTask(launch: Boolean): Def.Initialize[InputTask[Unit]] = Def.inputTa version.value, (scriptedSbtProj / Test / fullClasspathAsJars).value .map(_.data) + .map(converter.toPath) + .map(_.toFile) .filterNot(_.getName.contains("scala-compiler")), - (bundledLauncherProj / Compile / packageBin).value, + converter.toPath((bundledLauncherProj / Compile / packageBin).value).toFile, streams.value.log, - scriptedKeepTempDirectory.value, + local.LocalScriptedPlugin.autoImport.scriptedKeepTempDirectory.value, (scripted / includeFilter).value, (scripted / excludeFilter).value, ) @@ -1089,7 +1098,7 @@ lazy val nonRoots = allProjects.map(p => LocalProject(p.id)) ThisBuild / scriptedBufferLog := true ThisBuild / scriptedPrescripted := { _ => } -ThisBuild / scriptedKeepTempDirectory := false +ThisBuild / local.LocalScriptedPlugin.autoImport.scriptedKeepTempDirectory := false def otherRootSettings = Seq( @@ -1231,6 +1240,7 @@ lazy val lmIvy = (project in file("lm-ivy")) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .dependsOn(lmCore) .settings( + exportJars := false, commonSettings, lmTestSettings, name := "librarymanagement-ivy", @@ -1314,6 +1324,7 @@ lazy val lmCoursier = project lazy val lmCoursierShaded = project .in(file("lm-coursier/target/shaded-module")) .settings( + exportJars := false, lmCoursierSettings, Mima.settings, Mima.lmCoursierFilters, @@ -1410,13 +1421,15 @@ lazy val launcherPackageIntegrationTest = Test / fork := true, Test / javaOptions += { val cp = (Test / fullClasspath).value - .map(_.data.getAbsolutePath) + .map(_.data) + .map(fileConverter.value.toPath) + .map(_.toFile.getAbsolutePath) .mkString(java.io.File.pathSeparator) s"-Dsbt.test.classpath=$cp" }, Test / javaOptions += s"-Dsbt.test.integrationtest.basedir=${(baseDirectory).value.getAbsolutePath}", - Test / test := { - (Test / test) + Test / testFull := Def.uncached { + (Test / testFull) .dependsOn(launcherPackage / Universal / packageBin) .dependsOn(launcherPackage / Universal / stage) .value diff --git a/launcher-package/build.sbt b/launcher-package/build.sbt index ef87308fb..e9c31bfdd 100755 --- a/launcher-package/build.sbt +++ b/launcher-package/build.sbt @@ -54,9 +54,10 @@ lazy val isWindows: Boolean = lazy val isExperimental = sbtVersionToRelease.contains("RC") || sbtVersionToRelease.contains("M") val sbtLaunchJarUrl = SettingKey[String]("sbt-launch-jar-url") val sbtLaunchJarLocation = SettingKey[File]("sbt-launch-jar-location") -val sbtLaunchJar = TaskKey[File]("sbt-launch-jar", "Resolves SBT launch jar") +val sbtLaunchJar = TaskKey[HashedVirtualFileRef]("sbt-launch-jar", "Resolves SBT launch jar") val moduleID = (organization) apply { (o) => ModuleID(o, "sbt", sbtVersionToRelease) } -val sbtnJarsMappings = TaskKey[Seq[(File, String)]]("sbtn-jars-mappings", "Resolves sbtn JARs") +val sbtnJarsMappings = + TaskKey[Seq[(HashedVirtualFileRef, String)]]("sbtn-jars-mappings", "Resolves sbtn JARs") val sbtnJarsBaseUrl = SettingKey[String]("sbtn-jars-base-url") lazy val bintrayDebianUrl = settingKey[String]("API point for Debian packages") @@ -76,8 +77,10 @@ val bintrayReleaseAllStaged = val windowsBuildId = settingKey[Int]("build id for Windows installer") val debianBuildId = settingKey[Int]("build id for Debian") +@transient val exportRepoUsingCoursier = taskKey[File]("export Maven style repository") val exportRepoCsrDirectory = settingKey[File]("") +@transient val exportRepo = taskKey[File]("export Ivy style repository") val exportRepoDirectory = settingKey[File]("directory for exported repository") @@ -107,7 +110,7 @@ val launcherPackage = (project in file(".")) .settings( name := "sbt-launcher-packaging", packageName := "sbt", - crossTarget := target.value, + crossPaths := false, autoScalaLibrary := false, clean := { val _ = (dist / clean).value @@ -142,7 +145,7 @@ val launcherPackage = (project in file(".")) } } // TODO - GPG Trust validation. - file + fileConverter.value.toVirtualFile(file.toPath) }, sbtnJarsBaseUrl := "https://github.com/sbt/sbtn-dist/releases/download", sbtnJarsMappings := { @@ -226,14 +229,20 @@ val launcherPackage = (project in file(".")) IO.move(platformDir / "sbtn.exe", t / x86WindowsImageName) } if (!sbtIncludeSbtn) Seq() - else if (isWindows) Seq(t / x86WindowsImageName -> s"bin/$x86WindowsImageName") + else if (isWindows) + Seq( + fileConverter.value + .toVirtualFile((t / x86WindowsImageName).toPath) -> s"bin/$x86WindowsImageName" + ) else Seq( t / universalMacImageName -> s"bin/$universalMacImageName", t / x86LinuxImageName -> s"bin/$x86LinuxImageName", t / aarch64LinuxImageName -> s"bin/$aarch64LinuxImageName", t / x86WindowsImageName -> s"bin/$x86WindowsImageName" - ) + ).map { (k, v) => + fileConverter.value.toVirtualFile(k.toPath) -> v + } }, // GENERAL LINUX PACKAGING STUFFS @@ -332,7 +341,9 @@ val launcherPackage = (project in file(".")) Windows / packageName := packageName.value, Universal / version := sbtVersionToRelease, Universal / mappings += { - (baseDirectory.value.getParentFile / "sbt") -> ("bin" + java.io.File.separator + "sbt") + fileConverter.value.toVirtualFile( + (baseDirectory.value.getParentFile / "sbt").toPath + ) -> ("bin" + java.io.File.separator + "sbt") }, Universal / mappings := { val t = (Universal / target).value @@ -342,7 +353,7 @@ val launcherPackage = (project in file(".")) prev.toList map { case (k, BinSbt) => import java.nio.file.{ Files, FileSystems } - val x = IO.read(k) + val x = IO.read(fileConverter.value.toPath(k).toFile) IO.write( t / "sbt", x.replace( @@ -352,13 +363,13 @@ val launcherPackage = (project in file(".")) ) if (FileSystems.getDefault.supportedFileAttributeViews.contains("posix")) { - val perms = Files.getPosixFilePermissions(k.toPath) + val perms = Files.getPosixFilePermissions(fileConverter.value.toPath(k)) Files.setPosixFilePermissions((t / "sbt").toPath, perms) } - (t / "sbt", BinSbt) + (fileConverter.value.toVirtualFile((t / "sbt").toPath), BinSbt) case (k, BinBat) => - val x = IO.read(k) + val x = IO.read(fileConverter.value.toPath(k).toFile) IO.write( t / "sbt.bat", x.replace( @@ -366,7 +377,7 @@ val launcherPackage = (project in file(".")) s"set init_sbt_version=$sbtVersionToRelease" ) ) - (t / "sbt.bat", BinBat) + (fileConverter.value.toVirtualFile((t / "sbt.bat").toPath), BinBat) case (k, v) => (k, v) } }, @@ -377,29 +388,34 @@ val launcherPackage = (project in file(".")) sbtLaunchJar.value -> "bin/sbt-launch.jar" ) } - else Def.task { Seq[(File, String)]() } + else Def.task { Seq[(HashedVirtualFileRef, String)]() } }).value, Universal / mappings ++= sbtnJarsMappings.value, Universal / mappings ++= (Def.taskDyn { if (sbtOfflineInstall && sbtVersionToRelease.startsWith("1.")) Def.task { val _ = ((dist / exportRepoUsingCoursier)).value - directory(((dist / target)).value / "lib") + directory(((dist / target)).value / "lib").map { (k, v) => + fileConverter.value.toVirtualFile(k.toPath) -> v + } } else if (sbtOfflineInstall) Def.task { val _ = ((dist / exportRepo)).value - directory(((dist / target)).value / "lib") + directory(((dist / target)).value / "lib").map { (k, v) => + fileConverter.value.toVirtualFile(k.toPath) -> v + } } - else Def.task { Seq[(File, String)]() } + else Def.task { Seq[(HashedVirtualFileRef, String)]() } }).value, Universal / mappings ++= { val base = baseDirectory.value + val converter = fileConverter.value if (sbtVersionToRelease.startsWith("0.13.")) Nil else - Seq[(File, String)]( - base.getParentFile / "LICENSE" -> "LICENSE", - base / "NOTICE" -> "NOTICE" + Seq[(HashedVirtualFileRef, String)]( + converter.toVirtualFile((base.getParentFile / "LICENSE").toPath) -> "LICENSE", + converter.toVirtualFile((base / "NOTICE").toPath) -> "NOTICE" ) }, @@ -458,7 +474,7 @@ def makePublishToForConfig(config: Configuration) = { }, publishTo := { val (id, url, pattern) = bintrayTripple.value - val resolver = Resolver.url(id, new URI(url).toURL)(Patterns(pattern)) + val resolver = Resolver.url(id, new URI(url).toURL)(using Patterns(pattern)) Some(resolver) } ) diff --git a/launcher-package/integration-test/src/test/scala/ExtendedRunnerTest.scala b/launcher-package/integration-test/src/test/scala/ExtendedRunnerTest.scala index 90016e224..cb49e97e8 100755 --- a/launcher-package/integration-test/src/test/scala/ExtendedRunnerTest.scala +++ b/launcher-package/integration-test/src/test/scala/ExtendedRunnerTest.scala @@ -84,11 +84,11 @@ object ExtendedRunnerTest extends BasicTestSuite: "compile", "-v", "--sbt-jar", - "../target/universal/stage/bin/sbt-launch.jar" + "../../target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/sbt-launcher.jar" ).!!.linesIterator.toList assert( - out.contains[String]("../target/universal/stage/bin/sbt-launch.jar") || - out.contains[String]("\"../target/universal/stage/bin/sbt-launch.jar\"") + out.contains[String]("../../target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/sbt-launcher.jar") || + out.contains[String]("\"../../target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/sbt-launcher.jar\"") ) () } diff --git a/launcher-package/integration-test/src/test/scala/IntegrationTestPaths.scala b/launcher-package/integration-test/src/test/scala/IntegrationTestPaths.scala index 0978beddf..e477526e3 100644 --- a/launcher-package/integration-test/src/test/scala/IntegrationTestPaths.scala +++ b/launcher-package/integration-test/src/test/scala/IntegrationTestPaths.scala @@ -16,11 +16,11 @@ object IntegrationTestPaths { baseDir match { case Some(b) => val name = if (isWindows) "sbt.bat" else "sbt" - new File(b.getParentFile, s"target/universal/stage/bin/$name").getAbsoluteFile + new File(b.getParentFile.getParentFile, s"target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/$name").getAbsoluteFile case None => val rel = - if (isWindows) "../target/universal/stage/bin/sbt.bat" - else "../target/universal/stage/bin/sbt" + if (isWindows) "../../target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/sbt.bat" + else "../../target/out/jvm/u/sbt-launcher-packaging/universal/stage/bin/sbt" new File(rel).getAbsoluteFile } diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index 386eab8c8..63228435f 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -1,5 +1,6 @@ import sbt.* import Keys.* +import sbt.util.CacheImplicits.given object HouseRulesPlugin extends AutoPlugin { override def requires = plugins.JvmPlugin diff --git a/project/PackageSignerPlugin.scala b/project/PackageSignerPlugin.scala index 587b3e091..0c47efbca 100644 --- a/project/PackageSignerPlugin.scala +++ b/project/PackageSignerPlugin.scala @@ -1,5 +1,6 @@ import sbt.* import Keys.* +import sbt.util.CacheImplicits.given import sbt.internal.librarymanagement.IvyActions import com.jsuereth.sbtpgp.SbtPgp import com.typesafe.sbt.packager.universal.{ UniversalPlugin, UniversalDeployPlugin } @@ -25,28 +26,34 @@ object PackageSignerPlugin extends sbt.AutoPlugin { art.withExtension(ext) def packageSignerSettings: Seq[Setting[?]] = Seq( - signedArtifacts := { + signedArtifacts := Def.uncached { val artifacts = packagedArtifacts.value val r = pgpSigner.value val skipZ = (pgpSigner / skip).value val s = streams.value + val converter = fileConverter.value if (!skipZ) { - artifacts flatMap { case (art, f) => + artifacts flatMap { case (art, virtualFile) => + val f = converter.toPath(virtualFile).toFile Seq( - art -> f, + art -> virtualFile, subExtension(art, art.extension + gpgExtension) -> - r.sign(f, file(f.getAbsolutePath + gpgExtension), s) + converter.toVirtualFile(r.sign(f, file(f.getAbsolutePath + gpgExtension), s).toPath) ) } } else artifacts }, publishSignedConfiguration := Classpaths.publishConfig( publishMavenStyle = publishMavenStyle.value, - deliverIvyPattern = - (Compile / packageBin / artifactPath).value.getParent + "/[artifact]-[revision](-[classifier]).[ext]", + deliverIvyPattern = fileConverter.value + .toPath((Compile / packageBin / artifactPath).value) + .toFile + .getParent + "/[artifact]-[revision](-[classifier]).[ext]", status = if (isSnapshot.value) "integration" else "release", configurations = Vector.empty, - artifacts = signedArtifacts.value.toVector, + artifacts = signedArtifacts.value.map { (k, v) => + k -> fileConverter.value.toPath(v).toFile + }.toVector, checksums = (publish / checksums).value.toVector, resolverName = Classpaths.getPublishTo(publishTo.value).name, logging = ivyLoggingLevel.value, @@ -54,11 +61,15 @@ object PackageSignerPlugin extends sbt.AutoPlugin { ), publishLocalSignedConfiguration := Classpaths.publishConfig( publishMavenStyle = publishMavenStyle.value, - deliverIvyPattern = - (Compile / packageBin / artifactPath).value.getParent + "/[artifact]-[revision](-[classifier]).[ext]", + deliverIvyPattern = fileConverter.value + .toPath((Compile / packageBin / artifactPath).value) + .toFile + .getParent + "/[artifact]-[revision](-[classifier]).[ext]", status = if (isSnapshot.value) "integration" else "release", configurations = Vector.empty, - artifacts = signedArtifacts.value.toVector, + artifacts = signedArtifacts.value.map { (k, v) => + k -> fileConverter.value.toPath(v).toFile + }.toVector, checksums = (publish / checksums).value.toVector, resolverName = "local", logging = ivyLoggingLevel.value, diff --git a/project/PublishBinPlugin.scala b/project/PublishBinPlugin.scala index c69fea7bd..2bad88cf2 100644 --- a/project/PublishBinPlugin.scala +++ b/project/PublishBinPlugin.scala @@ -3,6 +3,7 @@ package sbt import java.nio.file.{ FileAlreadyExistsException, Files } import sbt.Keys.* +import sbt.util.CacheImplicits.given import sbt.internal.librarymanagement.IvyXml /** This local plugin provides ways of publishing just the binary jar. */ @@ -15,48 +16,57 @@ object PublishBinPlugin extends AutoPlugin { } import autoImport.* - private val dummyDoc = taskKey[File]("").withRank(Int.MaxValue) + private val dummyDoc = taskKey[HashedVirtualFileRef]("").withRank(Int.MaxValue) override val globalSettings = Seq(publishLocalBin := (())) override val projectSettings: Seq[Def.Setting[?]] = Def.settings( publishLocalBin := Classpaths .publishOrSkip(publishLocalBinConfig, publishLocalBin / skip) .value, - publishLocalBinConfig := Classpaths.publishConfig( - false, // publishMavenStyle.value, - Classpaths.deliverPattern(crossTarget.value), - if (isSnapshot.value) "integration" else "release", - ivyConfigurations.value.map(c => ConfigRef(c.name)).toVector, - (publishLocalBin / packagedArtifacts).value.toVector, - (publishLocalBin / checksums).value.toVector, - logging = ivyLoggingLevel.value, - overwrite = isSnapshot.value - ), - publishLocalBinConfig := publishLocalBinConfig - .dependsOn( - // Copied from sbt.internal. - Def.task { - val currentProject = { - val proj = csrProject.value - val publications = csrPublications.value - proj.withPublications(publications) - } - IvyXml.writeFiles(currentProject, None, ivySbt.value, streams.value.log) - } + publishLocalBinConfig := Def.uncached( + Classpaths.publishConfig( + false, // publishMavenStyle.value, + Classpaths.deliverPattern(crossTarget.value), + if (isSnapshot.value) "integration" else "release", + ivyConfigurations.value.map(c => ConfigRef(c.name)).toVector, + (publishLocalBin / packagedArtifacts).value.map { (k, v) => + k -> fileConverter.value.toPath(v).toFile + }.toVector, + (publishLocalBin / checksums).value.toVector, + logging = ivyLoggingLevel.value, + overwrite = isSnapshot.value ) - .value, + ), + publishLocalBinConfig := Def.uncached( + publishLocalBinConfig + .dependsOn( + // Copied from sbt.internal. + Def.task { + val currentProject = { + val proj = csrProject.value + val publications = csrPublications.value + proj.withPublications(publications) + } + IvyXml.writeFiles(currentProject, None, ivySbt.value, streams.value.log, Nil) + } + ) + .value + ), dummyDoc := { val dummyFile = streams.value.cacheDirectory / "doc.jar" try { Files.createDirectories(dummyFile.toPath.getParent) Files.createFile(dummyFile.toPath) } catch { case _: FileAlreadyExistsException => } - dummyFile + fileConverter.value.toVirtualFile(dummyFile.toPath) }, - dummyDoc / packagedArtifact := (Compile / packageDoc / artifact).value -> dummyDoc.value, - publishLocalBin / packagedArtifacts := + dummyDoc / packagedArtifact := Def.uncached( + (Compile / packageDoc / artifact).value -> dummyDoc.value + ), + publishLocalBin / packagedArtifacts := Def.uncached( Classpaths .packaged(Seq(Compile / packageBin, Compile / packageSrc, makePom, dummyDoc)) .value + ) ) } diff --git a/project/SbtLauncherPlugin.scala b/project/SbtLauncherPlugin.scala index d073b2714..ffb927c07 100644 --- a/project/SbtLauncherPlugin.scala +++ b/project/SbtLauncherPlugin.scala @@ -1,23 +1,30 @@ import sbt.Keys.* import sbt.* import sbt.io.CopyOptions +import sbt.util.CacheImplicits.given object SbtLauncherPlugin extends AutoPlugin { override def requires = plugins.IvyPlugin object autoImport { val SbtLaunchConfiguration = config("sbt-launch") - val sbtLaunchJar = taskKey[File]("constructs an sbt-launch.jar for this version of sbt.") + val sbtLaunchJar = + taskKey[HashedVirtualFileRef]("constructs an sbt-launch.jar for this version of sbt.") val rawSbtLaunchJar = - taskKey[File]("The released version of the sbt-launcher we use to bundle this application.") + taskKey[HashedVirtualFileRef]( + "The released version of the sbt-launcher we use to bundle this application." + ) } import autoImport.* override def projectConfigurations: Seq[Configuration] = Seq(SbtLaunchConfiguration) override def projectSettings: Seq[Setting[?]] = Seq( libraryDependencies += Dependencies.rawLauncher % SbtLaunchConfiguration.name, - rawSbtLaunchJar := { - Classpaths.managedJars(SbtLaunchConfiguration, Set("jar"), update.value).headOption match { + rawSbtLaunchJar := Def.uncached { + val converter = fileConverter.value + Classpaths + .managedJars(SbtLaunchConfiguration, Set("jar"), update.value, converter) + .headOption match { case Some(jar) => jar.data case None => sys.error( @@ -25,7 +32,7 @@ object SbtLauncherPlugin extends AutoPlugin { ) } }, - sbtLaunchJar := { + sbtLaunchJar := Def.uncached { val propFiles = (Compile / resources).value val propFileLocations = for (file <- propFiles; if file.getName != "resources") yield { @@ -33,7 +40,13 @@ object SbtLauncherPlugin extends AutoPlugin { else file.getName -> file } // TODO - We need to inject the appropriate boot.properties file for this version of sbt. - rebundle(rawSbtLaunchJar.value, propFileLocations.toMap, target.value / "sbt-launch.jar") + fileConverter.value.toVirtualFile( + rebundle( + fileConverter.value.toPath(rawSbtLaunchJar.value).toFile, + propFileLocations.toMap, + target.value / "sbt-launch.jar" + ).toPath + ) } ) diff --git a/project/Scripted.scala b/project/Scripted.scala index 71b343a12..a6fab8e6a 100644 --- a/project/Scripted.scala +++ b/project/Scripted.scala @@ -6,7 +6,7 @@ import sbt.* import sbt.internal.inc.ScalaInstance import sbt.internal.inc.classpath.{ ClasspathUtilities, FilteredLoader } import scala.annotation.nowarn -import scala.collection.JavaConverters.* +import scala.jdk.CollectionConverters.* object LocalScriptedPlugin extends AutoPlugin { override def requires = plugins.JvmPlugin @@ -21,6 +21,7 @@ trait ScriptedKeys { "Saves you some time when only your test has changed" ) val scriptedSource = settingKey[File]("") + @transient val scriptedPrescripted = taskKey[File => Unit]("") val scriptedKeepTempDirectory = settingKey[Boolean]( "If true, keeps the temporary directory after scripted tests complete for debugging." @@ -63,10 +64,10 @@ object Scripted { val p = f.getParentFile (p.getParentFile.getName, p.getName) } - val pairMap = pairs.groupBy(_._1).mapValues(_.map(_._2).toSet) + val pairMap = pairs.groupBy(_._1).view.mapValues(_.map(_._2).toSet).toMap val id = charClass(c => !c.isWhitespace && c != '/').+.string - val groupP = token(id.examples(pairMap.keySet)) <~ token('/') + val groupP = token(id.examples(pairMap.keySet.toSet)) <~ token('/') // A parser for page definitions val pageNumber = (NatBasic & not('0', "zero page number")).flatMap { i => @@ -128,9 +129,6 @@ object Scripted { logger.info(s"Tests selected: ${args.mkString("\n * ", "\n * ", "\n")}") logger.info("") - // Force Log4J to not use a thread context classloader otherwise it throws a CCE - sys.props(org.apache.logging.log4j.util.LoaderUtil.IGNORE_TCCL_PROPERTY) = "true" - val noJLine = new FilteredLoader(scriptedSbtInstance.loader, "jline." :: Nil) val loader = ClasspathUtilities.toLoader(classpath, noJLine) val bridgeClass = Class.forName("sbt.scriptedtest.ScriptedRunner", true, loader) @@ -171,7 +169,7 @@ object Scripted { case i if i > 0 => i case _ => 1 } - import scala.language.reflectiveCalls + import scala.reflect.Selectable.reflectiveSelectable bridge.runInParallel( sourcePath, diff --git a/project/Utils.scala b/project/Utils.scala index 403ea2ea9..38db2f21d 100644 --- a/project/Utils.scala +++ b/project/Utils.scala @@ -1,5 +1,7 @@ import scala.util.control.NonFatal import sbt.* +import sbt.given +import sbt.util.CacheImplicits.given import Keys.* import scalafix.sbt.ScalafixPlugin.autoImport.scalafix @@ -9,7 +11,9 @@ object Utils { val ExclusiveTest: Tags.Tag = Tags.Tag("exclusive-test") val componentID: SettingKey[Option[String]] = settingKey[Option[String]]("") + @transient val scalaKeywords: TaskKey[Set[String]] = taskKey[Set[String]]("") + @transient val generateKeywords: TaskKey[File] = taskKey[File]("") val sbtnVersion = SettingKey[String]("sbtn-version") @@ -66,7 +70,7 @@ object Utils { IO.read(propFile).contains(versionLine(version)) def publishPomSettings: Seq[Setting[?]] = Seq( - pomPostProcess := cleanPom _ + pomPostProcess := cleanPom ) def cleanPom(pomNode: scala.xml.Node) = { @@ -100,12 +104,11 @@ object Utils { } def getScalaKeywords: Set[String] = { - val g = new scala.tools.nsc.Global(new scala.tools.nsc.Settings) - g.nme.keywords.map(_.toString) + dotty.tools.dotc.core.StdNames.nme.keywords.map(_.toString).toSet } def writeScalaKeywords(base: File, keywords: Set[String]): File = { - val init = keywords.map(tn => '"' + tn + '"').mkString("Set(", ", ", ")") + val init = keywords.map(tn => "\"" + tn + "\"").mkString("Set(", ", ", ")") val ObjectName = "ScalaKeywords" val PackageName = "sbt.internal.util" val keywordsSrc = s""" @@ -123,7 +126,9 @@ object Utils { inConfig(Compile)( Seq( scalaKeywords := getScalaKeywords, - generateKeywords := writeScalaKeywords(sourceManaged.value, scalaKeywords.value), + generateKeywords := Def.uncached( + writeScalaKeywords(sourceManaged.value, scalaKeywords.value) + ), sourceGenerators += Def.task(Seq(generateKeywords.value)).taskValue ) ) @@ -145,6 +150,7 @@ object Utils { object Licensed { lazy val notice = SettingKey[Option[File]]("notice") + @transient lazy val extractLicenses = TaskKey[Seq[File]]("extract-licenses") lazy val seeRegex = """\(see (.*?)\)""".r diff --git a/project/build.properties b/project/build.properties index 6edd024b6..8e5bca2e2 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.12.10 +sbt.version=2.0.0-RC13 diff --git a/project/plugins.sbt b/project/plugins.sbt index a6a70315a..9a24fa9b4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ Global / semanticdbVersion := "4.15.2" -scalacOptions ++= Seq("-feature", "-Ywarn-unused:_,-imports") +scalacOptions ++= Seq("-feature", "-language:implicitConversions") addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.1.1") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.1") diff --git a/sbt-app/src/sbt-test/ivy/build-deps/project/plugins.sbt b/sbt-app/src/sbt-test/ivy/build-deps/project/plugins.sbt index abe6a97a4..15c7fdd35 100644 --- a/sbt-app/src/sbt-test/ivy/build-deps/project/plugins.sbt +++ b/sbt-app/src/sbt-test/ivy/build-deps/project/plugins.sbt @@ -1,4 +1,5 @@ -libraryDependencies += { - val sbtV = sbtVersion.value - ("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive() -} +libraryDependencies += Defaults.sbtPluginExtra( + "org.scala-sbt" % "sbt-ivy" % sbtVersion.value, + sbtVersion.value, + scalaVersion.value, +) diff --git a/sbt-app/src/sbt-test/ivy/deliver-artifacts/project/plugins.sbt b/sbt-app/src/sbt-test/ivy/deliver-artifacts/project/plugins.sbt index abe6a97a4..15c7fdd35 100644 --- a/sbt-app/src/sbt-test/ivy/deliver-artifacts/project/plugins.sbt +++ b/sbt-app/src/sbt-test/ivy/deliver-artifacts/project/plugins.sbt @@ -1,4 +1,5 @@ -libraryDependencies += { - val sbtV = sbtVersion.value - ("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive() -} +libraryDependencies += Defaults.sbtPluginExtra( + "org.scala-sbt" % "sbt-ivy" % sbtVersion.value, + sbtVersion.value, + scalaVersion.value, +) diff --git a/sbt-app/src/sbt-test/ivy/exclude-dependencies/project/plugins.sbt b/sbt-app/src/sbt-test/ivy/exclude-dependencies/project/plugins.sbt index abe6a97a4..15c7fdd35 100644 --- a/sbt-app/src/sbt-test/ivy/exclude-dependencies/project/plugins.sbt +++ b/sbt-app/src/sbt-test/ivy/exclude-dependencies/project/plugins.sbt @@ -1,4 +1,5 @@ -libraryDependencies += { - val sbtV = sbtVersion.value - ("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive() -} +libraryDependencies += Defaults.sbtPluginExtra( + "org.scala-sbt" % "sbt-ivy" % sbtVersion.value, + sbtVersion.value, + scalaVersion.value, +) diff --git a/sbt-app/src/sbt-test/ivy/make-ivy-xml/project/plugins.sbt b/sbt-app/src/sbt-test/ivy/make-ivy-xml/project/plugins.sbt index abe6a97a4..15c7fdd35 100644 --- a/sbt-app/src/sbt-test/ivy/make-ivy-xml/project/plugins.sbt +++ b/sbt-app/src/sbt-test/ivy/make-ivy-xml/project/plugins.sbt @@ -1,4 +1,5 @@ -libraryDependencies += { - val sbtV = sbtVersion.value - ("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive() -} +libraryDependencies += Defaults.sbtPluginExtra( + "org.scala-sbt" % "sbt-ivy" % sbtVersion.value, + sbtVersion.value, + scalaVersion.value, +) diff --git a/sbt-app/src/sbt-test/ivy/provided-multi/project/plugins.sbt b/sbt-app/src/sbt-test/ivy/provided-multi/project/plugins.sbt index abe6a97a4..15c7fdd35 100644 --- a/sbt-app/src/sbt-test/ivy/provided-multi/project/plugins.sbt +++ b/sbt-app/src/sbt-test/ivy/provided-multi/project/plugins.sbt @@ -1,4 +1,5 @@ -libraryDependencies += { - val sbtV = sbtVersion.value - ("org.scala-sbt" % s"sbt-ivy_sbt${sbtV}_${scalaBinaryVersion.value}" % sbtV).intransitive() -} +libraryDependencies += Defaults.sbtPluginExtra( + "org.scala-sbt" % "sbt-ivy" % sbtVersion.value, + sbtVersion.value, + scalaVersion.value, +) diff --git a/scripts/lm-coursier-ci.sh b/scripts/lm-coursier-ci.sh index a03de4565..e2d4f414c 100755 --- a/scripts/lm-coursier-ci.sh +++ b/scripts/lm-coursier-ci.sh @@ -19,7 +19,7 @@ else fi # publishing locally to ensure shading runs fine -./lm-coursier/metadata/scripts/with-test-repo.sh $SBT \ +./lm-coursier/metadata/scripts/with-test-repo.sh $SBT --server \ lmCoursierShadedPublishing/publishLocal \ lmCoursier/test \ 'scripted lm-coursier/*'