diff options
author | Christopher Vogt <oss.nsp@cvogt.org> | 2017-03-12 01:47:57 -0500 |
---|---|---|
committer | Christopher Vogt <oss.nsp@cvogt.org> | 2017-03-12 11:56:25 -0400 |
commit | 244f86a9cdf19904169456c234a2752f125dd427 (patch) | |
tree | 51e1f79100cc3651dfce66d4a284584d6bef3997 /stage2/Stage2.scala | |
parent | 4eb753e4d4ef5be7443b99832892bac697b10b50 (diff) | |
download | cbt-244f86a9cdf19904169456c234a2752f125dd427.tar.gz cbt-244f86a9cdf19904169456c234a2752f125dd427.tar.bz2 cbt-244f86a9cdf19904169456c234a2752f125dd427.zip |
revamp loop feature
now CBT and builds pass their file names to the current build
via the context. The build then simply blocks until any file changes.
Then it returns with a special exit code, which the bash script picks
up and restarts CBT. Thats works well for looping over project files.
It works less well for looping over builds and CBT itself. For this
a build has to success once, so that the .cbt-loop.tmp file exists.
Then looping works for cbt and builds, but the file list is not
updated in case of compile errors, etc.
Fixes
- https://github.com/cvogt/cbt/issues/406
- https://github.com/cvogt/cbt/issues/405
- https://github.com/cvogt/cbt/issues/202
- https://github.com/cvogt/cbt/issues/50
- https://github.com/cvogt/cbt/issues/22
We should improve for 1.0 in https://github.com/cvogt/cbt/issues/419
to handle looping over build files and cbt itself smarter.
Diffstat (limited to 'stage2/Stage2.scala')
-rw-r--r-- | stage2/Stage2.scala | 79 |
1 files changed, 39 insertions, 40 deletions
diff --git a/stage2/Stage2.scala b/stage2/Stage2.scala index d43c4f6..33a67ac 100644 --- a/stage2/Stage2.scala +++ b/stage2/Stage2.scala @@ -1,6 +1,6 @@ package cbt import java.io._ -import java.util._ +import java.util.{Set=>_,_} object Stage2 extends Stage2Base{ def getBuild(context: Context) = { @@ -13,19 +13,14 @@ object Stage2 extends Stage2Base{ import paths._ val lib = new Lib(args.logger) logger.stage2(s"Stage2 start") - val loop = args.args.lift(0) == Some("loop") - val taskIndex = if (loop) { - 1 - } else { - 0 - } - val task = args.args.lift( taskIndex ) + val task = args.args.lift( 0 ) + import scala.collection.JavaConverters._ val context: Context = new ContextImplementation( args.cwd, args.cwd, - args.args.drop( taskIndex +1 ).toArray, + args.args.drop( 1 ).toArray, logger.enabledLoggers.toArray, logger.start, args.stage2LastModified, @@ -36,38 +31,42 @@ object Stage2 extends Stage2Base{ args.cbtHome, args.cbtHome, args.compatibilityTarget, - null + null, + NailgunLauncher.compatibilitySourceFiles.asScala.toArray[File] + ++ NailgunLauncher.nailgunLauncherSourceFiles.asScala.toArray[File] + ++ NailgunLauncher.stage1SourceFiles.asScala.toArray[File] + ++ args.stage2sourceFiles.toArray[File] ) - val first = lib.loadRoot( context ) - val build = first.finalBuild( context.cwd ) - - val res = - if (loop) { - // TODO: this should allow looping over task specific files, like test files as well - val triggerFiles = first.triggerLoopFiles.map(lib.realpath) - val triggerCbtFiles = Seq( nailgun, stage1, stage2 ).map(lib.realpath _) - val allTriggerFiles = triggerFiles ++ triggerCbtFiles - - logger.loop("Looping change detection over:\n - "++allTriggerFiles.mkString("\n - ")) - - lib.watch(allTriggerFiles){ - case file if triggerCbtFiles.exists(file.toString startsWith _.toString) => - logger.loop("Change is in CBT's own source code.") - logger.loop("Restarting CBT.") - scala.util.control.Breaks.break - - case file if triggerFiles.exists(file.toString startsWith _.toString) => - val build = lib.loadRoot(context).finalBuild( context.cwd ) - logger.loop(s"Re-running $task for " ++ build.show) - lib.callReflective(build, task, context) - } - ExitCode.Success - } else { - val code = lib.callReflective(build, task, context) - logger.stage2(s"Stage2 end") - code + 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 } - - res + } + 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 + } + ) + } + logger.stage2(s"Stage2 end with exit code "+code.integer) + code } } |