Pages

12 April, 2013

A project file for CoffeeScript pojects

As you may know, I program a lot of UI stuff in CoffeeScript. To avoid recompilation, I usually tell coffee to watch for and recompile on changes: coffee -w -o ./lib -c ./src
In addition, I often start the coffee console to play around with some code interactively, e.g., to test the results of magic list and comprehension processing, etc. And I might also start a small static node.js webserver to serve files via HTTP rather than using file:// links.
Since this is a lot of stuff to start before I can even start programming, I usually write little project files (shell scripts) that will do all this automatically.

Here is an simple example that works for me in GitBash/Windows and in Linux (RedHat):
  1. It starts and detaches coffee -w and tracks the process id and group id
  2. Starts a node.js HTTP server and tracks the process id and group id
  3. Then starts the coffee console and waits for it to quit
  4. Finally it will bring down the all started programs and exit

#!/usr/bin/env bash

killGroup() {
    if [ -z "$1" ]; then
        echo "watcher gpid not set"
    else
        echo "killing gpid:$1"
        (sleep 1 && kill -- -$1)&
    fi
}
getGID() {
    ps='ps -eo pid,ppid,pgrp'
    $ps 1> /dev/null 2>&1 || ps='ps -l'
    $ps | awk "{ if (\$1 == $1) { print \$3 }}"
}

cwd=$(pwd)
pdir=$(dirname $0)

coffee -o $pdir/lib -wc $pdir/src&
watch=$!
gpid=$(getGID $watch)
echo "starting coffee watcher (pid: $watch, $gpid)..."

sleep 2

cd $pdir/..
coffee server.coffee&
server=$!
sgpid=$(getGID $server)
echo "starting coffee server (pid: $server, $gpid)..."

sleep 2
echo "starting coffee console..."
coffee

killGroup $gpid
killGroup $sgpid

exit 0
cd $cwd


After starting it looks like this:
$ sh project.sh
starting coffee watcher (pid: 10868, 17160)...
07:57:57 - compiled src\main.coffee
07:57:57 - compiled src\charts.coffee
07:57:57 - compiled src\datagen.coffee
07:57:57 - compiled src\algorithms.coffee
starting coffee console...
coffee>
The compiler output will be mixed into the coffee console output but that is just fine, since I do not have to maintain several console windows this way. Here is an example where I tested something on the console and then saved my main file.
coffee> a = [1,2,3]; a.map (d) -> value:d
[ { value: 1 }, { value: 2 }, { value: 3 } ]
coffee> 08:40:06 - compiled src\main.coffee
08:40:16 - compiled src\main.coffee
In a past post I said that bash syntax was awkward, I really have to revoke that statement now. Bash is really great for such tasks.

Cheers, Juve