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.
Usage
In your Cakefile
:
{build, action, coffee, uglify, zip, cmd} = require 'ake'
build(
# Create a raw action
action ['f1.in'], ['f2.out'], ({callback}) ->
console.info 'Generating f2.out...'
# ... perform the action
callback()
# 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'
)
Design
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
build(
action1,
action2,
[action3, [action4, action5]],
action6,
-> # 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/')