mirror of https://github.com/sbt/sbt.git
Remove watch loops
When source generators write into the unmanaged source directory, bad things can happen. Continuous builds will loop indefinitely and compiling will fail because the generated sources get added to the source list twice, causing the incremental compiler to complain about compiling classes it has already seen. My two-pronged solution is to de-duplicate the sources task and to filter out managed source files in watch sources. The drawback to the latter is that it causes the source generation task to be executed twice per compile.
This commit is contained in:
parent
bf8df381f5
commit
0de8345e33
|
|
@ -329,7 +329,18 @@ object Defaults extends BuildCommon {
|
|||
val baseDir = baseDirectory.value
|
||||
val bases = unmanagedSourceDirectories.value
|
||||
val include = (includeFilter in unmanagedSources).value
|
||||
val exclude = (excludeFilter in unmanagedSources).value
|
||||
val exclude = (excludeFilter in unmanagedSources).value match {
|
||||
case e =>
|
||||
(managedSources in ThisScope).value match {
|
||||
case l if l.nonEmpty =>
|
||||
e || new FileFilter {
|
||||
private val files = l.toSet
|
||||
override def accept(pathname: File): Boolean = files.contains(pathname)
|
||||
override def toString = s"ManagedSourcesFilter($files)"
|
||||
}
|
||||
case _ => e
|
||||
}
|
||||
}
|
||||
val baseSources =
|
||||
if (sourcesInBase.value) Seq(new Source(baseDir, include, exclude, recursive = false))
|
||||
else Nil
|
||||
|
|
@ -341,7 +352,7 @@ object Defaults extends BuildCommon {
|
|||
sourceDirectories := Classpaths
|
||||
.concatSettings(unmanagedSourceDirectories, managedSourceDirectories)
|
||||
.value,
|
||||
sources := Classpaths.concat(unmanagedSources, managedSources).value
|
||||
sources := Classpaths.concatDistinct(unmanagedSources, managedSources).value
|
||||
)
|
||||
lazy val resourceConfigPaths = Seq(
|
||||
resourceDirectory := sourceDirectory.value / "resources",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import java.nio.file.Files
|
||||
|
||||
lazy val watchLoopTest = taskKey[Unit]("Check that managed sources are filtered")
|
||||
|
||||
sourceGenerators in Compile += Def.task {
|
||||
val path = baseDirectory.value.toPath.resolve("src/main/scala/Foo.scala")
|
||||
Files.write(path, "object Foo".getBytes).toFile :: Nil
|
||||
}
|
||||
|
||||
watchLoopTest := {
|
||||
val watched = watchSources.value
|
||||
val managedSource = (managedSources in Compile).value.head
|
||||
assert(!SourceWrapper.accept(watched, managedSource))
|
||||
assert((sources in Compile).value.foldLeft((true, Set.empty[File])) {
|
||||
case ((res, set), f) => (res && !set.contains(f), set + f)
|
||||
}._1)
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package sbt
|
||||
|
||||
object SourceWrapper {
|
||||
def accept(sources: Seq[sbt.internal.io.Source], file: File): Boolean =
|
||||
sources.exists(_.accept(file.toPath))
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
object Bar
|
||||
|
|
@ -0,0 +1 @@
|
|||
object Foo
|
||||
|
|
@ -0,0 +1 @@
|
|||
> watchLoopTest
|
||||
Loading…
Reference in New Issue