smarter gulp restart

I wanted to make a gulpfile to restart a server when files changed. It seemed easy enough at first:

var gulp  = require('gulp')
var child = require('child-process')
gulp.task('default', function(){
  var ps
  function spawn(){
    if(ps) ps.kill() //spawn becomes respawn automatically
    ps = child.spawn('node', ['.'], {stdio: 'inherit'})
  }
  spawn()
  gulp.watch('*.js', spawn) //respawn on changes.
})

but I then wondered how to improve the logic by handling changes to my gulpfile and this led me to a few discoveries. The big thing I learned was that when you .kill() a child process in node, this sends a SIGTERM, to the process which is a special condition -- you can't catch this in a node script with process.on('exit'), which wasn't obvious to me at first. Eventually I want to further improve this build script by better handling server crashes and I'd like to build a TUI for it all like what I did on the routers project. But for now, the snippet below shows how to build a basic process restart which will automatically fire when files have been changed.

var gulp   = require('gulp')
var path   = require('path')
var child  = require('child_process')

//ANSI escape sequences to provide colors in the terminal.
var ansi   = {
	red      : "\x1b[31m",
	green    : "\x1b[32m",
	yellow   : "\x1b[33m",
	blue     : "\x1b[34m",
	purple   : "\x1b[35m",
	teal     : "\x1b[36m",
	grey     : "\x1b[37m",

	reset    : "\x1b[0m"
}

gulp.task('runServer', function(){
  var ps
  function spawn(){
    if(ps){
      console.log(ansi.yellow,"killing server",ansi.reset)
      ps.kill()
    }
    ps = child.spawn('node', ['.'], {stdio: 'inherit'})
    ps.on('exit', function(code, signal){
      if(signal) console.log(ansi.yellow, 
          "server received",signal,ansi.reset)
          console.log(ansi.yellow,
          "server exited with", code, ansi.reset)
      if(code !== 143){ //exit code 143 indicates SIGTERM.
        console.log(ansi.red,
        "***Looks like the server crashed.",
        "We'll try to restart it on the next file save.",ansi.reset)
      }
    })
    console.log(ansi.yellow, "server started", ansi.reset)
  }
  spawn()
  gulp.watch('*.js', function(event){
    //don't watch gulpfile in this context:
    if(event.path === path.join(__dirname, "gulpfile.js")) return;
    spawn()
  })

  process.on('SIGTERM', function(){
    if(ps){
      console.log(ansi.yellow,
      "killing server due to SIGTERM",ansi.reset)
      ps.kill()
    }
  })
})

gulp.task('default', function(){
  var ps
  function spawn(){
    if(ps) ps.kill()
    ps = child.spawn('gulp', ['runServer'], {stdio: 'inherit'})
  }
  spawn()
  gulp.watch('gulpfile.js', function(event){
    spawn()
  })
})