rexe 0.9.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +159 -56
- data/exe/rexe +125 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c0055b60141171c65564e56db902aeb407184a8dae5abc89a1957238b3b35eb
|
4
|
+
data.tar.gz: 801efa318ca3a7dc8eeaea81e44d0f96331428465789c0cf9899196d6501c934
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a87be47727dd851c36f93af89034f86ad7e268caa888a44018da344a6b1f9752f5e4e2bbf7460699f84b51bc47b2faf4b66cc6bac4f7b4f3b444856475cffd5
|
7
|
+
data.tar.gz: 9cdc86c7a7547e84c20286f6185162365453d5a3f0d556e98bc3b28dd6a2338b62999f722222394d4e749269535549cd22c1fa53ec68082fe0943377e8a6afb9
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
## rexe -- Ruby Command Line Executor
|
2
2
|
|
3
3
|
|
4
|
+
### v0.10.1
|
5
|
+
|
6
|
+
* Fix help text for input formats.
|
7
|
+
|
8
|
+
|
9
|
+
### v0.10.0
|
10
|
+
|
11
|
+
* Add input format option -i to simplify ingesting JSON, YAML, Marshal formats.
|
12
|
+
* Add Marshal output option.
|
13
|
+
* In -mn mode:
|
14
|
+
* change output behavior; now outputs last evaluated value like other modes.
|
15
|
+
* self is now a newly created object (Object.new), providing a clean slate for adding instance variables, methods, etc.
|
16
|
+
* Wrap execution in Bundler.with_clean_env to enable loading of gems not in Gemfile.
|
17
|
+
|
18
|
+
|
4
19
|
### v0.9.0
|
5
20
|
|
6
21
|
* Change -ms (single or separate string) mode to -ml (line) mode.
|
data/README.md
CHANGED
@@ -47,7 +47,7 @@ line, tipping the scale so that it is practical to do it more often.
|
|
47
47
|
Here is `rexe`'s help text as of the time of this writing:
|
48
48
|
|
49
49
|
```
|
50
|
-
rexe -- Ruby Command Line Executor/Filter -- v0.
|
50
|
+
rexe -- Ruby Command Line Executor/Filter -- v0.10.1 -- https://github.com/keithrbennett/rexe
|
51
51
|
|
52
52
|
Executes Ruby code on the command line, optionally taking standard input and writing to standard output.
|
53
53
|
|
@@ -55,13 +55,27 @@ Options:
|
|
55
55
|
|
56
56
|
-c --clear_options Clear all previous command line options specified up to now
|
57
57
|
-h, --help Print help and exit
|
58
|
+
-i, --input_format FORMAT Input format (none is default)
|
59
|
+
-ij JSON
|
60
|
+
-im Marshal
|
61
|
+
-in None
|
62
|
+
-iy YAML
|
58
63
|
-l, --load RUBY_FILE(S) Ruby file(s) to load, comma separated, or ! to clear
|
59
|
-
-m, --
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
-m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
|
65
|
+
-ml line mode; each line is ingested as a separate string
|
66
|
+
-me enumerator mode
|
67
|
+
-mb big string mode; all lines combined into single multiline string
|
68
|
+
-mn (default) no input mode; no special handling of input; self is not input
|
64
69
|
-n, --[no-]noop Do not execute the code (useful with -v); see note (1) below
|
70
|
+
-o, --output_format FORMAT Output format (puts is default):
|
71
|
+
-oi Inspect
|
72
|
+
-oj JSON
|
73
|
+
-oJ Pretty JSON
|
74
|
+
-om Marshal
|
75
|
+
-on No Output
|
76
|
+
-op Puts (default)
|
77
|
+
-os to_s
|
78
|
+
-oy YAML
|
65
79
|
-r, --require REQUIRES Gems and built-in libraries to require, comma separated, or ! to clear
|
66
80
|
-v, --[no-]verbose verbose mode (logs to stderr); see note (1) below
|
67
81
|
|
@@ -224,10 +238,11 @@ do so by using any of the following: `--[no-]verbose`, `-v n`, or `-v false`.
|
|
224
238
|
|
225
239
|
### Input Modes
|
226
240
|
|
227
|
-
`rexe` tries to make it simple and convenient for you to handle standard input,
|
241
|
+
`rexe` tries to make it simple and convenient for you to handle standard input,
|
242
|
+
and in different ways. Here is the help text relating to input modes:
|
228
243
|
|
229
244
|
```
|
230
|
-
-m, --
|
245
|
+
-m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
|
231
246
|
-ml line mode; each line is ingested as a separate string
|
232
247
|
-me enumerator mode
|
233
248
|
-mb big string mode; all lines combined into single multiline string
|
@@ -256,6 +271,10 @@ eybdoog
|
|
256
271
|
`reverse` is implicitly called on each line of standard input. `self`
|
257
272
|
is the input line in each call (we could also have used `self.reverse` but the `self` would have been redundant.).
|
258
273
|
|
274
|
+
Be aware that there is no way to selectively exclude records from being output. Even if the result of the code
|
275
|
+
is nil or the empty string, a newline will be output. If this is an issue, you might be better off using Enumerator
|
276
|
+
mode and calling `select`, `filter`, `reject`, etc.
|
277
|
+
|
259
278
|
|
260
279
|
#### -me "Enumerator" Filter Mode
|
261
280
|
|
@@ -304,9 +323,35 @@ input, you would have to code it yourself (e.g. as we did earlier with `STDIN.re
|
|
304
323
|
If you may have more input than would fit in memory, you can do the following:
|
305
324
|
|
306
325
|
* use `-ml` (line) mode so you are fed only 1 line at a time
|
307
|
-
* use
|
308
|
-
|
309
|
-
|
326
|
+
* use an Enumerator, either by specifying the `-me` (enumerator) mode option,
|
327
|
+
or using `-mn` (no input) mode in conjunction with something like `STDIN.each_line`. Then:
|
328
|
+
** Make sure not to call any methods (e.g. `map`, `select`)
|
329
|
+
that will produce an array of all the input because that will pull all the records into memory, or:
|
330
|
+
** use lazy enumerators
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
### Output Formats
|
335
|
+
|
336
|
+
Several output formats are provided for your convenience. Here they are in alphabetical order:
|
337
|
+
|
338
|
+
* `-oa` (Awesome Print) - calls `.ai` on the object to get the string that `ap` would print
|
339
|
+
* `-oi` (Inspect) - calls `inspect` on the object
|
340
|
+
* `-oj` (JSON) - calls `to_json` on the object
|
341
|
+
* `-oJ` (Pretty JSON) calls `JSON.pretty_generate` with the object
|
342
|
+
* `-on` (No Output) - output is suppressed
|
343
|
+
* `-op` (Puts) - produces what `puts` would output
|
344
|
+
* `-os` (To String) - calls `to_s` on the object
|
345
|
+
* `-oy` (YAML) - calls `to_yaml` on the object
|
346
|
+
|
347
|
+
All formats will implicitly `require` anything needed to accomplish their task (e.g. `require 'yaml'`).
|
348
|
+
|
349
|
+
You may wonder why these formats are provided, given that their functionality
|
350
|
+
could be included in the custom code instead. Here's why:
|
351
|
+
|
352
|
+
* The savings in command line length goes a long way to making these commands more readable and feasible.
|
353
|
+
* It's much simpler to use multiple formats, as there is no need to change the code itself. This also enables
|
354
|
+
parameterization of the output format.
|
310
355
|
|
311
356
|
|
312
357
|
### Implementing Domain Specific Languages (DSL's)
|
@@ -347,49 +392,7 @@ Ruby is supremely well suited for DSL's since it does not require parentheses fo
|
|
347
392
|
so calls to your custom methods _look_ like built in language commands and keywords.
|
348
393
|
|
349
394
|
|
350
|
-
|
351
|
-
|
352
|
-
The filter input modes will automatically call `puts` to output the last evaulated value of your code to stdout. There may be times you may want to do something _else_ with the input and send nothing to stdout. For example, you might want to write something to a file, send to a network, etc. The simplest way to suppress output is to make nil or the empty string the final value in the expression. This can be accomplished simply merely by appending `; nil` or `;''` to your code. For example, to only output directory entries containing the letter 'e' in `-ml` (line) mode:
|
353
|
-
|
354
|
-
```
|
355
|
-
# Output only entries that contain the letter 'e':
|
356
|
-
➜ / ls | sort | rexe -ml "include?('e') ? self : nil"
|
357
|
-
|
358
|
-
Incompatible Software
|
359
|
-
|
360
|
-
Network
|
361
|
-
...
|
362
|
-
```
|
363
|
-
|
364
|
-
However, as you can see, blank lines were displayed where `nil` was output. Why? Because in -ml mode,
|
365
|
-
puts will be called unconditionally on whatever value is the result of the expression. In the case of nil,
|
366
|
-
puts outputs an empty string and its usual newline. This is probably not what you want.
|
367
|
-
|
368
|
-
If you want to see the `nil`s, you could replace `nil` with `nil.inspect`, which returns the string `'nil'`,
|
369
|
-
unlike `nil.to_s` which returns the empty string. Of course,
|
370
|
-
there may be some other custom string you would want,
|
371
|
-
such as `[no match]` or `-`, or you could just specify the string `'nil'`. [^2]
|
372
|
-
|
373
|
-
But you probably don't want any line at all to display for excluded objects. For this it is best to use
|
374
|
-
`-me` (enumerator) mode. If you won't have a huge amount of input data you could use `select`:
|
375
|
-
|
376
|
-
```
|
377
|
-
# Output only entries that contain the letter 'e':
|
378
|
-
➜ / ls | sort | rexe -me "select { |s| s.include?('e') }"
|
379
|
-
Incompatible Software
|
380
|
-
Network
|
381
|
-
System
|
382
|
-
```
|
383
|
-
|
384
|
-
Here, `select` returns an array which is implicitly passed to `puts`. `puts` does _not_ call `to_s` when passed an array, but instead has special handling for arrays which prints each element on its own line. If instead we appended `.to_s`
|
385
|
-
or `.inspect` to the result array, we would get the more compact array notation:
|
386
|
-
|
387
|
-
```
|
388
|
-
➜ / ls | sort | rexe -me "select { |s| s.include?('e') }.to_s"
|
389
|
-
["Incompatible Software\n", "Network\n", ..., "private\n"]
|
390
|
-
```
|
391
|
-
|
392
|
-
#### Quoting Strings in Your Ruby Code
|
395
|
+
### Quoting Strings in Your Ruby Code
|
393
396
|
|
394
397
|
One complication of using utilities like `rexe` where Ruby code is specified on the shell command line is that
|
395
398
|
you need to be careful about the shell's special treatment of certain characters. For this reason, it is often
|
@@ -399,12 +402,12 @@ An excellent reference for how they differ is [here](https://stackoverflow.com/q
|
|
399
402
|
Feel free to fall back on Ruby's super useful `%q{}` and `%Q{}`, equivalent to single and double quotes, respectively.
|
400
403
|
|
401
404
|
|
402
|
-
|
405
|
+
### Mimicking Method Arguments
|
403
406
|
|
404
407
|
You may want to support arguments in your code. One of the previous examples downloaded currency conversion rates. Let's find out the available currency codes:
|
405
408
|
|
406
409
|
```
|
407
|
-
➜ / echo $
|
410
|
+
➜ / echo $EUR_RATES_JSON | rexe -rjson -mb \
|
408
411
|
"JSON.parse(self)['rates'].keys.sort.join(' ')"
|
409
412
|
AUD BGN BRL CAD CHF CNY CZK DKK GBP HKD HRK HUF IDR ILS INR ISK JPY KRW MXN MYR NOK NZD PHP PLN RON RUB SEK SGD THB TRY USD ZAR
|
410
413
|
```
|
@@ -422,6 +425,35 @@ AUD BGN BRL CAD CHF CNY CZK DKK GBP HKD HRK HUF IDR ILS INR ISK JPY KRW MXN MYR
|
|
422
425
|
In this code, `self` is the currency code `PHP` (Philippine Peso). We have accessed the JSON text to parse from the environment variable we previously populated.
|
423
426
|
|
424
427
|
|
428
|
+
### Using the Clipboard for Text Processing
|
429
|
+
|
430
|
+
Sometimes when editing text I need to do some one off text manipulation.
|
431
|
+
Using the system's commands for pasting to and copying from the clipboard,
|
432
|
+
this can easily be done. On the Mac, the `pbpaste` command outputs to stdout
|
433
|
+
the clipboard content, and the `pbcopy` command copies its stdin to the clipboard.
|
434
|
+
|
435
|
+
Let's say I have the following currency codes displayed on the screen:
|
436
|
+
|
437
|
+
```
|
438
|
+
AUD BGN BRL CAD CHF CNY CZK DKK GBP HKD HRK HUF IDR ILS INR ISK JPY KRW MXN MYR NOK NZD PHP PLN RON RUB SEK SGD THB TRY USD ZAR
|
439
|
+
```
|
440
|
+
|
441
|
+
...and I want to turn them into Ruby symbols for inclusion in Ruby source code as keys in a hash
|
442
|
+
whose values will be the display names of the currencies, e.g "Australian Dollar").
|
443
|
+
After copying this line to the clipboard, I could run this:
|
444
|
+
|
445
|
+
```
|
446
|
+
➜ ~ pbpaste | rexe -ml "split.map(&:downcase).map { |s| %Q{ #{s}: '',} }.join(%Q{\n})"
|
447
|
+
aud: '',
|
448
|
+
bgn: '',
|
449
|
+
brl: '',
|
450
|
+
# ...
|
451
|
+
```
|
452
|
+
|
453
|
+
If I add `| pbcopy` to the rexe command, then that output text would be copied into the clipboard instead of
|
454
|
+
displayed in the terminal, and I could then paste it in my editor.
|
455
|
+
|
456
|
+
|
425
457
|
### More Examples
|
426
458
|
|
427
459
|
Here are some more examples to illustrate the use of `rexe`.
|
@@ -529,7 +561,78 @@ straightforward to follow. Here's what it does:
|
|
529
561
|
* use C-style printf formatting to align the text into two columns
|
530
562
|
|
531
563
|
|
564
|
+
----
|
565
|
+
|
566
|
+
Let's go a little crazy with the YouTube example.
|
567
|
+
Let's have the video that loads be different for the success or failure
|
568
|
+
of the command.
|
569
|
+
|
570
|
+
If I put this in a load file (such as ~/.rexerc):
|
571
|
+
|
572
|
+
```
|
573
|
+
def play(piece_code)
|
574
|
+
pieces = {
|
575
|
+
hallelujah: "https://www.youtube.com/watch?v=IUZEtVbJT5c&t=0m20s",
|
576
|
+
rick_roll: "https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=0m43s",
|
577
|
+
valkyries: "http://www.youtube.com/watch?v=P73Z6291Pt8&t=0m28s",
|
578
|
+
wm_tell: "https://www.youtube.com/watch?v=j3T8-aeOrbg",
|
579
|
+
}
|
580
|
+
`open #{Shellwords.escape(pieces.fetch(piece_code))}`
|
581
|
+
end
|
582
|
+
|
583
|
+
|
584
|
+
def play_result(success)
|
585
|
+
play(success ? :hallelujah : :rick_roll)
|
586
|
+
end
|
587
|
+
|
532
588
|
|
589
|
+
def play_result_by_exit_code
|
590
|
+
play_result(STDIN.read.chomp == '0')
|
591
|
+
end
|
592
|
+
|
593
|
+
```
|
594
|
+
|
595
|
+
Then when I issue a command that succeeds, the Hallelujah Chorus is played:
|
596
|
+
|
597
|
+
```
|
598
|
+
➜ ~ uname; echo $? | rexe play_result_by_exit_code
|
599
|
+
```
|
600
|
+
|
601
|
+
...but when the command fails, in this case, with an executable which is not found, it plays Rick Astley's
|
602
|
+
"Never Gonna Give You Up":
|
603
|
+
|
604
|
+
```
|
605
|
+
➜ ~ uuuuu; echo $? | rexe play_result_by_exit_code
|
606
|
+
```
|
607
|
+
|
608
|
+
----
|
609
|
+
|
610
|
+
Another formatting example...I wanted to reformat this help text:
|
611
|
+
|
612
|
+
```
|
613
|
+
'i' => Inspect
|
614
|
+
'j' => JSON
|
615
|
+
'J' => Pretty JSON
|
616
|
+
'n' => No Output
|
617
|
+
'p' => Puts (default)
|
618
|
+
's' => to_s
|
619
|
+
'y' => YAML
|
620
|
+
```
|
621
|
+
|
622
|
+
Admittedly, the time it took to do this with rexe probably exceeded the time to do it manually,
|
623
|
+
but it was an interesting exercise and made it easy to try different formats. Here it is:
|
624
|
+
|
625
|
+
```
|
626
|
+
➜ ~ pbpaste | rexe -ml "sub(%q{'}, '-o').sub(%q{' =>}, %q{ })"
|
627
|
+
-oi Inspect
|
628
|
+
-oj JSON
|
629
|
+
-oJ Pretty JSON
|
630
|
+
-on No Output
|
631
|
+
-op Puts (default)
|
632
|
+
-os to_s
|
633
|
+
-oy YAML
|
634
|
+
```
|
635
|
+
|
533
636
|
|
534
637
|
|
535
638
|
### Conclusion
|
data/exe/rexe
CHANGED
@@ -4,12 +4,13 @@
|
|
4
4
|
#
|
5
5
|
# Inspired by https://github.com/thisredone/rb
|
6
6
|
|
7
|
+
require 'bundler'
|
7
8
|
require 'optparse'
|
8
9
|
require 'shellwords'
|
9
10
|
|
10
|
-
class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
11
|
+
class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :requires, :verbose, :noop)
|
11
12
|
|
12
|
-
VERSION = '0.
|
13
|
+
VERSION = '0.10.1'
|
13
14
|
|
14
15
|
def initialize
|
15
16
|
clear_options
|
@@ -19,10 +20,12 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
19
20
|
# Used as an initializer and also when `-!` is specified on the command line.
|
20
21
|
def clear_options
|
21
22
|
self.input_mode = :no_input
|
23
|
+
self.output_format = :puts
|
22
24
|
self.loads = []
|
23
25
|
self.requires = []
|
24
26
|
self.verbose = false
|
25
27
|
self.noop = false
|
28
|
+
@output_formatter = nil
|
26
29
|
end
|
27
30
|
|
28
31
|
|
@@ -37,13 +40,27 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
37
40
|
|
38
41
|
-c --clear_options Clear all previous command line options specified up to now
|
39
42
|
-h, --help Print help and exit
|
43
|
+
-i, --input_format FORMAT Input format (none is default)
|
44
|
+
-ij JSON
|
45
|
+
-im Marshal
|
46
|
+
-in None
|
47
|
+
-iy YAML
|
40
48
|
-l, --load RUBY_FILE(S) Ruby file(s) to load, comma separated, or ! to clear
|
41
|
-
-m, --
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
-m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
|
50
|
+
-ml line mode; each line is ingested as a separate string
|
51
|
+
-me enumerator mode
|
52
|
+
-mb big string mode; all lines combined into single multiline string
|
53
|
+
-mn (default) no input mode; no special handling of input; self is not input
|
46
54
|
-n, --[no-]noop Do not execute the code (useful with -v); see note (1) below
|
55
|
+
-o, --output_format FORMAT Output format (puts is default):
|
56
|
+
-oi Inspect
|
57
|
+
-oj JSON
|
58
|
+
-oJ Pretty JSON
|
59
|
+
-om Marshal
|
60
|
+
-on No Output
|
61
|
+
-op Puts (default)
|
62
|
+
-os to_s
|
63
|
+
-oy YAML
|
47
64
|
-r, --require REQUIRES Gems and built-in libraries to require, comma separated, or ! to clear
|
48
65
|
-v, --[no-]verbose verbose mode (logs to stderr); see note (1) below
|
49
66
|
|
@@ -80,6 +97,23 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
80
97
|
exit
|
81
98
|
end
|
82
99
|
|
100
|
+
parser.on('-i', '--input_format FORMAT',
|
101
|
+
'Mode with which to parse input values (n = none (default), j = JSON, m = Marshal, y = YAML') do |v|
|
102
|
+
|
103
|
+
modes = {
|
104
|
+
'j' => :json,
|
105
|
+
'm' => :marshal,
|
106
|
+
'n' => :none,
|
107
|
+
'y' => :yaml,
|
108
|
+
}
|
109
|
+
|
110
|
+
self.input_format = modes[v]
|
111
|
+
if self.input_format.nil?
|
112
|
+
puts help_text
|
113
|
+
raise "Input mode must be one of #{modes.keys}."
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
83
117
|
parser.on('-l', '--load RUBY_FILE(S)', 'Ruby file(s) to load, comma separated, or ! to clear') do |v|
|
84
118
|
if v == '!'
|
85
119
|
self.loads.clear
|
@@ -93,7 +127,7 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
93
127
|
end
|
94
128
|
end
|
95
129
|
|
96
|
-
parser.on('-m', '--
|
130
|
+
parser.on('-m', '--input_mode MODE',
|
97
131
|
'Mode with which to handle input (-ml, -me, -mb, -mn (default)') do |v|
|
98
132
|
|
99
133
|
modes = {
|
@@ -110,6 +144,28 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
110
144
|
end
|
111
145
|
end
|
112
146
|
|
147
|
+
parser.on('-o', '--output_format FORMAT',
|
148
|
+
'Mode with which to format values for output (`-o` + [aijJmnpsy])') do |v|
|
149
|
+
|
150
|
+
modes = {
|
151
|
+
'a' => :awesome_print,
|
152
|
+
'i' => :inspect,
|
153
|
+
'j' => :json,
|
154
|
+
'J' => :pretty_json,
|
155
|
+
'm' => :marshal,
|
156
|
+
'n' => :no_output,
|
157
|
+
'p' => :puts, # default
|
158
|
+
's' => :to_s,
|
159
|
+
'y' => :yaml,
|
160
|
+
}
|
161
|
+
|
162
|
+
self.output_format = modes[v]
|
163
|
+
if self.output_format.nil?
|
164
|
+
puts help_text
|
165
|
+
raise "Output mode must be one of #{modes.keys}."
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
113
169
|
parser.on('-r', '--require REQUIRE(S)',
|
114
170
|
'Gems and built-in libraries (e.g. shellwords, yaml) to require, comma separated, or ! to clear') do |v|
|
115
171
|
if v == '!'
|
@@ -143,6 +199,7 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
143
199
|
|
144
200
|
requires.uniq!
|
145
201
|
loads.uniq!
|
202
|
+
|
146
203
|
end
|
147
204
|
|
148
205
|
|
@@ -158,10 +215,13 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
158
215
|
|
159
216
|
|
160
217
|
def execute(eval_context_object, code)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
218
|
+
unless input_format == :none
|
219
|
+
eval_context_object = input_parser.(eval_context_object)
|
220
|
+
end
|
221
|
+
|
222
|
+
value = eval_context_object.instance_eval(&code)
|
223
|
+
unless output_format == :no_output
|
224
|
+
print output_formatter.(value)
|
165
225
|
end
|
166
226
|
rescue Errno::EPIPE
|
167
227
|
exit(-13)
|
@@ -195,7 +255,7 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
195
255
|
line: -> { STDIN.each { |l| execute(l.chomp, code) } },
|
196
256
|
enumerator: -> { execute(STDIN.each_line, code) },
|
197
257
|
one_big_string: -> { big_string = STDIN.read; execute(big_string, code) },
|
198
|
-
no_input: -> { execute(
|
258
|
+
no_input: -> { execute(Object.new, code) }
|
199
259
|
}
|
200
260
|
|
201
261
|
if self.noop
|
@@ -209,7 +269,58 @@ class Rexe < Struct.new(:input_mode, :loads, :requires, :verbose, :noop)
|
|
209
269
|
end
|
210
270
|
end
|
211
271
|
|
272
|
+
|
273
|
+
def input_parser
|
274
|
+
if @input_parser.nil?
|
275
|
+
|
276
|
+
require 'json' if input_format == :json
|
277
|
+
require 'yaml' if input_format == :yaml
|
278
|
+
|
279
|
+
parsers = {
|
280
|
+
json: ->(obj) { JSON.parse(obj) },
|
281
|
+
marshal: ->(obj) { Marshal.load(obj) },
|
282
|
+
none: ->(_obj) { obj },
|
283
|
+
yaml: ->(obj) { YAML.load(obj) },
|
284
|
+
}
|
285
|
+
|
286
|
+
@input_parser = parsers[input_format]
|
287
|
+
end
|
288
|
+
@input_parser
|
289
|
+
end
|
290
|
+
|
291
|
+
|
292
|
+
def output_formatter
|
293
|
+
if @output_formatter.nil?
|
294
|
+
|
295
|
+
if %i(json pretty_json).include?(output_format)
|
296
|
+
require 'json'
|
297
|
+
elsif output_format == :yaml
|
298
|
+
require 'yaml'
|
299
|
+
elsif output_format == :awesome_print
|
300
|
+
require 'awesome_print'
|
301
|
+
end
|
302
|
+
|
303
|
+
formatters = {
|
304
|
+
awesome_print: ->(obj) { obj.ai },
|
305
|
+
inspect: ->(obj) { obj.inspect + "\n" },
|
306
|
+
json: ->(obj) { obj.to_json },
|
307
|
+
marshal: ->(obj) { Marshal.dump(obj) },
|
308
|
+
no_output: ->(_obj) { nil },
|
309
|
+
pretty_json: ->(obj) { JSON.pretty_generate(obj) },
|
310
|
+
puts: ->(obj) { sio = StringIO.new; sio.puts(obj); sio.string }, # default
|
311
|
+
to_s: ->(obj) { obj.to_s + "\n" },
|
312
|
+
yaml: ->(obj) { obj.to_yaml },
|
313
|
+
}
|
314
|
+
|
315
|
+
@output_formatter = formatters[output_format]
|
316
|
+
end
|
317
|
+
@output_formatter
|
318
|
+
end
|
319
|
+
|
320
|
+
|
212
321
|
# This is needed because the gemspec file loads this file to access Rexe::VERSION
|
213
322
|
# and must not have it run at that time:
|
214
323
|
called_as_script = (File.basename($0) == File.basename(__FILE__))
|
215
|
-
|
324
|
+
if called_as_script
|
325
|
+
Bundler.with_clean_env { Rexe.new.call }
|
326
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rexe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keith Bennett
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|