mirror of https://github.com/sbt/sbt.git
perf: Use sync instead of copying the directory
**Problem** We currently need to split the output of the compiler from the classes directory so we can cache just the output without mixing it with the resource files while maintaining similar classes directory as sbt 1.x (as opposed to just splitting them completely). However, copying directory is a performance bottleneck. **Solution** This uses Sync.sync function to synchronize the backend directory to classes directory. This is more reliable than using Analysis information, since the compilers (and/or plugins) can generate non-class files on the side in META-INF, or tasty file in case of Scala 3.
This commit is contained in:
parent
2459663387
commit
b7e9c02240
|
|
@ -4064,20 +4064,23 @@ object Classpaths {
|
|||
|
||||
def makeProducts: Initialize[Task[Seq[File]]] = Def.task {
|
||||
val c = fileConverter.value
|
||||
val resources = copyResources.value.map(_._2).toSet
|
||||
val classDir = classDirectory.value
|
||||
val syncDir = target.value / (prefix(configuration.value.name) + "sync")
|
||||
val factory = CacheStoreFactory(syncDir)
|
||||
val cacheStore = factory.make("make-product")
|
||||
val t = classDirectory.value
|
||||
val vfBackendDir = compileIncremental.value._2
|
||||
val backendDir = c.toPath(vfBackendDir)
|
||||
// delete outdated files
|
||||
Path
|
||||
.allSubpaths(classDir)
|
||||
.collect { case (f, _) if f.isFile() && !resources.contains(f) => f }
|
||||
.foreach(IO.delete)
|
||||
IO.copyDirectory(
|
||||
source = backendDir.toFile(),
|
||||
target = classDir,
|
||||
)
|
||||
classDir :: Nil
|
||||
val flt: File => Option[File] = flat(t)
|
||||
val transform: File => Option[File] =
|
||||
(f: File) => rebase(backendDir.toFile(), t)(f).orElse(flt(f))
|
||||
val resources = copyResources.value.map(_._2).toSet
|
||||
val view = fileTreeView.value
|
||||
val classes = view.list((Glob(backendDir, RecursiveGlob / "*")))
|
||||
val mappings: Seq[(File, File)] = classes.flatMap:
|
||||
case (r, attr) if r != backendDir => transform(r.toFile()).map(r.toFile() -> _)
|
||||
case _ => None
|
||||
Sync.sync(cacheStore, fileConverter = c)(mappings)
|
||||
t :: Nil
|
||||
}
|
||||
|
||||
private[sbt] def makePickleProducts: Initialize[Task[Seq[VirtualFile]]] = Def.task {
|
||||
|
|
|
|||
Loading…
Reference in New Issue