Fetching contributors…
Cannot retrieve contributors at this time
82 lines (71 sloc) 2.66 KB
`#!/usr/bin/env node`
# `coke` is a simplified version of [Make](
# ([Rake](, [Jake](
# for Coco. You define tasks with names and descriptions in a Cokefile,
# and can call them from the command line, or invoke them from other tasks.
# Running `coke` with no arguments will print out a list of all the tasks in the
# current directory's Cokefile.
# Keep track of the list of defined tasks, the accepted options, and so on.
Tasks = __proto__: null
Aliases = __proto__: null
Flags = {}
Options = {}
# The top-level objects for Cokefiles to use directly.
global import
Coco : require \./coco
fs : require \fs
path : require \path
# Define a coke task with a short name, an optional sentence description,
# and the function to run as the action itself.
task: (name, description, action) ->
[action, description] = [description, ''] unless action
Aliases[name.split(/\W+/)filter(String)map(-> it.0)join ''] ||= name
Tasks[name] = {name, description, action}
# Define an option that the Cokefile accepts. The parsed options hash,
# containing all of the command-line options passed, will be made available
# as the first argument to the action.
option: (name, ...spec) -> Flags[name] = spec
# Invoke another task in the current Cokefile.
invoke: (name) ->
unless task = Tasks[name] or Tasks[Aliases[name]]
console.error 'no such task: "%s"' name
process.exit 1
task.action Options
# Utilities.
say : -> process.stdout.write it + \\n
slurp : -> '' + fs.readFileSync ...
spit : fs.writeFileSync
dir : fs.readdirSync
args = process.argv.slice 2
filename = args.0 of <[ -f --cokefile ]> and args.splice(0 2)1 or \Cokefile
fs.exists filename, :rec(yes) ->
unless yes
if process.cwd! is \/
console.error 'no "%s"' filename
process.exit 1
process.chdir \..
return fs.exists filename, rec
optparse = require \./optparse slurp(filename), {filename}
Options := optparse Flags, args
if args.length
# Execute tasks in order.
then Options.$args.forEach invoke
# If no tasks are passed, print the help screen.
else printTasks()
# Display the list of tasks in a format similar to `rake -T`.
function printTasks
say '''
Usage: coke [coke options] [task options] [tasks]
width = Math.max ...Object.keys(Tasks)map -> it.length
pad = ' ' * width
for name, task in Tasks
say " #{ (name + pad)slice 0 width } #{task.description}"
say '\nTask options:\n' + that if Options.toString()
say '''
Coke options:
-f, --cokefile FILE use FILE as the Cokefile