rexe 0.11.0 → 0.12.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 +7 -0
- data/README.md +27 -22
- data/exe/rexe +61 -37
- data/rexe.gemspec +5 -2
- metadata +7 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79b7eb979cbeb0ba6d95c150e58bccecef867212b4783808f06381d9e247aa55
|
4
|
+
data.tar.gz: e737abbe83eee2bd71d83466a336db48b49ceea1ef88a51615557dcfa623d1d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 729475e954a39717db0f64b1dbfa2e267c41cf23742fb26de919ba2c80347b25adb1951d4c9ae2a3069068a5ac3baa52c9e8761b235bb72491a1fd0b32f82d94
|
7
|
+
data.tar.gz: 53b3ae64d2f92db487299ce46a2808cb82afea02e8b1ed66dbe4d3dfd5d2eddcc31f2697a1f87194f60c9ac7ffa15cfef8d5d11f5bc0e04b666e9e6d4f7d6f79
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
## rexe -- Ruby Command Line Executor
|
2
2
|
|
3
3
|
|
4
|
+
### v0.12.0
|
5
|
+
|
6
|
+
* Change verbose -v boolean option to log output format -g option.
|
7
|
+
* Print error message and exit with nonzero exit code if no source code provided.
|
8
|
+
* Add $RC.i alias for $RC.count.
|
9
|
+
|
10
|
+
|
4
11
|
### v0.11.0
|
5
12
|
|
6
13
|
* Make global $RC (Rexe Context) OpenStruct available to user code; added `count` for record count in `-ml` mode.
|
data/README.md
CHANGED
@@ -61,7 +61,7 @@ line, tipping the scale so that it is practical to do it more often.
|
|
61
61
|
Here is `rexe`'s help text as of the time of this writing:
|
62
62
|
|
63
63
|
```
|
64
|
-
rexe -- Ruby Command Line Executor/Filter -- v0.
|
64
|
+
rexe -- Ruby Command Line Executor/Filter -- v0.12.0 -- https://github.com/keithrbennett/rexe
|
65
65
|
|
66
66
|
Executes Ruby code on the command line, optionally taking standard input and writing to standard output.
|
67
67
|
|
@@ -70,8 +70,9 @@ rexe [options] 'Ruby source code'
|
|
70
70
|
Options:
|
71
71
|
|
72
72
|
-c --clear_options Clear all previous command line options specified up to now
|
73
|
+
-g --log_format FORMAT Log format, logs to stderr, defaults to none (see -o for format options)
|
73
74
|
-h, --help Print help and exit
|
74
|
-
-i, --input_format FORMAT Input format (
|
75
|
+
-i, --input_format FORMAT Input format (defaults to none)
|
75
76
|
-ij JSON
|
76
77
|
-im Marshal
|
77
78
|
-in None
|
@@ -81,9 +82,10 @@ Options:
|
|
81
82
|
-ml line mode; each line is ingested as a separate string
|
82
83
|
-me enumerator mode
|
83
84
|
-mb big string mode; all lines combined into single multiline string
|
84
|
-
-mn (default) no input mode; no special handling of input; self is an Object.new
|
85
|
-
-n, --[no-]noop Do not execute the code (useful with -
|
86
|
-
-
|
85
|
+
-mn (default) no input mode; no special handling of input; self is an Object.new
|
86
|
+
-n, --[no-]noop Do not execute the code (useful with -g); the following are valid:
|
87
|
+
-n no, -n yes, -n false, -n true, -n n, -n y, -n +, but not -n -
|
88
|
+
-o, --output_format FORMAT Output format (defaults to puts):
|
87
89
|
-oi Inspect
|
88
90
|
-oj JSON
|
89
91
|
-oJ Pretty JSON
|
@@ -93,16 +95,12 @@ Options:
|
|
93
95
|
-os to_s
|
94
96
|
-oy YAML
|
95
97
|
-r, --require REQUIRE(S) Gems and built-in libraries to require, comma separated, or ! to clear
|
96
|
-
-v, --[no-]verbose verbose mode (logs to stderr); see note (1) below
|
97
98
|
|
98
|
-
If there is an .rexerc file in your home directory, it will be run as Ruby code
|
99
|
+
If there is an .rexerc file in your home directory, it will be run as Ruby code
|
99
100
|
before processing the input.
|
100
101
|
|
101
102
|
If there is a REXE_OPTIONS environment variable, its content will be prepended to the command line
|
102
103
|
so that you can specify options implicitly (e.g. `export REXE_OPTIONS="-r awesome_print,yaml"`)
|
103
|
-
|
104
|
-
(1) For boolean 'verbose' and 'noop' options, the following are valid:
|
105
|
-
-v no, -v yes, -v false, -v true, -v n, -v y, -v +, but not -v -
|
106
104
|
```
|
107
105
|
|
108
106
|
### Simplifying the Rexe Invocation
|
@@ -178,14 +176,16 @@ end
|
|
178
176
|
Alternatively you could escape the parentheses with backslashes.)
|
179
177
|
|
180
178
|
|
181
|
-
###
|
179
|
+
### Logging
|
182
180
|
|
183
|
-
|
184
|
-
|
181
|
+
A log entry is optionally output to standard error after completion of the code.
|
182
|
+
The entry is a hash containing the version, date/time of execution, source code
|
183
|
+
to be evaluated, options (specified by all approaches),
|
185
184
|
and the execution time of your Ruby code:
|
186
185
|
|
187
186
|
```
|
188
|
-
➜ ~ echo $EUR_RATES_JSON | rexe -
|
187
|
+
➜ ~ echo $EUR_RATES_JSON | rexe -gy -rjson,awesome_print "ap JSON.parse(STDIN.read)"
|
188
|
+
...
|
189
189
|
---
|
190
190
|
:count: 0
|
191
191
|
:rexe_version: 0.11.0
|
@@ -214,11 +214,9 @@ use it programatically.
|
|
214
214
|
If you would like to append this informational output to a file, you could do something like this:
|
215
215
|
|
216
216
|
```
|
217
|
-
➜ ~ rexe ... -
|
217
|
+
➜ ~ rexe ... -gy 2>>rexe.log
|
218
218
|
```
|
219
219
|
|
220
|
-
If verbose mode is enabled in configuration and you want to disable it, you can
|
221
|
-
do so by using any of the following: `--[no-]verbose`, `-v n`, or `-v false`.
|
222
220
|
|
223
221
|
### Input Modes
|
224
222
|
|
@@ -359,13 +357,13 @@ parameterization of the output format.
|
|
359
357
|
|
360
358
|
For your convenience, the information displayed in verbose mode is available to your code at runtime
|
361
359
|
by accessing the `$RC` global variable, which contains an OpenStruct. Probably most useful in that object
|
362
|
-
is the record count
|
360
|
+
is the record count, accessible with both `$RC.count` and `$RC.i`.
|
361
|
+
This is only really useful in line mode, because in the others
|
363
362
|
it will always be 0 or 1. Here is an example of how you might use it:
|
364
363
|
|
365
364
|
```
|
366
365
|
➜ ~ ➜ ~ find / | rexe -ml -on \
|
367
|
-
'
|
368
|
-
|
366
|
+
'if $RC.i % 1000 == 0; puts %Q{File entry ##{$RC.i} is #{self}}; end'
|
369
367
|
...
|
370
368
|
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
369
|
File entry #107000 is /usr/local/Cellar/go/1.11.5/libexec/src/go/types/testdata/cycles1.src
|
@@ -422,6 +420,13 @@ An excellent reference for how they differ is [here](https://stackoverflow.com/q
|
|
422
420
|
Feel free to fall back on Ruby's super useful `%q{}` and `%Q{}`, equivalent to single and double quotes, respectively.
|
423
421
|
|
424
422
|
|
423
|
+
### No Op Mode
|
424
|
+
|
425
|
+
The `-n` no-op mode will result in the specified source code _not_ being executed. This can sometimes be handy
|
426
|
+
in conjunction with a `-g` (logging) option; if you have a command ready to go but
|
427
|
+
you want to see the configuration options before running it for real.
|
428
|
+
|
429
|
+
|
425
430
|
### Mimicking Method Arguments
|
426
431
|
|
427
432
|
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:
|
@@ -562,10 +567,10 @@ Files loaded with the `-l` option are treated the same way.
|
|
562
567
|
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
568
|
|
564
569
|
```
|
565
|
-
➜ ~ rexe -
|
570
|
+
➜ ~ rexe -gy 2>&1 | grep duration
|
566
571
|
:duration_secs: 0.0012
|
567
572
|
|
568
|
-
➜ ~ rexe -
|
573
|
+
➜ ~ rexe -gy -r nokogiri 2>&1 | grep duration
|
569
574
|
:duration_secs: 0.148671
|
570
575
|
```
|
571
576
|
|
data/exe/rexe
CHANGED
@@ -10,9 +10,17 @@ require 'optparse'
|
|
10
10
|
require 'ostruct'
|
11
11
|
require 'shellwords'
|
12
12
|
|
13
|
-
class Rexe < Struct.new(
|
13
|
+
class Rexe < Struct.new(
|
14
|
+
:input_format,
|
15
|
+
:input_mode,
|
16
|
+
:loads,
|
17
|
+
:output_format,
|
18
|
+
:requires,
|
19
|
+
:log_format,
|
20
|
+
:noop)
|
14
21
|
|
15
|
-
|
22
|
+
|
23
|
+
VERSION = '0.12.0'
|
16
24
|
|
17
25
|
|
18
26
|
def initialize
|
@@ -82,7 +90,7 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
82
90
|
end
|
83
91
|
|
84
92
|
|
85
|
-
def
|
93
|
+
def require_format_require(format)
|
86
94
|
@format_requires ||= {
|
87
95
|
json: 'json',
|
88
96
|
pretty_json: 'json',
|
@@ -90,19 +98,20 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
90
98
|
pretty_print: 'pp',
|
91
99
|
yaml: 'yaml'
|
92
100
|
}
|
101
|
+
r = @format_requires[format]
|
102
|
+
require(r) if r
|
93
103
|
end
|
94
104
|
|
95
105
|
|
96
106
|
# Used as an initializer and also when `-!` is specified on the command line.
|
97
107
|
def clear_options
|
98
|
-
self.input_format
|
99
|
-
self.input_mode
|
108
|
+
self.input_format = :none
|
109
|
+
self.input_mode = :no_input
|
100
110
|
self.output_format = :puts
|
101
|
-
self.loads
|
102
|
-
self.requires
|
103
|
-
self.
|
104
|
-
self.noop
|
105
|
-
@output_formatter = nil
|
111
|
+
self.loads = []
|
112
|
+
self.requires = []
|
113
|
+
self.log_format = :none
|
114
|
+
self.noop = false
|
106
115
|
end
|
107
116
|
|
108
117
|
|
@@ -118,8 +127,9 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
118
127
|
Options:
|
119
128
|
|
120
129
|
-c --clear_options Clear all previous command line options specified up to now
|
130
|
+
-g --log_format FORMAT Log format, logs to stderr, defaults to none (see -o for format options)
|
121
131
|
-h, --help Print help and exit
|
122
|
-
-i, --input_format FORMAT Input format (
|
132
|
+
-i, --input_format FORMAT Input format (defaults to none)
|
123
133
|
-ij JSON
|
124
134
|
-im Marshal
|
125
135
|
-in None
|
@@ -130,8 +140,9 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
130
140
|
-me enumerator mode
|
131
141
|
-mb big string mode; all lines combined into single multiline string
|
132
142
|
-mn (default) no input mode; no special handling of input; self is an Object.new
|
133
|
-
-n, --[no-]noop Do not execute the code (useful with -
|
134
|
-
|
143
|
+
-n, --[no-]noop Do not execute the code (useful with -g); the following are valid:
|
144
|
+
-n no, -n yes, -n false, -n true, -n n, -n y, -n +, but not -n -
|
145
|
+
-o, --output_format FORMAT Output format (defaults to puts):
|
135
146
|
-oi Inspect
|
136
147
|
-oj JSON
|
137
148
|
-oJ Pretty JSON
|
@@ -141,7 +152,6 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
141
152
|
-os to_s
|
142
153
|
-oy YAML
|
143
154
|
-r, --require REQUIRE(S) Gems and built-in libraries to require, comma separated, or ! to clear
|
144
|
-
-v, --[no-]verbose verbose mode (logs to stderr); see note (1) below
|
145
155
|
|
146
156
|
If there is an .rexerc file in your home directory, it will be run as Ruby code
|
147
157
|
before processing the input.
|
@@ -149,9 +159,6 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
149
159
|
If there is a REXE_OPTIONS environment variable, its content will be prepended to the command line
|
150
160
|
so that you can specify options implicitly (e.g. `export REXE_OPTIONS="-r awesome_print,yaml"`)
|
151
161
|
|
152
|
-
(1) For boolean 'verbose' and 'noop' options, the following are valid:
|
153
|
-
-v no, -v yes, -v false, -v true, -v n, -v y, -v +, but not -v -
|
154
|
-
|
155
162
|
HEREDOC
|
156
163
|
end
|
157
164
|
|
@@ -169,6 +176,14 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
169
176
|
|
170
177
|
OptionParser.new do |parser|
|
171
178
|
|
179
|
+
parser.on('-g', '--log_format FORMAT', 'Log format, logs to stderr, defaults to none (see -o for format options)') do |v|
|
180
|
+
self.log_format = output_formats[v]
|
181
|
+
if self.log_format.nil?
|
182
|
+
puts help_text
|
183
|
+
raise "Output mode was '#{v}' but must be one of #{output_formats.keys}."
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
172
187
|
parser.on("-h", "--help", "Show help") do |_help_requested|
|
173
188
|
puts help_text
|
174
189
|
exit
|
@@ -227,23 +242,19 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
227
242
|
end
|
228
243
|
end
|
229
244
|
|
230
|
-
# See https://stackoverflow.com/questions/54576873/ruby-optionparser-short-code-for-boolean-option
|
231
|
-
# for an excellent explanation of this optparse incantation.
|
232
|
-
# According to the answer, valid options are:
|
233
|
-
# -v no, -v yes, -v false, -v true, -v n, -v y, -v +, but not -v -.
|
234
|
-
parser.on('-v', '--[no-]verbose [FLAG]', TrueClass, 'Verbose mode (logs to stderr)') do |v|
|
235
|
-
self.verbose = (v.nil? ? true : v)
|
236
|
-
end
|
237
|
-
|
238
245
|
parser.on('-c', '--clear_options', "Clear all previous command line options") do |v|
|
239
246
|
clear_options
|
240
247
|
end
|
241
248
|
|
242
|
-
|
249
|
+
# See https://stackoverflow.com/questions/54576873/ruby-optionparser-short-code-for-boolean-option
|
250
|
+
# for an excellent explanation of this optparse incantation.
|
251
|
+
# According to the answer, valid options are:
|
252
|
+
# -n no, -n yes, -n false, -n true, -n n, -n y, -n +, but not -n -.
|
253
|
+
parser.on('-n', '--[no-]noop [FLAG]', TrueClass, "Do not execute the code (useful with -g)") do |v|
|
243
254
|
self.noop = (v.nil? ? true : v)
|
244
255
|
end
|
245
256
|
|
246
|
-
parser.on('', '--version', 'Print version') do
|
257
|
+
parser.on('-v', '--version', 'Print version') do
|
247
258
|
puts VERSION
|
248
259
|
exit
|
249
260
|
end
|
@@ -280,7 +291,12 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
280
291
|
|
281
292
|
prepend_environment_options
|
282
293
|
parse_command_line
|
294
|
+
|
283
295
|
user_source_code = ARGV.join(' ')
|
296
|
+
if user_source_code.empty?
|
297
|
+
STDERR.puts "No source code provided. Use -h to display help."
|
298
|
+
exit(-1)
|
299
|
+
end
|
284
300
|
|
285
301
|
requires.each { |r| require(r) }
|
286
302
|
load_global_config_if_exists
|
@@ -289,9 +305,9 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
289
305
|
callable = eval("Proc.new { #{user_source_code} }")
|
290
306
|
|
291
307
|
actions = {
|
292
|
-
line: -> { STDIN.each { |l| execute(l.chomp, callable); $RC
|
293
|
-
enumerator: -> { execute(STDIN.each_line, callable); $RC
|
294
|
-
one_big_string: -> { big_string = STDIN.read; execute(big_string, callable); $RC
|
308
|
+
line: -> { STDIN.each { |l| execute(l.chomp, callable); $RC.count += 1 } },
|
309
|
+
enumerator: -> { execute(STDIN.each_line, callable); $RC.count += 1 },
|
310
|
+
one_big_string: -> { big_string = STDIN.read; execute(big_string, callable); $RC.count += 1 },
|
295
311
|
no_input: -> { execute(Object.new, callable) }
|
296
312
|
}
|
297
313
|
|
@@ -306,12 +322,13 @@ class Rexe < Struct.new(:input_format, :input_mode, :loads, :output_format, :req
|
|
306
322
|
$RC.source_code = user_source_code
|
307
323
|
$RC.options = self.to_h
|
308
324
|
|
325
|
+
def $RC.i; count end # `i` aliases `count` so you can more concisely get the count in your user code
|
326
|
+
|
309
327
|
actions[input_mode].() unless self.noop
|
310
328
|
|
311
|
-
if
|
329
|
+
if log_format != :none
|
312
330
|
$RC.duration_secs = Time.now - start_time.to_time
|
313
|
-
|
314
|
-
STDERR.puts($RC.to_h.to_yaml)
|
331
|
+
STDERR.puts(log_formatter.($RC.to_h))
|
315
332
|
end
|
316
333
|
end
|
317
334
|
end
|
@@ -319,8 +336,7 @@ end
|
|
319
336
|
|
320
337
|
def input_parser
|
321
338
|
if @input_parser.nil?
|
322
|
-
|
323
|
-
require require_spec if require_spec
|
339
|
+
require_format_require(input_format)
|
324
340
|
@input_parser = input_parsers[input_format]
|
325
341
|
end
|
326
342
|
@input_parser
|
@@ -329,14 +345,22 @@ end
|
|
329
345
|
|
330
346
|
def output_formatter
|
331
347
|
if @output_formatter.nil?
|
332
|
-
|
333
|
-
require require_spec if require_spec
|
348
|
+
require_format_require(output_format)
|
334
349
|
@output_formatter = formatters[output_format]
|
335
350
|
end
|
336
351
|
@output_formatter
|
337
352
|
end
|
338
353
|
|
339
354
|
|
355
|
+
def log_formatter
|
356
|
+
if @log_formatter.nil?
|
357
|
+
require_format_require(log_format)
|
358
|
+
@log_formatter = formatters[log_format]
|
359
|
+
end
|
360
|
+
@log_formatter
|
361
|
+
end
|
362
|
+
|
363
|
+
|
340
364
|
# This is needed because the gemspec file loads this file to access Rexe::VERSION
|
341
365
|
# and must not have it run at that time:
|
342
366
|
called_as_script = (File.basename($0) == File.basename(__FILE__))
|
data/rexe.gemspec
CHANGED
@@ -51,10 +51,13 @@ Gem::Specification.new do |spec|
|
|
51
51
|
WARNING!
|
52
52
|
|
53
53
|
The default rexe input mode was changed from -ms to -mn in version 0.6.0
|
54
|
-
|
55
|
-
|
54
|
+
|
55
|
+
The -ms (separate string mode) mode name was changed
|
56
56
|
to -ml (line mode) in version 0.9.0.
|
57
57
|
|
58
|
+
The verbose mode boolean switch (-v) was changed to the
|
59
|
+
log format option (-g) in version 0.12.0.
|
60
|
+
|
58
61
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
59
62
|
|
60
63
|
HEREDOC
|
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.12.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-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,19 +94,11 @@ metadata:
|
|
94
94
|
homepage_uri: https://github.com/keithrbennett/rexe
|
95
95
|
source_code_uri: https://github.com/keithrbennett/rexe
|
96
96
|
changelog_uri: https://github.com/keithrbennett/rexe/blob/master/README.md
|
97
|
-
post_install_message:
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
The default rexe input mode was changed from -ms to -mn in version 0.6.0
|
104
|
-
and
|
105
|
-
the -ms (separate string mode) mode name was changed
|
106
|
-
to -ml (line mode) in version 0.9.0.
|
107
|
-
|
108
|
-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
109
|
-
|
97
|
+
post_install_message: "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nWARNING!\n\nThe
|
98
|
+
default rexe input mode was changed from -ms to -mn in version 0.6.0\n\nThe -ms
|
99
|
+
(separate string mode) mode name was changed\nto -ml (line mode) in version 0.9.0.\n\nThe
|
100
|
+
verbose mode boolean switch (-v) was changed to the\nlog format option (-g) in version
|
101
|
+
0.12.0. \n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"
|
110
102
|
rdoc_options: []
|
111
103
|
require_paths:
|
112
104
|
- lib
|