/
coke.co
81 lines (71 loc) · 2.66 KB
/
coke.co
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
`#!/usr/bin/env node`
# `coke` is a simplified version of [Make](http://www.gnu.org/software/make/)
# ([Rake](http://rake.rubyforge.org/), [Jake](http://github.com/280north/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
Coco.run 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]
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
'''