mirror of https://github.com/sbt/sbt.git
Add scripted test for symlink source monitoring
The swoval library automatically watches the _target_ of symlinks. I had been meaning to add a scripted test to ensure that in sbt continuous builds detect changes to the target of symlinks. The naive approach of just watching all of the files in the source directory doesn't work because the native watch process will just watch the symlink node itself and not detect updates to its target. This test would have thus failed with 1.2.8. Watching symlinked files doesn't work at the moment on windows, but does work on mac and linux. Eventually I'd like there to be feature parity, but, for now, we'll just skip the file target test on windows. At least this test makes it explicit what does and doesn't work on each platform.
This commit is contained in:
parent
349d365bab
commit
bbd88e04dc
|
|
@ -0,0 +1,46 @@
|
|||
import java.nio.file.{ Files, Paths }
|
||||
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||
|
||||
val createSymlinks = taskKey[Unit]("create symlinks to source files and directories")
|
||||
createSymlinks := {
|
||||
val base = baseDirectory.value.toPath
|
||||
val srcDir = base / "src" / "main" / "scala"
|
||||
val foo = Files.createDirectories(srcDir / "file-source") / "Foo.scala"
|
||||
Files.createSymbolicLink(srcDir / "sources", Files.createDirectories(base / "sources"))
|
||||
Files.deleteIfExists(foo)
|
||||
Files.createSymbolicLink(foo, base / "file-source" / "Foo.scala")
|
||||
}
|
||||
|
||||
ThisBuild / watchOnFileInputEvent := {
|
||||
val srcDir = baseDirectory.value.toPath / "src" / "main" / "scala"
|
||||
(_: Int, event: Watch.Event) =>
|
||||
event.path match {
|
||||
case p if p == (srcDir / "file-source" / "Foo.scala") => Watch.CancelWatch
|
||||
case p if p == (srcDir / "sources" / "Bar.scala") => Watch.CancelWatch
|
||||
case _ => Watch.Ignore
|
||||
}
|
||||
}
|
||||
|
||||
val copySource = inputKey[Unit]("copy a source file from changes")
|
||||
copySource := {
|
||||
val relative = Def.spaceDelimited("").parsed.head.split("/") match {
|
||||
case Array(head) => Paths.get(head)
|
||||
case Array(head, tail @ _*) => tail.foldLeft(Paths.get(head))(_ / _)
|
||||
}
|
||||
val base = baseDirectory.value.toPath
|
||||
Files.copy((base / "changes").resolve(relative), base.resolve(relative), REPLACE_EXISTING)
|
||||
}
|
||||
|
||||
val removeLink = inputKey[Unit]("remove a symlink")
|
||||
removeLink := {
|
||||
val relative = Def.spaceDelimited("").parsed.head.split("/") match {
|
||||
case Array(head) => Paths.get(head)
|
||||
case Array(head, tail @ _*) => tail.foldLeft(Paths.get(head))(_ / _)
|
||||
}
|
||||
val srcDir = baseDirectory.value.toPath / "src" / "main" / "scala"
|
||||
Files.deleteIfExists(srcDir.resolve(relative))
|
||||
}
|
||||
|
||||
commands += Command.single("skipWindows") { (state, command) =>
|
||||
if (scala.util.Properties.isWin) state else command :: state
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
class Foo {}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package sources
|
||||
|
||||
class Bar
|
||||
|
|
@ -0,0 +1 @@
|
|||
class Foo
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
> createSymlinks
|
||||
|
||||
> skipWindows ~compile; copySource file-source/Foo.scala
|
||||
|
||||
> ~compile; copySource sources/Bar.scala
|
||||
|
||||
> skipWindows ~compile; removeLink file-source/Foo.scala
|
||||
|
||||
> ~compile; removeLink sources
|
||||
|
||||
> ~compile; createSymlinks
|
||||
|
||||
> copySource sources/Bar.scala
|
||||
|
||||
> ~compile; removeLink sources/Bar.scala
|
||||
Loading…
Reference in New Issue