1 | # ramda-cli [![npm version](https://badge.fury.io/js/ramda-cli.svg)](https://www.npmjs.com/package/ramda-cli) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
|
2 |
|
3 | A command-line tool for processing data with functional pipelines.
|
4 |
|
5 | ```sh
|
6 | $ npm install -g ramda-cli; alias R=ramda
|
7 | $ curl -L http://bit.do/people-json | R \
|
8 | 'filter (p) -> p.city is /Port/ or p.name is /^Dr\./' \
|
9 | 'project <[ name city mac ]>' \
|
10 | 'take 3' \
|
11 | -o table --compact
|
12 | ┌──────────────────┬─────────────────┬───────────────────┐
|
13 | │ name │ city │ mac │
|
14 | ├──────────────────┼─────────────────┼───────────────────┤
|
15 | │ Dr. Araceli Lang │ Yvettemouth │ 9e:ea:28:41:2a:50 │
|
16 | │ Terrell Boyle │ Port Reaganfort │ c5:32:09:5a:f7:15 │
|
17 | │ Libby Renner │ Port Reneeside │ 9c:63:13:31:c4:ac │
|
18 | └──────────────────┴─────────────────┴───────────────────┘
|
19 | ```
|
20 |
|
21 | Unites [Ramda's][ramda] curried, data-last API and
|
22 | [LiveScript's][livescript] terse and powerful syntax.
|
23 |
|
24 | With a variety of supported input/output types and the ability [pull any
|
25 | module from npm](#using-packages-from-npm), ramda-cli is a potent tool for
|
26 | many kinds of data manipulation in command-line environment.
|
27 |
|
28 | ##### Table of Contents
|
29 |
|
30 | - [Examples](#examples)
|
31 | - [Options](#options)
|
32 | - [Evaluation context](#evaluation-context)
|
33 | - [Configuration](#configuration)
|
34 | - [Using packages from NPM](#using-packages-from-npm)
|
35 | - [Promises](#promises)
|
36 | - [LiveScript?](#livescript)
|
37 | - [JavaScript support](#javascript-support)
|
38 | - [Questions or comments?](#questions-or-comments)
|
39 |
|
40 | ##### Resources
|
41 |
|
42 | - [Cookbook][cookbook]
|
43 | - [Tutorial: Using ramda-cli to process and display data from GitHub API][tutorial]
|
44 | - [Essential LiveScript for ramda-cli][essential-livescript]
|
45 |
|
46 | ## install
|
47 |
|
48 | ```sh
|
49 | npm install -g ramda-cli
|
50 | alias R='ramda'
|
51 | ```
|
52 |
|
53 | ## synopsis
|
54 |
|
55 | ```sh
|
56 | cat data.json | ramda [function] ...
|
57 | ```
|
58 |
|
59 | The idea is to [compose][composition] functions into a pipeline of operations that when
|
60 | applied to given data, produces the desired output.
|
61 |
|
62 | By default, the function is applied to a stream of JSON data read from stdin,
|
63 | and the output data is sent to standard out as stringified JSON.
|
64 |
|
65 | Technically, `function` should be a snippet of LiveScript (or JavaScript with
|
66 | `--js`) that evaluates into a function. If multiple `function` arguments are
|
67 | supplied as positional arguments, they are composed into a pipeline in order
|
68 | from left to right (see [`R.pipe`](http://ramdajs.com/docs/#pipe)).
|
69 |
|
70 | As a simple example, in `echo 1 | R inc 'multiply 2'`, which prints 4, the
|
71 | computation would look roughly as follows:
|
72 |
|
73 | ```js
|
74 | input = 1
|
75 | fn = pipe(inc, multiply(2))
|
76 | result = fn(input) // multiply(2, inc(1))
|
77 | result // => 4
|
78 | ```
|
79 |
|
80 | All Ramda's functions are available directly in the scope. See
|
81 | http://ramdajs.com/docs/ for a full list.
|
82 |
|
83 | ## examples
|
84 |
|
85 | ```sh
|
86 | # Add 1 to each value in a list
|
87 | echo [1,2,3] | R 'map add 1'
|
88 | [
|
89 | 2,
|
90 | 3,
|
91 | 4
|
92 | ]
|
93 | ```
|
94 |
|
95 | ```sh
|
96 | # Add 1 to each value with inline ES6 lambda and take product of all
|
97 | echo [1,2,3] | R --js 'map(x => x + 1)' product
|
98 | 24
|
99 | ```
|
100 |
|
101 | > Ramda functions used:
|
102 | > [`add`](http://ramdajs.com/docs/#add),
|
103 | > [`map`](http://ramdajs.com/docs/#map),
|
104 | > [`product`](http://ramdajs.com/docs/#product)
|
105 |
|
106 | ##### Get a list of people whose first name starts with "B"
|
107 |
|
108 | ```sh
|
109 | cat people.json | R 'pluck \name' 'filter (name) -> name.0 is \B)' -o raw
|
110 | Brando Jacobson
|
111 | Betsy Bayer
|
112 | Beverly Gleichner
|
113 | Beryl Lindgren
|
114 | ```
|
115 |
|
116 | > Ramda functions used:
|
117 | > [`pluck`](http://ramdajs.com/docs/#pluck),
|
118 | > [`filter`](http://ramdajs.com/docs/#filter)
|
119 | > Data: [people.json](https://gist.githubusercontent.com/raine/cd11686e0b8a4a43bbf6/raw/people.json)
|
120 |
|
121 | ##### Create a markdown TODO list
|
122 |
|
123 | ```sh
|
124 | curl -s http://jsonplaceholder.typicode.com/todos |\
|
125 | R --raw-output \
|
126 | 'filter where-eq user-id: 10' \
|
127 | 'map (t) -> "- [#{t.completed && "x" || " "}] #{t.title}"' \
|
128 | 'take 5' \
|
129 | 'unlines'
|
130 | ```
|
131 |
|
132 | __Output__
|
133 |
|
134 | - [ ] ut cupiditate sequi aliquam fuga maiores
|
135 | - [x] inventore saepe cumque et aut illum enim
|
136 | - [x] omnis nulla eum aliquam distinctio
|
137 | - [ ] molestias modi perferendis perspiciatis
|
138 | - [ ] voluptates dignissimos sed doloribus animi quaerat aut
|
139 |
|
140 | > Ramda functions used:
|
141 | > [`filter`](http://ramdajs.com/docs/#filter),
|
142 | > [`where-eq`](http://ramdajs.com/docs/#whereEq),
|
143 | > [`map`](http://ramdajs.com/docs/#map)
|
144 |
|
145 | ##### List versions of npm module with dates formatted with [`node-timeago`](https://github.com/ecto/node-timeago)
|
146 |
|
147 | It looks for `ecto/node-timeago` installed to `$HOME/node_modules`.
|
148 |
|
149 | ```sh
|
150 | npm view ramda --json | R --import timeago \
|
151 | 'prop \time' 'to-pairs' \
|
152 | 'map -> version: it.0, time: timeago(it.1)' \
|
153 | -o tsv | column -t -s $'\t'
|
154 | ...
|
155 | 0.12.0 2 months ago
|
156 | 0.13.0 2 months ago
|
157 | 0.14.0 12 days ago
|
158 | ```
|
159 |
|
160 | ##### Search twitter for people who tweeted about ramda and pretty print [the result](https://raw.githubusercontent.com/raine/ramda-cli/media/twarc-ramda.png)
|
161 |
|
162 | ```sh
|
163 | twarc.py --search '#ramda' | R --slurp -p 'map path [\user, \screen_name]' uniq
|
164 | ```
|
165 |
|
166 | > Ramda functions used:
|
167 | > [`map`](http://ramdajs.com/docs/#map),
|
168 | > [`path`](http://ramdajs.com/docs/#path)
|
169 |
|
170 |
|
171 | ##### Pull response status data from Graphite and visualize
|
172 |
|
173 | HTTP status codes per minute for last hour:
|
174 |
|
175 | ```sh
|
176 | graphite -t "summarize(stats_counts.status_codes.*, '1min', 'sum', false)" -f '-1h' -o json | \
|
177 | R --import sparkline 'map evolve datapoints: (map head) >> sparkline \
|
178 | 'sort-by prop \target' -o table
|
179 | ```
|
180 |
|
181 | [![graphite-http-codes](https://raw.githubusercontent.com/raine/ramda-cli/media/graphite-http-codes-thumb.png)](https://raw.githubusercontent.com/raine/ramda-cli/media/graphite-http-codes.png)
|
182 |
|
183 | > Ramda functions used:
|
184 | > [`evolve`](http://ramdajs.com/docs/#evolve),
|
185 | > [`sortBy`](http://ramdajs.com/docs/#sortBy)
|
186 |
|
187 | ##### Use `--slurp` to read multiple JSON objects into a single list before any operations
|
188 |
|
189 | ```sh
|
190 | cat <<EOF | R --slurp identity
|
191 | "foo bar"
|
192 | "test lol"
|
193 | "hello world"
|
194 | EOF
|
195 | [
|
196 | "foo bar",
|
197 | "test lol",
|
198 | "hello world"
|
199 | ]
|
200 | ```
|
201 |
|
202 | ##### Solution to the [credit card JSON to CSV challenge](https://gist.github.com/jorinvo/2e43ffa981a97bc17259) using `--output-type csv`
|
203 |
|
204 | ```bash
|
205 | #!/usr/bin/env bash
|
206 |
|
207 | data_url=https://gist.githubusercontent.com/jorinvo/7f19ce95a9a842956358/raw/e319340c2f6691f9cc8d8cc57ed532b5093e3619/data.json
|
208 | curl $data_url | R \
|
209 | 'filter where creditcard: (!= null)' `# filter out those who don't have credit card` \
|
210 | 'project [\name, \creditcard]' `# pick name and creditcard fields from all objects` \
|
211 | -o csv > `date "+%Y%m%d"`.csv `# print output as csv to a file named as the current date`
|
212 | ```
|
213 |
|
214 | ##### List a project's dependencies in a table
|
215 |
|
216 | ```sh
|
217 | npm ls --json | R 'prop \dependencies' 'map-obj prop \version' -o table --compact
|
218 | ┌───────────────┬────────┐
|
219 | │ JSONStream │ 1.0.4 │
|
220 | │ treis │ 2.3.9 │
|
221 | │ ramda │ 0.14.0 │
|
222 | │ livescript │ 1.4.0 │
|
223 | │ cli-table │ 0.3.1 │
|
224 | └───────────────┴────────┘
|
225 | ```
|
226 |
|
227 | > Ramda functions used:
|
228 | > [`filter`](http://ramdajs.com/docs/#filter),
|
229 | > [`where`](http://ramdajs.com/docs/#where),
|
230 | > [`project`](http://ramdajs.com/docs/#project),
|
231 | > [`mapObj`](http://ramdajs.com/docs/#mapObj),
|
232 | > [`prop`](http://ramdajs.com/docs/#prop)
|
233 |
|
234 | ##### Generate HTML with hyperscript
|
235 |
|
236 | With [`hyperscript`][hyperscript] installed to `${HOME,PWD}/node_modules`.
|
237 |
|
238 | ```sh
|
239 | cat <<EOF > shopping.txt
|
240 | milk
|
241 | cheese
|
242 | peanuts
|
243 | EOF
|
244 | ```
|
245 |
|
246 | ```sh
|
247 | cat shopping.txt | R --import h=hyperscript \
|
248 | -rR --slurp `# read raw input into a list` \
|
249 | 'map (h \li.item, _)' `# apply <li class="item"> into each item` \
|
250 | 'h \ul#list, _' `# wrap list inside <ul id="list">` \
|
251 | '.outer-HTML' `# finally, grab the HTML`
|
252 | ```
|
253 |
|
254 | ```html
|
255 | <ul id="list">
|
256 | <li class="item">milk</li>
|
257 | <li class="item">cheese</li>
|
258 | <li class="item">peanuts</li>
|
259 | </ul>
|
260 | ```
|
261 |
|
262 | Reason for underscores (e.g. `h \ul, _`) is that hyperscript API is not
|
263 | curried (and can't be because it's variadic). We need to explicitly state
|
264 | that this function is waiting for one more argument.
|
265 |
|
266 | For more examples, see the [Cookbook][cookbook].
|
267 |
|
268 | ## options
|
269 |
|
270 | ```
|
271 | Usage: ramda [options] [function] ...
|
272 |
|
273 | -f, --file read a function from a js/ls file instead of args; useful for
|
274 | larger scripts
|
275 | -c, --compact compact output for JSON and tables
|
276 | -s, --slurp read JSON objects from stdin as one big list
|
277 | -S, --unslurp unwraps a list before output so that each item is formatted and
|
278 | printed separately
|
279 | -t, --transduce use pipeline as a transducer to transform stdin
|
280 | -P, --json-path parse stream with JSONPath expression
|
281 | -i, --input-type read input from stdin as (#{format-enum-list INPUT_TYPES})
|
282 | -o, --output-type format output sent to stdout (#{format-enum-list OUTPUT_TYPES})
|
283 | -p, --pretty pretty-printed output with colors, alias to -o pretty
|
284 | -D, --pretty-depth set how deep objects are pretty printed
|
285 | -r, --raw-input alias for --input-type raw
|
286 | -R, --raw-output alias for --output-type raw
|
287 | -n, --no-stdin don't read input from stdin
|
288 | --[no-]headers csv/tsv has a header row
|
289 | --csv-delimiter custom csv delimiter character
|
290 | --js use javascript instead of livescript
|
291 | -I, --import require module as a variable
|
292 | -C, --configure edit config in $EDITOR
|
293 | -v, --verbose print debugging information (use -vv for even more)
|
294 | --version print version
|
295 | -h, --help displays help
|
296 | ```
|
297 |
|
298 | #### `-f, --file`
|
299 |
|
300 | Load a function pipeline from a file. Useful for scripts difficult to express
|
301 | in command-line.
|
302 |
|
303 | __Example__
|
304 |
|
305 | ```js
|
306 | // shout.js
|
307 | var R = require('ramda');
|
308 | module.exports = R.pipe(R.toUpper, R.add(R.__, '!'));
|
309 | ```
|
310 |
|
311 | ```sh
|
312 | echo -n '"hello world"' | R --file shout.js
|
313 | "HELLO WORLD!"
|
314 | ```
|
315 |
|
316 | You can overwrite command-line arguments through the script by exporting a
|
317 | string in property `opts`.
|
318 |
|
319 | ```js
|
320 | module.exports = function() { /* ... */ }
|
321 | module.exports.opts = '--slurp -o table'
|
322 | ```
|
323 |
|
324 | #### `-c, --compact`
|
325 |
|
326 | Print compact tables and JSON output without whitespace.
|
327 |
|
328 | When used with `--output-type raw`, no line breaks are added to output.
|
329 |
|
330 | __Example__
|
331 |
|
332 | ```sh
|
333 | seq 10 | R --input-type raw --output-type raw --compact identity # or -rRc
|
334 | 12345678910%
|
335 | ```
|
336 |
|
337 | #### `-s, --slurp`
|
338 |
|
339 | Read all input from `stdin` and wrap the data in a list before operations.
|
340 |
|
341 | __Example__
|
342 |
|
343 | ```sh
|
344 | cat <<EOF | R --slurp 'map to-upper'
|
345 | "foo"
|
346 | "bar"
|
347 | "xyz"
|
348 | EOF
|
349 | [
|
350 | "FOO",
|
351 | "BAR",
|
352 | "XYZ"
|
353 | ]
|
354 | ```
|
355 |
|
356 | #### `-S, --unslurp`
|
357 |
|
358 | After the pipeline is applied to an item and if the result is an array, its
|
359 | items are printed separately.
|
360 |
|
361 | __Example__
|
362 |
|
363 | ```sh
|
364 | echo '[1,2,3]' | R --unslurp 'map inc'
|
365 | 2
|
366 | 3
|
367 | 4
|
368 | ```
|
369 |
|
370 | #### `-t, --transduce`
|
371 |
|
372 | Transform the input stream using the pipeline as a
|
373 | [transducer][transducers-explained]. Requires all functions in the pipeline
|
374 | to be able to act as transducers.
|
375 |
|
376 | This option essentially allows performing operations like
|
377 | [`R.map`](http://ramdajs.com/docs/#map) or
|
378 | [`R.filter`](http://ramdajs.com/docs/#filter) on items as they come without
|
379 | waiting for the stream to complete or wrapping the input stream in a
|
380 | collection with [`--slurp`](#-s---slurp).
|
381 |
|
382 | __Example__
|
383 |
|
384 | ```sh
|
385 | echo '1 2 2 3 3 4' | R --transduce drop-repeats
|
386 | 1
|
387 | 2
|
388 | 3
|
389 | 4
|
390 | ```
|
391 |
|
392 | #### `-P, --json-path`
|
393 |
|
394 | Parse the input stream with given [JSONPath](http://goessner.net/articles/JsonPath/) expression.
|
395 |
|
396 | See also: [JSONStream documentation](https://github.com/dominictarr/JSONStream#jsonstreamparsepath)
|
397 |
|
398 | __Examples__
|
399 |
|
400 | Process a huge JSON array one by one without reading the whole thing first.
|
401 |
|
402 | `*` as JSON path unwraps the array and objects are passed to `identity` one by one.
|
403 |
|
404 | ```sh
|
405 | curl -Ls http://bit.do/countries-json | R --json-path '*' --compact identity
|
406 | {"name":"Afghanistan","code":"AF"}
|
407 | {"name":"Åland Islands","code":"AX"}
|
408 | {"name":"Albania","code":"AL"}
|
409 | ...
|
410 | ```
|
411 |
|
412 | #### `-i, --input-type`
|
413 |
|
414 | Parse `stdin` as one of these formats: `raw`, `csv`, `tsv`.
|
415 |
|
416 | __Examples__
|
417 |
|
418 | ```sh
|
419 | echo foo | R --input-type raw to-upper
|
420 | "FOO"
|
421 | ```
|
422 |
|
423 | ```sh
|
424 | $ cat <<EOF | R --input-type csv identity
|
425 | id,name
|
426 | 1,Bob
|
427 | 2,Alice
|
428 | EOF
|
429 | [
|
430 | { "id": "1", "name": "Bob" },
|
431 | { "id": "2", "name": "Alice" }
|
432 | ]
|
433 | ```
|
434 |
|
435 | #### `-o, --output-type`
|
436 |
|
437 | Instead of JSON, format output as one of: `pretty`, `raw`, `csv`, `tsv`, `table`.
|
438 |
|
439 | ##### `-o pretty`
|
440 |
|
441 | Print pretty output.
|
442 |
|
443 | ##### `-o raw`
|
444 |
|
445 | With raw output type when a string value is produced, the result will be
|
446 | written to stdout as is without any formatting.
|
447 |
|
448 | ##### `-o csv` and `-o tsv`
|
449 |
|
450 | CSV or TSV output type can be used when pipeline evaluates to an array of
|
451 | objects, an array of arrays or when stdin consists of a stream of bare
|
452 | objects. First object's keys will determine the headers.
|
453 |
|
454 | ##### `-o table`
|
455 |
|
456 | Print nearly any type of data as a table. If used with a list of objects,
|
457 | uses the first object's keys as headers.
|
458 |
|
459 | __Example__
|
460 |
|
461 | ```sh
|
462 | curl -Ls http://bit.do/countries-json | R 'take 3' -o table --compact
|
463 | ┌───────────────┬──────┐
|
464 | │ name │ code │
|
465 | ├───────────────┼──────┤
|
466 | │ Afghanistan │ AF │
|
467 | │ Åland Islands │ AX │
|
468 | │ Albania │ AL │
|
469 | └───────────────┴──────┘
|
470 | ```
|
471 |
|
472 | #### `-p, --pretty`
|
473 |
|
474 | Alias of `--output-type pretty`.
|
475 |
|
476 | #### `-D, --pretty-depth`
|
477 |
|
478 | When using pretty-printed output, set how deep structures are verbosely
|
479 | printed.
|
480 |
|
481 | Useful when output is huge and you want to see the general structure of an
|
482 | object or list.
|
483 |
|
484 | See documentation of [`util.inspect(object[, options])`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
|
485 |
|
486 | #### `-n, --no-stdin`
|
487 |
|
488 | Don't read `stdin` for input. Useful when starting a pipeline with a constant
|
489 | function.
|
490 |
|
491 | __Example__
|
492 |
|
493 | ```sh
|
494 | R --no-stdin 'always "hello world"' 'add __, \!'
|
495 | "hello world!"
|
496 | ```
|
497 |
|
498 | #### `--[no-]headers`
|
499 |
|
500 | Set if input csv/tsv contains a header row.
|
501 |
|
502 | By default, csv/tsv input is assumed to contain headers.
|
503 |
|
504 | #### `--csv-delimiter`
|
505 |
|
506 | Use a custom csv delimiter. Delimiter is comma by default.
|
507 |
|
508 | Example: `--csv-delimiter=';'`
|
509 |
|
510 | #### `--js`
|
511 |
|
512 | Interpret positional arguments as JavaScript instead of LiveScript.
|
513 |
|
514 | __Example__
|
515 |
|
516 | ```sh
|
517 | echo '[1,2,3]' | R --js 'map(x => Math.pow(x, 2))'
|
518 | [
|
519 | 1,
|
520 | 4,
|
521 | 9
|
522 | ]
|
523 | ```
|
524 |
|
525 | #### `-I, --import`
|
526 |
|
527 | Make modules installed with `npm install` accessible in positional code
|
528 | arguments.
|
529 |
|
530 | Modules are looked for in `$HOME/node_modules` and current directory's
|
531 | `node_modules`.
|
532 |
|
533 | Symbol `=` can be used to declare the variable module should appear as.
|
534 | Otherwise, module's name is used as the variable name.
|
535 |
|
536 | __Example__
|
537 |
|
538 | ```sh
|
539 | echo test | R -rR --import c=chalk 'c.bold'
|
540 | **test**
|
541 | ```
|
542 |
|
543 | #### `-C, --configure`
|
544 |
|
545 | Edit ramda-cli config file in `$EDITOR`.
|
546 |
|
547 | See [Configuration](#configuration).
|
548 |
|
549 | ## evaluation context
|
550 |
|
551 | ### functions
|
552 |
|
553 | All of [Ramda's functions][ramda-docs] are available, and also:
|
554 |
|
555 | | function | signature | description |
|
556 | |----------------|------------------------------|--------------------------------------------------|
|
557 | | `id` | `a → a` | Alias to `R.identity` |
|
558 | | [`flat`][flat] | `* → Object` | Flatten a deep structure into a shallow object |
|
559 | | `readFile` | `filePath → String` | Read a file as string |
|
560 | | `lines` | `String → [String]` | Split a string into lines |
|
561 | | `words` | `String → [String]` | Split a string into words |
|
562 | | `unlines` | `[String] → String` | Join a list of lines into a string |
|
563 | | `unwords` | `[String] → String` | Join a list of words into a string |
|
564 | | `then` | `Function → Promise` | Map a value inside Promise |
|
565 | | `pickDotPaths` | `[k] → {k: v} → {k: v}` | Like `R.pick` but deep using dot delimited paths |
|
566 | | `renameKeysBy` | `Function → {k: v} → {k: v}` | Like `R.map` but for keys instead of values |
|
567 |
|
568 | ### objects
|
569 |
|
570 | | object | description |
|
571 | |-----------|-------------------------------------|
|
572 | | `process` | https://nodejs.org/api/process.html |
|
573 | | `console` | https://nodejs.org/api/console.html |
|
574 |
|
575 | `process.exit()` can be used to short-circuit pipeline in case of an error,
|
576 | for example:
|
577 |
|
578 | ```sh
|
579 | curl api | ramda 'tap (res) -> if res.error then console.error(res); process.exit(1)'
|
580 | ```
|
581 |
|
582 | An alternative is to use `Maybe` type.
|
583 |
|
584 | ## configuration
|
585 |
|
586 | ### config file
|
587 |
|
588 | Path: `$HOME/.config/ramda-cli.{js,ls}`
|
589 |
|
590 | The purpose of a global config file is to carry functions you might find
|
591 | useful to have around. The functions it exports in an object are made
|
592 | available.
|
593 |
|
594 | For example,
|
595 |
|
596 | ```js
|
597 | // ~/.config/ramda-cli.js
|
598 | exports.date = (val) => new Date(val);
|
599 | exports.timeago = require('timeago');
|
600 | exports.debug = (val) => {
|
601 | console.log('debug:', val);
|
602 | return val;
|
603 | };
|
604 | ```
|
605 |
|
606 | ```sh
|
607 | echo 1442667243000 | R date debug timeago
|
608 | debug: Sat Sep 19 2015 12:54:03 GMT+0000 (UTC)
|
609 | "12 minutes ago"
|
610 | ```
|
611 |
|
612 | ### default options
|
613 |
|
614 | To make some options be passed by default, it is best to use a shell alias.
|
615 | For example:
|
616 |
|
617 | ```sh
|
618 | # always interpret as javascript
|
619 | alias R="ramda --js"
|
620 | echo 1 | R '(x) => x + 1'
|
621 | 2
|
622 | ```
|
623 |
|
624 | ```sh
|
625 | # always use identity function, instead of showing help without args
|
626 | alias R="ramda identity"
|
627 | echo 1 | R
|
628 | 1
|
629 | ```
|
630 |
|
631 | ## using packages from npm
|
632 |
|
633 | Packages installed to `$HOME/node_modules` or `$PWD/node_modules` can used
|
634 | with `require()`.
|
635 |
|
636 | ```sh
|
637 | date -v +7d +%s | R -rR --js 'require("moment").unix' 'x => x.fromNow()'
|
638 | in 7 days
|
639 | ```
|
640 |
|
641 | Additionally, there is `-I, --import` which can be used as a shorthand for
|
642 | `require()`.
|
643 |
|
644 | ```sh
|
645 | echo test | R -rR --import c=chalk 'c.bold'
|
646 | **test**
|
647 | ```
|
648 |
|
649 | ## promises
|
650 |
|
651 | Promise values are unwrapped at the end of pipeline.
|
652 |
|
653 | `then` helper function can be used to map promise values.
|
654 |
|
655 | ```sh
|
656 | echo 1 | R --js 'x => Promise.resolve(x)' 'then(add(5))'
|
657 | 6
|
658 | ```
|
659 |
|
660 | ```sh
|
661 | echo '192.168.1.1\ngoogle.com\nyahoo.com' | \
|
662 | R -r --js --import ping 'ping.promise.probe' 'then(omit(["output", "numeric_host"]))' | \
|
663 | R --slurp -o table --compact
|
664 | ┌─────────────┬───────┬─────────┬─────────┬─────────┬─────────┬────────┐
|
665 | │ host │ alive │ time │ min │ max │ avg │ stddev │
|
666 | ├─────────────┼───────┼─────────┼─────────┼─────────┼─────────┼────────┤
|
667 | │ 192.168.1.1 │ true │ 1.325 │ 1.325 │ 1.325 │ 1.325 │ 0.000 │
|
668 | │ google.com │ true │ 10.729 │ 10.729 │ 10.729 │ 10.729 │ 0.000 │
|
669 | │ yahoo.com │ true │ 115.418 │ 115.418 │ 115.418 │ 115.418 │ 0.000 │
|
670 | └─────────────┴───────┴─────────┴─────────┴─────────┴─────────┴────────┘
|
671 | ```
|
672 |
|
673 | ## debugging
|
674 |
|
675 | You can turn on the debug output with `-v, --verbose` flag. Use `-vv` for
|
676 | even more verbose output.
|
677 |
|
678 | Verbose output shows what entered LiveScript compiled to.
|
679 |
|
680 | To debug individual functions in the pipeline, you can use something like [`treis`][treis].
|
681 |
|
682 | ```sh
|
683 | echo 1 | R --import treis 'treis(add(1))'
|
684 | ```
|
685 |
|
686 | ## livescript?
|
687 |
|
688 | > [LiveScript][livescript] is a language which compiles to JavaScript. It has
|
689 | a straightforward mapping to JavaScript and allows you to write expressive
|
690 | code devoid of repetitive boilerplate.
|
691 |
|
692 | ### comparison table
|
693 |
|
694 | All expressions in the table evaluate to a function, and are valid in
|
695 | ramda-cli.
|
696 |
|
697 | | Ramda | LiveScript | JavaScript |
|
698 | |---------------------------|---------------------|---------------------------|
|
699 | | `not` | `(not)` | `x => !x` |
|
700 | | `nth(0)` | `(.0)` | `x => x[0]` |
|
701 | | `prop('name')` | `(.name)` | `x => x.name` |
|
702 | | `add(1)` | `(+ 1)` | `x => x + 1` |
|
703 | | `add(__, '!')` | `(+ '!')` | `x => x + '!'` |
|
704 | | `gt(__, 2)` | `(> 2)` | `x => x > 2` |
|
705 | | `contains(__, xs)` | `(in xs)` | `x => xs.includes(x)` |
|
706 | | `pipe(length, gt(__, 2))` | `(.length > 2)` | `x => x.length > 2 ` |
|
707 | | `isNil` | `(~= null)` | `x => x == null` |
|
708 | | `complement(isNil)` | `(!~= null)` | `x => x != null` |
|
709 | | `match(/foo/)` | `(is /foo/)` | `x => x.match(/foo/)` |
|
710 | | `replace('a', '')` | `(- 'a')` | `x => x.replace('a', '')` |
|
711 | | `join(',')` | `(* ',')` | `x => x.join(',')` |
|
712 | | `split(',')` | `(/ ',')` | `x => x.split(',')` |
|
713 | | `toUpper` | `(.to-upper-case!)` | `x => x.toUpperCase()` |
|
714 |
|
715 | See also: [Essential LiveScript for ramda-cli][essential-livescript]
|
716 |
|
717 | ## javascript support
|
718 |
|
719 | With the release of node v4 came the ES6 arrow function syntax without a
|
720 | compilation penalty. This makes JS more attractive choice for ramda-cli, so
|
721 | now there is `--js` flag.
|
722 |
|
723 | ```sh
|
724 | echo '[1,2,3]' | R --js 'map(x => x + 1)'
|
725 | [
|
726 | 2,
|
727 | 3,
|
728 | 4
|
729 | ]
|
730 | ```
|
731 |
|
732 | ## questions or comments?
|
733 |
|
734 | - [Ask on Gitter][gitter]
|
735 | - [Open an issue](https://github.com/raine/ramda-cli/issues/new)
|
736 | - [Tweet at `@rane`](https://twitter.com/rane)
|
737 |
|
738 | [![wercker status](https://app.wercker.com/status/92dbf35ece249fade3e8198181d93ec1/s/master "wercker status")](https://app.wercker.com/project/bykey/92dbf35ece249fade3e8198181d93ec1)
|
739 |
|
740 | [flat]: https://github.com/hughsk/flat
|
741 | [composition]: http://en.wikipedia.org/wiki/Function_composition_%28computer_science%29
|
742 | [livescript]: http://livescript.net
|
743 | [treis]: https://github.com/raine/treis
|
744 | [hyperscript]: https://github.com/dominictarr/hyperscript
|
745 | [ramda]: http://ramdajs.com
|
746 | [ramda-docs]: http://ramdajs.com/docs/
|
747 | [tutorial]: https://gistlog.co/raine/d12d0ec3e72b2945510b
|
748 | [essential-livescript]: https://gistlog.co/raine/6486b985c767954781b1
|
749 | [cookbook]: https://github.com/raine/ramda-cli/wiki/Cookbook
|
750 | [transducers-explained]: http://simplectic.com/blog/2014/transducers-explained-1/
|
751 | [gitter]: https://gitter.im/raine/ramda-cli
|