-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuildCommander.caf
More file actions
113 lines (87 loc) · 2.91 KB
/
buildCommander.caf
File metadata and controls
113 lines (87 loc) · 2.91 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
###
TODO - guess what? I'm going to build my own Commander.
What I want:
1) I want to be able to add "commands" which each have their own options:
cli myCommand -zyx
2) I want fully automatic single-letter assignment.
3) I want common options across commands (--verbose)
4) I want a nice, declarative API.
a) uses Validator
artCommander
loadData:
help: "load test data"
options:
# validator declaration
# validator is exclusive - if it's not here, it's an error.
parallel: "boolean"
# args is special - it's all the arguments which are not -/-- options.
# It is an array of strings.
args: validate: (v) -> v.length > 1
# options is a plain object with all the options
action: (options) ->
{parallel, args} = options
5) I want a sane and automatic way of handling "help"
###
import &ArtStandardLib
(options) ->
{actions, beforeActions, title = 'artCommander'} = options
commander = require "commander"
{version, name} = options.package
commander.version "#{name} v#{version}"
commander.option "-v, --verbose"
commander.option "-q, --quiet"
actionTaken = false
letterAssignments = v: true q: true
actionsToLetters = {}
assignLetters = (offset = 0) ->
allAssigned = true
each v, k in actions when !actionsToLetters[k]
if letter = getCodeWords(k)[offset]?.slice(0, 1)?.toLowerCase()
if letterAssignments[letter]
allAssigned = false
else
letterAssignments[letter] = k
actionsToLetters[k] = letter
unless allAssigned
assignLetters offset + 1
assignLetters()
actionMap = {}
each v, k in actions
command = lowerCamelCase k
action = if v.constructor == Object
{params, action, help} = v
invokeParameters =
if params
"" --#{command} #{params}
else
"" --#{command}
action
else
invokeParameters = "" --#{command}
v
if letter = actionsToLetters[k]
invokeParameters = "-#{letter}, #{baseCommand = invokeParameters}"
commander.option invokeParameters, help
actionMap[command] = (arg)->
arg = null if arg == true
args = compactFlatten [] arg
unless quiet
log.full [title]: {}
command
&process.title
inputs: args
actionTaken = true
Promise.resolve beforeActions? commander
.then (beforeActionsOptions) -> action merge beforeActionsOptions, {} args, quiet, verbose
.then (out) -> !quiet && log.full [title]: {} command, output: out
.catch (error) -> log.full [title]: {} command, error
parsed = commander
.parse process.argv
{quiet, verbose} = parsed
each action, command in actionMap
if parsed[command]
action parsed[command]
unless actionTaken
console.error "" No command given.
commander.outputHelp()
process.exit 1