aboutsummaryrefslogtreecommitdiff
path: root/stage2
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-03-12 22:00:00 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2017-03-12 22:34:02 -0400
commit828adac48d0e08766d192c7ce01021083cfc4d67 (patch)
tree06e19c3f9117c24e6c6a5e8a95990011a0efe4b3 /stage2
parentc14e288996d2b56b6b06a0624f4f2fca315369c7 (diff)
downloadcbt-828adac48d0e08766d192c7ce01021083cfc4d67.tar.gz
cbt-828adac48d0e08766d192c7ce01021083cfc4d67.tar.bz2
cbt-828adac48d0e08766d192c7ce01021083cfc4d67.zip
fix file watching for real
last file watching update didn’t work well enough. This now - rips out barbary watch service as it seems buggy crashing the jvm - make cbt exclusively write files to watch to a file - uses fswatch instead watching all files in that file
Diffstat (limited to 'stage2')
-rw-r--r--stage2/BasicBuild.scala29
-rw-r--r--stage2/BuildBuild.scala3
-rw-r--r--stage2/BuildDependency.scala5
-rw-r--r--stage2/GitDependency.scala3
-rw-r--r--stage2/Lib.scala49
-rw-r--r--stage2/Stage2.scala37
6 files changed, 17 insertions, 109 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index 1308155..37b1786 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -5,7 +5,7 @@ import java.net._
import java.nio.file._
class BasicBuild(final val context: Context) extends BaseBuild
-trait BaseBuild extends BuildInterface with DependencyImplementation with TriggerLoop with SbtDependencyDsl{
+trait BaseBuild extends BuildInterface with DependencyImplementation with SbtDependencyDsl{
//* DO NOT OVERRIDE CONTEXT in non-idempotent ways, because .copy and new Build
// will create new instances given the context, which means operations in the
// overrides will happen multiple times and if they are not idempotent stuff likely breaks
@@ -127,12 +127,6 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
pathToNestedBuild: _*
)
- def triggerLoopFiles: Set[File] = (
- context.triggerLoopFiles
- ++ sources
- ++ transitiveDependencies.collect{ case b: TriggerLoop => b.triggerLoopFiles }.flatten
- )
-
def localJars: Seq[File] =
Seq(projectDirectory ++ "/lib")
.filter(_.exists)
@@ -164,6 +158,14 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
final def lastModified: Long = compile.getOrElse(0L)
+ def triggerLoopFiles: Set[File] = sources.toSet
+
+ if(context.loop){
+ taskCache[BasicBuild]( "loop-file-cache" ).memoize{
+ lib.addLoopFiles( context.cwd, triggerLoopFiles )
+ }
+ }
+
def compile: Option[Long] = taskCache[BaseBuild]("_compile").memoize{
lib.compile(
Math.max( context.cbtLastModified, context.parentBuild.map(_.lastModified).getOrElse(0L) ),
@@ -325,17 +327,4 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with Trigge
final def crossScalaVersionsArray = Array(scalaVersion)
def publish: Seq[URL] = Seq()
-
- def loop = {
- lib.callReflective(this, context.args.headOption, context.copy(args=context.args.drop(1)))
- val files = triggerLoopFiles
- lib.watch{ () =>
- logger.loop("Looping change detection over:\n - "++files.mkString("\n - "))
- files
- }()
- context.loopFile.getParentFile.mkdirs
- lib.write( context.loopFile, files.mkString("\n"), StandardOpenOption.CREATE )
-
- ExitCode(253) // signal bash script to restart
- }
}
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index 9811db5..7be4714 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -37,8 +37,7 @@ trait BuildBuildWithoutEssentials extends BaseBuild{
protected def managedContext = context.copy(
workingDirectory = managedBuildDirectory,
- parentBuild=Some(this),
- triggerLoopFiles = triggerLoopFiles
+ parentBuild=Some(this)
)
override def dependencies =
diff --git a/stage2/BuildDependency.scala b/stage2/BuildDependency.scala
index 9e35c41..bd3ed9e 100644
--- a/stage2/BuildDependency.scala
+++ b/stage2/BuildDependency.scala
@@ -10,10 +10,6 @@ sealed abstract class ProjectProxy extends Ha{
def dependencies = Seq(delegate)
}
*/
-trait TriggerLoop extends DependencyImplementation{
- final def triggerLoopFilesArray = triggerLoopFiles.toArray
- def triggerLoopFiles: Set[File]
-}
/** You likely want to use the factory method in the BasicBuild class instead of this. */
object DirectoryDependency{
def apply(context: Context, pathToNestedBuild: String*): BuildInterface = {
@@ -52,7 +48,6 @@ object DirectoryDependency{
/*
case class DependencyOr(first: DirectoryDependency, second: JavaDependency) extends ProjectProxy with DirectoryDependencyBase{
val isFirst = new File(first.projectDirectory).exists
- def triggerLoopFiles = if(isFirst) first.triggerLoopFiles else Set()
protected val delegate = if(isFirst) first else second
}
*/
diff --git a/stage2/GitDependency.scala b/stage2/GitDependency.scala
index f6812e4..20e1d36 100644
--- a/stage2/GitDependency.scala
+++ b/stage2/GitDependency.scala
@@ -26,7 +26,8 @@ object GitDependency{
val c = taskCache[Dependency]("checkout").memoize{ checkout( url, ref ) }
DirectoryDependency(
context.copy(
- workingDirectory = subDirectory.map(c / _).getOrElse(c)
+ workingDirectory = subDirectory.map(c / _).getOrElse(c),
+ loop = false
),
pathToNestedBuild: _*
)
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index 5e35ea7..ceea004 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -151,6 +151,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
case c: ClassPath => c.string
case ExitCode(int) => System.err.println(int); System.exit(int); ???
case s: Seq[_] => s.map(render).mkString("\n")
+ case s: Set[_] => s.map(render).toSeq.sorted.mkString("\n")
case _ => obj.toString
}
}
@@ -478,54 +479,6 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
url
}
-
- // code for continuous compile
- def watch[T]( files: () => Set[File] )(
- action: Seq[File] => Option[T] = (f: Seq[File]) => Some(f)
- ): T = {
- import com.barbarysoftware.watchservice._
- import scala.collection.JavaConversions._
- Iterator.continually{
- val watcher = WatchService.newWatchService
- val realFiles = files().map(realpath)
- realFiles.map{
- // WatchService can only watch folders
- case file if file.isFile => dirname(file)
- case file => file
- }.map{ file =>
- val watchableFile = new WatchableFile(file)
- val key = watchableFile.register(
- watcher,
- StandardWatchEventKind.ENTRY_CREATE,
- StandardWatchEventKind.ENTRY_DELETE,
- StandardWatchEventKind.ENTRY_MODIFY
- )
- }
- Option( watcher.take ) -> realFiles
- }.collect{
- case (Some(key),f) => key -> f
- }.map{ case (key, realFiles) =>
- logger.loop("Waiting for file changes...")
- val changedFiles = key
- .pollEvents
- .toVector
- .filterNot(_.kind == StandardWatchEventKind.OVERFLOW)
- .map(_.context.toString)
- // make sure we don't react on other files changed
- // in the same folder like the files we care about
- .filter{ name => realFiles.exists(name startsWith _.toString) }
- .map(new File(_))
-
- changedFiles.foreach( f => logger.loop( "Changed: " ++ f.toString ) )
- val res = action(changedFiles)
- key.reset
- res
- }.filterNot(_.isEmpty)
- .take(1)
- .toList
- .head.get
- }
-
def findInnerMostModuleDirectory(directory: File): File = {
val buildDir = realpath( directory ++ ("/" ++ lib.buildDirectoryName) )
// do not appent buildFileName here, so that we detect empty build folders
diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala
index 33a67ac..eaf776e 100644
--- a/stage2/Stage2.scala
+++ b/stage2/Stage2.scala
@@ -32,40 +32,11 @@ object Stage2 extends Stage2Base{
args.cbtHome,
args.compatibilityTarget,
null,
- NailgunLauncher.compatibilitySourceFiles.asScala.toArray[File]
- ++ NailgunLauncher.nailgunLauncherSourceFiles.asScala.toArray[File]
- ++ NailgunLauncher.stage1SourceFiles.asScala.toArray[File]
- ++ args.stage2sourceFiles.toArray[File]
+ args.loop
)
- def loop( code: ExitCode, files: () => Set[File] ): ExitCode = {
- code match {
- case c@ExitCode(253 | 130) => c // CBT signals loop | user pressed ctrl+C
- case c if !task.contains("loop") => c
- case c =>
- // this allows looping over broken builds
- lib.watch{ files }()
- c
- }
- }
- val code = lib.trapExitCode{
- val first = lib.loadRoot( context )
- val build = first.finalBuild( context.cwd )
- val code = lib.callReflective(build, task, context)
- if( !context.loopFile.exists ){
- loop( code, () => build.triggerLoopFiles )
- }
- code
- }
- if( context.loopFile.exists ){
- loop(
- code,
- () => {
- val files = context.loopFile.readAsString.split("\n").map(new File(_)).toSet
- logger.loop("Looping change detection over:\n - "++files.mkString("\n - "))
- files
- }
- )
- }
+ val first = lib.loadRoot( context )
+ val build = first.finalBuild( context.cwd )
+ val code = lib.callReflective(build, task, context)
logger.stage2(s"Stage2 end with exit code "+code.integer)
code
}