rbbt-util 5.13.31 → 5.13.32
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/bin/rbbt +11 -0
- data/lib/rbbt/monitor.rb +152 -10
- data/lib/rbbt/persist/tsv/adapter.rb +109 -0
- data/lib/rbbt/persist/tsv/kyotocabinet.rb +3 -77
- data/lib/rbbt/persist/tsv/lmdb.rb +1 -88
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +126 -93
- data/lib/rbbt/persist/tsv.rb +2 -0
- data/lib/rbbt/persist.rb +21 -91
- data/lib/rbbt/tsv/parallel/traverse.rb +9 -5
- data/lib/rbbt/util/cmd.rb +1 -1
- data/lib/rbbt/util/log.rb +7 -6
- data/lib/rbbt/util/misc/concurrent_stream.rb +2 -1
- data/lib/rbbt/util/misc/development.rb +23 -0
- data/lib/rbbt/util/misc/lock.rb +18 -13
- data/lib/rbbt/util/misc/pipes.rb +23 -11
- data/lib/rbbt/util/open.rb +5 -5
- data/lib/rbbt/util/simpleopt/doc.rb +1 -1
- data/lib/rbbt/workflow/step/run.rb +3 -2
- data/lib/rbbt/workflow/step.rb +7 -1
- data/lib/rbbt/workflow.rb +18 -11
- data/share/rbbt_commands/system/clean +57 -58
- data/share/rbbt_commands/system/status +59 -40
- data/share/rbbt_commands/tsv/info +1 -1
- data/test/rbbt/test_monitor.rb +13 -0
- data/test/rbbt/tsv/parallel/test_traverse.rb +44 -22
- data/test/rbbt/util/test_misc.rb +10 -0
- data/test/rbbt/util/test_open.rb +16 -0
- metadata +5 -2
@@ -3,7 +3,9 @@ require 'tokyocabinet'
|
|
3
3
|
module Persist
|
4
4
|
|
5
5
|
module TCAdapter
|
6
|
-
|
6
|
+
include Persist::TSVAdapter
|
7
|
+
|
8
|
+
attr_accessor :tokyocabinet_class
|
7
9
|
|
8
10
|
def self.open(path, write, serializer, tokyocabinet_class = TokyoCabinet::HDB)
|
9
11
|
tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB" or tokyocabinet_class.nil?
|
@@ -27,21 +29,6 @@ module Persist
|
|
27
29
|
database
|
28
30
|
end
|
29
31
|
|
30
|
-
MAX_CHAR = 255.chr
|
31
|
-
|
32
|
-
def prefix(key)
|
33
|
-
range(key, 1, key + MAX_CHAR, 1)
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_prefix(key)
|
37
|
-
keys = prefix(key)
|
38
|
-
select(:key => keys)
|
39
|
-
end
|
40
|
-
|
41
|
-
def closed?
|
42
|
-
@closed
|
43
|
-
end
|
44
|
-
|
45
32
|
def close
|
46
33
|
@closed = true
|
47
34
|
super
|
@@ -73,83 +60,129 @@ module Persist
|
|
73
60
|
self
|
74
61
|
end
|
75
62
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
def
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
63
|
+
#MAX_CHAR = 255.chr
|
64
|
+
|
65
|
+
#def prefix(key)
|
66
|
+
# range(key, 1, key + MAX_CHAR, 1)
|
67
|
+
#end
|
68
|
+
|
69
|
+
#def get_prefix(key)
|
70
|
+
# keys = prefix(key)
|
71
|
+
# select(:key => keys)
|
72
|
+
#end
|
73
|
+
|
74
|
+
#def closed?
|
75
|
+
# @closed
|
76
|
+
#end
|
77
|
+
|
78
|
+
#def close
|
79
|
+
# @closed = true
|
80
|
+
# super
|
81
|
+
#end
|
82
|
+
|
83
|
+
#def read(force = false)
|
84
|
+
# return if not write? and not closed and not force
|
85
|
+
# self.close
|
86
|
+
# if !self.open(@persistence_path, tokyocabinet_class::OREADER)
|
87
|
+
# ecode = self.ecode
|
88
|
+
# raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
89
|
+
# end
|
90
|
+
# @writable = false
|
91
|
+
# @closed = false
|
92
|
+
# self
|
93
|
+
#end
|
94
|
+
|
95
|
+
#def write(force = true)
|
96
|
+
# return if write? and not closed and not force
|
97
|
+
# self.close
|
98
|
+
|
99
|
+
# if !self.open(@persistence_path, tokyocabinet_class::OWRITER)
|
100
|
+
# ecode = self.ecode
|
101
|
+
# raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
|
102
|
+
# end
|
103
|
+
|
104
|
+
# @writable = true
|
105
|
+
# @closed = false
|
106
|
+
# self
|
107
|
+
#end
|
108
|
+
|
109
|
+
#def write?
|
110
|
+
# @writable
|
111
|
+
#end
|
112
|
+
|
113
|
+
#def read?
|
114
|
+
# ! write?
|
115
|
+
#end
|
116
|
+
|
117
|
+
#def collect
|
118
|
+
# res = []
|
119
|
+
# each do |key, value|
|
120
|
+
# res << if block_given?
|
121
|
+
# yield key, value
|
122
|
+
# else
|
123
|
+
# [key, value]
|
124
|
+
# end
|
125
|
+
# end
|
126
|
+
# res
|
127
|
+
#end
|
128
|
+
|
129
|
+
#def delete(key)
|
130
|
+
# out(key)
|
131
|
+
#end
|
132
|
+
|
133
|
+
#def write_and_read
|
134
|
+
# lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
|
135
|
+
# Misc.lock(lock_filename) do
|
136
|
+
# @mutex.synchronize do
|
137
|
+
# write if @closed or not write?
|
138
|
+
# res = begin
|
139
|
+
# yield
|
140
|
+
# ensure
|
141
|
+
# read
|
142
|
+
# end
|
143
|
+
# res
|
144
|
+
# end
|
145
|
+
# end
|
146
|
+
#end
|
147
|
+
|
148
|
+
#def write_and_close
|
149
|
+
# lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
|
150
|
+
# Misc.lock(lock_filename) do
|
151
|
+
# @mutex.synchronize do
|
152
|
+
# write if @closed or not write?
|
153
|
+
# res = begin
|
154
|
+
# yield
|
155
|
+
# ensure
|
156
|
+
# close
|
157
|
+
# end
|
158
|
+
# res
|
159
|
+
# end
|
160
|
+
# end
|
161
|
+
#end
|
162
|
+
|
163
|
+
#def read_and_close
|
164
|
+
# @mutex.synchronize do
|
165
|
+
# read if @closed or not read?
|
166
|
+
# res = begin
|
167
|
+
# yield
|
168
|
+
# ensure
|
169
|
+
# close
|
170
|
+
# end
|
171
|
+
# res
|
172
|
+
# end
|
173
|
+
#end
|
174
|
+
|
175
|
+
|
176
|
+
#def merge!(hash)
|
177
|
+
# hash.each do |key,values|
|
178
|
+
# self[key] = values
|
179
|
+
# end
|
180
|
+
#end
|
181
|
+
|
182
|
+
|
183
|
+
#def range(*args)
|
184
|
+
# super(*args) #- TSV::ENTRY_KEYS.to_a
|
185
|
+
#end
|
153
186
|
end
|
154
187
|
|
155
188
|
|
data/lib/rbbt/persist/tsv.rb
CHANGED
data/lib/rbbt/persist.rb
CHANGED
@@ -111,16 +111,8 @@ module Persist
|
|
111
111
|
res
|
112
112
|
when :marshal
|
113
113
|
Open.open(path) do |stream|
|
114
|
-
|
115
|
-
|
116
|
-
begin
|
117
|
-
Marshal.load(stream)
|
118
|
-
rescue
|
119
|
-
raise $!
|
120
|
-
end
|
121
|
-
else
|
122
|
-
Marshal.load(stream)
|
123
|
-
end
|
114
|
+
content = stream.read.unpack("m").first
|
115
|
+
Marshal.load(content)
|
124
116
|
end
|
125
117
|
when :yaml
|
126
118
|
Open.open(path) do |stream|
|
@@ -180,7 +172,8 @@ module Persist
|
|
180
172
|
when :marshal_tsv
|
181
173
|
Misc.sensiblewrite(path, Marshal.dump(content.dup))
|
182
174
|
when :marshal
|
183
|
-
|
175
|
+
dump = Marshal.dump(content)
|
176
|
+
Misc.sensiblewrite(path, [dump].pack("m"))
|
184
177
|
when :yaml
|
185
178
|
Misc.sensiblewrite(path, YAML.dump(content))
|
186
179
|
when :float, :integer, :tsv
|
@@ -288,36 +281,25 @@ module Persist
|
|
288
281
|
if stream
|
289
282
|
if persist_options[:no_load] == :stream
|
290
283
|
res = tee_stream(stream, path, type, stream.respond_to?(:callback)? stream.callback : nil, stream.respond_to?(:abort_callback)? stream.abort_callback : nil)
|
284
|
+
res.lockfile = lockfile
|
291
285
|
|
292
|
-
ConcurrentStream.setup res do
|
293
|
-
begin
|
294
|
-
lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
|
295
|
-
rescue Exception
|
296
|
-
Log.medium "Lockfile exception: " << $!.message
|
297
|
-
end
|
298
|
-
end
|
299
|
-
res.abort_callback = Proc.new do
|
300
|
-
begin
|
301
|
-
lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
|
302
|
-
rescue Exception
|
303
|
-
Log.medium "Lockfile exception: " << $!.message
|
304
|
-
end
|
305
|
-
end
|
306
286
|
raise KeepLocked.new res
|
307
287
|
else
|
288
|
+
stream = res.get_stream if res.respond_to? :get_stream
|
308
289
|
begin
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
290
|
+
Open.write(path, stream)
|
291
|
+
Open.open(path) do |stream|
|
292
|
+
case type
|
293
|
+
when :array
|
294
|
+
stream.read.split "\n"
|
295
|
+
when :tsv
|
296
|
+
TSV.open(stream)
|
297
|
+
else
|
298
|
+
stream.read
|
299
|
+
end
|
300
|
+
end
|
319
301
|
rescue
|
320
|
-
|
302
|
+
stream.abort if stream.respond_to? :abort
|
321
303
|
raise $!
|
322
304
|
end
|
323
305
|
end
|
@@ -326,61 +308,7 @@ module Persist
|
|
326
308
|
end
|
327
309
|
end
|
328
310
|
|
329
|
-
def self._get_result(path, type, persist_options, lockfile, &block)
|
330
|
-
res = yield
|
331
|
-
|
332
|
-
if persist_options[:no_load] == :stream
|
333
|
-
stream = IO === res ? res : res.stream
|
334
|
-
res = tee_stream(stream, path, type, stream.respond_to?(:callback)? stream.callback : nil, stream.respond_to?(:abort_callback)? stream.abort_callback : nil)
|
335
|
-
|
336
|
-
ConcurrentStream.setup res do
|
337
|
-
begin
|
338
|
-
lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
|
339
|
-
rescue Exception
|
340
|
-
Log.medium "Lockfile exception: " << $!.message
|
341
|
-
end
|
342
|
-
end
|
343
|
-
res.abort_callback = Proc.new do
|
344
|
-
begin
|
345
|
-
lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
|
346
|
-
rescue Exception
|
347
|
-
Log.medium "Lockfile exception: " << $!.message
|
348
|
-
end
|
349
|
-
end
|
350
|
-
raise KeepLocked.new res
|
351
|
-
end
|
352
|
-
|
353
|
-
case res
|
354
|
-
when IO
|
355
|
-
begin
|
356
|
-
res = case
|
357
|
-
when :array
|
358
|
-
res.read.split "\n"
|
359
|
-
when :tsv
|
360
|
-
TSV.open(res)
|
361
|
-
else
|
362
|
-
res.read
|
363
|
-
end
|
364
|
-
res.join if res.respond_to? :join
|
365
|
-
rescue
|
366
|
-
res.abort if res.respond_to? :abort
|
367
|
-
raise $!
|
368
|
-
end
|
369
|
-
when (defined? TSV and TSV::Dumper)
|
370
|
-
begin
|
371
|
-
io = res.stream
|
372
|
-
res = TSV.open(io)
|
373
|
-
io.join if io.respond_to? :join
|
374
|
-
rescue
|
375
|
-
io.abort if io.respond_to? :abort
|
376
|
-
raise $!
|
377
|
-
end
|
378
|
-
end
|
379
|
-
res
|
380
|
-
end
|
381
|
-
|
382
311
|
def self.persist_file(path, type, persist_options, &block)
|
383
|
-
|
384
312
|
begin
|
385
313
|
if is_persisted?(path, persist_options)
|
386
314
|
Log.low "Persist up-to-date: #{ path } - #{Misc.fingerprint persist_options}"
|
@@ -414,7 +342,9 @@ module Persist
|
|
414
342
|
save_file(path, type, res)
|
415
343
|
end
|
416
344
|
|
417
|
-
persist_options[:no_load]
|
345
|
+
return path if persist_options[:no_load]
|
346
|
+
|
347
|
+
res
|
418
348
|
end
|
419
349
|
|
420
350
|
rescue Lockfile::StolenLockError
|
@@ -281,11 +281,13 @@ module TSV
|
|
281
281
|
rescue Exception
|
282
282
|
Log.medium{"Exception traversing #{stream_name(obj)}"}
|
283
283
|
Log.exception $!
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
284
|
+
begin
|
285
|
+
stream = obj_stream(obj)
|
286
|
+
stream.abort if stream and stream.respond_to? :abort
|
287
|
+
stream = obj_stream(options[:into])
|
288
|
+
stream.abort if stream.respond_to? :abort
|
289
|
+
raise $!
|
290
|
+
end
|
289
291
|
end
|
290
292
|
end
|
291
293
|
|
@@ -425,6 +427,8 @@ module TSV
|
|
425
427
|
end
|
426
428
|
|
427
429
|
def self.traverse_run(obj, threads, cpus, options = {}, &block)
|
430
|
+
threads = nil if threads == 1
|
431
|
+
cpus = nil if cpus == 1
|
428
432
|
if ENV["RBBT_NO_MAP_REDUCE"] == "true" or (threads.nil? and cpus.nil?)
|
429
433
|
traverse_obj obj, options, &block
|
430
434
|
else
|
data/lib/rbbt/util/cmd.rb
CHANGED
data/lib/rbbt/util/log.rb
CHANGED
@@ -17,15 +17,16 @@ module Log
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.ignore_stderr
|
20
|
-
backup_stderr = STDERR.dup
|
21
20
|
LOG_MUTEX.synchronize do
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
backup_stderr = STDERR.dup
|
22
|
+
File.open('/dev/null', 'w') do |f|
|
23
|
+
STDERR.reopen(f)
|
24
|
+
begin
|
25
25
|
yield
|
26
|
+
ensure
|
27
|
+
STDERR.reopen backup_stderr
|
28
|
+
backup_stderr.close
|
26
29
|
end
|
27
|
-
ensure
|
28
|
-
STDERR.reopen backup_stderr
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ConcurrentStream
|
2
|
-
attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin
|
2
|
+
attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile
|
3
3
|
|
4
4
|
def self.setup(stream, options = {}, &block)
|
5
5
|
threads, pids, callback, filename, autojoin = Misc.process_options options, :threads, :pids, :callback, :filename, :autojoin
|
@@ -87,6 +87,7 @@ module ConcurrentStream
|
|
87
87
|
|
88
88
|
@joined = true
|
89
89
|
close unless closed?
|
90
|
+
lockfile.unlock if lockfile and lockfile.locked?
|
90
91
|
end
|
91
92
|
|
92
93
|
def abort_threads
|
@@ -220,4 +220,27 @@ module Misc
|
|
220
220
|
ary.values_at *p
|
221
221
|
end
|
222
222
|
end
|
223
|
+
|
224
|
+
def self.object_delta(*args)
|
225
|
+
res, delta = nil, nil
|
226
|
+
Thread.exclusive do
|
227
|
+
pre = Set.new
|
228
|
+
delta = Set.new
|
229
|
+
|
230
|
+
GC.start
|
231
|
+
ObjectSpace.each_object(*args) do |o|
|
232
|
+
pre.add o
|
233
|
+
end
|
234
|
+
|
235
|
+
res = yield
|
236
|
+
|
237
|
+
GC.start
|
238
|
+
ObjectSpace.each_object(*args) do |o|
|
239
|
+
delta.add o unless pre.include? o
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
Log.info "Delta: #{delta.inspect}"
|
244
|
+
res
|
245
|
+
end
|
223
246
|
end
|
data/lib/rbbt/util/misc/lock.rb
CHANGED
@@ -1,17 +1,22 @@
|
|
1
|
-
if ENV["RBBT_NO_LOCKFILE_REFRESH"] == "true"
|
2
|
-
Lockfile.refresh = false
|
3
|
-
Lockfile.max_age = 60 * 60 * 5
|
4
|
-
Lockfile.max_age = 15
|
5
|
-
Lockfile.suspend = 10
|
6
|
-
else
|
7
|
-
Lockfile.dont_use_lock_id = true
|
8
|
-
Lockfile.refresh = 5
|
9
|
-
Lockfile.max_age = 60
|
10
|
-
Lockfile.suspend = 15
|
11
|
-
end
|
12
|
-
|
13
|
-
|
14
1
|
module Misc
|
2
|
+
def self.use_lock_id=(use = true)
|
3
|
+
if use
|
4
|
+
Log.medium "Activating lockfile ids"
|
5
|
+
Lockfile.dont_use_lock_id = false
|
6
|
+
Lockfile.refresh = 20
|
7
|
+
Lockfile.max_age = 60 * 10
|
8
|
+
Lockfile.suspend = 10
|
9
|
+
else
|
10
|
+
Log.medium "De-activating lockfile ids"
|
11
|
+
Lockfile.dont_use_lock_id = false
|
12
|
+
Lockfile.dont_use_lock_id = true
|
13
|
+
Lockfile.refresh = 2
|
14
|
+
Lockfile.max_age = 5
|
15
|
+
Lockfile.suspend = 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
self.use_lock_id = ENV["RBBT_NO_LOCKFILE_ID"] != "true"
|
15
20
|
|
16
21
|
LOCK_MUTEX = Mutex.new
|
17
22
|
def self.lock(file, unlock = true, options = {})
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -83,7 +83,6 @@ module Misc
|
|
83
83
|
|
84
84
|
splitter_thread = Thread.new(Thread.current) do |parent|
|
85
85
|
begin
|
86
|
-
filename = stream.respond_to?(:filename)? stream.filename : nil
|
87
86
|
skip1 = skip2 = false
|
88
87
|
while block = stream.read(2048)
|
89
88
|
begin
|
@@ -148,7 +147,7 @@ module Misc
|
|
148
147
|
str
|
149
148
|
end
|
150
149
|
|
151
|
-
def self.consume_stream(io, in_thread = false)
|
150
|
+
def self.consume_stream(io, in_thread = false, into = nil)
|
152
151
|
return if Path === io
|
153
152
|
return unless io.respond_to? :read
|
154
153
|
if io.respond_to? :closed? and io.closed?
|
@@ -163,16 +162,19 @@ module Misc
|
|
163
162
|
else
|
164
163
|
Log.medium "Consuming stream #{Misc.fingerprint io}"
|
165
164
|
begin
|
166
|
-
while block = io.read(2048)
|
165
|
+
while not io.closed? and block = io.read(2048)
|
166
|
+
into << block if into
|
167
167
|
end
|
168
168
|
io.join if io.respond_to? :join
|
169
|
+
io.close unless io.closed?
|
169
170
|
rescue Aborted
|
170
171
|
Log.medium "Consume stream aborted #{Misc.fingerprint io}"
|
171
172
|
io.abort if io.respond_to? :abort
|
173
|
+
io.close unless io.closed?
|
172
174
|
rescue Exception
|
173
175
|
Log.medium "Exception consuming stream: #{Misc.fingerprint io}: #{$!.message}"
|
174
176
|
io.abort if io.respond_to? :abort
|
175
|
-
io.
|
177
|
+
io.close unless io.closed?
|
176
178
|
raise $!
|
177
179
|
end
|
178
180
|
end
|
@@ -207,20 +209,30 @@ module Misc
|
|
207
209
|
begin
|
208
210
|
case
|
209
211
|
when block_given?
|
210
|
-
File.open(tmp_path, '
|
212
|
+
File.open(tmp_path, 'wb', &block)
|
211
213
|
when String === content
|
212
|
-
File.open(tmp_path, '
|
214
|
+
File.open(tmp_path, 'wb') do |f| f.write content end
|
213
215
|
when (IO === content or StringIO === content or File === content)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
216
|
+
|
217
|
+
out = nil
|
218
|
+
PIPE_MUTEX.synchronize do
|
219
|
+
out = File.open(tmp_path, 'wb')
|
220
|
+
out.sync = true
|
221
|
+
OPEN_PIPE_IN << out
|
218
222
|
end
|
223
|
+
|
224
|
+
while block = content.read(2048);
|
225
|
+
out.write block
|
226
|
+
end
|
227
|
+
|
228
|
+
content.close
|
229
|
+
out.close
|
219
230
|
else
|
220
|
-
File.open(tmp_path, '
|
231
|
+
File.open(tmp_path, 'wb') do |f| end
|
221
232
|
end
|
222
233
|
|
223
234
|
Open.mv tmp_path, path
|
235
|
+
content.join if content.respond_to? :join
|
224
236
|
rescue Aborted
|
225
237
|
Log.medium "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
|
226
238
|
content.abort if content.respond_to? :abort
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -146,8 +146,8 @@ module Open
|
|
146
146
|
def self.get_stream_from_repo(dir, sub_path)
|
147
147
|
repo = get_repo_from_dir(dir)
|
148
148
|
repo.read_and_close do
|
149
|
-
|
150
|
-
|
149
|
+
content = repo[sub_path]
|
150
|
+
content.nil? ? nil : StringIO.new(content)
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
@@ -367,9 +367,9 @@ module Open
|
|
367
367
|
file_open(in_cache(url, wget_options), options[:grep], mode, options[:invert_grep])
|
368
368
|
else
|
369
369
|
io = wget(url, wget_options)
|
370
|
-
|
371
|
-
|
372
|
-
|
370
|
+
new, save = Misc.tee_stream io
|
371
|
+
add_cache(url, save, wget_options)
|
372
|
+
new
|
373
373
|
end
|
374
374
|
io = unzip(io) if ((String === url and zip?(url)) and not options[:noz]) or options[:zip]
|
375
375
|
io = gunzip(io) if ((String === url and gzip?(url)) and not options[:noz]) or options[:gzip]
|
@@ -106,7 +106,7 @@ module SOPT
|
|
106
106
|
|
107
107
|
if description and not description.empty?
|
108
108
|
doc << Log.color(:magenta, "## DESCRIPTION") << "\n\n"
|
109
|
-
doc << Misc.format_paragraph(description)
|
109
|
+
doc << Misc.format_paragraph(description) << "\n\n"
|
110
110
|
end
|
111
111
|
|
112
112
|
doc << Log.color(:magenta, "## OPTIONS") << "\n\n"
|
@@ -400,7 +400,8 @@ class Step
|
|
400
400
|
stream = get_stream if @result
|
401
401
|
if stream
|
402
402
|
begin
|
403
|
-
|
403
|
+
@stream_data = StringIO.new
|
404
|
+
Misc.consume_stream stream, false, @stream_data
|
404
405
|
rescue Exception
|
405
406
|
self._abort
|
406
407
|
raise $!
|
@@ -409,7 +410,7 @@ class Step
|
|
409
410
|
end
|
410
411
|
|
411
412
|
def grace
|
412
|
-
until done? or result or error? or aborted? or streaming?
|
413
|
+
until done? or result or error? or aborted? or streaming?
|
413
414
|
sleep 1
|
414
415
|
end
|
415
416
|
self
|