1 | **cli is a toolkit for rapidly building command line apps - it includes:**
|
2 |
|
3 | - Full featured opts/args parser
|
4 | - Plugin support for adding common options and switches
|
5 | - Helper methods for working with input/output and spawning child processes
|
6 | - Output colored/styled messages, [progress bars](https://github.com/chriso/cli/blob/master/examples/progress.js) or [spinners](https://github.com/chriso/cli/blob/master/examples/spinner.js)
|
7 | - Command [auto-completion](https://github.com/chriso/cli/blob/master/examples/command.js) and [glob support](https://github.com/chriso/cli/blob/master/examples/glob.js)
|
8 |
|
9 | Install using `npm install cli` or just bundle [cli.js](https://github.com/chriso/cli/raw/master/cli.js) with your app.
|
10 |
|
11 | ## Example apps
|
12 |
|
13 | ### sort.js
|
14 |
|
15 | ```javascript
|
16 | #!/usr/bin/env node
|
17 | require('cli').withStdinLines(function(lines, newline) {
|
18 | this.output(lines.sort().join(newline));
|
19 | });
|
20 | ```
|
21 |
|
22 | Try it out
|
23 |
|
24 | ```bash
|
25 | $ ./sort.js < input.txt
|
26 | ```
|
27 |
|
28 | Let's add support for an `-n` switch to use a numeric sort, and a `-r` switch to reverse output - only 5 extra lines of code (!)
|
29 |
|
30 | ```javascript
|
31 | var cli = require('cli'), options = cli.parse();
|
32 |
|
33 | cli.withStdinLines(function(lines, newline) {
|
34 | lines.sort(!options.n ? null : function(a, b) {
|
35 | return parseInt(a) > parseInt(b);
|
36 | });
|
37 | if (options.r) lines.reverse();
|
38 | this.output(lines.join(newline));
|
39 | });
|
40 | ```
|
41 |
|
42 | ### static.js
|
43 |
|
44 | Let's create a static file server with daemon support to see the opts parser + plugins in use - note: this requires `npm install creationix daemon`
|
45 |
|
46 | ```javascript
|
47 | var cli = require('cli').enable('daemon', 'status'); //Enable 2 plugins
|
48 |
|
49 | cli.parse({
|
50 | log: ['l', 'Enable logging'],
|
51 | port: ['p', 'Listen on this port', 'number', 8080],
|
52 | serve: [false, 'Serve static files from PATH', 'path', './public']
|
53 | });
|
54 |
|
55 | cli.main(function(args, options) {
|
56 | var server, middleware = [];
|
57 |
|
58 | if (options.log) {
|
59 | this.debug('Enabling logging');
|
60 | middleware.push(require('creationix/log')());
|
61 | }
|
62 |
|
63 | this.debug('Serving files from ' + options.serve);
|
64 | middleware.push(require('creationix/static')('/', options.serve, 'index.html'));
|
65 |
|
66 | server = this.createServer(middleware).listen(options.port);
|
67 |
|
68 | this.ok('Listening on port ' + options.port);
|
69 | });
|
70 | ```
|
71 |
|
72 | To output usage information
|
73 |
|
74 | ```bash
|
75 | $ ./static.js --help
|
76 | ```
|
77 |
|
78 | To create a daemon that serves files from */tmp*, run
|
79 |
|
80 | ```bash
|
81 | $ ./static.js -ld --serve=/tmp
|
82 | ```
|
83 |
|
84 | For more examples, see [./examples](https://github.com/chriso/cli/tree/master/examples)
|
85 |
|
86 | ## Helper methods
|
87 |
|
88 | cli has methods that collect stdin (newline is autodetected as \n or \r\n)
|
89 |
|
90 | ```javascript
|
91 | cli.withStdin(callback); //callback receives stdin as a string
|
92 | cli.withStdinLines(callback); //callback receives stdin split into an array of lines (lines, newline)
|
93 | ```
|
94 |
|
95 | cli also has a lower level method for working with input line by line (see [./examples/cat.js](https://github.com/chriso/cli/blob/master/examples/cat.js) for an example).
|
96 |
|
97 | ```javascript
|
98 | cli.withInput(file, function (line, newline, eof) {
|
99 | if (!eof) {
|
100 | this.output(line + newline);
|
101 | }
|
102 | });
|
103 | ```
|
104 |
|
105 | *Note: `file` can be omitted if you want to work with stdin*
|
106 |
|
107 | To output a progress bar, call
|
108 |
|
109 | ```javascript
|
110 | cli.progress(progress); //Where 0 <= progress <= 1
|
111 | ```
|
112 |
|
113 | To spawn a child process, use
|
114 |
|
115 | ```javascript
|
116 | cli.exec(cmd, callback); //callback receives the output of the process (split into lines)
|
117 | ```
|
118 |
|
119 | cli also comes bundled with kof's [node-natives](https://github.com/kof/node-natives) (access with cli.native) and creationix' [stack](https://github.com/creationix/stack) (access with cli.createServer)
|
120 |
|
121 | ## Plugins
|
122 |
|
123 | Plugins are a way of adding common opts and can be enabled using
|
124 |
|
125 | ```javascript
|
126 | cli.enable(plugin1, [plugin2, ...]); //To disable, use the equivalent disable() method
|
127 | ```
|
128 |
|
129 | **help** - *enabled by default*
|
130 |
|
131 | Adds `-h,--help` to output auto-generated usage information
|
132 |
|
133 | **version**
|
134 |
|
135 | Adds `-v,--version` to output version information for the app. cli will attempt to locate and parse a nearby *package.json*
|
136 |
|
137 | To set your own app name and version, use `cli.setApp(app_name, version)`
|
138 |
|
139 | **status**
|
140 |
|
141 | Adds options to show/hide the stylized status messages that are output to the console when using one of these methods
|
142 |
|
143 | ```javascript
|
144 | cli.debug(msg); //Only shown when using --debug
|
145 | cli.error(msg);
|
146 | cli.fatal(msg); //Exits the process after outputting msg
|
147 | cli.info(msg);
|
148 | cli.ok(msg);
|
149 | ```
|
150 |
|
151 | `-k,--no-color` will omit ANSI color escapes from the output
|
152 |
|
153 | **glob** - *requires* `npm install glob`
|
154 |
|
155 | Enables glob matching of arguments
|
156 |
|
157 | **daemon** - *requires* `npm install daemon`
|
158 |
|
159 | Adds `-d,--daemon ARG` for daemonizing the process and controlling the resulting daemon
|
160 |
|
161 | `ARG` can be either start (default), stop, restart, pid (outputs the daemon's pid if it's running), or log (output the daemon's stdout+stderr)
|
162 |
|
163 | **timeout**
|
164 |
|
165 | Adds `-t,--timeout N` to exit the process after N seconds with an error
|
166 |
|
167 | **catchall**
|
168 |
|
169 | Adds `-c,--catch` to catch and output uncaughtExceptions and resume execution
|
170 |
|
171 | *Note: Plugins are automatically disabled if an option or switch of the same name is already defined*
|
172 |
|
173 | ## LICENSE
|
174 |
|
175 | (MIT license)
|
176 |
|
177 | Copyright (c) 2010 Chris O'Hara <cohara87@gmail.com>
|
178 |
|
179 | Permission is hereby granted, free of charge, to any person obtaining
|
180 | a copy of this software and associated documentation files (the
|
181 | "Software"), to deal in the Software without restriction, including
|
182 | without limitation the rights to use, copy, modify, merge, publish,
|
183 | distribute, sublicense, and/or sell copies of the Software, and to
|
184 | permit persons to whom the Software is furnished to do so, subject to
|
185 | the following conditions:
|
186 |
|
187 | The above copyright notice and this permission notice shall be
|
188 | included in all copies or substantial portions of the Software.
|
189 |
|
190 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
191 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
192 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
193 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
194 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
195 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
196 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|