rexe 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/LICENSE.txt +201 -21
- data/README.md +140 -53
- data/exe/rexe +254 -164
- data/rexe.gemspec +2 -0
- metadata +17 -3
data/exe/rexe
CHANGED
@@ -10,115 +10,141 @@ require 'optparse'
|
|
10
10
|
require 'ostruct'
|
11
11
|
require 'shellwords'
|
12
12
|
|
13
|
-
class Rexe
|
14
|
-
:input_format,
|
15
|
-
:input_mode,
|
16
|
-
:loads,
|
17
|
-
:output_format,
|
18
|
-
:requires,
|
19
|
-
:log_format,
|
20
|
-
:noop)
|
13
|
+
class Rexe
|
21
14
|
|
15
|
+
VERSION = '0.13.0'
|
22
16
|
|
23
|
-
|
17
|
+
PROJECT_URL = 'https://github.com/keithrbennett/rexe'
|
24
18
|
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
class Options < Struct.new(
|
21
|
+
:input_format,
|
22
|
+
:input_mode,
|
23
|
+
:loads,
|
24
|
+
:output_format,
|
25
|
+
:requires,
|
26
|
+
:log_format,
|
27
|
+
:noop)
|
29
28
|
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
'b' => :one_big_string,
|
36
|
-
'n' => :no_input
|
37
|
-
}
|
38
|
-
end
|
30
|
+
def initialize
|
31
|
+
super
|
32
|
+
clear
|
33
|
+
end
|
39
34
|
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
36
|
+
def clear
|
37
|
+
self.input_format = :none
|
38
|
+
self.input_mode = :no_input
|
39
|
+
self.output_format = :puts
|
40
|
+
self.loads = []
|
41
|
+
self.requires = []
|
42
|
+
self.log_format = :none
|
43
|
+
self.noop = false
|
44
|
+
end
|
48
45
|
end
|
49
46
|
|
50
47
|
|
51
|
-
def input_parsers
|
52
|
-
@input_parsers ||= {
|
53
|
-
json: ->(obj) { JSON.parse(obj) },
|
54
|
-
marshal: ->(obj) { Marshal.load(obj) },
|
55
|
-
none: ->(obj) { obj },
|
56
|
-
yaml: ->(obj) { YAML.load(obj) },
|
57
|
-
}
|
58
|
-
end
|
59
48
|
|
60
49
|
|
61
|
-
def output_formats
|
62
|
-
@output_formats ||= {
|
63
|
-
'a' => :awesome_print,
|
64
|
-
'i' => :inspect,
|
65
|
-
'j' => :json,
|
66
|
-
'J' => :pretty_json,
|
67
|
-
'm' => :marshal,
|
68
|
-
'n' => :no_output,
|
69
|
-
'p' => :puts, # default
|
70
|
-
'P' => :pretty_print,
|
71
|
-
's' => :to_s,
|
72
|
-
'y' => :yaml,
|
73
|
-
}
|
74
|
-
end
|
75
50
|
|
51
|
+
class Lookups
|
52
|
+
def input_modes
|
53
|
+
@input_modes ||= {
|
54
|
+
'l' => :line,
|
55
|
+
'e' => :enumerator,
|
56
|
+
'b' => :one_big_string,
|
57
|
+
'n' => :no_input
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def input_formats
|
63
|
+
@input_formats ||= {
|
64
|
+
'j' => :json,
|
65
|
+
'm' => :marshal,
|
66
|
+
'n' => :none,
|
67
|
+
'y' => :yaml,
|
68
|
+
}
|
69
|
+
end
|
76
70
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
71
|
+
|
72
|
+
def input_parsers
|
73
|
+
@input_parsers ||= {
|
74
|
+
json: ->(obj) { JSON.parse(obj) },
|
75
|
+
marshal: ->(obj) { Marshal.load(obj) },
|
76
|
+
none: ->(obj) { obj },
|
77
|
+
yaml: ->(obj) { YAML.load(obj) },
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def output_formats
|
83
|
+
@output_formats ||= {
|
84
|
+
'a' => :awesome_print,
|
85
|
+
'i' => :inspect,
|
86
|
+
'j' => :json,
|
87
|
+
'J' => :pretty_json,
|
88
|
+
'm' => :marshal,
|
89
|
+
'n' => :no_output,
|
90
|
+
'p' => :puts, # default
|
91
|
+
'P' => :pretty_print,
|
92
|
+
's' => :to_s,
|
93
|
+
'y' => :yaml,
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def formatters
|
99
|
+
@formatters ||= {
|
100
|
+
awesome_print: ->(obj) { obj.ai },
|
101
|
+
inspect: ->(obj) { obj.inspect + "\n" },
|
102
|
+
json: ->(obj) { obj.to_json },
|
103
|
+
marshal: ->(obj) { Marshal.dump(obj) },
|
104
|
+
no_output: ->(_obj) { nil },
|
105
|
+
pretty_json: ->(obj) { JSON.pretty_generate(obj) },
|
106
|
+
pretty_print: ->(obj) { obj.pretty_inspect },
|
107
|
+
puts: ->(obj) { sio = StringIO.new; sio.puts(obj); sio.string }, # default
|
108
|
+
to_s: ->(obj) { obj.to_s + "\n" },
|
109
|
+
yaml: ->(obj) { obj.to_yaml },
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
def format_requires
|
114
|
+
@format_requires ||= {
|
115
|
+
json: 'json',
|
116
|
+
pretty_json: 'json',
|
117
|
+
awesome_print: 'awesome_print',
|
118
|
+
pretty_print: 'pp',
|
119
|
+
yaml: 'yaml'
|
120
|
+
}
|
121
|
+
end
|
90
122
|
end
|
91
123
|
|
92
124
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
require(r) if r
|
125
|
+
|
126
|
+
attr_reader :callable, :input_parser, :lookups, :options, :output_formatter,
|
127
|
+
:log_formatter, :start_time, :user_source_code
|
128
|
+
|
129
|
+
|
130
|
+
def initialize
|
131
|
+
@start_time = DateTime.now
|
132
|
+
@options = Options.new
|
133
|
+
@lookups = Lookups.new
|
103
134
|
end
|
104
135
|
|
105
136
|
|
106
|
-
#
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
self.output_format = :puts
|
111
|
-
self.loads = []
|
112
|
-
self.requires = []
|
113
|
-
self.log_format = :none
|
114
|
-
self.noop = false
|
137
|
+
# Requires the 'require' appropriate to the specified format.
|
138
|
+
private def require_format_require(format)
|
139
|
+
r = lookups.format_requires[format]
|
140
|
+
require!(r) if r
|
115
141
|
end
|
116
142
|
|
117
143
|
|
118
144
|
def help_text
|
119
145
|
<<~HEREDOC
|
120
146
|
|
121
|
-
rexe -- Ruby Command Line Executor/Filter -- v#{VERSION} --
|
147
|
+
rexe -- Ruby Command Line Executor/Filter -- v#{VERSION} -- #{PROJECT_URL}
|
122
148
|
|
123
149
|
Executes Ruby code on the command line, optionally taking standard input and writing to standard output.
|
124
150
|
|
@@ -134,7 +160,8 @@ class Rexe < Struct.new(
|
|
134
160
|
-im Marshal
|
135
161
|
-in None
|
136
162
|
-iy YAML
|
137
|
-
-l, --load RUBY_FILE(S) Ruby file(s) to load, comma separated
|
163
|
+
-l, --load RUBY_FILE(S) Ruby file(s) to load, comma separated;
|
164
|
+
! to clear all, or precede a name with '-' to remove
|
138
165
|
-m, --input_mode MODE Mode with which to handle input (i.e. what `self` will be in your code):
|
139
166
|
-ml line mode; each line is ingested as a separate string
|
140
167
|
-me enumerator mode
|
@@ -151,7 +178,8 @@ class Rexe < Struct.new(
|
|
151
178
|
-op Puts (default)
|
152
179
|
-os to_s
|
153
180
|
-oy YAML
|
154
|
-
-r, --require REQUIRE(S) Gems and built-in libraries to require, comma separated
|
181
|
+
-r, --require REQUIRE(S) Gems and built-in libraries to require, comma separated;
|
182
|
+
! to clear all, or precede a name with '-' to remove
|
155
183
|
|
156
184
|
If there is an .rexerc file in your home directory, it will be run as Ruby code
|
157
185
|
before processing the input.
|
@@ -163,7 +191,8 @@ class Rexe < Struct.new(
|
|
163
191
|
end
|
164
192
|
|
165
193
|
|
166
|
-
|
194
|
+
# Inserts contents of REXE_OPTIONS environment variable at the beginning of ARGV.
|
195
|
+
private def prepend_environment_options
|
167
196
|
env_opt_string = ENV['REXE_OPTIONS']
|
168
197
|
if env_opt_string
|
169
198
|
args_to_prepend = Shellwords.shellsplit(env_opt_string)
|
@@ -172,15 +201,38 @@ class Rexe < Struct.new(
|
|
172
201
|
end
|
173
202
|
|
174
203
|
|
175
|
-
def
|
204
|
+
def open_resource(resource_identifier)
|
205
|
+
command = case (`uname`.chomp)
|
206
|
+
when 'Darwin'
|
207
|
+
'open'
|
208
|
+
when 'Linux'
|
209
|
+
'xdg-open'
|
210
|
+
else
|
211
|
+
'start'
|
212
|
+
end
|
213
|
+
|
214
|
+
`#{command} #{resource_identifier}`
|
215
|
+
end
|
216
|
+
|
217
|
+
|
218
|
+
def add_format_requires_to_requires_list
|
219
|
+
formats = [options.input_format, options.output_format, options.log_format]
|
220
|
+
requires = formats.map { |format| lookups.format_requires[format] }.uniq.compact
|
221
|
+
requires.each { |r| options.requires << r }
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
# Using 'optparse', parses the command line.
|
226
|
+
# Settings go into this instance's properties (see Struct declaration).
|
227
|
+
private def parse_command_line
|
176
228
|
|
177
229
|
OptionParser.new do |parser|
|
178
230
|
|
179
231
|
parser.on('-g', '--log_format FORMAT', 'Log format, logs to stderr, defaults to none (see -o for format options)') do |v|
|
180
|
-
|
181
|
-
if
|
232
|
+
options.log_format = lookups.output_formats[v]
|
233
|
+
if options.log_format.nil?
|
182
234
|
puts help_text
|
183
|
-
raise "Output mode was '#{v}' but must be one of #{output_formats.keys}."
|
235
|
+
raise "Output mode was '#{v}' but must be one of #{lookups.output_formats.keys}."
|
184
236
|
end
|
185
237
|
end
|
186
238
|
|
@@ -192,58 +244,68 @@ class Rexe < Struct.new(
|
|
192
244
|
parser.on('-i', '--input_format FORMAT',
|
193
245
|
'Mode with which to parse input values (n = none (default), j = JSON, m = Marshal, y = YAML') do |v|
|
194
246
|
|
195
|
-
|
196
|
-
if
|
247
|
+
options.input_format = lookups.input_formats[v]
|
248
|
+
if options.input_format.nil?
|
197
249
|
puts help_text
|
198
|
-
raise "Input mode was '#{v}' but must be one of #{input_formats.keys}."
|
250
|
+
raise "Input mode was '#{v}' but must be one of #{lookups.input_formats.keys}."
|
199
251
|
end
|
200
252
|
end
|
201
253
|
|
202
254
|
parser.on('-l', '--load RUBY_FILE(S)', 'Ruby file(s) to load, comma separated, or ! to clear') do |v|
|
203
255
|
if v == '!'
|
204
|
-
|
256
|
+
options.loads.clear
|
205
257
|
else
|
206
258
|
loadfiles = v.split(',').map(&:strip)
|
207
|
-
|
259
|
+
removes, adds = loadfiles.partition { |filespec| filespec[0] == '-' }
|
260
|
+
|
261
|
+
existent, nonexistent = adds.partition { |filespec| File.exists?(filespec) }
|
208
262
|
if nonexistent.any?
|
209
|
-
raise("\nDid not find the following files to load: #{nonexistent
|
263
|
+
raise("\nDid not find the following files to load: #{nonexistent}\n\n")
|
210
264
|
else
|
211
|
-
existent.each { |filespec|
|
265
|
+
existent.each { |filespec| options.loads << filespec }
|
212
266
|
end
|
267
|
+
|
268
|
+
removes.each { |filespec| options.loads -= [filespec[1..-1]] }
|
213
269
|
end
|
214
270
|
end
|
215
271
|
|
216
272
|
parser.on('-m', '--input_mode MODE',
|
217
273
|
'Mode with which to handle input (-ml, -me, -mb, -mn (default)') do |v|
|
218
274
|
|
219
|
-
|
220
|
-
if
|
275
|
+
options.input_mode = lookups.input_modes[v]
|
276
|
+
if options.input_mode.nil?
|
221
277
|
puts help_text
|
222
|
-
raise "Input mode was '#{v}' but must be one of #{input_modes.keys}."
|
278
|
+
raise "Input mode was '#{v}' but must be one of #{lookups.input_modes.keys}."
|
223
279
|
end
|
224
280
|
end
|
225
281
|
|
226
282
|
parser.on('-o', '--output_format FORMAT',
|
227
283
|
'Mode with which to format values for output (`-o` + [aijJmnpsy])') do |v|
|
228
284
|
|
229
|
-
|
230
|
-
if
|
285
|
+
options.output_format = lookups.output_formats[v]
|
286
|
+
if options.output_format.nil?
|
231
287
|
puts help_text
|
232
|
-
raise "Output mode was '#{v}' but must be one of #{output_formats.keys}."
|
288
|
+
raise "Output mode was '#{v}' but must be one of #{lookups.output_formats.keys}."
|
233
289
|
end
|
234
290
|
end
|
235
291
|
|
236
292
|
parser.on('-r', '--require REQUIRE(S)',
|
237
293
|
'Gems and built-in libraries (e.g. shellwords, yaml) to require, comma separated, or ! to clear') do |v|
|
238
294
|
if v == '!'
|
239
|
-
|
295
|
+
options.requires.clear
|
240
296
|
else
|
241
|
-
v.split(',').map(&:strip).each
|
297
|
+
v.split(',').map(&:strip).each do |r|
|
298
|
+
if r[0] == '-'
|
299
|
+
options.requires -= [r[1..-1]]
|
300
|
+
else
|
301
|
+
options.requires << r
|
302
|
+
end
|
303
|
+
end
|
242
304
|
end
|
243
305
|
end
|
244
306
|
|
245
307
|
parser.on('-c', '--clear_options', "Clear all previous command line options") do |v|
|
246
|
-
|
308
|
+
options.clear
|
247
309
|
end
|
248
310
|
|
249
311
|
# See https://stackoverflow.com/questions/54576873/ruby-optionparser-short-code-for-boolean-option
|
@@ -251,34 +313,55 @@ class Rexe < Struct.new(
|
|
251
313
|
# According to the answer, valid options are:
|
252
314
|
# -n no, -n yes, -n false, -n true, -n n, -n y, -n +, but not -n -.
|
253
315
|
parser.on('-n', '--[no-]noop [FLAG]', TrueClass, "Do not execute the code (useful with -g)") do |v|
|
254
|
-
|
316
|
+
options.noop = (v.nil? ? true : v)
|
255
317
|
end
|
256
318
|
|
257
319
|
parser.on('-v', '--version', 'Print version') do
|
258
320
|
puts VERSION
|
259
321
|
exit
|
260
322
|
end
|
323
|
+
|
324
|
+
# Undocumented feature
|
325
|
+
parser.on('', '--open-project') do
|
326
|
+
open_resource(PROJECT_URL)
|
327
|
+
exit(0)
|
328
|
+
end
|
329
|
+
|
261
330
|
end.parse!
|
262
331
|
|
263
|
-
|
264
|
-
|
332
|
+
# We want to do this after all options have been processed because we don't want any clearing of the
|
333
|
+
# options (by '-c', etc.) to result in exclusion of these needed requires.
|
334
|
+
add_format_requires_to_requires_list
|
335
|
+
|
336
|
+
options.requires.uniq!
|
337
|
+
options.loads.uniq!
|
265
338
|
|
266
339
|
end
|
267
340
|
|
268
341
|
|
269
|
-
def load_global_config_if_exists
|
342
|
+
private def load_global_config_if_exists
|
270
343
|
filespec = File.join(Dir.home, '.rexerc')
|
271
344
|
load(filespec) if File.exists?(filespec)
|
272
345
|
end
|
273
346
|
|
274
347
|
|
275
|
-
def
|
276
|
-
|
348
|
+
private def init_parser_and_formatters
|
349
|
+
@input_parser = lookups.input_parsers[options.input_format]
|
350
|
+
@output_formatter = lookups.formatters[options.output_format]
|
351
|
+
@log_formatter = lookups.formatters[options.log_format]
|
352
|
+
end
|
353
|
+
|
354
|
+
|
355
|
+
# Executes the user specified code in the manner appropriate to the input mode.
|
356
|
+
# Performs any optionally specified parsing on input and formatting on output.
|
357
|
+
private def execute(eval_context_object, code)
|
358
|
+
if options.input_format != :none && options.input_mode != :no_input
|
277
359
|
eval_context_object = input_parser.(eval_context_object)
|
278
360
|
end
|
279
361
|
|
280
362
|
value = eval_context_object.instance_eval(&code)
|
281
|
-
|
363
|
+
|
364
|
+
unless options.output_format == :no_output
|
282
365
|
print output_formatter.(value)
|
283
366
|
end
|
284
367
|
rescue Errno::EPIPE
|
@@ -286,84 +369,91 @@ class Rexe < Struct.new(
|
|
286
369
|
end
|
287
370
|
|
288
371
|
|
289
|
-
|
290
|
-
|
372
|
+
# The global $RC (Rexe Context) OpenStruct is available in your user code.
|
373
|
+
# In order to make it possible to access this object in your loaded files, we are not creating
|
374
|
+
# it here; instead we add properties to it. This way, you can initialize an OpenStruct yourself
|
375
|
+
# in your loaded code and it will still work. If you do that, beware, any properties you add will be
|
376
|
+
# included in the log output. If the to_s of your added objects is large, that might be a pain.
|
377
|
+
private def init_rexe_context
|
378
|
+
$RC ||= OpenStruct.new
|
379
|
+
$RC.count = 0
|
380
|
+
$RC.rexe_version = VERSION
|
381
|
+
$RC.start_time = start_time.iso8601
|
382
|
+
$RC.source_code = user_source_code
|
383
|
+
$RC.options = options.to_h
|
291
384
|
|
292
|
-
|
293
|
-
|
385
|
+
def $RC.i; count end # `i` aliases `count` so you can more concisely get the count in your user code
|
386
|
+
end
|
294
387
|
|
295
|
-
|
296
|
-
|
388
|
+
|
389
|
+
private def create_callable
|
390
|
+
if user_source_code.empty? && (! options.noop)
|
297
391
|
STDERR.puts "No source code provided. Use -h to display help."
|
298
392
|
exit(-1)
|
299
393
|
end
|
300
394
|
|
301
|
-
|
302
|
-
|
303
|
-
loads.each { |file| load(file) }
|
395
|
+
eval("Proc.new { #{user_source_code} }")
|
396
|
+
end
|
304
397
|
|
305
|
-
callable = eval("Proc.new { #{user_source_code} }")
|
306
398
|
|
307
|
-
|
399
|
+
private def lookup_action(mode)
|
400
|
+
{
|
308
401
|
line: -> { STDIN.each { |l| execute(l.chomp, callable); $RC.count += 1 } },
|
309
402
|
enumerator: -> { execute(STDIN.each_line, callable); $RC.count += 1 },
|
310
403
|
one_big_string: -> { big_string = STDIN.read; execute(big_string, callable); $RC.count += 1 },
|
311
404
|
no_input: -> { execute(Object.new, callable) }
|
312
|
-
}
|
313
|
-
|
314
|
-
# This global $RC (Rexe Context) OpenStruct is available in your user code.
|
315
|
-
# In order to make it possible to access this hash in your loaded files, we are not initializing
|
316
|
-
# the hash here; instead we add key/value pairs to it. This way, you can initialize a hash yourself
|
317
|
-
# in your loaded code.
|
318
|
-
$RC ||= OpenStruct.new
|
319
|
-
$RC.count = 0
|
320
|
-
$RC.rexe_version = VERSION
|
321
|
-
$RC.start_time = start_time.iso8601
|
322
|
-
$RC.source_code = user_source_code
|
323
|
-
$RC.options = self.to_h
|
324
|
-
|
325
|
-
def $RC.i; count end # `i` aliases `count` so you can more concisely get the count in your user code
|
405
|
+
}[mode]
|
406
|
+
end
|
326
407
|
|
327
|
-
actions[input_mode].() unless self.noop
|
328
408
|
|
329
|
-
|
409
|
+
private def output_log_entry
|
410
|
+
if options.log_format != :none
|
330
411
|
$RC.duration_secs = Time.now - start_time.to_time
|
331
412
|
STDERR.puts(log_formatter.($RC.to_h))
|
332
413
|
end
|
333
414
|
end
|
334
|
-
end
|
335
415
|
|
336
416
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
417
|
+
# Bypasses Bundler's restriction on loading gems
|
418
|
+
# (see https://stackoverflow.com/questions/55144094/bundler-doesnt-permit-using-gems-in-project-home-directory)
|
419
|
+
private def require!(the_require)
|
420
|
+
begin
|
421
|
+
require the_require
|
422
|
+
rescue LoadError => error
|
423
|
+
gem_path = `gem which #{the_require}`
|
424
|
+
if gem_path.chomp.strip.empty?
|
425
|
+
raise error # re-raise the error, can't fix it
|
426
|
+
else
|
427
|
+
load_dir = File.dirname(gem_path)
|
428
|
+
$LOAD_PATH << load_dir
|
429
|
+
require the_require
|
430
|
+
end
|
431
|
+
end
|
341
432
|
end
|
342
|
-
@input_parser
|
343
|
-
end
|
344
433
|
|
345
434
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
@output_formatter
|
352
|
-
end
|
435
|
+
# This class' entry point.
|
436
|
+
def call
|
437
|
+
|
438
|
+
prepend_environment_options
|
439
|
+
parse_command_line
|
353
440
|
|
441
|
+
options.requires.each { |r| require!(r) }
|
442
|
+
load_global_config_if_exists
|
443
|
+
options.loads.each { |file| load(file) }
|
444
|
+
|
445
|
+
@user_source_code = ARGV.join(' ')
|
446
|
+
@callable = create_callable
|
447
|
+
|
448
|
+
init_rexe_context
|
449
|
+
init_parser_and_formatters
|
354
450
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
451
|
+
# This is where the user's source code will be executed; the action will in turn call `execute`.
|
452
|
+
lookup_action(options.input_mode).call unless options.noop
|
453
|
+
|
454
|
+
output_log_entry
|
359
455
|
end
|
360
|
-
@log_formatter
|
361
456
|
end
|
362
457
|
|
363
458
|
|
364
|
-
|
365
|
-
# and must not have it run at that time:
|
366
|
-
called_as_script = (File.basename($0) == File.basename(__FILE__))
|
367
|
-
if called_as_script
|
368
|
-
Bundler.with_clean_env { Rexe.new.call }
|
369
|
-
end
|
459
|
+
Bundler.with_clean_env { Rexe.new.call }
|