rexe 0.10.3 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +84 -49
- data/exe/rexe +117 -101
- 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: 148f8f91ef5ee20f245d74ee2b16b75550622b7ba80c139a671a26e2e383a482
|
4
|
+
data.tar.gz: 495447fbd26d0b8205d5c703e6c02577e5b9f85df11ec0892d4717689c17837e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fae8f53b62e75773a1245ea5b7e411328146a8bb80538522ec344dd18a86df65523e3226e15421537865a1db7196352f2cd25004303e63b5d0af3fb944e52dcf
|
7
|
+
data.tar.gz: eacd19481d49bd663ce6d8a9033a73c6eec711031ac766593b60aeca28296c4dacfb38450893ab857bc005663bd29b95883d7a638d45e878d36b7dab7388d5b3
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
## rexe -- Ruby Command Line Executor
|
2
2
|
|
3
3
|
|
4
|
+
### v0.11.0
|
5
|
+
|
6
|
+
* Make global $RC (Rexe Context) OpenStruct available to user code; added `count` for record count in `-ml` mode.
|
7
|
+
* Change verbose output to YAML format.
|
8
|
+
* Failure to load a file now raises an error.
|
9
|
+
* Add pretty print output format.
|
10
|
+
* Fix tests.
|
11
|
+
|
12
|
+
|
4
13
|
### v0.10.3
|
5
14
|
|
6
15
|
* Fix: parsing should not be attempted if in no input mode.
|
data/README.md
CHANGED
@@ -56,10 +56,12 @@ This command does the same thing as the previous `ruby` command:
|
|
56
56
|
`gem install rexe`. `rexe` provides several ways to simplify Ruby on the command
|
57
57
|
line, tipping the scale so that it is practical to do it more often.
|
58
58
|
|
59
|
+
----
|
60
|
+
|
59
61
|
Here is `rexe`'s help text as of the time of this writing:
|
60
62
|
|
61
63
|
```
|
62
|
-
rexe -- Ruby Command Line Executor/Filter -- v0.
|
64
|
+
rexe -- Ruby Command Line Executor/Filter -- v0.11.0 -- https://github.com/keithrbennett/rexe
|
63
65
|
|
64
66
|
Executes Ruby code on the command line, optionally taking standard input and writing to standard output.
|
65
67
|
|
@@ -126,29 +128,9 @@ Like any environment variable, `REXE_OPTIONS` could also be set in your startup
|
|
126
128
|
|
127
129
|
### Loading Files
|
128
130
|
|
129
|
-
The environment variable approach works well for command line _options_, but what if we want to specify Ruby _code_ (e.g. methods) that can be used by
|
131
|
+
The environment variable approach works well for command line _options_, but what if we want to specify Ruby _code_ (e.g. methods) that can be used by your `rexe` code?
|
130
132
|
|
131
|
-
For this, `rexe` lets you _load_ Ruby files, using the `-l` option, or implicitly (without your specifying it) in the case of the `~/.rexerc` file. Here is an example of something you might include in such a file
|
132
|
-
|
133
|
-
```
|
134
|
-
require 'json'
|
135
|
-
require 'yaml'
|
136
|
-
require 'awesome_print'
|
137
|
-
```
|
138
|
-
|
139
|
-
Requiring gems and modules for _all_ invocations of `rexe` will make your commands simpler and more concise, but will be a waste of execution time if they are not needed. You can inspect the execution times to see just how much time is being wasted. For example, we can find out that nokogiri takes about 0.7 seconds to load on my laptop by observing and comparing the execution times with and without the require (output has been abbreviated):
|
140
|
-
|
141
|
-
```
|
142
|
-
➜ ~ rexe -v
|
143
|
-
rexe time elapsed: 0.094946 seconds.
|
144
|
-
|
145
|
-
➜ ~ rexe -v -r nokogiri
|
146
|
-
rexe time elapsed: 0.165996 seconds.
|
147
|
-
```
|
148
|
-
|
149
|
-
### Using Loaded Files in Your Commands
|
150
|
-
|
151
|
-
Here's something else you could include in such a load file:
|
133
|
+
For this, `rexe` lets you _load_ Ruby files, using the `-l` option, or implicitly (without your specifying it) in the case of the `~/.rexerc` file. Here is an example of something you might include in such a file:
|
152
134
|
|
153
135
|
```
|
154
136
|
# Open YouTube to Wagner's "Ride of the Valkyries"
|
@@ -166,7 +148,9 @@ an explicitly loaded file:
|
|
166
148
|
➜ ~ tar czf /tmp/my-whole-user-space.tar.gz ~ ; rexe valkyries
|
167
149
|
```
|
168
150
|
|
169
|
-
|
151
|
+
(Note that `;` is used rather than `&&` because we want to hear the music whether or not the command succeeds.)
|
152
|
+
|
153
|
+
You might be thinking that creating an alias or a minimal shell script for this `open` would be a simpler and more natural
|
170
154
|
approach, and I would agree with you. However, over time the number of these could become unmanageable, whereas using Ruby
|
171
155
|
you could build a pretty extensive and well organized library of functionality. Moreover, that functionality could be made available to _all_ your Ruby code (for example, by putting it in a gem), and not just command line one liners.
|
172
156
|
|
@@ -194,41 +178,39 @@ end
|
|
194
178
|
Alternatively you could escape the parentheses with backslashes.)
|
195
179
|
|
196
180
|
|
197
|
-
### Clearing the Require and Load Lists
|
198
|
-
|
199
|
-
There may be times when you have specified a load or require on the command line
|
200
|
-
or in the `REXE_OPTIONS` environment variable,
|
201
|
-
but you want to override it for a single invocation. Currently you cannot
|
202
|
-
unspecify a single resource, but you can unspecify _all_ the requires or loads
|
203
|
-
with the `-r!` and `-l!` command line options, respectively.
|
204
|
-
|
205
|
-
|
206
|
-
### Clearing _All_ Options
|
207
|
-
|
208
|
-
You can also clear _all_ options specified up to a certain point in time with the _clear options_ option (`-c`).
|
209
|
-
This is especially useful if you have specified options in the `REXE_OPTIONS` environment variable,
|
210
|
-
and want to ignore all of them.
|
211
|
-
|
212
|
-
|
213
181
|
### Verbose Mode
|
214
182
|
|
215
|
-
|
216
|
-
to be evaluated, options specified (by all approaches),
|
183
|
+
Verbose mode will display the version, date/time of execution, source code
|
184
|
+
to be evaluated, options specified (by all approaches), that the global file has been loaded (if it was found),
|
185
|
+
and the execution time of your Ruby code:
|
217
186
|
|
218
187
|
```
|
219
188
|
➜ ~ echo $EUR_RATES_JSON | rexe -v -rjson,awesome_print "ap JSON.parse(STDIN.read)"
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
189
|
+
---
|
190
|
+
:count: 0
|
191
|
+
:rexe_version: 0.11.0
|
192
|
+
:start_time: '2019-03-11T20:16:02+07:00'
|
193
|
+
:source_code: ap JSON.parse(STDIN.read)
|
194
|
+
:options:
|
195
|
+
:input_format: :none
|
196
|
+
:input_mode: :no_input
|
197
|
+
:loads: []
|
198
|
+
:output_format: :puts
|
199
|
+
:requires:
|
200
|
+
- json
|
201
|
+
- awesome_print
|
202
|
+
:verbose: true
|
203
|
+
:noop: false
|
204
|
+
:duration_secs: 0.032174
|
226
205
|
```
|
227
206
|
|
228
207
|
This extra output is sent to standard error (_stderr_) instead of standard output
|
229
208
|
(_stdout_) so that it will not pollute the "real" data when stdout is piped to
|
230
209
|
another command.
|
231
210
|
|
211
|
+
As you can see, the data is the YAML representation of a hash, so you could easily ingest it and
|
212
|
+
use it programatically.
|
213
|
+
|
232
214
|
If you would like to append this informational output to a file, you could do something like this:
|
233
215
|
|
234
216
|
```
|
@@ -373,6 +355,24 @@ could be included in the custom code instead. Here's why:
|
|
373
355
|
parameterization of the output format.
|
374
356
|
|
375
357
|
|
358
|
+
### The $RC Global OpenStruct
|
359
|
+
|
360
|
+
For your convenience, the information displayed in verbose mode is available to your code at runtime
|
361
|
+
by accessing the `$RC` global variable, which contains an OpenStruct. Probably most useful in that object
|
362
|
+
is the record count (as `$RC.count`). This is only really useful in line mode, because in the others
|
363
|
+
it will always be 0 or 1. Here is an example of how you might use it:
|
364
|
+
|
365
|
+
```
|
366
|
+
➜ ~ ➜ ~ find / | rexe -ml -on \
|
367
|
+
'n = $RC.count; if n % 1000 == 0; puts %Q{File entry ##{n} is #{self}}; end'
|
368
|
+
|
369
|
+
...
|
370
|
+
File entry #106000 is /usr/local/Cellar/go/1.11.5/libexec/src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
|
371
|
+
File entry #107000 is /usr/local/Cellar/go/1.11.5/libexec/src/go/types/testdata/cycles1.src
|
372
|
+
File entry #108000 is /usr/local/Cellar/go/1.11.5/libexec/src/runtime/os_linux_novdso.go
|
373
|
+
...
|
374
|
+
```
|
375
|
+
|
376
376
|
### Implementing Domain Specific Languages (DSL's)
|
377
377
|
|
378
378
|
Defining methods in your loaded files enables you to effectively define a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for your command line use. You could use different load files for different projects, domains, or contexts, and define aliases or one line scripts to give them meaningful names. For example, if I wrote code to work with Ansible and put it in `~/projects/rexe-ansible.rb`, I could define an alias in my startup script:
|
@@ -473,6 +473,10 @@ After copying this line to the clipboard, I could run this:
|
|
473
473
|
If I add `| pbcopy` to the rexe command, then that output text would be copied into the clipboard instead of
|
474
474
|
displayed in the terminal, and I could then paste it in my editor.
|
475
475
|
|
476
|
+
Using the clipboard in manual operations is handy, but using it in automated scripts is a very bad idea, since
|
477
|
+
there is only one clipboard per user session. If you use the clipboard in an automated script you risk
|
478
|
+
an error situation if its content is changed by others, or, conversely, you could mess up another task
|
479
|
+
when you change the content of the clipboard.
|
476
480
|
|
477
481
|
### Multiline Ruby Commands
|
478
482
|
|
@@ -523,6 +527,22 @@ puts to_a"
|
|
523
527
|
```
|
524
528
|
|
525
529
|
|
530
|
+
### Clearing the Require and Load Lists
|
531
|
+
|
532
|
+
There may be times when you have specified a load or require on the command line
|
533
|
+
or in the `REXE_OPTIONS` environment variable,
|
534
|
+
but you want to override it for a single invocation. Currently you cannot
|
535
|
+
unspecify a single resource, but you can unspecify _all_ the requires or loads
|
536
|
+
with the `-r!` and `-l!` command line options, respectively.
|
537
|
+
|
538
|
+
|
539
|
+
### Clearing _All_ Options
|
540
|
+
|
541
|
+
You can also clear _all_ options specified up to a certain point in time with the _clear options_ option (`-c`).
|
542
|
+
This is especially useful if you have specified options in the `REXE_OPTIONS` environment variable,
|
543
|
+
and want to ignore all of them.
|
544
|
+
|
545
|
+
|
526
546
|
### Comma Separated Requires and Loads
|
527
547
|
|
528
548
|
For consistency with the `ruby` interpreter, `rexe` supports requires with the `-r` option, but
|
@@ -536,6 +556,21 @@ also allows grouping them together using commas:
|
|
536
556
|
|
537
557
|
Files loaded with the `-l` option are treated the same way.
|
538
558
|
|
559
|
+
|
560
|
+
### Beware of Configured Requires
|
561
|
+
|
562
|
+
Requiring gems and modules for _all_ invocations of `rexe` will make your commands simpler and more concise, but will be a waste of execution time if they are not needed. You can inspect the execution times to see just how much time is being wasted. For example, we can find out that nokogiri takes about 0.15 seconds to load on my laptop by observing and comparing the execution times with and without the require (output has been abbreviated using the redirection and grep):
|
563
|
+
|
564
|
+
```
|
565
|
+
➜ ~ rexe -v 2>&1 | grep duration
|
566
|
+
:duration_secs: 0.0012
|
567
|
+
|
568
|
+
➜ ~ rexe -v -r nokogiri 2>&1 | grep duration
|
569
|
+
:duration_secs: 0.148671
|
570
|
+
```
|
571
|
+
|
572
|
+
|
573
|
+
|
539
574
|
### More Examples
|
540
575
|
|
541
576
|
Here are some more examples to illustrate the use of `rexe`.
|
@@ -737,7 +772,7 @@ A word of caution though --
|
|
737
772
|
the complexity and difficulty of sharing your `rexe` scripts across systems
|
738
773
|
will be proportional to the extent to which you use environment variables
|
739
774
|
and loaded files for configuration and shared code.
|
740
|
-
Be responsible and disciplined in making this configuration and code as organized as possible.
|
775
|
+
Be responsible and disciplined in making this configuration and code as clean and organized as possible.
|
741
776
|
|
742
777
|
#### Footnotes
|
743
778
|
|
data/exe/rexe
CHANGED
@@ -5,18 +5,94 @@
|
|
5
5
|
# Inspired by https://github.com/thisredone/rb
|
6
6
|
|
7
7
|
require 'bundler'
|
8
|
+
require 'date'
|
8
9
|
require 'optparse'
|
10
|
+
require 'ostruct'
|
9
11
|
require 'shellwords'
|
10
12
|
|
11
13
|
class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :requires, :verbose, :noop)
|
12
14
|
|
13
|
-
VERSION = '0.
|
15
|
+
VERSION = '0.11.0'
|
16
|
+
|
14
17
|
|
15
18
|
def initialize
|
16
19
|
clear_options
|
17
20
|
end
|
18
21
|
|
19
22
|
|
23
|
+
def input_modes
|
24
|
+
@input_modes ||= {
|
25
|
+
'l' => :line,
|
26
|
+
'e' => :enumerator,
|
27
|
+
'b' => :one_big_string,
|
28
|
+
'n' => :no_input
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def input_formats
|
34
|
+
@input_formats ||= {
|
35
|
+
'j' => :json,
|
36
|
+
'm' => :marshal,
|
37
|
+
'n' => :none,
|
38
|
+
'y' => :yaml,
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def input_parsers
|
44
|
+
@input_parsers ||= {
|
45
|
+
json: ->(obj) { JSON.parse(obj) },
|
46
|
+
marshal: ->(obj) { Marshal.load(obj) },
|
47
|
+
none: ->(obj) { obj },
|
48
|
+
yaml: ->(obj) { YAML.load(obj) },
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def output_formats
|
54
|
+
@output_formats ||= {
|
55
|
+
'a' => :awesome_print,
|
56
|
+
'i' => :inspect,
|
57
|
+
'j' => :json,
|
58
|
+
'J' => :pretty_json,
|
59
|
+
'm' => :marshal,
|
60
|
+
'n' => :no_output,
|
61
|
+
'p' => :puts, # default
|
62
|
+
'P' => :pretty_print,
|
63
|
+
's' => :to_s,
|
64
|
+
'y' => :yaml,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def formatters
|
70
|
+
@formatters ||= {
|
71
|
+
awesome_print: ->(obj) { obj.ai },
|
72
|
+
inspect: ->(obj) { obj.inspect + "\n" },
|
73
|
+
json: ->(obj) { obj.to_json },
|
74
|
+
marshal: ->(obj) { Marshal.dump(obj) },
|
75
|
+
no_output: ->(_obj) { nil },
|
76
|
+
pretty_json: ->(obj) { JSON.pretty_generate(obj) },
|
77
|
+
pretty_print: ->(obj) { obj.pretty_inspect },
|
78
|
+
puts: ->(obj) { sio = StringIO.new; sio.puts(obj); sio.string }, # default
|
79
|
+
to_s: ->(obj) { obj.to_s + "\n" },
|
80
|
+
yaml: ->(obj) { obj.to_yaml },
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def parser_and_format_requires
|
86
|
+
@format_requires ||= {
|
87
|
+
json: 'json',
|
88
|
+
pretty_json: 'json',
|
89
|
+
awesome_print: 'awesome_print',
|
90
|
+
pretty_print: 'pp',
|
91
|
+
yaml: 'yaml'
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
|
20
96
|
# Used as an initializer and also when `-!` is specified on the command line.
|
21
97
|
def clear_options
|
22
98
|
self.input_format = :none
|
@@ -91,8 +167,6 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
91
167
|
|
92
168
|
def parse_command_line
|
93
169
|
|
94
|
-
prepend_environment_options
|
95
|
-
|
96
170
|
OptionParser.new do |parser|
|
97
171
|
|
98
172
|
parser.on("-h", "--help", "Show help") do |_help_requested|
|
@@ -103,17 +177,10 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
103
177
|
parser.on('-i', '--input_format FORMAT',
|
104
178
|
'Mode with which to parse input values (n = none (default), j = JSON, m = Marshal, y = YAML') do |v|
|
105
179
|
|
106
|
-
|
107
|
-
'j' => :json,
|
108
|
-
'm' => :marshal,
|
109
|
-
'n' => :none,
|
110
|
-
'y' => :yaml,
|
111
|
-
}
|
112
|
-
|
113
|
-
self.input_format = modes[v]
|
180
|
+
self.input_format = input_formats[v]
|
114
181
|
if self.input_format.nil?
|
115
182
|
puts help_text
|
116
|
-
raise "Input mode must be one of #{
|
183
|
+
raise "Input mode was '#{v}' but must be one of #{input_formats.keys}."
|
117
184
|
end
|
118
185
|
end
|
119
186
|
|
@@ -124,48 +191,30 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
124
191
|
loadfiles = v.split(',').map(&:strip)
|
125
192
|
existent, nonexistent = loadfiles.partition { |filespec| File.exists?(filespec) }
|
126
193
|
if nonexistent.any?
|
127
|
-
|
194
|
+
raise("\nDid not find the following files to load: #{nonexistent.to_s}\n\n")
|
195
|
+
else
|
196
|
+
existent.each { |filespec| self.loads << filespec }
|
128
197
|
end
|
129
|
-
existent.each { |filespec| self.loads << filespec }
|
130
198
|
end
|
131
199
|
end
|
132
200
|
|
133
201
|
parser.on('-m', '--input_mode MODE',
|
134
202
|
'Mode with which to handle input (-ml, -me, -mb, -mn (default)') do |v|
|
135
203
|
|
136
|
-
|
137
|
-
'l' => :line,
|
138
|
-
'e' => :enumerator,
|
139
|
-
'b' => :one_big_string,
|
140
|
-
'n' => :no_input
|
141
|
-
}
|
142
|
-
|
143
|
-
self.input_mode = modes[v]
|
204
|
+
self.input_mode = input_modes[v]
|
144
205
|
if self.input_mode.nil?
|
145
206
|
puts help_text
|
146
|
-
raise "Input mode must be one of #{
|
207
|
+
raise "Input mode was '#{v}' but must be one of #{input_modes.keys}."
|
147
208
|
end
|
148
209
|
end
|
149
210
|
|
150
211
|
parser.on('-o', '--output_format FORMAT',
|
151
212
|
'Mode with which to format values for output (`-o` + [aijJmnpsy])') do |v|
|
152
213
|
|
153
|
-
|
154
|
-
'a' => :awesome_print,
|
155
|
-
'i' => :inspect,
|
156
|
-
'j' => :json,
|
157
|
-
'J' => :pretty_json,
|
158
|
-
'm' => :marshal,
|
159
|
-
'n' => :no_output,
|
160
|
-
'p' => :puts, # default
|
161
|
-
's' => :to_s,
|
162
|
-
'y' => :yaml,
|
163
|
-
}
|
164
|
-
|
165
|
-
self.output_format = modes[v]
|
214
|
+
self.output_format = output_formats[v]
|
166
215
|
if self.output_format.nil?
|
167
216
|
puts help_text
|
168
|
-
raise "Output mode must be one of #{
|
217
|
+
raise "Output mode was '#{v}' but must be one of #{output_formats.keys}."
|
169
218
|
end
|
170
219
|
end
|
171
220
|
|
@@ -208,12 +257,7 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
208
257
|
|
209
258
|
def load_global_config_if_exists
|
210
259
|
filespec = File.join(Dir.home, '.rexerc')
|
211
|
-
|
212
|
-
if exists
|
213
|
-
log_if_verbose("Loading global config file #{filespec}")
|
214
|
-
load(filespec)
|
215
|
-
end
|
216
|
-
exists ? filespec : nil
|
260
|
+
load(filespec) if File.exists?(filespec)
|
217
261
|
end
|
218
262
|
|
219
263
|
|
@@ -231,62 +275,53 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
231
275
|
end
|
232
276
|
|
233
277
|
|
234
|
-
def log_if_verbose(string)
|
235
|
-
STDERR.puts(string) if verbose
|
236
|
-
end
|
237
|
-
|
238
|
-
|
239
278
|
def call
|
240
|
-
start_time =
|
279
|
+
start_time = DateTime.now
|
241
280
|
|
281
|
+
prepend_environment_options
|
242
282
|
parse_command_line
|
243
|
-
|
244
|
-
log_if_verbose("rexe version #{VERSION} -- #{Time.now}")
|
245
|
-
log_if_verbose('Source Code: ' + ARGV.join(' '))
|
246
|
-
log_if_verbose('Options: ' + self.to_h.to_s)
|
283
|
+
user_source_code = ARGV.join(' ')
|
247
284
|
|
248
285
|
requires.each { |r| require(r) }
|
249
|
-
|
250
286
|
load_global_config_if_exists
|
251
|
-
|
252
287
|
loads.each { |file| load(file) }
|
253
288
|
|
254
|
-
|
255
|
-
code = eval(source_code)
|
289
|
+
callable = eval("Proc.new { #{user_source_code} }")
|
256
290
|
|
257
291
|
actions = {
|
258
|
-
line: -> { STDIN.each { |l| execute(l.chomp,
|
259
|
-
enumerator: -> { execute(STDIN.each_line,
|
260
|
-
one_big_string: -> { big_string = STDIN.read; execute(big_string,
|
261
|
-
no_input: -> { execute(Object.new,
|
292
|
+
line: -> { STDIN.each { |l| execute(l.chomp, callable); $RC[:count] += 1 } },
|
293
|
+
enumerator: -> { execute(STDIN.each_line, callable); $RC[:count] += 1 },
|
294
|
+
one_big_string: -> { big_string = STDIN.read; execute(big_string, callable); $RC[:count] += 1 },
|
295
|
+
no_input: -> { execute(Object.new, callable) }
|
262
296
|
}
|
263
297
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
298
|
+
# This global $RC (Rexe Context) OpenStruct is available in your user code.
|
299
|
+
# In order to make it possible to access this hash in your loaded files, we are not initializing
|
300
|
+
# the hash here; instead we add key/value pairs to it. This way, you can initialize a hash yourself
|
301
|
+
# in your loaded code.
|
302
|
+
$RC ||= OpenStruct.new
|
303
|
+
$RC.count = 0
|
304
|
+
$RC.rexe_version = VERSION
|
305
|
+
$RC.start_time = start_time.iso8601
|
306
|
+
$RC.source_code = user_source_code
|
307
|
+
$RC.options = self.to_h
|
308
|
+
|
309
|
+
actions[input_mode].() unless self.noop
|
310
|
+
|
311
|
+
if verbose
|
312
|
+
$RC.duration_secs = Time.now - start_time.to_time
|
313
|
+
require 'yaml'
|
314
|
+
STDERR.puts($RC.to_h.to_yaml)
|
268
315
|
end
|
269
|
-
|
270
|
-
duration = Time.now - start_time
|
271
|
-
log_if_verbose("rexe time elapsed: #{duration} seconds.")
|
272
316
|
end
|
273
317
|
end
|
274
318
|
|
275
319
|
|
276
320
|
def input_parser
|
277
321
|
if @input_parser.nil?
|
278
|
-
|
279
|
-
require
|
280
|
-
|
281
|
-
|
282
|
-
parsers = {
|
283
|
-
json: ->(obj) { JSON.parse(obj) },
|
284
|
-
marshal: ->(obj) { Marshal.load(obj) },
|
285
|
-
none: ->(_obj) { obj },
|
286
|
-
yaml: ->(obj) { YAML.load(obj) },
|
287
|
-
}
|
288
|
-
|
289
|
-
@input_parser = parsers[input_format]
|
322
|
+
require_spec = parser_and_format_requires[input_format]
|
323
|
+
require require_spec if require_spec
|
324
|
+
@input_parser = input_parsers[input_format]
|
290
325
|
end
|
291
326
|
@input_parser
|
292
327
|
end
|
@@ -294,27 +329,8 @@ end
|
|
294
329
|
|
295
330
|
def output_formatter
|
296
331
|
if @output_formatter.nil?
|
297
|
-
|
298
|
-
if
|
299
|
-
require 'json'
|
300
|
-
elsif output_format == :yaml
|
301
|
-
require 'yaml'
|
302
|
-
elsif output_format == :awesome_print
|
303
|
-
require 'awesome_print'
|
304
|
-
end
|
305
|
-
|
306
|
-
formatters = {
|
307
|
-
awesome_print: ->(obj) { obj.ai },
|
308
|
-
inspect: ->(obj) { obj.inspect + "\n" },
|
309
|
-
json: ->(obj) { obj.to_json },
|
310
|
-
marshal: ->(obj) { Marshal.dump(obj) },
|
311
|
-
no_output: ->(_obj) { nil },
|
312
|
-
pretty_json: ->(obj) { JSON.pretty_generate(obj) },
|
313
|
-
puts: ->(obj) { sio = StringIO.new; sio.puts(obj); sio.string }, # default
|
314
|
-
to_s: ->(obj) { obj.to_s + "\n" },
|
315
|
-
yaml: ->(obj) { obj.to_yaml },
|
316
|
-
}
|
317
|
-
|
332
|
+
require_spec = parser_and_format_requires[output_format]
|
333
|
+
require require_spec if require_spec
|
318
334
|
@output_formatter = formatters[output_format]
|
319
335
|
end
|
320
336
|
@output_formatter
|
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.11.0
|
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-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|