• Cakefile

  • ¶
    • build - compiles your src directory to your lib directory
    • watch - watches any changes in your src directory and automatically compiles to the lib directory
    • test - runs mocha test framework, you can edit this task to use your favorite test framework
    • docs - generates annotated documentation using docco
    • clean - clean generated .js files
    files = [
      'lib'
      'src'
    ]
    
    fs = require 'fs'
    {print} = require 'util'
    {spawn, exec} = require 'child_process'
    
    try
      which = require('which').sync
    catch err
      if process.platform.match(/^win/)?
        console.log 'WARNING: the which module is required for windows\ntry: npm install which'
      which = null
  • ¶

    ANSI Terminal Colors

    bold = '\x1b[0;1m'
    green = '\x1b[0;32m'
    reset = '\x1b[0m'
    red = '\x1b[0;31m'
    
    option "-m", "--map", "generate source map and save as .map files"
  • ¶

    Cakefile Tasks

    docs

    Generate Annotated Documentation

    Usage

    cake docs
    
    task 'docs', 'generate documentation', -> docco()
  • ¶

    build

    Builds Source

    Usage

    cake build
    
    task 'build', 'compile source', (options) ->
      build false, (-> log "🍻  Build Successful", green), useMapping: useMapping = options.map
  • ¶

    watch

    Builds your source whenever it changes

    Usage

    cake watch
    
    task 'watch', 'compile and watch', (options) ->
      build true, (-> log ":-)", green), useMapping: useMapping = options.map
  • ¶

    test

    Runs your test suite.

    Usage

    cake test
    
    task 'test', 'run tests', -> build -> mocha -> log ":)", green
  • ¶

    clean

    Cleans up generated js files

    Usage

    cake clean
    
    task 'clean', 'clean generated files', -> clean -> log ";)", green
  • ¶

    Internal Functions

    walk

    given string as dir which represents a directory in relation to local directory and callback as done in the form of (err, results) then recurse through directory returning an array of files

    Examples

    walk 'src', (err, results) -> console.log results
    
    walk = (dir, done) ->
      results = []
      fs.readdir dir, (err, list) ->
        return done(err, []) if err
        pending = list.length
        return done(null, results) unless pending
        for name in list
          file = "#{dir}/#{name}"
          try
            stat = fs.statSync file
          catch err
            stat = null
          if stat?.isDirectory()
            walk file, (err, res) ->
              results.push name for name in res
              done(null, results) unless --pending
          else
            results.push file
            done(null, results) unless --pending
  • ¶

    log

    given string as a message and string as a color and optional string as an explanation then builds a statement and logs to console.

    log = (message, color, explanation) -> console.log color + message + reset + ' ' + (explanation or '')
  • ¶

    launch

    given string as a cmd and optional array and option flags and optional callback then spawn cmd with options and pipe to process stdout and stderr respectively and on child process exit emit callback if set and status is 0

    launch = (cmd, options=[], callback) ->
      cmd = which(cmd) if which
      app = spawn cmd, options
      app.stdout.pipe(process.stdout)
      app.stderr.pipe(process.stderr)
      app.on 'exit', (status) ->
        if status is 0
          callback()
        else
          process.exit(status);
  • ¶

    build

    given optional boolean as watch and optional function as callback then invoke launch passing coffee command and defaulted options to compile src to lib

    build = (watch, callback, {useMapping} = {}) ->
      useMapping ?= false
    
      if typeof watch is 'function'
        callback = watch
        watch = false
    
      options = ['-c', '-b']
      options.push("--map") if useMapping
      options.push("-o")
      options = options.concat files
      options.unshift '-w' if watch
      launch 'coffee', options, callback
  • ¶

    unlinkIfCoffeeFile

    given string as file and file ends in ‘.coffee’ then convert ‘.coffee’ to ‘.js’ and remove the result

    unlinkIfCoffeeFile = (file) ->
      if file.match /\.coffee$/
        fs.unlink file.replace('src','lib').replace(/\.coffee$/, '.map'), ->
        fs.unlink file.replace('src','lib').replace(/\.coffee$/, '.js'), ->
        true
      else false
  • ¶

    clean

    given optional function as callback then loop through files variable and call unlinkIfCoffeeFile on each

    clean = (callback) ->
      try
        for file in files
          unless unlinkIfCoffeeFile file
            walk file, (err, results) ->
              for f in results
                unlinkIfCoffeeFile f
    
        callback?()
      catch err
  • ¶

    moduleExists

    given name for module when trying to require module and not found then* print not found message with install helper in red and* return false if not found

    moduleExists = (name) ->
      try
        require name
      catch err
        log "#{name} required: npm install #{name}", red
        false
  • ¶

    mocha

    given optional array of option flags and optional function as callback then invoke launch passing mocha command

    mocha = (options, callback) ->
  • ¶

    if moduleExists(‘mocha’)

      if typeof options is 'function'
        callback = options
        options = []
    
      launch 'node_modules/.bin/mocha', options, callback
  • ¶

    docco

    given optional function as callback then invoke launch passing docco command

    docco = (callback) ->
  • ¶

    if moduleExists(‘docco’)

      walk 'src', (err, files) -> launch 'node_modules/.bin/docco', files, callback