UNPKG

11.3 kBMarkdownView Raw
1<img width="945" alt="2017-07-26 9 27 05" src="https://user-images.githubusercontent.com/8784712/28623641-373450f4-7249-11e7-854d-1b076dab274d.png">
2
3[![NPM version](https://img.shields.io/npm/v/cac.svg?style=flat)](https://npmjs.com/package/cac) [![NPM downloads](https://img.shields.io/npm/dm/cac.svg?style=flat)](https://npmjs.com/package/cac) [![CircleCI](https://circleci.com/gh/cacjs/cac/tree/master.svg?style=shield)](https://circleci.com/gh/cacjs/cac/tree/master) [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/egoist/donate) [![chat](https://img.shields.io/badge/chat-on%20discord-7289DA.svg?style=flat)](https://chat.egoist.moe) [![install size](https://badgen.net/packagephobia/install/cac)](https://packagephobia.now.sh/result?p=cac)
4
5## Introduction
6
7**C**ommand **A**nd **C**onquer is a JavaScript library for building CLI apps.
8
9## Table of Contents
10
11<!-- toc -->
12
13- [Install](#install)
14- [Usage](#usage)
15 - [Simple Parsing](#simple-parsing)
16 - [Display Help Message and Version](#display-help-message-and-version)
17 - [Command-specific Options](#command-specific-options)
18 - [Brackets](#brackets)
19 - [Variadic Arguments](#variadic-arguments)
20 - [Dot-nested Options](#dot-nested-options)
21 - [Default Command](#default-command)
22 - [With TypeScript](#with-typescript)
23- [Projects Using CAC](#projects-using-cac)
24- [References](#references)
25 - [CLI Instance](#cli-instance)
26 - [cli.command(name, description, config?)](#clicommandname-description-config)
27 - [cli.option(name, description, config?)](#clioptionname-description-config)
28 - [cli.parse(argv?)](#cliparseargv)
29 - [cli.version(version, customFlags?)](#cliversionversion-customflags)
30 - [cli.help(callback?)](#clihelpcallback)
31 - [cli.outputHelp(subCommand?)](#clioutputhelpsubcommand)
32 - [Command Instance](#command-instance)
33 - [command.option()](#commandoption)
34 - [command.action(callback)](#commandactioncallback)
35 - [command.alias(name)](#commandaliasname)
36 - [command.allowUnknownOptions()](#commandallowunknownoptions)
37 - [command.example(example)](#commandexampleexample)
38 - [Events](#events)
39- [FAQ](#faq)
40 - [How is the name written and pronounced?](#how-is-the-name-written-and-pronounced)
41- [Contributing](#contributing)
42- [Author](#author)
43
44<!-- tocstop -->
45
46## Install
47
48```bash
49yarn add cac
50```
51
52## Usage
53
54### Simple Parsing
55
56Use CAC as simple argument parser:
57
58```js
59// examples/basic-usage.js
60const cli = require('cac')()
61
62cli.option('--type [type]', 'Choose a project type', {
63 default: 'node'
64})
65
66const parsed = cli.parse()
67
68console.log(JSON.stringify(parsed, null, 2))
69```
70
71<img width="500" alt="2018-11-26 12 28 03" src="https://user-images.githubusercontent.com/8784712/48981576-2a871000-f112-11e8-8151-80f61e9b9908.png">
72
73### Display Help Message and Version
74
75```js
76// examples/help.js
77const cli = require('cac')()
78
79cli.option('--type [type]', 'Choose a project type', {
80 default: 'node'
81})
82cli.option('--name <name>', 'Provide your name')
83
84cli.command('lint [...files]', 'Lint files').action((files, options) => {
85 console.log(files, options)
86})
87
88// Display help message when `-h` or `--help` appears
89cli.help()
90// Display version number when `-h` or `--help` appears
91cli.version('0.0.0')
92
93cli.parse()
94```
95
96<img width="500" alt="2018-11-25 8 21 14" src="https://user-images.githubusercontent.com/8784712/48979012-acb20d00-f0ef-11e8-9cc6-8ffca00ab78a.png">
97
98### Command-specific Options
99
100You can attach options to a command.
101
102```js
103const cli = require('cac')()
104
105cli
106 .command('rm <dir>')
107 .option('-r, --recursive', 'Remove recursively')
108 .action((dir, options) => {
109 console.log('remove ' + dir + (options.recursive ? ' recursively' : ''))
110 })
111
112cli.parse()
113```
114
115A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated. If you really want to use unknown options, use [`command.allowUnknownOptions`](#commandallowunknownoptions).
116
117### Brackets
118
119When using brackets in command name, angled brackets indicate required command arguments, while sqaure bracket indicate optional arguments.
120
121When using brackets in option name, angled brackets indicate that the option value is required, while sqaure bracket indicate that the value is optional.
122
123```js
124const cli = require('cac')()
125
126cli
127 .command('deploy <folder>', 'Deploy a folder to AWS')
128 .option('--scale [level]', 'Scaling level')
129 .action((folder, options) => {
130 console.log(folder)
131 console.log(options)
132 })
133
134cli.parse()
135```
136
137### Variadic Arguments
138
139The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to add `...` to the start of argument name, just like the rest operator in JavaScript. Here is an example:
140
141```js
142const cli = require('cac')()
143
144cli
145 .command('build <entry> [...otherFiles]', 'Build your app')
146 .option('--foo', 'Foo option')
147 .action((entry, otherFiles, options) => {
148 console.log(entry)
149 console.log(otherFiles)
150 console.log(options)
151 })
152
153cli.help()
154
155cli.parse()
156```
157
158<img width="500" alt="2018-11-25 8 25 30" src="https://user-images.githubusercontent.com/8784712/48979056-47125080-f0f0-11e8-9d8f-3219e0beb0ed.png">
159
160### Dot-nested Options
161
162Dot-nested options will be merged into a single option.
163
164```js
165const cli = require('cac')()
166
167cli
168 .command('build', 'desc')
169 .option('--env <env>', 'Set envs')
170 .example('--env.API_SECRET xxx')
171 .action(options => {
172 console.log(options)
173 })
174
175cli.help()
176
177cli.parse()
178```
179
180<img width="500" alt="2018-11-25 9 37 53" src="https://user-images.githubusercontent.com/8784712/48979771-6ada9400-f0fa-11e8-8192-e541b2cfd9da.png">
181
182### Default Command
183
184Register a command that will be used when no other command is matched.
185
186```js
187const cli = require('cac')()
188
189cli
190 // Simply omit the command name, just brackets
191 .command('[...files]', 'Build files')
192 .option('--minimize', 'Minimize output')
193 .action((files, options) => {
194 console.log(files)
195 console.log(options.minimize)
196 })
197
198cli.parse()
199```
200
201### With TypeScript
202
203First you need `@types/node` to be installed as a dev dependency in your project:
204
205```bash
206yarn add @types/node --dev
207```
208
209Then everything just works out of the box:
210
211```js
212const cac = require('cac')
213// OR ES modules
214import cac from 'cac'
215```
216
217## Projects Using CAC
218
219Projects that use **CAC**:
220
221- [SAO](https://github.com/egoist/sao): ⚔️ Futuristic scaffolding tool.
222- [DocPad](https://github.com/docpad/docpad): 🏹 Powerful Static Site Generator.
223- [Poi](https://github.com/egoist/poi): ⚡️ Delightful web development.
224- [bili](https://github.com/egoist/bili): 🥂 Schweizer Armeemesser for bundling JavaScript libraries.
225- [lass](https://github.com/lassjs/lass): 💁🏻 Scaffold a modern package boilerplate for Node.js.
226- Feel free to add yours here...
227
228## References
229
230### CLI Instance
231
232CLI instance is created by invoking the `cac` function:
233
234```js
235const cac = require('cac')
236const cli = cac()
237```
238
239#### cli.command(name, description, config?)
240
241- Type: `(name: string, description: string) => Command`
242
243Create a command instance.
244
245The option also accepts a third argument `config` for addtional command config:
246
247- `config.allowUnknownOptions`: `boolean` Allow unknown options in this command.
248- `config.ignoreOptionDefaultValue`: `boolean` Don't use the options's default value in parsed options, only display them in help message.
249
250#### cli.option(name, description, config?)
251
252- Type: `(name: string, description: string, config?: OptionConfig) => CLI`
253
254Add a global option.
255
256The option also accepts a third argument `config` for addtional option config:
257
258- `config.default`: Default value for the option.
259- `config.coerce`: `(value: any) => newValue` A function to process the option value.
260
261#### cli.parse(argv?)
262
263- Type: `(argv = process.argv) => ParsedArgv`
264
265```ts
266interface ParsedArgv {
267 args: string[]
268 options: {
269 [k: string]: any
270 }
271}
272```
273
274When this method is called, `cli.rawArgs` `cli.args` `cli.options` `cli.matchedCommand` will also be available.
275
276#### cli.version(version, customFlags?)
277
278- Type: `(version: string, customFlags = '-v, --version') => CLI`
279
280Output version number when `-v, --version` flag appears.
281
282#### cli.help(callback?)
283
284- Type: `(callback?: HelpCallback) => CLI`
285
286Output help message when `-h, --help` flag appears.
287
288Optional `callback` allows post-processing of help text before it is displayed:
289
290```ts
291type HelpCallback = (sections: HelpSection[]) => void
292
293interface HelpSection {
294 title?: string
295 body: string
296}
297```
298
299#### cli.outputHelp(subCommand?)
300
301- Type: `(subCommand?: boolean) => CLI`
302
303Output help message. Optional `subCommand` argument if you want to output the help message for the matched sub-command instead of the global help message.
304
305### Command Instance
306
307Command instance is created by invoking the `cli.command` method:
308
309```js
310const command = cli.command('build [...files]', 'Build given files')
311```
312
313#### command.option()
314
315Basically the same as `cli.option` but this adds the option to specific command.
316
317#### command.action(callback)
318
319- Type: `(callback: ActionCallback) => Command`
320
321Use a callback function as the command action when the command matches user inputs.
322
323```ts
324type ActionCallback = (
325 // Parsed CLI args
326 // The last arg will be an array if it's an varadic argument
327 ...args: string | string[] | number | number[]
328 // Parsed CLI options
329 options: Options
330) => any
331
332interface Options {
333 [k: string]: any
334}
335```
336
337#### command.alias(name)
338
339- Type: `(name: string) => Command`
340
341Add an alias name to this command, the `name` here can't contain brackets.
342
343#### command.allowUnknownOptions()
344
345- Type: `() => Command`
346
347Allow unknown options in this command, by default CAC will log an error when unknown options are used.
348
349#### command.example(example)
350
351- Type: `(example: CommandExample) => Command`
352
353Add an example which will be displayed at the end of help message.
354
355```ts
356type CommandExample = ((bin: string) => string) | string
357```
358
359### Events
360
361Listen to commands:
362
363```js
364// Listen to the `foo` command
365cli.on('command:foo', () => {
366 // Do something
367})
368
369// Listen to the default command
370cli.on('command:!', () => {
371 // Do something
372})
373
374// Listen to unknown commands
375cli.on('command:*', () => {
376 console.error('Invalid command: %', cli.args.join(' '))
377 process.exit(1)
378})
379```
380
381## FAQ
382
383### How is the name written and pronounced?
384
385CAC, or cac, pronounced `C-A-C`.
386
387This project is dedicated to our lovely C.C. sama. Maybe CAC stands for C&C as well :P
388
389<img src="http://i.giphy.com/v3FeH4swox9mg.gif" width="400"/>
390
391## Contributing
392
3931. Fork it!
3942. Create your feature branch: `git checkout -b my-new-feature`
3953. Commit your changes: `git commit -am 'Add some feature'`
3964. Push to the branch: `git push origin my-new-feature`
3975. Submit a pull request :D
398
399## Author
400
401**CAC** © [EGOIST](https://github.com/egoist), Released under the [MIT](./LICENSE) License.<br>
402Authored and maintained by egoist with help from contributors ([list](https://github.com/cacjs/cac/contributors)).
403
404> [Website](https://egoist.sh) · GitHub [@egoist](https://github.com/egoist) · Twitter [@\_egoistlily](https://twitter.com/_egoistlily)