UNPKG

11 kBMarkdownView Raw
1Capitano
2========
3
4[![npm version](https://badge.fury.io/js/capitano.svg)](http://badge.fury.io/js/capitano)
5[![dependencies](https://david-dm.org/resin-io/capitano.png)](https://david-dm.org/username/repo.png)
6
7Capitano allows you to craft powerful command line applications, your way.
8
9```coffee
10capitano = require('capitano')
11
12capitano.command
13 signature: 'utils print <title> [words...]'
14 options: [
15 signature: 'date'
16 boolean: true
17 alias: [ 'd' ]
18 ]
19 action: (params, options) ->
20 log = ''
21
22 if options.date
23 log += "#{new Date()} "
24
25 log += "#{params.title}: #{params.words}"
26
27 console.log(log)
28
29capitano.run(process.argv)
30```
31
32***
33
34```sh
35$ myCoolApp utils print Error Something very bad happened
36Error: Something very bad happened
37
38$ myCoolApp utils print Error Something very bad happened -d
39Thu Dec 18 2014 14:49:27 GMT-0400 (BOT) Error: Something very bad happened
40```
41
42Features
43--------
44
45- Infinitely nested git-like subcommands.
46- Global and per-command options.
47- Variadic arguments.
48- Option aliases.
49- Separate between parsing and executing command line arguments.
50- No built-in generated help page, you roll your own.
51- No built-in commands, you have a high degree of control over your app.
52
53Installation
54------------
55
56Install `capitano` by running:
57
58```sh
59$ npm install --save capitano
60```
61
62API
63-------
64
65## capitano.command(options)
66
67Register a command. Capitano understands the following options, but you can pass custom options to do nifty things (see the [examples section](https://github.com/resin-io/capitano#examples)):
68
69### signature (string)
70
71The command signature. If it's `*`, it will match anything that is not matched by other commands.
72
73### action (function)
74
75Function to call when the signature is matched. This function gets passed a parameter and an options object.
76
77### options ([object])
78
79Array of objects describing the options specific to this command. See the [options section](https://github.com/resin-io/capitano#option) for more information.
80
81## capitano.globalOption(options)
82
83Register a global option, which will be accessible from every command (and from outside too!) so be careful about naming collisions!
84
85It accepts an object containing the following options:
86
87### signature (string)
88
89The option signature **excluding** any parameter (`foo` instead of `foo <bar>`).
90
91### boolean (boolean)
92
93Whether the option is boolean (doesn't accepts any parameters). It defaults to `false`. If `parameter` is defined, then `boolean` should be `false`.
94
95### parameter (string)
96
97The name of the parameter, excluding required/optional tags (`bar` instead of `<bar>`). Notice that if you set `boolean: true`, then you have to omit this option.
98
99
100### alias (string|[string])
101
102Define an alias, or a set of alias for an option. Aliases can contain single letter abbreviations (`f`, `l`) or full option names (`baz`, `foo`).
103
104## capitano.run(argv)
105
106Run and execute the application given a set of arguments (usually `process.argv`):
107
108```coffee
109capitano.run(process.argv)
110```
111
112**Note:** `capitano.run` is a shorcut function for `capitano.execute(capitano.parse(argv))`. You will usually use this function, however you can use `parse()` and `execute()` in particular situations when you need to differenciate between parsing and executing the commands.
113
114## capitano.parse(argv)
115
116Parse, but not execute the command line arguments (usually `process.argv`).
117
118It returns a `cli` object containing three fields:
119
120### command (string)
121
122A string representing the issued command, omitting any option.
123
124### options (object)
125
126An object containing the raw representation of the given options.
127
128### globals (object)
129
130An object containing the matches and parsed global options.
131
132## capitano.execute(cli)
133
134It accepts a `cli` object (returned by [capitano.parse()](https://github.com/resin-io/capitano#capitanoparseargv)) and
135executes the corresponding command, with it's corresponding options.
136
137## capitano.state
138
139An object containing the current registered commands an options. As with Capitano you're expected to implement every command (including `help`, etc) this object comes handy to accomplish a wide range of tasks.
140
141It includes the following fields:
142
143### commands (array)
144
145An array containing every registered command so far (with `capitano.command()`)
146
147See the [Command class](https://github.com/resin-io/capitano#command) for more information.
148
149### globalOptions (array)
150
151An array containing every registered global option so far (with `capitano.globalOption()`).
152
153See the [Option class](https://github.com/resin-io/capitano#option) for more information.
154
155### findCommandBySignature(signature)
156
157A self explanatory function that returns a command that matches a specific signature.
158
159### getMatchCommand(signature)
160
161Get command that matches a signature, without taking parameters into account.
162
163This means that a command `app create <id>` will be matched by a signature `app create`.
164
165## capitano.defaults
166
167An object containing some settings used by Capitano.
168
169It includes the following fields:
170
171- `signatures.wildcard (string)` The wildcard symbol. Defaults to `*`.
172- `actions.commandNotFound(signature)` The function called when a command was not found. By default, it prints a boring `Command not found: <signature>` and exits with an error code 1.
173- `actions.onError(Error)` The function called when there is an error. By default, it prints the error message and exits with an error code 1.
174
175**Pro tip:** If you want to modify these settings, do it as early as possible (before registering any commands/global options) as some settings are used when performing the mentioned tasks.
176
177Classes
178-------
179
180### Command
181
182The Capitano Command class contains the following public fields:
183
184#### Command#signature (Signature)
185
186See the [Signature class](https://github.com/resin-io/capitano#signature).
187
188#### Command#options ([Option])
189
190An array of [Option classes](https://github.com/resin-io/capitano#option).
191
192#### Command#isWildcard()
193
194A predicate method that returns `true` if a command represents a wildcard.
195
196***
197
198### Signature
199
200The Capitano Signature class contains the following public fields:
201
202#### Signature#hasParameters()
203
204A predicate method that returns `true` if the signature has at least one parameter.
205
206#### Signature#hasVariadicParameters()
207
208A predicate method that returns `true` if the signature has at least one variadic parameter.
209
210#### Signature#isWildcard()
211
212A predicate method that returns `true` if the signature represents a wildcard.
213
214***
215
216### Option
217
218The Capitano Option class contains the following public fields:
219
220#### Option#signature
221
222See [Signature class](https://github.com/resin-io/capitano#signature).
223
224#### Option#alias (string|[string])
225
226A string or array of string alias.
227
228#### Option#boolean (boolean)
229
230Whether the option is boolean or not.
231
232#### Option#parameter (string)
233
234An option parameter (optional).
235
236#### Option#required (boolean|string)
237
238Defines whether an option is required. If the field is `true`, a generic error is thrown, otherwise you can set a custom error message by setting to a `string`.
239
240Examples
241--------
242
243Capitano is very flexible, allowing you to implement all sort of crazy stuff. Here I present some common patterns that I've been doing on Capitano. If you have an interesting idea that you think it's worth to share, please submit a PR!
244
245### Generated help
246
247Notice this is a very rudimentary help page and lacks features such as printing global options, command specific options, handling correct aligment, etc, but you can at least get an idea on how to implement this for yourself.
248
249```coffee
250capitano = require('capitano')
251
252capitano.command
253 signature: 'version'
254 description: 'output version information'
255 action: ...
256
257capitano.command
258 signature: 'help'
259 description: 'output general help page'
260 action: ->
261 console.log("Usage: #{myAppName} [COMMANDS] [OPTIONS]")
262 console.log('\nCommands:\n')
263
264 for command in capitano.state.commands
265 continue if command.isWildcard()
266 console.log("\t#{command.signature}\t\t\t"#{command.description})
267
268capitano.run(process.argv)
269```
270
271***
272
273```sh
274$ app help
275Usage: MyCoolApp [COMMANDS] [OPTIONS]
276
277Commands:
278
279 version output version information
280 help output general help page
281```
282
283### Command specific help pages
284
285```coffee
286capitano = require('capitano')
287
288capitano.command
289 signature: 'version'
290 description: 'output version information'
291 help: '''
292 Software versioning is the process of assigning either unique version names or unique version numbers to unique states of computer software. Within a given version number category (major, minor), these numbers are generally assigned in increasing order and correspond to new developments in the software. At a fine-grained level, revision control is often used for keeping track of incrementally different versions of electronic information, whether or not this information is computer software.
293 '''
294 action: ...
295
296capitano.command
297 signature: 'help [command...]'
298 description: 'output general help page'
299 action: (params) ->
300 return outputGeneralHelp() if not params?
301
302 command = capitano.state.getMatchCommand(params.command)
303 if not command? or command.isWildcard()
304 return capitano.defaults.actions.commandNotFound(params.command)
305
306 console.log(command.help)
307
308capitano.run(process.argv)
309```
310
311***
312
313```sh
314$ app help version
315Software versioning is the process of assigning either unique version names or unique version numbers to unique states of computer software. Within a given version number category (major, minor), these numbers are generally assigned in increasing order and correspond to new developments in the software. At a fine-grained level, revision control is often used for keeping track of incrementally different versions of electronic information, whether or not this information is computer software.
316```
317
318Tests
319-----
320
321Run the test suite by doing:
322
323```sh
324$ gulp test
325```
326
327ChangeLog
328---------
329
330### 1.1.1
331
332- Fix issue with parsing words that start with a number.
333
334### 1.1.0
335
336- Implement support for required options.
337
338### 1.0.4
339
340- Fix issue when instantiating Parameter instances with a number directly.
341
342### 1.0.3
343
344- Fix issue with quotation of multi word parameters. Thanks [@Page-](https://github.com/Page-)!
345
346### 1.0.2
347
348- Fix https://github.com/resin-io/capitano/issues/4.
349
350### 1.0.1
351
352- Fix issues with path and quoted multi string parameters.
353
354Contribute
355----------
356
357- Issue Tracker: [github.com/resin-io/capitano/issues](https://github.com/resin-io/capitano/issues)
358- Source Code: [github.com/resin-io/capitano](https://github.com/resin-io/capitano)
359
360Before submitting a PR, please make sure that you include tests, and that [coffeelint](http://www.coffeelint.org/) runs without any warning:
361
362```sh
363$ gulp lint
364```
365
366Support
367-------
368
369If you're having any problem, please [raise an issue](https://github.com/resin-io/capitano/issues) on GitHub.
370
371TODO
372-------
373
374- Options default values.
375
376License
377-------
378
379The project is licensed under the MIT license.