A build tool

Ake is a build system. Not a real build system but rather a library you can call from your Cakefile or from another build tool that runs on nodejs.

The idea

I needed a build system for my projects, one that

  • takes advantage of node's asynchronous calls.

  • doesn't need to spawn new processes for actions which can run in the same v8 instance, such as compiling CoffeeScript.

  • makes use of mtime to detect outdated files. I know, this is unreliable in some degenerate cases but I'm not willing to pay the price of computing hashes from the content of files.

  • can run in the background and watch my source files and immediately do a rebuild whenever it detects a change.

  • doesn't require its own ?akefile and doesn't invent its own configuration language. Instead it makes itself available as a library to other tools.


In your Cakefile:

{build, action, coffee, uglify, zip, cmd} = require 'ake'

    # Create a raw action
    action ['f1.in'], ['f2.out'], ({callback}) ->
        console.info 'Generating f2.out...'
        # ... perform the action

    # Create an action that will compile a CoffeeScript file
    # `coffee(...)` calls `action(...)` internally and provides
    # the last argument
    coffee 'src/a.coffee', 'lib/a.js'

    # If you specify a directory as a second argument, it figures out the
    # name of the js file
    coffee 'src/b.coffee', 'lib/'

    # If you don't specify a second argument, it defaults to the same directory
    # where the source file is
    coffee 'src/c.coffee'

    # It does globbing
    coffee 'src/d*.coffee', 'lib/'

    # Obfuscate and minify
    uglify 'lib/a.js', 'lib/a.min.js'

    # Compress
    zip 'lib/**/*.js', 'release.tgz'

    # Run an arbitrary shell command as a pipe
    cmd('sha1sum') 'release.tgz', 'release.sha'


Ake knows about files and actions that generate them.

A file is identified by its path, a string.

An action is defined as the record of:

    inPaths: ['file1', 'file2']    # the list of input files
    outPaths: ['file3', 'file4']   # the list of output files
    action: ({callback}) -> ...      # a function to generate outPaths from inPaths

The call

    [action3, [action4, action5]],
    -> # an optional continuation after the build is ready

will flatten its argument list, check the timestamps of files mentioned as inPaths or outPaths, and rebuild those that are out of date.

There will be convenience functions to create an action object (or an array of action objects) for a specific purpose, such as:

coffee('src/*.coffee', 'lib/')