rbbt-util 5.44.1 → 6.0.4

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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/bin/rbbt +67 -90
  4. data/bin/rbbt_exec.rb +2 -2
  5. data/etc/app.d/base.rb +2 -2
  6. data/etc/app.d/semaphores.rb +3 -3
  7. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  8. data/lib/rbbt/annotations/refactor.rb +27 -0
  9. data/lib/rbbt/annotations/util.rb +282 -282
  10. data/lib/rbbt/annotations.rb +343 -320
  11. data/lib/rbbt/association/database.rb +200 -225
  12. data/lib/rbbt/association/index.rb +294 -291
  13. data/lib/rbbt/association/item.rb +227 -227
  14. data/lib/rbbt/association/open.rb +35 -34
  15. data/lib/rbbt/association/util.rb +0 -169
  16. data/lib/rbbt/association.rb +2 -4
  17. data/lib/rbbt/entity/identifiers.rb +119 -118
  18. data/lib/rbbt/entity/refactor.rb +12 -0
  19. data/lib/rbbt/entity.rb +319 -315
  20. data/lib/rbbt/hpc/batch.rb +72 -53
  21. data/lib/rbbt/hpc/lsf.rb +2 -2
  22. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  24. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  25. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  26. data/lib/rbbt/hpc/slurm.rb +18 -18
  27. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  28. data/lib/rbbt/knowledge_base/query.rb +2 -2
  29. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  30. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  31. data/lib/rbbt/knowledge_base.rb +1 -1
  32. data/lib/rbbt/monitor.rb +36 -25
  33. data/lib/rbbt/persist/refactor.rb +166 -0
  34. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  35. data/lib/rbbt/persist/tsv.rb +187 -185
  36. data/lib/rbbt/persist.rb +556 -551
  37. data/lib/rbbt/refactor.rb +20 -0
  38. data/lib/rbbt/resource/path/refactor.rb +178 -0
  39. data/lib/rbbt/resource/path.rb +317 -497
  40. data/lib/rbbt/resource/util.rb +0 -48
  41. data/lib/rbbt/resource.rb +3 -390
  42. data/lib/rbbt/tsv/accessor.rb +2 -838
  43. data/lib/rbbt/tsv/attach.rb +303 -299
  44. data/lib/rbbt/tsv/change_id.rb +244 -245
  45. data/lib/rbbt/tsv/csv.rb +87 -85
  46. data/lib/rbbt/tsv/dumper.rb +2 -100
  47. data/lib/rbbt/tsv/excel.rb +26 -24
  48. data/lib/rbbt/tsv/field_index.rb +4 -1
  49. data/lib/rbbt/tsv/filter.rb +3 -2
  50. data/lib/rbbt/tsv/index.rb +2 -284
  51. data/lib/rbbt/tsv/manipulate.rb +750 -747
  52. data/lib/rbbt/tsv/marshal.rb +3 -3
  53. data/lib/rbbt/tsv/matrix.rb +2 -2
  54. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  55. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  56. data/lib/rbbt/tsv/parser.rb +678 -678
  57. data/lib/rbbt/tsv/refactor.rb +195 -0
  58. data/lib/rbbt/tsv/stream.rb +253 -251
  59. data/lib/rbbt/tsv/util.rb +420 -420
  60. data/lib/rbbt/tsv.rb +210 -208
  61. data/lib/rbbt/util/R/eval.rb +4 -4
  62. data/lib/rbbt/util/R/plot.rb +62 -166
  63. data/lib/rbbt/util/R.rb +21 -18
  64. data/lib/rbbt/util/cmd.rb +2 -318
  65. data/lib/rbbt/util/color.rb +269 -269
  66. data/lib/rbbt/util/colorize.rb +89 -89
  67. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  68. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  69. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  70. data/lib/rbbt/util/config.rb +169 -167
  71. data/lib/rbbt/util/filecache.rb +1 -1
  72. data/lib/rbbt/util/iruby.rb +20 -0
  73. data/lib/rbbt/util/log/progress/report.rb +241 -241
  74. data/lib/rbbt/util/log/progress/util.rb +99 -99
  75. data/lib/rbbt/util/log/progress.rb +102 -102
  76. data/lib/rbbt/util/log/refactor.rb +49 -0
  77. data/lib/rbbt/util/log.rb +486 -532
  78. data/lib/rbbt/util/migrate.rb +2 -2
  79. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  80. data/lib/rbbt/util/misc/development.rb +12 -11
  81. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  82. data/lib/rbbt/util/misc/format.rb +2 -230
  83. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  84. data/lib/rbbt/util/misc/inspect.rb +2 -476
  85. data/lib/rbbt/util/misc/lock.rb +109 -106
  86. data/lib/rbbt/util/misc/omics.rb +9 -1
  87. data/lib/rbbt/util/misc/pipes.rb +765 -793
  88. data/lib/rbbt/util/misc/refactor.rb +20 -0
  89. data/lib/rbbt/util/misc/ssw.rb +27 -17
  90. data/lib/rbbt/util/misc/system.rb +92 -105
  91. data/lib/rbbt/util/misc.rb +39 -20
  92. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  93. data/lib/rbbt/util/named_array.rb +3 -220
  94. data/lib/rbbt/util/open/refactor.rb +7 -0
  95. data/lib/rbbt/util/open.rb +3 -857
  96. data/lib/rbbt/util/procpath.rb +6 -6
  97. data/lib/rbbt/util/python/paths.rb +27 -0
  98. data/lib/rbbt/util/python/run.rb +115 -0
  99. data/lib/rbbt/util/python/script.rb +110 -0
  100. data/lib/rbbt/util/python/util.rb +3 -3
  101. data/lib/rbbt/util/python.rb +22 -81
  102. data/lib/rbbt/util/semaphore.rb +152 -148
  103. data/lib/rbbt/util/simpleopt.rb +9 -8
  104. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  105. data/lib/rbbt/util/ssh.rb +122 -118
  106. data/lib/rbbt/util/tar.rb +117 -115
  107. data/lib/rbbt/util/tmpfile.rb +69 -67
  108. data/lib/rbbt/util/version.rb +2 -0
  109. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  110. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  111. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  112. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  113. data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
  114. data/lib/rbbt/workflow/refactor.rb +150 -0
  115. data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
  116. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  117. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  118. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  119. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  120. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  121. data/lib/rbbt/workflow/step/run.rb +766 -766
  122. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  123. data/lib/rbbt/workflow/step.rb +2 -362
  124. data/lib/rbbt/workflow/task.rb +118 -118
  125. data/lib/rbbt/workflow/usage.rb +289 -287
  126. data/lib/rbbt/workflow/util/archive.rb +6 -5
  127. data/lib/rbbt/workflow/util/data.rb +1 -1
  128. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  129. data/lib/rbbt/workflow/util/trace.rb +79 -44
  130. data/lib/rbbt/workflow.rb +4 -882
  131. data/lib/rbbt-util.rb +21 -13
  132. data/lib/rbbt.rb +16 -3
  133. data/python/rbbt/__init__.py +96 -4
  134. data/python/rbbt/workflow/remote.py +104 -0
  135. data/python/rbbt/workflow.py +64 -0
  136. data/python/test.py +10 -0
  137. data/share/Rlib/plot.R +37 -37
  138. data/share/Rlib/svg.R +22 -5
  139. data/share/install/software/lib/install_helpers +1 -1
  140. data/share/rbbt_commands/hpc/list +2 -3
  141. data/share/rbbt_commands/hpc/orchestrate +4 -4
  142. data/share/rbbt_commands/hpc/tail +2 -0
  143. data/share/rbbt_commands/hpc/task +10 -7
  144. data/share/rbbt_commands/lsf/list +2 -3
  145. data/share/rbbt_commands/lsf/orchestrate +4 -4
  146. data/share/rbbt_commands/lsf/tail +2 -0
  147. data/share/rbbt_commands/lsf/task +10 -7
  148. data/share/rbbt_commands/migrate +1 -1
  149. data/share/rbbt_commands/pbs/list +2 -3
  150. data/share/rbbt_commands/pbs/orchestrate +4 -4
  151. data/share/rbbt_commands/pbs/tail +2 -0
  152. data/share/rbbt_commands/pbs/task +10 -7
  153. data/share/rbbt_commands/resource/produce +8 -1
  154. data/share/rbbt_commands/slurm/list +2 -3
  155. data/share/rbbt_commands/slurm/orchestrate +4 -4
  156. data/share/rbbt_commands/slurm/tail +2 -0
  157. data/share/rbbt_commands/slurm/task +10 -7
  158. data/share/rbbt_commands/system/clean +5 -5
  159. data/share/rbbt_commands/system/status +5 -5
  160. data/share/rbbt_commands/tsv/get +2 -3
  161. data/share/rbbt_commands/tsv/info +10 -13
  162. data/share/rbbt_commands/tsv/keys +18 -14
  163. data/share/rbbt_commands/tsv/slice +2 -2
  164. data/share/rbbt_commands/tsv/transpose +6 -2
  165. data/share/rbbt_commands/workflow/info +20 -24
  166. data/share/rbbt_commands/workflow/list +1 -1
  167. data/share/rbbt_commands/workflow/prov +20 -13
  168. data/share/rbbt_commands/workflow/retry +43 -0
  169. data/share/rbbt_commands/workflow/server +12 -2
  170. data/share/rbbt_commands/workflow/task +80 -73
  171. data/share/rbbt_commands/workflow/write_info +26 -9
  172. data/share/software/opt/ssw/ssw.c +861 -0
  173. data/share/software/opt/ssw/ssw.h +130 -0
  174. data/share/workflow_config.ru +3 -3
  175. metadata +45 -6
@@ -1,476 +1,2 @@
1
- module Misc
2
- ARRAY_MAX_LENGTH = 1000
3
- STRING_MAX_LENGTH = ARRAY_MAX_LENGTH * 100
4
- TSV_MAX_FIELDS=100
5
- TSV_MAX_ROWS=100
6
-
7
- def self.break_lines(text, char_size=80)
8
- text = text.gsub("\n", " ")
9
- lines = []
10
- line = []
11
- text.split(/([\s\-]+)/).each do |part|
12
- if line.join("").length + part.length > char_size
13
- lines << line * ""
14
- line = []
15
- end
16
- line << part
17
- end
18
-
19
- lines << line * ""
20
-
21
- lines.flatten.collect{|l| l.strip} * "\n"
22
- end
23
-
24
- def self.name2basename(file)
25
- sanitize_filename(file.gsub("/",'>').gsub("~", '-'))
26
- end
27
-
28
- def self.sanitize_filename(filename, length = 254)
29
- if filename.length > length
30
- if filename =~ /(\..{2,9})$/
31
- extension = $1
32
- else
33
- extension = ''
34
- end
35
-
36
- post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension
37
-
38
- filename = filename[0..(length - post_fix.length - 1)] << post_fix
39
- else
40
- filename
41
- end
42
- filename
43
- end
44
-
45
- def self.fingerprint(obj)
46
- case obj
47
- when nil
48
- "nil"
49
- when (defined? Step and Step)
50
- "<Step:" << (obj.short_path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
51
- when TrueClass
52
- "true"
53
- when FalseClass
54
- "false"
55
- when Symbol
56
- ":" << obj.to_s
57
- when String
58
- if obj.length > 100
59
- digest = Misc.digest(obj)
60
- "'" << obj.slice(0,30) << "<...#{obj.length} - #{digest[0..4]}...>" << obj.slice(-10,30)<< "'"
61
- else
62
- "'" << obj << "'"
63
- end
64
- when (defined? AnnotatedArray and AnnotatedArray)
65
- "<A: #{fingerprint Annotated.purge(obj)} #{fingerprint obj.info}>"
66
- when (defined? TSV and TSV::Parser)
67
- filename = obj.filename
68
- filename = "STDIN(#{rand})" if filename == '-'
69
- "<TSVStream:" + (filename || "NOFILENAME") + "--" << Misc.fingerprint(obj.options) << ">"
70
- when IO
71
- (obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect + rand(100000)) + ">" : obj.inspect
72
- when File
73
- "<File:" + obj.path + ">"
74
- when NamedArray
75
- fields = obj.fields
76
- fields = fields.collect if NamedArray === fields
77
- "[<NamedArray: fields=#{fingerprint fields} -- values=#{fingerprint obj[0..-1]}]"
78
- when Array
79
- if (length = obj.length) > 10
80
- "[#{length}--" << (obj.values_at(0,1, length / 2, -2, -1).collect{|e| fingerprint(e)} * ",") << "]"
81
- else
82
- "[" << (obj.collect{|e| fingerprint(e) } * ", ") << "]"
83
- end
84
- when (defined? TSV and TSV)
85
- obj.with_unnamed do
86
- "TSV:{"<< fingerprint(obj.all_fields|| []) << ";" << fingerprint(obj.keys) << "}"
87
- end
88
- when Hash
89
- if obj.length > 10
90
- "H:{"<< fingerprint(obj.keys) << ";" << fingerprint(obj.values) << "}"
91
- else
92
- new = "{"
93
- obj.each do |k,v|
94
- new << fingerprint(k) << '=>' << fingerprint(v) << ' '
95
- end
96
- if new.length > 1
97
- new[-1] = "}"
98
- else
99
- new << '}'
100
- end
101
- new
102
- end
103
- when Float
104
- if obj.abs > 10
105
- "%.1f" % obj
106
- elsif obj.abs > 1
107
- "%.3f" % obj
108
- else
109
- "%.6f" % obj
110
- end
111
- else
112
- obj.to_s
113
- end
114
- end
115
-
116
-
117
- def self.remove_long_items(obj)
118
- case
119
- when IO === obj
120
- remove_long_items("IO: " + (obj.respond_to?(:filename) ? (obj.filename || obj.inspect) : obj.inspect ))
121
- when obj.respond_to?(:path)
122
- remove_long_items("File: " + obj.path)
123
- when TSV::Parser === obj
124
- filename = obj.filename
125
- filename = "STDIN(rand-#{rand(10000000)})" if filename == '-'
126
- remove_long_items("TSV Stream: " + filename + " -- " << Misc.fingerprint(obj.options))
127
- when TSV === obj
128
- tsv = obj
129
- fields = tsv.fields
130
-
131
- if obj.size > TSV_MAX_ROWS
132
- tsv = obj.head(TSV_MAX_ROWS)
133
- tsv["Truncated rows at #{TSV_MAX_ROWS} (#{obj.size})"] = nil
134
- end
135
-
136
- if fields && fields.length > TSV_MAX_FIELDS
137
- tsv = obj.slice(fields[0..TSV_MAX_ROWS-1])
138
- tsv.add_field "Truncated at #{TSV_MAX_ROWS} (#{fields.length})" do
139
- nil
140
- end
141
- elsif fields.nil?
142
- new = tsv.annotate({})
143
- tsv.each do |k,v|
144
- new[k] = Misc.remove_long_items(v)
145
- end
146
- tsv = new
147
- end
148
-
149
- tsv
150
- when (Array === obj and obj.length > ARRAY_MAX_LENGTH)
151
- remove_long_items(obj[0..ARRAY_MAX_LENGTH-2] << "TRUNCATED at #{ ARRAY_MAX_LENGTH }/#{obj.length}")
152
- when (Hash === obj and obj.length > ARRAY_MAX_LENGTH)
153
- remove_long_items(obj.collect.compact[0..ARRAY_MAX_LENGTH-2] << ["TRUNCATED", "at #{ ARRAY_MAX_LENGTH }/#{obj.length}"])
154
- when (String === obj and obj.length > STRING_MAX_LENGTH)
155
- obj[0..STRING_MAX_LENGTH-1] << " TRUNCATED at #{STRING_MAX_LENGTH}/#{obj.length}"
156
- when Hash === obj
157
- new = {}
158
- obj.each do |k,v|
159
- new[k] = remove_long_items(v)
160
- end
161
- new
162
- when Array === obj
163
- obj.collect do |e| remove_long_items(e) end
164
- else
165
- obj
166
- end
167
- end
168
-
169
- def self.digest(text)
170
- Digest::MD5.hexdigest(text)
171
- end
172
-
173
- def self.sample_large_obj(obj, max = 100)
174
- length = obj.length
175
- head = obj[0..max/2]
176
- tail = obj[-max/2..-1]
177
- middle = (1..9).to_a.collect{|i| pos = (length / 10) * i + i; obj[pos-1..pos+1]}.flatten
178
- if Array === obj
179
- head + middle + tail + ["LENGTH: #{obj.length}"]
180
- else
181
- head << "..." << middle*"," << "..." << tail << "(#{obj.length})"
182
- end
183
- end
184
-
185
- HASH2MD5_MAX_STRING_LENGTH = 1000
186
- HASH2MD5_MAX_ARRAY_LENGTH = 100
187
- def self.hash2md5(hash)
188
- return "" if hash.nil? or hash.empty?
189
-
190
- str = ""
191
- keys = hash.keys
192
- keys = keys.clean_annotations if keys.respond_to? :clean_annotations
193
- keys = keys.sort_by{|k| k.to_s}
194
-
195
- if hash.respond_to? :unnamed
196
- unnamed = hash.unnamed
197
- hash.unnamed = true
198
- end
199
-
200
-
201
- keys.each do |k|
202
- next if k == :monitor or k == "monitor" or k == :in_situ_persistence or k == "in_situ_persistence"
203
- _v = hash[k]
204
- _k = k
205
- v = TSV === _v ? _v : Annotated.purge(_v)
206
- k = Annotated.purge(k)
207
-
208
- case
209
- when TrueClass === v
210
- str << k.to_s << "=>true"
211
- when FalseClass === v
212
- str << k.to_s << "=>false"
213
- when TSV === v
214
- str << k.to_s << "=>" << obj2md5(v)
215
- when Hash === v
216
- str << k.to_s << "=>" << hash2md5(v)
217
- when Symbol === v
218
- str << k.to_s << "=>" << v.to_s
219
- when (String === v and v.length > HASH2MD5_MAX_STRING_LENGTH)
220
- #str << k.to_s << "=>" << v[0..HASH2MD5_MAX_STRING_LENGTH] << v[v.length-3..v.length+3] << v[-3..-1] << "; #{ v.length }"
221
- str << k.to_s << "=>" << v[0..HASH2MD5_MAX_STRING_LENGTH] << "; #{ v.length }"
222
- when String === v
223
- str << k.to_s << "=>" << v
224
- when (Array === v and v.length > HASH2MD5_MAX_ARRAY_LENGTH)
225
- #str << k.to_s << "=>[" << (v[0..HASH2MD5_MAX_ARRAY_LENGTH] + v[v.length-3..v.length+3] + v[-3..-1]) * "," << "; #{ v.length }]"
226
- str << k.to_s << "=>[" << v[0..HASH2MD5_MAX_ARRAY_LENGTH] * "," << "; #{ v.length }]"
227
- when TSV::Parser === v
228
- str << remove_long_items(v)
229
- when Array === v
230
- str << k.to_s << "=>[" << v * "," << "]"
231
- when File === v
232
- str << k.to_s << "=>[File:" << v.path << "]"
233
- else
234
- begin
235
- v_ins = v.inspect
236
- rescue
237
- v_ins = "#Object:" << v.object_id.to_s
238
- end
239
-
240
- case
241
- when v_ins =~ /:0x0/
242
- str << k.to_s << "=>" << v_ins.sub(/:0x[a-f0-9]+@/,'')
243
- else
244
- str << k.to_s << "=>" << v_ins
245
- end
246
- end
247
-
248
- if _v and defined? Annotated and Annotated === _v and not (defined? AssociationItem and AssociationItem === _v)
249
- info = _v.info
250
- info = Annotated.purge(info)
251
- str << "_" << hash2md5(info)
252
- end
253
- end
254
- hash.unnamed = unnamed if hash.respond_to? :unnamed
255
-
256
- if str.empty?
257
- ""
258
- else
259
- digest(str)
260
- end
261
- end
262
-
263
- def self.txt_digest_str(txt)
264
- "digest: " << digest(txt)
265
- end
266
-
267
- def self.mtime_str(path)
268
- path = path.find if Path === path
269
- if File.exist? path
270
- "mtime: " << File.mtime(path).to_s
271
- else
272
- "mtime: not present"
273
- end
274
- end
275
-
276
-
277
- def self.step_file?(path)
278
- return false unless path =~ /\.files(?:\/|$)/
279
- parts = path.split("/")
280
- job = parts.select{|p| p =~ /\.files$/}.first
281
- if job
282
- i = parts.index job
283
- begin
284
- workflow, task = parts.values_at i - 2, i - 1
285
- _loaded = false
286
- begin
287
- Kernel.const_get(workflow)
288
- rescue
289
- if ! _loaded
290
- Workflow.require_workflow workflow
291
- _loaded = true
292
- retry
293
- end
294
- raise $!
295
- end
296
- #return Kernel.const_get(workflow).tasks.include? task.to_sym
297
- return parts[i-2..-1] * "/"
298
- rescue
299
- Log.exception $!
300
- end
301
- end
302
- false
303
- end
304
-
305
- RBBT_IDENTIFY_PATH = ENV["RBBT_IDENTIFY_PATH"] != 'false'
306
-
307
- def self.obj2str(obj)
308
- _obj = obj
309
- obj = Annotated.purge(obj) if Annotated === obj
310
-
311
- str = case obj
312
- when nil
313
- 'nil'
314
- when Numeric
315
- Float === obj && obj % 1 == 0 ? obj.to_i.to_s : obj.to_s
316
- when Symbol
317
- obj.to_s
318
- when TrueClass
319
- 'true'
320
- when FalseClass
321
- 'false'
322
- when Hash
323
- "{"<< obj.collect{|k,v| obj2str(k) + '=>' << obj2str(v)}*"," << "}"
324
- when (defined?(Path) && Path)
325
- if defined?(Step) && Open.exists?(Step.info_file(obj))
326
- obj2str(Workflow.load_step(obj))
327
- elsif step_file_path = step_file?(obj)
328
- "Step file: " + step_file_path
329
- else
330
- if obj.exists?
331
- obj = (obj.resource || Rbbt).identify obj if RBBT_IDENTIFY_PATH
332
- if obj.directory?
333
- files = obj.glob("**/*")
334
- "directory: #{Misc.fingerprint(files.collect{|f| Misc.path_relative_to(obj.find, f)}.sort)}"
335
- elsif obj.located?
336
- "file: " << Open.realpath(obj) << "--" << mtime_str(obj)
337
- else
338
- "path: " << obj
339
- end
340
- else
341
- obj + " (file missing)"
342
- end
343
- end
344
- when String
345
- good_filename = Misc.is_filename?(obj, false) && ! %w(. ..).include?(obj) && %w(. /).include?(obj[0])
346
- if good_filename
347
- obj = obj.dup
348
- obj.extend Path
349
- obj2str obj
350
- else
351
- obj = obj.chomp if String === obj
352
- if obj.length > HASH2MD5_MAX_STRING_LENGTH
353
- sample_large_obj(obj, HASH2MD5_MAX_STRING_LENGTH) << "--" << txt_digest_str(obj)
354
- else
355
- obj
356
- end
357
- end
358
- when Array
359
- if obj.length > HASH2MD5_MAX_ARRAY_LENGTH
360
- "[" << sample_large_obj(obj, HASH2MD5_MAX_ARRAY_LENGTH).collect{|v| obj2str(v.nil? ? "" : v) } * "," << "]"
361
- else
362
- "[" << obj.collect{|v| obj2str(v.nil? ? "" : v) } * "," << "]"
363
- end
364
- when TSV::Parser
365
- remove_long_items(obj)
366
- when File
367
- if obj.respond_to? :filename and obj.filename
368
- if defined?(Step) && Open.exists?(Step.info_file(obj.filename))
369
- obj2str(Workflow.load_step(obj.filename))
370
- else
371
- "<IO:" << obj.filename << "--" << mtime_str(obj.filename) << ">"
372
- end
373
- else
374
- "<IO:" << obj.path << "--" << mtime_str(obj.path) << ">"
375
- end
376
- when (defined? Step and Step)
377
- "<IO:" << obj.short_path_real << ">"
378
- when IO
379
- if obj.respond_to? :filename and obj.filename
380
- if defined?(Step) && Open.exists?(Step.info_file(obj.filename))
381
- obj2str(Workflow.load_step(obj.filename))
382
- else
383
- "<IO:" << obj.filename << "--" << mtime_str(obj.filename) << ">"
384
- end
385
- else
386
-
387
- if obj.respond_to? :obj2str
388
- obj.obj2str
389
- else
390
- class << obj
391
- attr_accessor :obj2str
392
- end
393
- obj.obj2str = obj.inspect + rand(1000000).to_s
394
- end
395
- end
396
- else
397
- if obj.respond_to? :filename and obj.filename
398
- "<IO:" << obj.filename << "--" << mtime_str(obj.filename) << ">"
399
- else
400
- obj_ins = obj.inspect
401
- obj_str = if obj_ins =~ /:0x0/
402
- obj_ins.gsub(/:0x[a-f0-9]+/,'')
403
- else
404
- obj_ins
405
- end
406
- end
407
- end
408
-
409
- if defined? Annotated and Annotated === _obj and not (defined? AssociationItem and AssociationItem === _obj)
410
- info = Annotated.purge(_obj.info)
411
- str << "_" << obj2str(info)
412
- end
413
-
414
- str
415
- end
416
-
417
-
418
- def self.obj2digest(obj)
419
- str = obj2str(obj)
420
-
421
- if str.empty?
422
- ""
423
- else
424
- digest(str)
425
- end
426
- end
427
-
428
- def self.obj2md5(obj)
429
- obj2digest(obj)
430
- end
431
-
432
- def self.file2md5(file)
433
- if File.exist?(file + '.md5')
434
- Open.read(file + '.md5')
435
- else
436
- md5 = CMD.cmd("md5sum '#{file}'").read.strip.split(" ").first
437
- begin
438
- Open.write(file + '.md5', md5)
439
- rescue
440
- end
441
- md5
442
- end
443
- end
444
-
445
- def self.get_filename(obj)
446
- if obj.respond_to? :filename
447
- obj.filename
448
- elsif obj.respond_to? :path
449
- obj.path
450
- elsif (Path === obj || (String === obj && Misc.is_filename?(obj)))
451
- obj
452
- else
453
- nil
454
- end
455
- end
456
-
457
- def self.scan_version_text(text, cmd = nil)
458
- text = Misc.fixutf8 text
459
- cmd = "NOCMDGIVE" if cmd.nil? || cmd.empty?
460
- text.split("\n").each do |line|
461
- next unless line =~ /\W#{cmd}\W/i
462
- m = line.match(/(v(?:\d+\.)*\d+(?:-[a-z_]+)?)/i)
463
- return m[1] if m
464
- m = line.match(/((?:\d+\.)*\d+(?:-[a-z_]+)?v)/i)
465
- return m[1] if m
466
- next unless line =~ /\Wversion\W/i
467
- m = line.match(/((?:\d+\.)*\d+(?:-[a-z_]+)?)/i)
468
- return m[1] if m
469
- end
470
- m = text.match(/(?:version.*?|#{cmd}.*?|#{cmd.to_s.split(/[-_.]/).first}.*?|v)((?:\d+\.)*\d+(?:-[a-z_]+)?)/i)
471
- return m[1] if m
472
- m = text.match(/(?:#{cmd}.*(v.*|.*v))/i)
473
- return m[1] if m
474
- nil
475
- end
476
- end
1
+ require_relative '../../refactor'
2
+ Rbbt.require_instead 'scout/log'
@@ -1,106 +1,109 @@
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 = 2
7
- Lockfile.max_age = 30
8
- Lockfile.suspend = 4
9
- else
10
- Log.medium "De-activating lockfile ids"
11
- Lockfile.dont_use_lock_id = true
12
- Lockfile.refresh = 4
13
- Lockfile.max_age = 60
14
- Lockfile.suspend = 8
15
- end
16
- end
17
-
18
- self.use_lock_id = ENV["RBBT_NO_LOCKFILE_ID"] != "true"
19
-
20
- LOCK_MUTEX = Mutex.new
21
- def self.lock(file, unlock = true, options = {})
22
- unlock, options = true, unlock if Hash === unlock
23
- return yield if file.nil? and not Lockfile === options[:lock]
24
-
25
- file = file.find if Path === file
26
- FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exist? File.dirname(File.expand_path(file))
27
-
28
-
29
- begin
30
- case options[:lock]
31
- when Lockfile
32
- lockfile = options[:lock]
33
- lockfile.lock unless lockfile.locked?
34
- when FalseClass
35
- lockfile = nil
36
- unlock = false
37
- when Path, String
38
- lock_path = options[:lock].find
39
- lockfile = Lockfile.new(lock_path, options)
40
- lockfile.lock
41
- else
42
- lock_path = File.expand_path(file + '.lock')
43
- lockfile = Lockfile.new(lock_path, options)
44
- lockfile.lock
45
- end
46
- rescue Aborted, Interrupt
47
- raise LockInterrupted
48
- end
49
-
50
- res = nil
51
-
52
- begin
53
- res = yield lockfile
54
- rescue KeepLocked
55
- unlock = false
56
- res = $!.payload
57
- ensure
58
- if unlock
59
- begin
60
- if lockfile.locked?
61
- lockfile.unlock
62
- else
63
- end
64
- rescue Exception
65
- Log.warn "Exception unlocking: #{lockfile.path}"
66
- Log.exception $!
67
- end
68
- end
69
- end
70
-
71
- res
72
- end
73
-
74
-
75
- LOCK_REPO_SERIALIZER=Marshal
76
- def self.lock_in_repo(repo, key, *args)
77
- return yield file, *args if repo.nil? or key.nil?
78
-
79
- lock_key = "lock-" << key
80
-
81
- begin
82
- if repo[lock_key] and
83
- Misc.hostname == (info = LOCK_REPO_SERIALIZER.load(repo[lock_key]))["host"] and
84
- info["pid"] and not Misc.pid_exists?(info["pid"])
85
-
86
- Log.info("Removing lockfile: #{lock_key}. This pid #{Process.pid}. Content: #{info.inspect}")
87
- repo.out lock_key
88
- end
89
- rescue
90
- Log.warn("Error checking lockfile #{lock_key}: #{$!.message}. Removing. Content: #{begin repo[lock_key] rescue "Could not open file" end}")
91
- repo.out lock_key if repo.include? lock_key
92
- end
93
-
94
- while repo[lock_key]
95
- sleep 1
96
- end
97
-
98
- repo[lock_key] = LOCK_REPO_SERIALIZER.dump({:hostname => Misc.hostname, :pid => Process.pid})
99
-
100
- res = yield lock_key, *args
101
-
102
- repo.delete lock_key
103
-
104
- res
105
- end
106
- end
1
+ require_relative '../../refactor'
2
+ Rbbt.require_instead 'scout/open/lock'
3
+ require_relative 'refactor'
4
+ #module Misc
5
+ # def self.use_lock_id=(use = true)
6
+ # if use
7
+ # Log.medium "Activating lockfile ids"
8
+ # Lockfile.dont_use_lock_id = false
9
+ # Lockfile.refresh = 2
10
+ # Lockfile.max_age = 30
11
+ # Lockfile.suspend = 4
12
+ # else
13
+ # Log.medium "De-activating lockfile ids"
14
+ # Lockfile.dont_use_lock_id = true
15
+ # Lockfile.refresh = 4
16
+ # Lockfile.max_age = 60
17
+ # Lockfile.suspend = 8
18
+ # end
19
+ # end
20
+ #
21
+ # self.use_lock_id = ENV["RBBT_NO_LOCKFILE_ID"] != "true"
22
+ #
23
+ # LOCK_MUTEX = Mutex.new
24
+ # def self.lock(file, unlock = true, options = {})
25
+ # unlock, options = true, unlock if Hash === unlock
26
+ # return yield if file.nil? and not Lockfile === options[:lock]
27
+ #
28
+ # file = file.find if Path === file
29
+ # FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exist? File.dirname(File.expand_path(file))
30
+ #
31
+ #
32
+ # begin
33
+ # case options[:lock]
34
+ # when Lockfile
35
+ # lockfile = options[:lock]
36
+ # lockfile.lock unless lockfile.locked?
37
+ # when FalseClass
38
+ # lockfile = nil
39
+ # unlock = false
40
+ # when Path, String
41
+ # lock_path = options[:lock].find
42
+ # lockfile = Lockfile.new(lock_path, options)
43
+ # lockfile.lock
44
+ # else
45
+ # lock_path = File.expand_path(file + '.lock')
46
+ # lockfile = Lockfile.new(lock_path, options)
47
+ # lockfile.lock
48
+ # end
49
+ # rescue Aborted, Interrupt
50
+ # raise LockInterrupted
51
+ # end
52
+ #
53
+ # res = nil
54
+ #
55
+ # begin
56
+ # res = yield lockfile
57
+ # rescue KeepLocked
58
+ # unlock = false
59
+ # res = $!.payload
60
+ # ensure
61
+ # if unlock
62
+ # begin
63
+ # if lockfile.locked?
64
+ # lockfile.unlock
65
+ # else
66
+ # end
67
+ # rescue Exception
68
+ # Log.warn "Exception unlocking: #{lockfile.path}"
69
+ # Log.exception $!
70
+ # end
71
+ # end
72
+ # end
73
+ #
74
+ # res
75
+ # end
76
+ #
77
+ #
78
+ # LOCK_REPO_SERIALIZER=Marshal
79
+ # def self.lock_in_repo(repo, key, *args)
80
+ # return yield file, *args if repo.nil? or key.nil?
81
+ #
82
+ # lock_key = "lock-" << key
83
+ #
84
+ # begin
85
+ # if repo[lock_key] and
86
+ # Misc.hostname == (info = LOCK_REPO_SERIALIZER.load(repo[lock_key]))["host"] and
87
+ # info["pid"] and not Misc.pid_exists?(info["pid"])
88
+ #
89
+ # Log.info("Removing lockfile: #{lock_key}. This pid #{Process.pid}. Content: #{info.inspect}")
90
+ # repo.out lock_key
91
+ # end
92
+ # rescue
93
+ # Log.warn("Error checking lockfile #{lock_key}: #{$!.message}. Removing. Content: #{begin repo[lock_key] rescue "Could not open file" end}")
94
+ # repo.out lock_key if repo.include? lock_key
95
+ # end
96
+ #
97
+ # while repo[lock_key]
98
+ # sleep 1
99
+ # end
100
+ #
101
+ # repo[lock_key] = LOCK_REPO_SERIALIZER.dump({:hostname => Misc.hostname, :pid => Process.pid})
102
+ #
103
+ # res = yield lock_key, *args
104
+ #
105
+ # repo.delete lock_key
106
+ #
107
+ # res
108
+ # end
109
+ #end