scout-gear 7.1.0 → 7.2.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +29 -0
  3. data/VERSION +1 -1
  4. data/bin/scout +5 -1
  5. data/lib/rbbt-scout.rb +5 -0
  6. data/lib/scout/concurrent_stream.rb +6 -2
  7. data/lib/scout/config.rb +168 -0
  8. data/lib/scout/exceptions.rb +4 -3
  9. data/lib/scout/indiferent_hash/options.rb +1 -0
  10. data/lib/scout/indiferent_hash.rb +4 -2
  11. data/lib/scout/log/color.rb +3 -1
  12. data/lib/scout/log/progress/report.rb +1 -0
  13. data/lib/scout/log/progress/util.rb +1 -1
  14. data/lib/scout/log/progress.rb +5 -3
  15. data/lib/scout/log.rb +3 -2
  16. data/lib/scout/misc/monitor.rb +3 -0
  17. data/lib/scout/misc/system.rb +15 -0
  18. data/lib/scout/misc.rb +1 -0
  19. data/lib/scout/named_array.rb +68 -0
  20. data/lib/scout/open/stream.rb +38 -7
  21. data/lib/scout/path/find.rb +27 -3
  22. data/lib/scout/path/util.rb +7 -4
  23. data/lib/scout/persist/serialize.rb +7 -14
  24. data/lib/scout/persist.rb +21 -1
  25. data/lib/scout/resource/produce.rb +7 -94
  26. data/lib/scout/resource/software.rb +176 -0
  27. data/lib/scout/tsv/dumper.rb +107 -0
  28. data/lib/scout/tsv/index.rb +49 -0
  29. data/lib/scout/tsv/parser.rb +203 -30
  30. data/lib/scout/tsv/path.rb +13 -0
  31. data/lib/scout/tsv/persist/adapter.rb +348 -0
  32. data/lib/scout/tsv/persist/tokyocabinet.rb +113 -0
  33. data/lib/scout/tsv/persist.rb +15 -0
  34. data/lib/scout/tsv/traverse.rb +48 -0
  35. data/lib/scout/tsv/util.rb +24 -0
  36. data/lib/scout/tsv.rb +16 -3
  37. data/lib/scout/work_queue/worker.rb +3 -3
  38. data/lib/scout/work_queue.rb +22 -7
  39. data/lib/scout/workflow/definition.rb +93 -4
  40. data/lib/scout/workflow/step/config.rb +18 -0
  41. data/lib/scout/workflow/step/dependencies.rb +40 -0
  42. data/lib/scout/workflow/step/file.rb +15 -0
  43. data/lib/scout/workflow/step/info.rb +31 -4
  44. data/lib/scout/workflow/step/provenance.rb +148 -0
  45. data/lib/scout/workflow/step.rb +68 -19
  46. data/lib/scout/workflow/task.rb +3 -2
  47. data/lib/scout/workflow/usage.rb +1 -1
  48. data/lib/scout/workflow.rb +11 -3
  49. data/lib/scout-gear.rb +1 -0
  50. data/lib/scout.rb +1 -0
  51. data/scout-gear.gemspec +34 -3
  52. data/scout_commands/find +1 -1
  53. data/scout_commands/workflow/task +16 -10
  54. data/share/software/install_helpers +523 -0
  55. data/test/scout/log/test_progress.rb +0 -2
  56. data/test/scout/misc/test_system.rb +21 -0
  57. data/test/scout/open/test_stream.rb +159 -0
  58. data/test/scout/path/test_find.rb +14 -7
  59. data/test/scout/resource/test_software.rb +24 -0
  60. data/test/scout/test_config.rb +66 -0
  61. data/test/scout/test_meta_extension.rb +10 -0
  62. data/test/scout/test_named_array.rb +19 -0
  63. data/test/scout/test_persist.rb +35 -0
  64. data/test/scout/test_tmpfile.rb +2 -2
  65. data/test/scout/test_tsv.rb +41 -1
  66. data/test/scout/test_work_queue.rb +40 -13
  67. data/test/scout/tsv/persist/test_adapter.rb +34 -0
  68. data/test/scout/tsv/persist/test_tokyocabinet.rb +92 -0
  69. data/test/scout/tsv/test_dumper.rb +44 -0
  70. data/test/scout/tsv/test_index.rb +64 -0
  71. data/test/scout/tsv/test_parser.rb +86 -0
  72. data/test/scout/tsv/test_persist.rb +36 -0
  73. data/test/scout/tsv/test_traverse.rb +9 -0
  74. data/test/scout/tsv/test_util.rb +0 -0
  75. data/test/scout/work_queue/test_worker.rb +3 -3
  76. data/test/scout/workflow/step/test_dependencies.rb +25 -0
  77. data/test/scout/workflow/step/test_info.rb +15 -17
  78. data/test/scout/workflow/step/test_load.rb +16 -18
  79. data/test/scout/workflow/step/test_provenance.rb +25 -0
  80. data/test/scout/workflow/test_step.rb +206 -10
  81. data/test/scout/workflow/test_task.rb +0 -3
  82. data/test/test_helper.rb +6 -0
  83. metadata +33 -2
@@ -1,3 +1,4 @@
1
+ require_relative '../named_array'
1
2
  module TSV
2
3
  def self.cast_value(value, cast)
3
4
  if Array === value
@@ -13,9 +14,11 @@ module TSV
13
14
  if positions.nil? && key == 0
14
15
  key = items.shift
15
16
  elsif positions.nil?
16
- key = items.delete(key)
17
+ key = items.delete_at(key)
18
+ key = key.split(sep2) if type == :double
17
19
  else
18
20
  key, items = items[key], items.values_at(*positions)
21
+ key = key.split(sep2) if type == :double
19
22
  end
20
23
 
21
24
  items = case type
@@ -29,7 +32,6 @@ module TSV
29
32
  items.collect{|i| i.split(sep2, -1) }
30
33
  end
31
34
 
32
- key = key.partition(sep2).first if type == :double
33
35
 
34
36
  if cast
35
37
  items = cast_value(items, cast)
@@ -38,10 +40,12 @@ module TSV
38
40
  [key, items]
39
41
  end
40
42
 
41
- def self.parse_stream(stream, data: nil, merge: true, type: :list, fix: true, bar: false, first_line: nil, **kargs, &block)
43
+ def self.parse_stream(stream, data: nil, source_type: nil, type: :list, merge: true, one2one: false, fix: true, bar: false, first_line: nil, **kargs, &block)
42
44
  begin
43
45
  bar = Log::ProgressBar.new_bar(bar) if bar
44
46
 
47
+ source_type = type if source_type.nil?
48
+
45
49
  data = {} if data.nil?
46
50
  merge = false if type != :double
47
51
  line = first_line || stream.gets
@@ -50,30 +54,85 @@ module TSV
50
54
  line.strip!
51
55
  line = Misc.fixutf8(line) if fix
52
56
  bar.tick if bar
53
- key, items = parse_line(line, type: type, **kargs)
57
+ key, items = parse_line(line, type: source_type, **kargs)
54
58
 
55
- if block_given?
56
- res = block.call(key, items)
57
- data[key] = res unless res.nil?
58
- next
59
+ if Array === key
60
+ keys = key
61
+ if one2one
62
+ key_items = keys.length.times.collect{|i| items.collect{|list| [list[i] || list[0]] } }
63
+ else
64
+ key_items = false
65
+ end
66
+ else
67
+ keys = [key]
68
+ key_items = false
59
69
  end
60
70
 
61
- if ! merge || ! data.include?(key)
62
- data[key] = items
63
- else
64
- current = data[key]
65
- if merge == :concat
66
- items.each_with_index do |new,i|
67
- next if new.empty?
68
- current[i].concat(new)
69
- end
71
+ keys.each_with_index do |key,i|
72
+ if key_items
73
+ these_items = key_items[i]
74
+ else
75
+ these_items = items
76
+ end
77
+
78
+ these_items = case [source_type, type]
79
+ when [:single, :single]
80
+ these_items
81
+ when [:list, :single]
82
+ these_items.first
83
+ when [:flat, :single]
84
+ these_items.first
85
+ when [:double, :single]
86
+ these_items.first.first
87
+ when [:single, :list]
88
+ [these_items]
89
+ when [:list, :list]
90
+ these_items
91
+ when [:flat, :list]
92
+ these_items
93
+ when [:double, :list]
94
+ these_items.collect{|l| l.first }
95
+ when [:single, :flat]
96
+ [these_items]
97
+ when [:list, :flat]
98
+ these_items
99
+ when [:flat, :flat]
100
+ these_items
101
+ when [:double, :flat]
102
+ these_items.flatten
103
+ when [:single, :double]
104
+ [[these_items]]
105
+ when [:list, :double]
106
+ these_items.collect{|l| [l] }
107
+ when [:flat, :double]
108
+ [these_items]
109
+ when [:double, :double]
110
+ these_items
111
+ end
112
+
113
+ if block_given?
114
+ res = block.call(key, these_items)
115
+ data[key] = res unless res.nil? || FalseClass === data
116
+ next
117
+ end
118
+
119
+ if ! merge || ! data.include?(key)
120
+ data[key] = these_items
70
121
  else
71
- merged = []
72
- items.each_with_index do |new,i|
73
- next if new.empty?
74
- merged[i] = current[i] + new
122
+ current = data[key]
123
+ if merge == :concat
124
+ these_items.each_with_index do |new,i|
125
+ next if new.empty?
126
+ current[i].concat(new)
127
+ end
128
+ else
129
+ merged = []
130
+ these_items.each_with_index do |new,i|
131
+ next if new.empty?
132
+ merged[i] = current[i] + new
133
+ end
134
+ data[key] = merged
75
135
  end
76
- data[key] = merged
77
136
  end
78
137
  end
79
138
  ensure
@@ -86,7 +145,7 @@ module TSV
86
145
  end
87
146
  end
88
147
 
89
- def self.parse_header(stream, fix: true, header_hash: '#', sep: "\n")
148
+ def self.parse_header(stream, fix: true, header_hash: '#', sep: "\t")
90
149
  raise "Closed stream" if IO === stream && stream.closed?
91
150
 
92
151
  options = {}
@@ -131,14 +190,128 @@ module TSV
131
190
  [options, key_field, fields, first_line, preamble]
132
191
  end
133
192
 
134
- def self.parse(stream, **kwargs)
135
- options, key_field, fields, first_line, preamble = parse_header(stream)
193
+ KEY_PARAMETERS = begin
194
+ params = []
195
+ (method(:parse_line).parameters + method(:parse_stream).parameters).each do |type, name|
196
+ params << name if type == :key
197
+ end
198
+ params
199
+ end
200
+
201
+ class Parser
202
+ attr_accessor :stream, :options, :key_field, :fields, :first_line, :preamble
203
+ def initialize(file, fix: true, header_hash: "#", sep: "\t")
204
+ if IO === file
205
+ @stream = file
206
+ else
207
+ @stream = Open.open(file)
208
+ end
209
+ @options, @key_field, @fields, @first_line, @preamble = TSV.parse_header(@stream, fix:fix, header_hash:header_hash, sep:sep)
210
+ @options[:sep] = sep if @options[:sep].nil?
211
+ end
212
+
213
+ def all_fields
214
+ [@key_field] + @fields
215
+ end
216
+
217
+ def traverse(key_field: nil, fields: nil, filename: nil, namespace: nil, **kwargs, &block)
218
+ if fields
219
+ all_field_names ||= [@key_field] + @fields
220
+ positions = NamedArray.identify_name(all_field_names, fields)
221
+ kwargs[:positions] = positions
222
+ field_names = all_field_names.values_at *positions
223
+ else
224
+ field_names = @fields
225
+ end
226
+
227
+ if key_field
228
+ all_field_names ||= [@key_field] + @fields
229
+ key = NamedArray.identify_name(all_field_names, key_field)
230
+ kwargs[:key] = key
231
+ key_field_name = all_field_names[key]
232
+ if fields.nil?
233
+ field_names = all_field_names - [@key_field]
234
+ end
235
+ else
236
+ key_field_name = @key_field
237
+ end
238
+
239
+ @options.each do |option,value|
240
+ option = option.to_sym
241
+ next unless KEY_PARAMETERS.include? option
242
+ kwargs[option] = value unless kwargs.include?(option)
243
+ end
244
+
245
+ kwargs[:source_type] = @options[:type]
246
+ kwargs[:data] = false if kwargs[:data].nil?
247
+
248
+ data = TSV.parse_stream(@stream, first_line: @first_line, **kwargs, &block)
249
+
250
+ TSV.setup(data, :key_field => key_field_name, :fields => field_names, :type => @type) if data
251
+
252
+ data || self
253
+ end
254
+
255
+ end
256
+
257
+ def self.parse(stream, fix: true, header_hash: "#", sep: "\t", filename: nil, namespace: nil, **kwargs, &block)
258
+ parser = TSV::Parser.new stream, fix: fix, header_hash: header_hash, sep: sep
259
+ kwargs = parser.options.merge(kwargs)
136
260
 
137
- options.each do |option,value|
138
- option = option.to_sym
139
- kwargs[option] = value unless kwargs.include?(option)
261
+ type = kwargs[:type] ||= :double
262
+ if (data = kwargs[:data]) && data.respond_to?(:persistence_class)
263
+ TSV.setup(data, type: type)
264
+ data.extend TSVAdapter
140
265
  end
141
- data = parse_stream(stream, first_line: first_line, **kwargs)
142
- TSV.setup data, :key_field => key_field, :fields => fields
266
+
267
+ kwargs[:data] = {} if kwargs[:data].nil?
268
+
269
+ data = parser.traverse **kwargs, &block
270
+ data.type = type
271
+ data.filename = filename
272
+ data.namespace = namespace
273
+ data
143
274
  end
275
+
276
+ #def self.parse_alt(stream, key_field: nil, fields: nil, filename: nil, namespace: nil, **kwargs, &block)
277
+ # options, key_field_name, field_names, first_line, preamble = parse_header(stream)
278
+
279
+ # if fields
280
+ # all_field_names ||= [key_field_name] + field_names
281
+ # positions = NamedArray.identify_name(all_field_names, fields)
282
+ # kwargs[:positions] = positions
283
+ # field_names = all_field_names.values_at *positions
284
+ # end
285
+
286
+ # if key_field
287
+ # all_field_names ||= [key_field_name] + field_names
288
+ # key = NamedArray.identify_name(all_field_names, key_field)
289
+ # kwargs[:key] = key
290
+ # key_field_name = all_field_names[key]
291
+ # if fields.nil?
292
+ # field_names = all_field_names - [key_field_name]
293
+ # end
294
+ # end
295
+
296
+ # options.each do |option,value|
297
+ # option = option.to_sym
298
+ # next unless KEY_PARAMETERS.include? option
299
+ # kwargs[option] = value unless kwargs.include?(option)
300
+ # end
301
+
302
+ # kwargs[:source_type] = options[:type]
303
+
304
+ # type = kwargs[:type] ||= :double
305
+ # if (data = kwargs[:data]) && data.respond_to?(:persistence_class)
306
+ # TSV.setup(data, type: type, key_field: key_field_name, fields: field_names)
307
+ # data.extend TSVAdapter
308
+ # end
309
+
310
+ # data = parse_stream(stream, first_line: first_line, **kwargs, &block)
311
+
312
+ # TSV.setup(data, :key_field => key_field_name, :fields => field_names, :type => type, filename: filename, namespace: namespace)
313
+
314
+ # data
315
+ #end
316
+
144
317
  end
@@ -0,0 +1,13 @@
1
+ module Path
2
+ def tsv(...)
3
+ found = self.find
4
+ found = self.set_extension('tsv').find unless found.exists?
5
+ TSV.open(found, ...)
6
+ end
7
+
8
+ def index(...)
9
+ found = self.find
10
+ found = self.set_extension('tsv').find unless found.exists?
11
+ TSV.index(found, ...)
12
+ end
13
+ end
@@ -0,0 +1,348 @@
1
+ require_relative '../../open/lock'
2
+
3
+ module TSVAdapter
4
+ attr_accessor :persistence_path, :persistence_class, :closed, :writable
5
+
6
+ class << self
7
+ attr_accessor :lock_dir
8
+ def lock_dir
9
+ @lock_dir ||= Path.setup('tmp/tsv_locks')
10
+ end
11
+ end
12
+
13
+ EXTENSION_ATTR_HASH_KEY = "__extension_attr_hash__"
14
+ EXTENSION_ATTR_HASH_SERIALIZER = Marshal
15
+
16
+ def load_extension_attr_hash
17
+ EXTENSION_ATTR_HASH_SERIALIZER.load(self[EXTENSION_ATTR_HASH_KEY])
18
+ end
19
+
20
+ def save_extension_attr_hash
21
+ self[EXTENSION_ATTR_HASH_KEY]= EXTENSION_ATTR_HASH_SERIALIZER.dump(self.extension_attr_hash)
22
+ end
23
+
24
+ def self.extended(base)
25
+ if base.include?(EXTENSION_ATTR_HASH_KEY)
26
+ TSV.setup(base, base.load_extension_attr_hash)
27
+ elsif TSV === base
28
+ base[EXTENSION_ATTR_HASH_KEY] = EXTENSION_ATTR_HASH_SERIALIZER.dump(base.extension_attr_hash)
29
+ end
30
+
31
+ class << base
32
+ alias orig_set []=
33
+ alias orig_get []
34
+
35
+ def [](key)
36
+ self.read_lock do
37
+ load_value(super(key))
38
+ end
39
+ end
40
+
41
+ def []=(key, value)
42
+ self.write_lock do
43
+ super(key, save_value(value))
44
+ end
45
+ end
46
+ end
47
+
48
+ case base.type
49
+ when :single
50
+ class << base
51
+ def load_value(value)
52
+ value
53
+ end
54
+ def save_value(value)
55
+ value
56
+ end
57
+ end
58
+ when :list, :flat
59
+ class << base
60
+ def load_value(value)
61
+ value.nil? ? nil : value.split("\t")
62
+ end
63
+ def save_value(value)
64
+ value * "\t"
65
+ end
66
+ end
67
+ when :double
68
+ class << base
69
+ def load_value(value)
70
+ value.nil? ? nil : value.split("\t").collect{|v| v.split("|") }
71
+ end
72
+ def save_value(value)
73
+ value.collect{|v| v * "|" } * "\t"
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def keys(*args)
80
+ k = self.read_lock do
81
+ super(*args)
82
+ end
83
+
84
+ if k[0] == EXTENSION_ATTR_HASH_KEY
85
+ k.slice(1,k.length-1)
86
+ elsif k[-1] == EXTENSION_ATTR_HASH_KEY
87
+ k.slice(0,k.length-2)
88
+ else
89
+ k - [EXTENSION_ATTR_HASH_KEY]
90
+ end
91
+ end
92
+
93
+ def each(&block)
94
+ self.read_lock do
95
+ super do |k,v|
96
+ next if k == EXTENSION_ATTR_HASH_KEY
97
+ yield(k, load_value(v))
98
+ end
99
+ end
100
+ end
101
+
102
+ def collect(&block)
103
+ res = []
104
+ if block_given?
105
+ each do |k,v|
106
+ res << yield(k, v)
107
+ end
108
+ else
109
+ each do |k,v|
110
+ res << [k, v]
111
+ end
112
+ end
113
+ res
114
+ end
115
+
116
+ def values
117
+ collect{|k,v| v }
118
+ end
119
+
120
+ alias map collect
121
+
122
+ def closed?
123
+ @closed
124
+ end
125
+
126
+ def write?
127
+ @writable
128
+ end
129
+
130
+ def read?
131
+ ! (write? || closed?)
132
+ end
133
+
134
+ def write(*args)
135
+ begin
136
+ super(*args)
137
+ @writable = true
138
+ rescue NoMethodError
139
+ end
140
+ end
141
+
142
+ def close(*args)
143
+ begin
144
+ super(*args)
145
+ @closed = true
146
+ rescue NoMethodError
147
+ end
148
+ self
149
+ end
150
+
151
+ def read(*args)
152
+ begin
153
+ super(*args)
154
+ rescue NoMethodError
155
+ end
156
+ end
157
+
158
+ def delete(key)
159
+ self.write_lock do
160
+ out(key)
161
+ end
162
+ end
163
+
164
+ def lock
165
+ return yield if @locked
166
+ lock_filename = Persist.persistence_path(persistence_path, {:dir => TSVAdapter.lock_dir})
167
+ Open.lock(lock_filename) do
168
+ begin
169
+ @locked = true
170
+ yield
171
+ ensure
172
+ @locked = false
173
+ end
174
+ end
175
+ end
176
+
177
+ def lock_and_close
178
+ lock do
179
+ begin
180
+ yield
181
+ ensure
182
+ close
183
+ end
184
+ end
185
+ end
186
+
187
+ def write_and_read
188
+ if write?
189
+ begin
190
+ return yield
191
+ ensure
192
+ read
193
+ end
194
+ end
195
+
196
+ lock do
197
+ write(true) if closed? || !write?
198
+ begin
199
+ yield
200
+ ensure
201
+ read
202
+ end
203
+ end
204
+ end
205
+
206
+ def write_and_close
207
+ if write?
208
+ begin
209
+ return yield
210
+ ensure
211
+ close unless @locked
212
+ end
213
+ end
214
+
215
+ lock do
216
+ write(true) if closed? || ! write?
217
+ res = begin
218
+ yield
219
+ ensure
220
+ close
221
+ end
222
+ res
223
+ end
224
+ end
225
+
226
+ def with_read(&block)
227
+ if read? || write?
228
+ return yield
229
+ else
230
+ read_and_close &block
231
+ end
232
+ end
233
+
234
+ def with_write(&block)
235
+ if write?
236
+ return yield
237
+ else
238
+ if self.read?
239
+ self.write_and_read do
240
+ return yield
241
+ end
242
+ else
243
+ self.write_and_close do
244
+ return yield
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+
251
+ def read_and_close
252
+ if read? || write?
253
+ begin
254
+ return yield
255
+ ensure
256
+ close unless @locked
257
+ end
258
+ end
259
+
260
+ lock do
261
+ read true if closed? || ! read?
262
+ begin
263
+ yield
264
+ ensure
265
+ close
266
+ end
267
+ end
268
+ end
269
+
270
+ def read_lock
271
+ read if closed?
272
+ if read? || write?
273
+ return yield
274
+ end
275
+
276
+ lock do
277
+ close
278
+ read true
279
+ begin
280
+ yield
281
+ end
282
+ end
283
+ end
284
+
285
+ def write_lock
286
+ write if closed?
287
+ if write?
288
+ return yield
289
+ end
290
+
291
+ lock do
292
+ close
293
+ write true
294
+ begin
295
+ yield
296
+ end
297
+ end
298
+ end
299
+
300
+ def merge!(hash)
301
+ hash.each do |key,values|
302
+ self[key] = values
303
+ end
304
+ end
305
+
306
+ def range(*args)
307
+ begin
308
+ self.read_lock do
309
+ super(*args)
310
+ end
311
+ rescue
312
+ []
313
+ end
314
+ end
315
+
316
+ def include?(*args)
317
+ self.read_lock do
318
+ super(*args) #- TSV::ENTRY_KEYS.to_a
319
+ end
320
+ end
321
+
322
+ MAX_CHAR = 255.chr
323
+
324
+ def prefix(key)
325
+ self.read_lock do
326
+ range(key, 1, key + MAX_CHAR, 1)
327
+ end
328
+ end
329
+
330
+ def get_prefix(key)
331
+ keys = prefix(key)
332
+ select(:key => keys)
333
+ end
334
+
335
+ def size(*args)
336
+ self.read_lock do
337
+ super(*args)
338
+ end
339
+ end
340
+
341
+ def values_at(*keys)
342
+ self.read_lock do
343
+ keys.collect do |k|
344
+ self[k]
345
+ end
346
+ end
347
+ end
348
+ end