From 8865565004a4c1b855526a96b1a9c3b340bf9100 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 10 Apr 2024 11:50:59 +0200 Subject: [PATCH] Fix classloader-cache/resources --- main/src/main/scala/sbt/Defaults.scala | 37 +++++++++++++------ main/src/main/scala/sbt/Keys.scala | 2 +- sbt-app/src/sbt-test/actions/call/build.sbt | 7 ++-- sbt-app/src/sbt-test/actions/call/test | 2 - .../sbt-test/actions/compile-clean/build.sbt | 3 +- .../src/sbt-test/actions/compile-clean/test | 26 ++++++------- .../resources/{pending => test} | 2 +- .../sbt-test/java/track-anonymous/build.sbt | 1 + .../src/sbt-test/java/track-anonymous/test | 2 - .../source-dependencies/compactify/build.sbt | 10 +++-- .../test/scala/testpkg/BuildServerTest.scala | 2 +- 11 files changed, 53 insertions(+), 41 deletions(-) rename sbt-app/src/sbt-test/classloader-cache/resources/{pending => test} (97%) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index f41c7fda5..93905ea88 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -663,7 +663,7 @@ object Defaults extends BuildCommon { classDirectory := target.value / (prefix(configuration.value.name) + "classes"), backendOutput := { val converter = fileConverter.value - val dir = classDirectory.value + val dir = target.value / (prefix(configuration.value.name) + "backend") converter.toVirtualFile(dir.toPath) }, earlyOutput / artifactPath := configArtifactPathSetting(artifact, "early").value, @@ -913,11 +913,16 @@ object Defaults extends BuildCommon { tastyFiles := Def.taskIf { if (ScalaArtifacts.isScala3(scalaVersion.value)) { val _ = compile.value - val tastyFiles = classDirectory.value.**("*.tasty").get() + val c = fileConverter.value + val dir = c.toPath(backendOutput.value).toFile + val tastyFiles = dir.**("*.tasty").get() tastyFiles.map(_.getAbsoluteFile) } else Nil }.value, - clean := (compileOutputs / clean).value, + clean := { + (compileOutputs / clean).value + (products / clean).value + }, earlyOutputPing := Def.promise[Boolean], compileProgress := { val s = streams.value @@ -2458,8 +2463,14 @@ object Defaults extends BuildCommon { val reporter = (compile / bspReporter).value val store = analysisStore(compileAnalysisFile) val ci = (compile / compileInputs).value + val c = fileConverter.value + val dir = c.toPath(backendOutput.value).toFile result match case Result.Value(res) => + val rawJarPath = c.toPath(res._2) + IO.delete(dir) + IO.unzip(rawJarPath.toFile, dir) + IO.delete(dir / "META-INF" / "MANIFEST.MF") val analysis = store.unsafeGet().getAnalysis() reporter.sendSuccessReport(analysis) bspTask.notifySuccess(analysis) @@ -2497,9 +2508,7 @@ object Defaults extends BuildCommon { val contents = AnalysisContents.create(analysisResult.analysis(), analysisResult.setup()) store.set(contents) Def.declareOutput(analysisOut) - val dir = classDirectory.value - if (dir / "META-INF" / "MANIFEST.MF").exists then IO.delete(dir / "META-INF" / "MANIFEST.MF") - // inline mappings + val dir = ci.options.classesDirectory.toFile() val mappings = Path .allSubpaths(dir) .filter(_._1.isFile()) @@ -4233,14 +4242,18 @@ object Classpaths { def makeProducts: Initialize[Task[Seq[File]]] = Def.task { val c = fileConverter.value - Def.unit(copyResources.value) - Def.unit(compile.value) - val dir = c.toPath(backendOutput.value) + val resources = copyResources.value.map(_._2).toSet + val dir = classDirectory.value val rawJar = compileIncremental.value._2 val rawJarPath = c.toPath(rawJar) - IO.unzip(rawJarPath.toFile, dir.toFile) - IO.delete(dir.toFile / "META-INF" / "MANIFEST.MF") - dir.toFile :: Nil + // delete outdated files + Path + .allSubpaths(dir) + .collect { case (f, _) if f.isFile() && !resources.contains(f) => f } + .foreach(IO.delete) + IO.unzip(rawJarPath.toFile, dir) + IO.delete(dir / "META-INF" / "MANIFEST.MF") + dir :: Nil } private[sbt] def makePickleProducts: Initialize[Task[Seq[VirtualFile]]] = Def.task { diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 61ee89863..df617d8b4 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -174,7 +174,7 @@ object Keys { @cacheLevel(include = Array.empty) val classDirectory = settingKey[File]("Directory for compiled classes and copied resources.").withRank(AMinusSetting) val earlyOutput = settingKey[VirtualFile]("JAR file for pickles used for build pipelining") - val backendOutput = settingKey[VirtualFile]("Directory or JAR file for compiled classes and copied resources") + val backendOutput = settingKey[VirtualFile]("Output directory of the compiler backend") val cleanFiles = taskKey[Seq[File]]("The files to recursively delete during a clean.").withRank(BSetting) val cleanKeepFiles = settingKey[Seq[File]]("Files or directories to keep during a clean. Must be direct children of target.").withRank(CSetting) val cleanKeepGlobs = settingKey[Seq[Glob]]("Globs to keep during a clean. Must be direct children of target.").withRank(CSetting) diff --git a/sbt-app/src/sbt-test/actions/call/build.sbt b/sbt-app/src/sbt-test/actions/call/build.sbt index 720ea3346..c3ef319f3 100644 --- a/sbt-app/src/sbt-test/actions/call/build.sbt +++ b/sbt-app/src/sbt-test/actions/call/build.sbt @@ -3,7 +3,8 @@ sbtPlugin := true val copyOutputDir = taskKey[Unit]("Copies the compiled classes to a root-level directory") copyOutputDir := { - val cd = (Compile / classDirectory).value - val to = baseDirectory.value / "out spaced" - IO.copyDirectory(cd, to) + val _ = (Compile / products).value + val cd = (Compile / classDirectory).value + val to = baseDirectory.value / "out spaced" + IO.copyDirectory(cd, to) } diff --git a/sbt-app/src/sbt-test/actions/call/test b/sbt-app/src/sbt-test/actions/call/test index 30bf3e1e8..465f4f71d 100644 --- a/sbt-app/src/sbt-test/actions/call/test +++ b/sbt-app/src/sbt-test/actions/call/test @@ -1,5 +1,3 @@ -# compiles a new State => State instance -> compile # puts the classes in a stable location (out spaced/ to test escaping) > copyOutputDir diff --git a/sbt-app/src/sbt-test/actions/compile-clean/build.sbt b/sbt-app/src/sbt-test/actions/compile-clean/build.sbt index e6774e270..eb4421492 100644 --- a/sbt-app/src/sbt-test/actions/compile-clean/build.sbt +++ b/sbt-app/src/sbt-test/actions/compile-clean/build.sbt @@ -1,6 +1,7 @@ import sbt.nio.file.Glob +Global / cacheStores := Seq.empty name := "compile-clean" scalaVersion := "2.12.17" Compile / cleanKeepGlobs += - Glob((Compile / compile / classDirectory).value, "X.class") + Glob(target.value) / RecursiveGlob / "X.class" diff --git a/sbt-app/src/sbt-test/actions/compile-clean/test b/sbt-app/src/sbt-test/actions/compile-clean/test index 14bce965a..83a5a81db 100644 --- a/sbt-app/src/sbt-test/actions/compile-clean/test +++ b/sbt-app/src/sbt-test/actions/compile-clean/test @@ -1,19 +1,17 @@ -$ touch target/cant-touch-this +$ touch target/out/jvm/scala-2.12.17/compile-clean/backend/cant-touch-this -> Test/products -$ exists target/out/jvm/scala-2.12.17/compile-clean/classes/A.class -$ exists target/out/jvm/scala-2.12.17/compile-clean/test-classes/B.class +> Test/compile +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/A.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/X.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/test-backend/B.class > Test/clean -$ exists target/cant-touch-this -$ exists target/out/jvm/scala-2.12.17/compile-clean/classes/A.class -$ exists target/out/jvm/scala-2.12.17/compile-clean/classes/X.class -$ absent target/out/jvm/scala-2.12.17/compile-clean/test-classes/B.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/cant-touch-this +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/A.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/X.class +$ absent target/out/jvm/scala-2.12.17/compile-clean/test-backend/B.class -# compiling everything again, but now cleaning only compile classes -> Test/products > Compile/clean -$ exists target/cant-touch-this -$ absent target/out/jvm/scala-2.12.17/compile-clean/classes/A.class -$ exists target/out/jvm/scala-2.12.17/compile-clean/test-classes/B.class -$ exists target/out/jvm/scala-2.12.17/compile-clean/classes/X.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/cant-touch-this +$ absent target/out/jvm/scala-2.12.17/compile-clean/backend/A.class +$ exists target/out/jvm/scala-2.12.17/compile-clean/backend/X.class diff --git a/sbt-app/src/sbt-test/classloader-cache/resources/pending b/sbt-app/src/sbt-test/classloader-cache/resources/test similarity index 97% rename from sbt-app/src/sbt-test/classloader-cache/resources/pending rename to sbt-app/src/sbt-test/classloader-cache/resources/test index 57e1f61f5..63aa35f05 100644 --- a/sbt-app/src/sbt-test/classloader-cache/resources/pending +++ b/sbt-app/src/sbt-test/classloader-cache/resources/test @@ -12,4 +12,4 @@ $ copy-file changes/updated-test.txt src/test/resources/bar.txt $ copy-file changes/UpdatedResourceTest.scala src/test/scala/scripted/ResourceTest.scala -> test \ No newline at end of file +> test diff --git a/sbt-app/src/sbt-test/java/track-anonymous/build.sbt b/sbt-app/src/sbt-test/java/track-anonymous/build.sbt index 1dacbc629..ede90b6c6 100644 --- a/sbt-app/src/sbt-test/java/track-anonymous/build.sbt +++ b/sbt-app/src/sbt-test/java/track-anonymous/build.sbt @@ -3,6 +3,7 @@ val parser = token(Space ~> ( ("exists" ^^^ true) | ("absent" ^^^ false) ) ) InputKey[Unit]("checkOutput") := { val shouldExist = parser.parsed + val _ = (Compile / products).value val dir = (Compile / classDirectory).value if((dir / "Anon.class").exists != shouldExist) sys.error("Top level class incorrect" ) diff --git a/sbt-app/src/sbt-test/java/track-anonymous/test b/sbt-app/src/sbt-test/java/track-anonymous/test index 2c48f4402..16f215752 100644 --- a/sbt-app/src/sbt-test/java/track-anonymous/test +++ b/sbt-app/src/sbt-test/java/track-anonymous/test @@ -1,6 +1,4 @@ $ copy-file changes/Anon.java src/main/java/Anon.java -> compile > checkOutput exists $ delete src/main/java/Anon.java -> compile > checkOutput absent diff --git a/sbt-app/src/sbt-test/source-dependencies/compactify/build.sbt b/sbt-app/src/sbt-test/source-dependencies/compactify/build.sbt index d6e89fe63..10eb6d602 100644 --- a/sbt-app/src/sbt-test/source-dependencies/compactify/build.sbt +++ b/sbt-app/src/sbt-test/source-dependencies/compactify/build.sbt @@ -1,7 +1,9 @@ -TaskKey[Unit]("outputEmpty") := ((Configurations.Compile / classDirectory) map { outputDirectory => - def classes = (outputDirectory ** "*.class").get() - if (!classes.isEmpty) sys.error("Classes existed:\n\t" + classes.mkString("\n\t")) else () -}).value +TaskKey[Unit]("outputEmpty") := { + val c = fileConverter.value + val dir = c.toPath((Compile / backendOutput).value).toFile() + def classes = dir.**("*.class").get() + if (!classes.isEmpty) sys.error("Classes existed:\n\t" + classes.mkString("\n\t")) +} // apparently Travis CI stopped allowing long file names // it fails with the default setting of 255 characters so diff --git a/server-test/src/test/scala/testpkg/BuildServerTest.scala b/server-test/src/test/scala/testpkg/BuildServerTest.scala index 3a55469f5..32a6f1f22 100644 --- a/server-test/src/test/scala/testpkg/BuildServerTest.scala +++ b/server-test/src/test/scala/testpkg/BuildServerTest.scala @@ -254,7 +254,7 @@ class BuildServerTest extends AbstractServerTest { test("buildTarget/cleanCache") { def classFile = svr.baseDirectory.toPath.resolve( - "target/out/jvm/scala-2.13.8/runandtest/classes/main/Main.class" + "target/out/jvm/scala-2.13.8/runandtest/backend/main/Main.class" ) val buildTarget = buildTargetUri("runAndTest", "Compile") compile(buildTarget, id = 43)