scout-gear 7.3.0 → 8.0.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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +20 -9
  3. data/VERSION +1 -1
  4. data/bin/scout +6 -3
  5. data/lib/rbbt-scout.rb +1 -0
  6. data/lib/scout/cmd.rb +1 -1
  7. data/lib/scout/concurrent_stream.rb +26 -23
  8. data/lib/scout/config.rb +1 -1
  9. data/lib/scout/log/color.rb +4 -1
  10. data/lib/scout/log/progress/report.rb +1 -1
  11. data/lib/scout/log/progress/util.rb +58 -54
  12. data/lib/scout/log/progress.rb +1 -1
  13. data/lib/scout/log/trap.rb +107 -0
  14. data/lib/scout/log.rb +56 -21
  15. data/lib/scout/meta_extension.rb +13 -6
  16. data/lib/scout/misc/digest.rb +1 -1
  17. data/lib/scout/misc/format.rb +12 -0
  18. data/lib/scout/misc/insist.rb +1 -1
  19. data/lib/scout/misc/monitor.rb +11 -0
  20. data/lib/scout/misc/system.rb +10 -0
  21. data/lib/scout/named_array.rb +65 -3
  22. data/lib/scout/open/lock/lockfile.rb +587 -0
  23. data/lib/scout/open/lock.rb +28 -2
  24. data/lib/scout/open/remote.rb +4 -0
  25. data/lib/scout/open/stream.rb +90 -15
  26. data/lib/scout/open/util.rb +13 -3
  27. data/lib/scout/path/find.rb +9 -1
  28. data/lib/scout/path/util.rb +35 -0
  29. data/lib/scout/persist/serialize.rb +18 -5
  30. data/lib/scout/persist.rb +28 -12
  31. data/lib/scout/resource/path.rb +53 -0
  32. data/lib/scout/resource/produce.rb +0 -8
  33. data/lib/scout/resource/util.rb +2 -1
  34. data/lib/scout/tmpfile.rb +7 -8
  35. data/lib/scout/tsv/attach.rb +177 -0
  36. data/lib/scout/tsv/change_id.rb +40 -0
  37. data/lib/scout/tsv/dumper.rb +72 -46
  38. data/lib/scout/tsv/index.rb +69 -13
  39. data/lib/scout/tsv/open.rb +138 -84
  40. data/lib/scout/tsv/parser.rb +135 -80
  41. data/lib/scout/tsv/path.rb +1 -2
  42. data/lib/scout/tsv/persist/adapter.rb +15 -45
  43. data/lib/scout/tsv/persist/fix_width_table.rb +3 -0
  44. data/lib/scout/tsv/persist/tokyocabinet.rb +4 -1
  45. data/lib/scout/tsv/persist.rb +4 -0
  46. data/lib/scout/tsv/transformer.rb +141 -0
  47. data/lib/scout/tsv/traverse.rb +96 -92
  48. data/lib/scout/tsv/util/filter.rb +9 -0
  49. data/lib/scout/tsv/util/reorder.rb +81 -0
  50. data/lib/scout/tsv/util/select.rb +78 -33
  51. data/lib/scout/tsv/util/unzip.rb +86 -0
  52. data/lib/scout/tsv/util.rb +60 -11
  53. data/lib/scout/tsv.rb +26 -3
  54. data/lib/scout/work_queue/socket.rb +6 -1
  55. data/lib/scout/work_queue/worker.rb +5 -2
  56. data/lib/scout/work_queue.rb +15 -8
  57. data/lib/scout/workflow/definition.rb +21 -2
  58. data/lib/scout/workflow/step/dependencies.rb +24 -4
  59. data/lib/scout/workflow/step/info.rb +36 -5
  60. data/lib/scout/workflow/step/provenance.rb +8 -7
  61. data/lib/scout/workflow/step/status.rb +45 -0
  62. data/lib/scout/workflow/step.rb +100 -34
  63. data/lib/scout/workflow/task/inputs.rb +14 -20
  64. data/lib/scout/workflow/task.rb +81 -46
  65. data/lib/scout/workflow/usage.rb +8 -6
  66. data/scout-gear.gemspec +24 -20
  67. data/scout_commands/workflow/task +34 -7
  68. data/test/scout/open/test_stream.rb +60 -58
  69. data/test/scout/path/test_find.rb +10 -1
  70. data/test/scout/resource/test_produce.rb +15 -0
  71. data/test/scout/test_meta_extension.rb +25 -0
  72. data/test/scout/test_named_array.rb +18 -0
  73. data/test/scout/test_persist.rb +6 -0
  74. data/test/scout/test_tsv.rb +212 -2
  75. data/test/scout/test_work_queue.rb +21 -19
  76. data/test/scout/tsv/persist/test_adapter.rb +1 -1
  77. data/test/scout/tsv/persist/test_tokyocabinet.rb +29 -1
  78. data/test/scout/tsv/test_attach.rb +227 -0
  79. data/test/scout/tsv/test_change_id.rb +98 -0
  80. data/test/scout/tsv/test_dumper.rb +1 -1
  81. data/test/scout/tsv/test_index.rb +35 -3
  82. data/test/scout/tsv/test_open.rb +160 -2
  83. data/test/scout/tsv/test_parser.rb +19 -2
  84. data/test/scout/tsv/test_persist.rb +2 -0
  85. data/test/scout/tsv/test_transformer.rb +108 -0
  86. data/test/scout/tsv/test_traverse.rb +88 -3
  87. data/test/scout/tsv/test_util.rb +1 -0
  88. data/test/scout/tsv/util/test_reorder.rb +94 -0
  89. data/test/scout/tsv/util/test_select.rb +25 -11
  90. data/test/scout/tsv/util/test_unzip.rb +112 -0
  91. data/test/scout/work_queue/test_socket.rb +0 -1
  92. data/test/scout/workflow/step/test_status.rb +31 -0
  93. data/test/scout/workflow/task/test_inputs.rb +14 -14
  94. data/test/scout/workflow/test_step.rb +3 -3
  95. data/test/scout/workflow/test_task.rb +168 -32
  96. data/test/scout/workflow/test_usage.rb +33 -6
  97. metadata +20 -6
@@ -56,6 +56,7 @@ module Open
56
56
 
57
57
  while c = io.read(BLOCK_SIZE)
58
58
  into << c if into
59
+ last_c = c if c
59
60
  break if io.closed?
60
61
  end
61
62
 
@@ -65,13 +66,15 @@ module Open
65
66
  into.close if into and into_close and not into.closed?
66
67
  block.call if block_given?
67
68
 
68
- c
69
+ last_c
69
70
  rescue Aborted
71
+ Thread.current["exception"] = true
70
72
  Log.low "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
71
73
  io.abort $! if io.respond_to? :abort
72
74
  into.close if into.respond_to?(:closed?) && ! into.closed?
73
75
  FileUtils.rm into_path if into_path and File.exist?(into_path)
74
76
  rescue Exception
77
+ Thread.current["exception"] = true
75
78
  Log.low "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
76
79
  exception = (io.respond_to?(:stream_exception) && io.stream_exception) ? io.stream_exception : $!
77
80
  io.abort exception if io.respond_to? :abort
@@ -109,7 +112,6 @@ module Open
109
112
  FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory?(File.dirname(tmp_path))
110
113
  FileUtils.rm_f tmp_path if File.exist? tmp_path
111
114
  begin
112
-
113
115
  case
114
116
  when block_given?
115
117
  File.open(tmp_path, 'wb', &block)
@@ -117,7 +119,6 @@ module Open
117
119
  File.open(tmp_path, 'wb') do |f| f.write content end
118
120
  when (IO === content or StringIO === content or File === content)
119
121
  Open.write(tmp_path) do |f|
120
- #f.sync = true
121
122
  while block = content.read(BLOCK_SIZE)
122
123
  f.write block
123
124
  break if content.closed?
@@ -139,14 +140,15 @@ module Open
139
140
  content.join if content.respond_to?(:join) and not Path === content and not (content.respond_to?(:joined?) && content.joined?)
140
141
 
141
142
  Open.notify_write(path)
143
+ Log.debug "Done sensible write: [#{Process.pid}] -- #{ path }"
142
144
  rescue Aborted
143
- Log.low "Aborted sensible_write -- #{ Log.reset << Log.color(:blue, path) }"
145
+ Log.low "Aborted sensible_write -- #{ Log.reset << path }"
144
146
  content.abort if content.respond_to? :abort
145
147
  Open.rm path if File.exist? path
146
148
  rescue Exception
147
149
  exception = (AbortedStream === content and content.exception) ? content.exception : $!
148
- Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ Log.color :blue, path }"
149
- content.abort if content.respond_to? :abort
150
+ Log.low "Exception in sensible_write: [#{Process.pid}] #{exception.message} -- #{ path }"
151
+ content.abort(exception) if content.respond_to? :abort
150
152
  Open.rm path if File.exist? path
151
153
  raise exception
152
154
  rescue
@@ -187,7 +189,7 @@ module Open
187
189
  FileUtils.rm path if erase && File.exist?(path)
188
190
  end
189
191
  end
190
-
192
+
191
193
  def self.release_pipes(*pipes)
192
194
  PIPE_MUTEX.synchronize do
193
195
  pipes.flatten.each do |pipe|
@@ -239,7 +241,7 @@ module Open
239
241
  begin
240
242
  Thread.current.report_on_exception = false
241
243
  Thread.current["name"] = "Pipe input #{Log.fingerprint sin} => #{Log.fingerprint sout}"
242
-
244
+
243
245
  yield sin
244
246
 
245
247
  sin.close if close and not sin.closed? and not sin.aborted?
@@ -306,9 +308,16 @@ module Open
306
308
  stream.close unless stream.closed?
307
309
  in_pipes.first.close unless in_pipes.first.closed?
308
310
  rescue Aborted, Interrupt
309
- stream.abort if stream.respond_to? :abort
310
- out_pipes.each do |sout|
311
- sout.abort if sout.respond_to? :abort
311
+ stream.abort if stream.respond_to?(:abort) && ! stream.aborted?
312
+ out_pipes.reverse.each do |sout|
313
+ sout.threads.delete(Thread.current)
314
+ begin
315
+ sout.abort($!) if sout.respond_to?(:abort) && ! sout.aborted?
316
+ rescue
317
+ end
318
+ end
319
+ in_pipes.each do |sin|
320
+ sin.close unless sin.closed?
312
321
  end
313
322
  Log.low "Tee aborting #{Log.fingerprint stream}"
314
323
  raise $!
@@ -327,12 +336,14 @@ module Open
327
336
  end
328
337
  Log.low "Tee exception #{Log.fingerprint stream}"
329
338
  rescue
330
- Log.exception $!
331
339
  ensure
332
- in_pipes.each do |sin|
333
- sin.close unless sin.closed?
340
+ begin
341
+ in_pipes.each do |sin|
342
+ sin.close unless sin.closed?
343
+ end
344
+ ensure
345
+ raise $!
334
346
  end
335
- raise $!
336
347
  end
337
348
  end
338
349
  end
@@ -425,5 +436,69 @@ module Open
425
436
  end
426
437
  end
427
438
 
439
+ def self.process_stream(s)
440
+ begin
441
+ yield s
442
+ s.close if s.respond_to?(:close) && ! s.closed?
443
+ s.join if s.respond_to?(:join)
444
+ rescue
445
+ s.abort($!) if s.respond_to? :abort
446
+ raise $!
447
+ end
448
+ end
449
+
450
+
451
+ def self.collapse_stream(s, line: nil, sep: "\t", header: nil, &block)
452
+ sep ||= "\t"
453
+ Open.open_pipe do |sin|
454
+ sin.puts header if header
455
+ process_stream(s) do |s|
456
+ line ||= s.gets
457
+
458
+ current_parts = []
459
+ while line
460
+ key, *parts = line.chomp.split(sep, -1)
461
+ case
462
+ when key.nil?
463
+ when current_parts.nil?
464
+ current_parts = parts
465
+ current_key = key
466
+ when current_key == key
467
+ parts.each_with_index do |part,i|
468
+ if current_parts[i].nil?
469
+ current_parts[i] = "|" << part
470
+ else
471
+ current_parts[i] = current_parts[i] << "|" << part
472
+ end
473
+ end
474
+
475
+ (parts.length..current_parts.length-1).to_a.each do |pos|
476
+ current_parts[pos] = current_parts[pos] << "|" << ""
477
+ end
478
+ when current_key.nil?
479
+ current_key = key
480
+ current_parts = parts
481
+ when current_key != key
482
+ if block_given?
483
+ res = block.call(current_parts)
484
+ sin.puts [current_key, res] * sep
485
+ else
486
+ sin.puts [current_key, current_parts].flatten * sep
487
+ end
488
+ current_key = key
489
+ current_parts = parts
490
+ end
491
+ line = s.gets
492
+ end
493
+
494
+ if block_given?
495
+ res = block.call(current_parts)
496
+ sin.puts [current_key, res] * sep
497
+ else
498
+ sin.puts [current_key, current_parts].flatten * sep
499
+ end unless current_key.nil?
500
+ end
501
+ end
502
+ end
428
503
 
429
504
  end
@@ -94,6 +94,11 @@ module Open
94
94
  File.symlink?(path) && ! File.exist?(File.readlink(path))
95
95
  end
96
96
 
97
+ def self.directory?(file)
98
+ file = file.find if Path === file
99
+ File.directory?(file)
100
+ end
101
+
97
102
  def self.exists?(file)
98
103
  file = file.find if Path === file
99
104
  File.exist?(file)
@@ -111,7 +116,7 @@ module Open
111
116
  end
112
117
 
113
118
  def self.rm(file)
114
- FileUtils.rm(file) if File.exist?(file) or Open.broken_link?(file)
119
+ FileUtils.rm(file) if File.exist?(file) || Open.broken_link?(file)
115
120
  end
116
121
 
117
122
  def self.rm_rf(file)
@@ -155,7 +160,7 @@ module Open
155
160
  begin
156
161
  if File.symlink?(file) || File.stat(file).nlink > 1
157
162
  if File.exist?(file + '.info') && defined?(Step)
158
- done = Step::INFO_SERIALIZER.load(Open.open(file + '.info'))[:done]
163
+ done = Persist.load(file + '.info', Step::SERIALIZER)[:done]
159
164
  return done if done
160
165
  end
161
166
 
@@ -173,7 +178,7 @@ module Open
173
178
  target = target.find if Path === target
174
179
 
175
180
  FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
176
- FileUtils.rm target if File.exist?(target)
181
+ FileUtils.rm_rf target if File.exist?(target)
177
182
  FileUtils.cp_r source, target
178
183
  end
179
184
 
@@ -222,4 +227,9 @@ module Open
222
227
  end
223
228
  nil
224
229
  end
230
+
231
+ def self.list(file)
232
+ file = file.produce_and_find if Path === file
233
+ Open.read(file).split("\n")
234
+ end
225
235
  end
@@ -10,8 +10,10 @@ module Path
10
10
  file =~ /(?:scout|rbbt)\/(?:.*\/)?path\.rb/ or
11
11
  file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
12
12
  file =~ /(?:scout|rbbt)\/persist.rb/ or
13
+ file =~ /scout\/resource\/produce.rb/ or
13
14
  file =~ /modules\/rbbt-util/
14
15
  end
16
+ return nil if file.nil?
15
17
  file = file.sub(/\.rb[^\w].*/,'.rb')
16
18
  end
17
19
 
@@ -38,7 +40,7 @@ module Path
38
40
  sub('{SUBPATH}', path._subpath).
39
41
  sub('{BASENAME}', File.basename(path)).
40
42
  sub('{PATH}', path).
41
- sub('{LIBDIR}', path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir).
43
+ sub('{LIBDIR}', path.libdir || (path.pkgdir.respond_to?(:libdir) && path.pkgdir.libdir) || Path.caller_lib_dir || "NOLIBDIR").
42
44
  sub('{MAPNAME}', map_name.to_s).
43
45
  sub('{REMOVE}/', '').
44
46
  sub('{REMOVE}', '').gsub(/\/+/,'/')
@@ -188,4 +190,10 @@ module Path
188
190
  .select{|file| file.exist? }.uniq
189
191
  end
190
192
 
193
+ def find_with_extension(extension, *args)
194
+ found = self.find(*args)
195
+ return found if found.exists?
196
+ found_with_extension = self.set_extension(extension).find
197
+ found_with_extension.exists? ? found_with_extension : found
198
+ end
191
199
  end
@@ -12,6 +12,23 @@ module Path
12
12
  return false
13
13
  end
14
14
 
15
+ def self.sanitize_filename(filename, length = 254)
16
+ if filename.length > length
17
+ if filename =~ /(\..{2,9})$/
18
+ extension = $1
19
+ else
20
+ extension = ''
21
+ end
22
+
23
+ post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension
24
+
25
+ filename = filename[0..(length - post_fix.length - 1)] << post_fix
26
+ else
27
+ filename
28
+ end
29
+ filename
30
+ end
31
+
15
32
  def directory?
16
33
  return nil unless self.exist?
17
34
  File.directory?(self.find)
@@ -64,4 +81,22 @@ module Path
64
81
  def set_extension(extension)
65
82
  self.annotate(self + ".#{extension}")
66
83
  end
84
+
85
+ # Is 'file' newer than 'path'? return non-true if path is newer than file
86
+ def self.newer?(path, file, by_link = false)
87
+ return true if not Open.exists?(file)
88
+ path = path.find if Path === path
89
+ file = file.find if Path === file
90
+ if by_link
91
+ patht = File.exist?(path) ? File.lstat(path).mtime : nil
92
+ filet = File.exist?(file) ? File.lstat(file).mtime : nil
93
+ else
94
+ patht = Open.mtime(path)
95
+ filet = Open.mtime(file)
96
+ end
97
+ return true if patht.nil? || filet.nil?
98
+ diff = patht - filet
99
+ return diff if diff < 0
100
+ return false
101
+ end
67
102
  end
@@ -1,5 +1,6 @@
1
1
  require_relative '../open'
2
2
  require_relative 'open'
3
+ require 'set'
3
4
 
4
5
  module Persist
5
6
  TRUE_STRINGS = Set.new ["true", "True", "TRUE", "t", "T", "1", "yes", "Yes", "YES", "y", "Y", "ON", "on"] unless defined? TRUE_STRINGS
@@ -19,7 +20,7 @@ module Persist
19
20
  type = type.to_sym if String === type
20
21
  type = SERIALIZER if type == :serializer
21
22
  case type
22
- when nil, :string, :integer, :float, :boolean, :file, :path
23
+ when nil, :string, :integer, :float, :boolean, :file, :path, :select, :folder
23
24
  if IO === content || StringIO === content
24
25
  content.read
25
26
  else
@@ -46,8 +47,9 @@ module Persist
46
47
  def self.deserialize(serialized, type)
47
48
  type = type.to_sym if String === type
48
49
  type = SERIALIZER if type == :serializer
50
+
49
51
  case type
50
- when nil, :string, :file, :stream
52
+ when nil, :string, :file, :stream, :select, :folder
51
53
  serialized
52
54
  when :path
53
55
  Path.setup(serialized)
@@ -99,9 +101,18 @@ module Persist
99
101
  return save_drivers[type].call(file, content)
100
102
  end
101
103
  end
102
- serialized = serialize(content, type)
103
- Open.sensible_write(file, serialized, :force => true)
104
- return nil
104
+
105
+ if type == :binary
106
+ content.force_encoding("ASCII-8BIT") if content.respond_to? :force_encoding
107
+ Open.open(path, :mode => 'wb') do |f|
108
+ f.puts content
109
+ end
110
+ content
111
+ else
112
+ serialized = serialize(content, type)
113
+ Open.sensible_write(file, serialized, :force => true)
114
+ return nil
115
+ end
105
116
  end
106
117
 
107
118
  def self.load(file, type = :serializer)
@@ -118,6 +129,8 @@ module Persist
118
129
  end
119
130
 
120
131
  case type
132
+ when :binary
133
+ Open.read(file, :mode => 'rb')
121
134
  when :yaml
122
135
  Open.yaml(file)
123
136
  when :json
data/lib/scout/persist.rb CHANGED
@@ -21,7 +21,9 @@ module Persist
21
21
  def self.persistence_path(name, options = {})
22
22
  options = IndiferentHash.add_defaults options, :dir => Persist.cache_dir
23
23
  other_options = IndiferentHash.pull_keys options, :other
24
- TmpFile.tmp_for_file(name, options, other_options)
24
+ name = name.filename if name.respond_to?(:filename) && name.filename
25
+ persist_options = {}
26
+ TmpFile.tmp_for_file(name, options.merge(persist_options), other_options)
25
27
  end
26
28
 
27
29
  MEMORY_CACHE = {}
@@ -31,25 +33,31 @@ module Persist
31
33
  return yield if FalseClass === persist_options[:persist]
32
34
  file = persist_options[:path] || options[:path] || persistence_path(name, options)
33
35
 
34
- lockfile = persist_options[:lockfile] || options[:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir})
35
-
36
- update = options[:update] || persist_options[:update]
37
- update = Open.mtime(update) if Path === update
38
- update = Open.mtime(file) >= update ? false : true if Time === update
39
-
40
36
  if type == :memory
41
37
  repo = options[:memory] || options[:repo] || MEMORY_CACHE
42
38
  repo[file] ||= yield
43
39
  return repo[file]
44
40
  end
45
41
 
42
+ update = options[:update] || persist_options[:update]
43
+ update = Open.mtime(update) if Path === update
44
+ update = Open.mtime(file) >= update ? false : true if Time === update
45
+
46
+ lockfile = persist_options[:lockfile] || options[:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir})
47
+
46
48
  Open.lock lockfile do |lock|
47
49
  if Open.exist?(file) && ! update
48
50
  Persist.load(file, type)
49
51
  else
50
- return yield(file) if block.arity == 1
51
- res = yield
52
52
  begin
53
+ file = file.find if Path === file
54
+ return yield(file) if block.arity == 1
55
+ res = yield
56
+
57
+ if res.nil?
58
+ return Persist.load(file, type)
59
+ end
60
+
53
61
  Open.rm(file)
54
62
 
55
63
  if IO === res || StringIO === res
@@ -73,16 +81,24 @@ module Persist
73
81
  res = pres unless pres.nil?
74
82
  end
75
83
  rescue
84
+ Thread.handle_interrupt(Exception => :never) do
85
+ if Open.exist?(file)
86
+ Log.debug "Failed persistence #{file} - erasing"
87
+ Open.rm file
88
+ else
89
+ Log.debug "Failed persistence #{file}"
90
+ end
91
+ end
76
92
  raise $! unless options[:canfail]
77
- Log.debug "Could not persist #{type} on #{file}"
78
93
  end
79
94
  res
80
95
  end
81
96
  end
82
97
  end
83
98
 
84
- def self.memory(name, *args, &block)
85
- self.persist(name, :memory, *args, &block)
99
+ def self.memory(name, options = {}, &block)
100
+ options[:persist_path] ||= options[:path] ||= [name, options[:key]].compact * ":"
101
+ self.persist(name, :memory, options, &block)
86
102
  end
87
103
 
88
104
  end
@@ -1,4 +1,47 @@
1
1
  module Path
2
+ def produce(force = false)
3
+ return self if ! force && (Open.exist?(self) || @produced)
4
+ begin
5
+ if Resource === self.pkgdir
6
+ self.pkgdir.produce self
7
+ else
8
+ false
9
+ end
10
+ rescue ResourceNotFound
11
+ false
12
+ rescue
13
+ message = $!.message
14
+ message = "No exception message" if message.nil? || message.empty?
15
+ Log.warn "Error producing #{self}: #{message}"
16
+ false
17
+ ensure
18
+ @produced = true
19
+ end
20
+ end
21
+
22
+ def produce_with_extension(extension, *args)
23
+ begin
24
+ self.produce(*args)
25
+ rescue Exception
26
+ exception = $!
27
+ begin
28
+ self.set_extension(extension).produce(*args)
29
+ rescue Exception
30
+ raise exception
31
+ end
32
+ end
33
+ end
34
+
35
+ def produce_and_find(extension = nil, *args)
36
+ if extension
37
+ found = find_with_extension(extension, *args)
38
+ found.exists? ? found : produce_with_extension(extension, *args)
39
+ else
40
+ found = find
41
+ found.exists? ? found : produce(*args)
42
+ end
43
+ end
44
+
2
45
  def relocate
3
46
  return self if Open.exists?(self)
4
47
  Resource.relocate(self)
@@ -17,4 +60,14 @@ module Path
17
60
  def write(*args, &block)
18
61
  Open.write(self.find, *args, &block)
19
62
  end
63
+
64
+ def list
65
+ found = produce_and_find('list')
66
+ Open.list(found)
67
+ end
68
+
69
+ def exists?
70
+ return true if Open.exists?(self.find)
71
+ self.produce
72
+ end
20
73
  end
@@ -149,11 +149,3 @@ module Resource
149
149
  end
150
150
 
151
151
  end
152
-
153
- module Path
154
- def produce(force = false)
155
- return self if ! force && Open.exist?(self)
156
- self.pkgdir.produce self if Resource === self.pkgdir
157
- return self
158
- end
159
- end
@@ -1,7 +1,8 @@
1
1
  module Resource
2
2
  def identify(path)
3
3
  return path unless path.start_with?("/")
4
- path_maps = path.path_maps || self.path_maps || Path.path_maps
4
+ path_maps = path.path_maps if Path === path
5
+ path_maps ||= self.path_maps || Path.path_maps
5
6
  path = File.expand_path(path)
6
7
  path += "/" if File.directory?(path)
7
8
 
data/lib/scout/tmpfile.rb CHANGED
@@ -93,19 +93,18 @@ module TmpFile
93
93
  end
94
94
  end
95
95
 
96
+ SLASH_REPLACE = '·'
96
97
  def self.tmp_for_file(file, tmp_options = {}, other_options = {})
97
- tmp_for_file = IndiferentHash.process_options tmp_options, :file
98
+ tmp_for_file, prefix, key, persistence_dir = IndiferentHash.process_options tmp_options, :file, :prefix, :key, :dir
98
99
  return tmp_for_file unless tmp_for_file.nil?
99
100
 
100
- prefix = IndiferentHash.process_options tmp_options, :prefix
101
-
102
101
  if prefix.nil?
103
- perfile = file.to_s.gsub(/\//, '>')
102
+ perfile = file.to_s.sub(/\.b?gz$/,'')
104
103
  else
105
- perfile = prefix.to_s + ":" + file.to_s.gsub(/\//, '>')
104
+ perfile = prefix.to_s + ":" + file.to_s.sub(/\.b?gz$/,'')
106
105
  end
107
106
 
108
- perfile.sub!(/\.b?gz$/,'')
107
+ perfile += "[#{ key }]" if key
109
108
 
110
109
  if other_options.include? :filters
111
110
  other_options[:filters].each do |match,value|
@@ -113,10 +112,10 @@ module TmpFile
113
112
  end
114
113
  end
115
114
 
116
- persistence_dir = IndiferentHash.process_options(tmp_options, :dir) || TmpFile.tmpdir
115
+ persistence_dir = TmpFile.tmpdir if persistence_dir.nil?
117
116
  Path.setup(persistence_dir) unless Path === persistence_dir
118
117
 
119
- filename = perfile.gsub(/\s/,'_').gsub(/\//,'>')
118
+ filename = perfile.gsub(/\s/,'_').gsub('/', SLASH_REPLACE)
120
119
  clean_options = other_options.dup
121
120
  clean_options.delete :unnamed
122
121
  clean_options.delete "unnamed"