aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-06-15 22:38:53 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2017-06-15 22:43:59 -0400
commit09051773461b98d374d1b46dd0a2caa57768ab30 (patch)
treed67c88d10906647c7fd56229e6e56121a9107744
parentb5194aab6f1f57aff6e4538acaf91245fdf15039 (diff)
downloadcbt-09051773461b98d374d1b46dd0a2caa57768ab30.tar.gz
cbt-09051773461b98d374d1b46dd0a2caa57768ab30.tar.bz2
cbt-09051773461b98d374d1b46dd0a2caa57768ab30.zip
add sbt-resolver like restart feature
-rw-r--r--README.md5
-rwxr-xr-xcbt16
-rw-r--r--examples/restart/Readme.md10
-rw-r--r--examples/restart/build/build.scala4
-rw-r--r--examples/restart/src/Main.scala6
-rw-r--r--stage1/Stage1Lib.scala15
-rw-r--r--stage2/BasicBuild.scala13
7 files changed, 69 insertions, 0 deletions
diff --git a/README.md b/README.md
index 94aa2ab..90dd845 100644
--- a/README.md
+++ b/README.md
@@ -226,6 +226,11 @@ To also clear the screen on each run use:
$ cbt loop clear run
```
+To call and restart the main method on file change (like sbt-revolver)
+```
+$ cbt direct loop restart
+```
+
### Adding tests
The simplest way to add tests is putting a few assertions into the previously
diff --git a/cbt b/cbt
index 4a5b736..e2014ec 100755
--- a/cbt
+++ b/cbt
@@ -290,6 +290,7 @@ stage1 () {
USER_PRESSED_CTRL_C=130
CBT_LOOP_FILE="$CWD/target/.cbt-loop.tmp"
+CBT_KILL_FILE="$CWD/target/.cbt-kill.tmp"
if [ $loop -eq 0 ]; then
which fswatch >/dev/null 2>/dev/null
export fswatch_installed=$?
@@ -305,6 +306,9 @@ while true; do
if [ -f "$CBT_LOOP_FILE" ]; then
rm "$CBT_LOOP_FILE"
fi
+ if [ -f "$CBT_KILL_FILE" ]; then
+ rm "$CBT_KILL_FILE"
+ fi
stage1 "$@"
if [ ! $loop -eq 0 ] || [ $exitCode -eq $USER_PRESSED_CTRL_C ]; then
log "not looping, exiting" "$@"
@@ -316,6 +320,10 @@ while true; do
files=
if [ -f "$CBT_LOOP_FILE" ]; then
files=($(sort "$CBT_LOOP_FILE"))
+ fi
+ pids=
+ if [ -f "$CBT_KILL_FILE" ]; then
+ pids=($(cat "$CBT_KILL_FILE")) # FIXME: should we uniq here?
#rm "$CBT_LOOP_FILE"
fi
echo ""
@@ -326,6 +334,14 @@ while true; do
fi
done
fswatch --one-event "${files[@]}"
+ for pid in "${pids[@]}"; do
+ if [ $pid == "" ]; then
+ echo "warning: empty pid found in pid kill list" 1>&2
+ else
+ log "killing process $pid"
+ kill -KILL $pid
+ fi
+ done
fi
done
diff --git a/examples/restart/Readme.md b/examples/restart/Readme.md
new file mode 100644
index 0000000..e4bf1b5
--- /dev/null
+++ b/examples/restart/Readme.md
@@ -0,0 +1,10 @@
+This example's main method simply prints the current process id.
+This can be used to experiment with cbt's restart feature
+(the equivalent to sbt-revolver).
+
+```
+cbt direct loop restart
+```
+
+starts the main method in a separate process and kills it, when
+a change in project, build file or cbt is detected.
diff --git a/examples/restart/build/build.scala b/examples/restart/build/build.scala
new file mode 100644
index 0000000..a18f951
--- /dev/null
+++ b/examples/restart/build/build.scala
@@ -0,0 +1,4 @@
+import cbt._
+class Build(val context: Context) extends BaseBuild{
+ override def dependencies = super.dependencies :+ libraries.cbt.process
+} \ No newline at end of file
diff --git a/examples/restart/src/Main.scala b/examples/restart/src/Main.scala
new file mode 100644
index 0000000..1c03832
--- /dev/null
+++ b/examples/restart/src/Main.scala
@@ -0,0 +1,6 @@
+object Main extends App {
+ while(true){
+ Thread.sleep(1000)
+ println( "process " + cbt.process.currentProcessId + " is still running" )
+ }
+}
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index ab95a41..89e52b6 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -417,6 +417,21 @@ ${sourceFiles.sorted.mkString(" \\\n")}
StandardOpenOption.APPEND
)
}
+
+ /**
+ add process id to a cbt internal list of processes to kill
+ when looping after a file change
+ */
+ def addProcessIdToKillList(cwd: File, processId: Int) = {
+ val file = cwd / "target/.cbt-kill.tmp"
+ file.createNewFile
+ lib.write(
+ file,
+ processId.toString + "\n",
+ StandardOpenOption.APPEND
+ )
+ }
+
def cached[T]( targetDirectory: File, inputLastModified: Long )( action: () => T ): (Option[T],Long) = {
val t = targetDirectory
val start = System.currentTimeMillis
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala
index e41545b..3a9c958 100644
--- a/stage2/BasicBuild.scala
+++ b/stage2/BasicBuild.scala
@@ -327,6 +327,19 @@ trait BaseBuild extends BuildInterface with DependencyImplementation with SbtDep
waitFor()
}
+ /** currently only produces output when run via cbt direct */
+ def restart: Int = {
+ val pid = restart( mainClassOrFail.getName, context.args )
+ System.err.print("started process with pid: ")
+ pid
+ }
+
+ def restart( className: String, args: Seq[String] ): Int = {
+ val ( pid, waitFor, destroy ) = runForked( mainClassOrFail.getName, context.args )
+ lib.addProcessIdToKillList( context.cwd, pid )
+ pid
+ }
+
protected def runForkedHandles = runForked( mainClassOrFail.getName, context.args )
def runForked( className: String, args: Seq[String] ): ( Int, () => ExitCode, () => ExitCode ) =