rbbt-util 5.38.0 → 5.38.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df9e238ba28f6bc0e16d1a22d8c9c34f7b57334f795ad9c4104ee1e689bc8fd5
4
- data.tar.gz: 61cc2c91be510161edde982567750f13abb2388cf624e15ca1e4c72633382a3b
3
+ metadata.gz: 1121593dec25c29d7986047727d555ed0e75df6b158f9f1332764ad4886462c5
4
+ data.tar.gz: c8e39ef65e23445cf5d0c8817af961a9206016c5e3665d87e042f0fadec2b8df
5
5
  SHA512:
6
- metadata.gz: a3528b56bfc0faebf62c701fcc637a43af8ffe0639a795859f56dca57749b60a3cd821941b7e7bf079cca27a9a8aa8d9d69f71235b41c1ff48e73b4292a31683
7
- data.tar.gz: dd71f1e7b233fb46d5e1210466bd6f64b0dd9162633d475f7e38bc8a057c853411bf27c35ffb3ce935f10b6e8d0055efdd7f5822adf09ff8f95a0bfa0efe8971
6
+ metadata.gz: 22c87766544a52c9c6f0d6da369422a452f553d1a61b82a54674f676a3867a6c1d29028c2efd031563f982cdadbce56d36950c8e100bd34ac2a7e95b39af8a58
7
+ data.tar.gz: 0a79edc89dad388bca9b94dfeccba1df64c4294e84c4f19743608038e55f8800181911d787980adae3ec1c715a993430ccbf2bc07d6212485b89843ada93de74
@@ -154,6 +154,8 @@ module Annotated
154
154
 
155
155
  def self.purge(object)
156
156
  case object
157
+ when Path
158
+ object
157
159
  when String
158
160
  object.respond_to?(:clean_annotations) ?
159
161
  object.clean_annotations :
data/lib/rbbt/persist.rb CHANGED
@@ -115,7 +115,7 @@ module Persist
115
115
  begin
116
116
  case (type || :marshal).to_sym
117
117
  when :path
118
- path
118
+ Path.setup(Open.read(path).strip)
119
119
  when :nil
120
120
  nil
121
121
  when :boolean
@@ -172,7 +172,7 @@ module Persist
172
172
 
173
173
  case (type || :marshal).to_sym
174
174
  when :path
175
- nil
175
+ Open.write(path, content)
176
176
  when :nil
177
177
  nil
178
178
  when :boolean
data/lib/rbbt/resource.rb CHANGED
@@ -350,6 +350,7 @@ url='#{url}'
350
350
  end
351
351
 
352
352
  def identify(path)
353
+ return path unless path.start_with?("/")
353
354
  path = File.expand_path(path)
354
355
  path += "/" if File.directory?(path)
355
356
  resource ||= Rbbt
@@ -357,6 +358,7 @@ url='#{url}'
357
358
  locations -= [:current, "current"]
358
359
  locations << :current
359
360
  search_paths = IndiferentHash.setup(resource.search_paths)
361
+ choices = []
360
362
  locations.uniq.each do |name|
361
363
  pattern = search_paths[name]
362
364
  pattern = resource.search_paths[pattern] while Symbol === pattern
@@ -370,12 +372,15 @@ url='#{url}'
370
372
  "(?:/(?<REST>.*))?/?$"
371
373
  if m = path.match(regexp)
372
374
  if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] == resource.pkgdir
373
- return self[m["TOPLEVEL"]][m["SUBPATH"]][m["REST"]]
375
+ unlocated = ([m["TOPLEVEL"],m["SUBPATH"],m["REST"]] * "/")
376
+ unlocated.gsub!(/\/+/,'/')
377
+ unlocated[self.subdir] = "" if self.subdir
378
+ choices << self.annotate(unlocated)
374
379
  end
375
380
  end
376
381
  end
377
382
  end
378
- nil
383
+ choices.sort_by{|s| s.length }.first
379
384
  end
380
385
  end
381
386
 
@@ -154,7 +154,11 @@ module TSV
154
154
  sheet1 = book.create_worksheet
155
155
  sheet1.name = sheet if sheet
156
156
 
157
- sheet1.row(0).concat fields
157
+ if fields
158
+ sheet1.row(0).concat fields if fields
159
+ else
160
+ sheet1.row(0).concat ["No field info"]
161
+ end
158
162
 
159
163
  rows.each_with_index do |cells,i|
160
164
  sheet1.row(i+1).concat cells
@@ -130,12 +130,12 @@ module TSV
130
130
  keys = parts[key_position].split(@sep2, -1)
131
131
  values = case
132
132
  when field_positions.nil?
133
- parts.tap{|o| o.delete_at key_position}
133
+ parts.tap{|o| o.delete_at key_position}
134
134
  when field_positions.empty?
135
135
  []
136
136
  else
137
137
  parts.values_at *field_positions
138
- end.collect{|value| (value.nil? || value.empty?) ? [] : value.split(@sep2, -1) }
138
+ end.collect{|value| (value.nil? || value.empty?) ? [""] : value.split(@sep2, -1) }
139
139
  [keys, values]
140
140
  end
141
141
 
@@ -432,8 +432,6 @@ def self.add_libdir(dir=nil)
432
432
 
433
433
  def self.ssh_run(server, script = nil)
434
434
  require 'rbbt/util/ssh'
435
- Log.debug "Run ssh script in #{server}:\n#{script}"
436
-
437
435
  SSHLine.ruby(server, script)
438
436
  end
439
437
 
@@ -27,6 +27,9 @@ module Misc
27
27
 
28
28
  def self.format_paragraph(text, size = 80, indent = 0, offset = 0)
29
29
  i = 0
30
+ offset = 0 if offset.nil?
31
+ indent = 0 if indent.nil?
32
+ size = 80 if size.nil?
30
33
  size = size + offset + indent
31
34
  re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/
32
35
  text.split(re).collect do |paragraph|
@@ -22,18 +22,21 @@ module IndiferentHash
22
22
  @_default ||= self.default or self.default_proc
23
23
  end
24
24
 
25
- def [](key)
26
- res = super(key)
25
+ def [](key, *args)
26
+ res = super(key, *args)
27
+ res = IndiferentHash.setup(res) if Hash === res
27
28
  return res unless res.nil? or (_default? and not keys.include? key)
28
29
 
29
30
  case key
30
31
  when Symbol, Module
31
- super(key.to_s)
32
+ res = super(key.to_s, *args)
32
33
  when String
33
- super(key.to_sym)
34
- else
35
- res
34
+ res = super(key.to_sym, *args)
36
35
  end
36
+
37
+ res = IndiferentHash.setup(res) if Hash === res
38
+
39
+ res
37
40
  end
38
41
 
39
42
  def values_at(*key_list)
@@ -275,7 +275,6 @@ module Misc
275
275
 
276
276
 
277
277
  def self.step_file?(path)
278
- return true if defined?(Step) && Step === path.resource
279
278
  return false unless path =~ /\.files(?:\/|$)/
280
279
  parts = path.split("/")
281
280
  job = parts.select{|p| p =~ /\.files$/}.first
@@ -283,9 +282,19 @@ module Misc
283
282
  i = parts.index job
284
283
  begin
285
284
  workflow, task = parts.values_at i - 2, i - 1
286
- Workflow.require_workflow workflow
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
287
296
  #return Kernel.const_get(workflow).tasks.include? task.to_sym
288
- return true
297
+ return parts[i-2..-1] * "/"
289
298
  rescue
290
299
  Log.exception $!
291
300
  end
@@ -293,6 +302,8 @@ module Misc
293
302
  false
294
303
  end
295
304
 
305
+ RBBT_IDENTIFY_PATH = ENV["RBBT_IDENTIFY_PATH"] != 'false'
306
+
296
307
  def self.obj2str(obj)
297
308
  _obj = obj
298
309
  obj = Annotated.purge(obj) if Annotated === obj
@@ -310,18 +321,21 @@ module Misc
310
321
  'false'
311
322
  when Hash
312
323
  "{"<< obj.collect{|k,v| obj2str(k) + '=>' << obj2str(v)}*"," << "}"
313
- when (defined?(Path) and Path)
324
+ when (defined?(Path) && Path)
314
325
  if defined?(Step) && Open.exists?(Step.info_file(obj))
315
326
  obj2str(Workflow.load_step(obj))
316
- elsif step_file?(obj)
317
- "Step file: " + obj
327
+ elsif step_file_path = step_file?(obj)
328
+ "Step file: " + step_file_path
318
329
  else
319
330
  if obj.exists?
331
+ obj = (obj.resource || Rbbt).identify obj if RBBT_IDENTIFY_PATH
320
332
  if obj.directory?
321
333
  files = obj.glob("**/*")
322
- "directory: #{Misc.fingerprint(files)}"
323
- else
334
+ "directory: #{Misc.fingerprint(files.collect{|f| Misc.path_relative_to(obj.find, f)}.sort)}"
335
+ elsif obj.located?
324
336
  "file: " << Open.realpath(obj) << "--" << mtime_str(obj)
337
+ else
338
+ "path: " << obj
325
339
  end
326
340
  else
327
341
  obj + " (file missing)"
@@ -111,7 +111,7 @@ module Misc
111
111
  html = if content.nil?
112
112
  "<#{ tag }#{attr_str}/>"
113
113
  else
114
- "<#{ tag }#{attr_str}>#{ content }</#{ tag }>"
114
+ "<#{ tag }#{attr_str}>#{ content.to_s }</#{ tag }>"
115
115
  end
116
116
 
117
117
  html
@@ -318,9 +318,9 @@ module Misc
318
318
  Open.mkdir dir unless Open.exists?(dir)
319
319
  into_path, into = into, Open.open(into, :mode => 'w')
320
320
  end
321
- into.sync = true if IO === into
321
+ #into.sync = true if IO === into
322
322
  into_close = false unless into.respond_to? :close
323
- io.sync = true
323
+ #io.sync = true
324
324
 
325
325
  begin
326
326
  while c = io.readpartial(BLOCK_SIZE)
@@ -402,7 +402,7 @@ module Misc
402
402
  when (IO === content or StringIO === content or File === content)
403
403
 
404
404
  Open.write(tmp_path) do |f|
405
- f.sync = true
405
+ #f.sync = true
406
406
  while block = content.read(BLOCK_SIZE)
407
407
  f.write block
408
408
  end
@@ -240,7 +240,6 @@ module Open
240
240
  end
241
241
 
242
242
  def self.find_repo_dir(file)
243
- return nil
244
243
  self.repository_dirs.each do |dir|
245
244
  dir = dir + '/' unless dir.chars[-1] == "/"
246
245
 
data/lib/rbbt/util/ssh.rb CHANGED
@@ -37,7 +37,7 @@ class SSHLine
37
37
  @complete_output = true
38
38
  end
39
39
 
40
- def cmd(command)
40
+ def run(command)
41
41
  send_cmd(command)
42
42
  @ssh.loop{ ! @complete_output}
43
43
  if @exit_status.to_i == 0
@@ -51,6 +51,7 @@ class SSHLine
51
51
  @output = ""
52
52
  @complete_output = false
53
53
  cmd = "ruby -e \"#{script.gsub('"','\\"')}\"\n"
54
+ Log.debug "Running ruby on #{@host}:\n#{ script }"
54
55
  @ch.send_data(cmd)
55
56
  @ch.send_data("echo DONECMD: $?\n")
56
57
  @ssh.loop{ !@complete_output }
@@ -61,16 +62,57 @@ class SSHLine
61
62
  end
62
63
  end
63
64
 
65
+ def rbbt(script)
66
+ rbbt_script =<<-EOF
67
+ require 'rbbt-util'
68
+ require 'rbbt/workflow'
69
+
70
+ res = begin
71
+ old_stdout = STDOUT.dup; STDOUT.reopen(STDERR)
72
+ #{script}
73
+ ensure
74
+ STDOUT.reopen(old_stdout)
75
+ end
76
+
77
+ puts Marshal.dump(res)
78
+ EOF
79
+
80
+ m = ruby(rbbt_script)
81
+ Marshal.load m
82
+ end
83
+
84
+ def workflow(workflow, script)
85
+ preamble =<<-EOF
86
+ wf = Workflow.require_workflow('#{workflow}')
87
+ EOF
88
+
89
+ rbbt(preamble + "\n" + script)
90
+ end
91
+
64
92
  @connections = {}
65
93
  def self.open(host, user = nil)
66
94
  @connections[[host, user]] ||= SSHLine.new host, user
67
95
  end
68
96
 
69
- def self.run(server, cmd)
70
- open(server).cmd(cmd)
97
+ def self.run(server, cmd, options = nil)
98
+ cmd = cmd * " " if Array === cmd
99
+ cmd += " " + CMD.process_cmd_options(options) if options
100
+ open(server).run(cmd)
71
101
  end
72
102
 
73
103
  def self.ruby(server, script)
74
104
  open(server).ruby(script)
75
105
  end
106
+
107
+ def self.rbbt(server, script)
108
+ open(server).rbbt(script)
109
+ end
110
+
111
+ def self.workflow(server, workflow, script)
112
+ open(server).workflow(workflow, script)
113
+ end
114
+
115
+ def self.command(server, command, argv = [], options = nil)
116
+ run(server, [command] + argv, options)
117
+ end
76
118
  end
@@ -99,7 +99,7 @@ STDOUT.write res.to_json
99
99
  JSON.parse(json)
100
100
  end
101
101
 
102
- def self.get_raw(url, params)
102
+ def self.get_raw(url, params = {})
103
103
  server, path = parse_url(url)
104
104
  script = path_script(path)
105
105
 
@@ -224,7 +224,7 @@ job.clean
224
224
  def self.upload_dependencies(job_list, server, search_path = 'user', produce_dependencies = false)
225
225
  server, path = parse_url(server) if server =~ /^ssh:\/\//
226
226
 
227
- job_list = [job] unless Array === job_list
227
+ job_list = [job_list] unless Array === job_list
228
228
 
229
229
  all_deps = {}
230
230
  if produce_dependencies
@@ -242,7 +242,6 @@ job.clean
242
242
  all_deps[dep] << job
243
243
  end
244
244
  end
245
- iif all_deps
246
245
 
247
246
  missing_deps = []
248
247
  all_deps.each do |dep,jobs|
@@ -250,10 +249,10 @@ job.clean
250
249
  Log.medium "Producing #{dep.workflow}:#{dep.short_path} dependency for #{Misc.fingerprint jobs}"
251
250
  dep.run(true)
252
251
  missing_deps << dep
253
- end
252
+ end if produce_dependencies
254
253
  Step.wait_for_jobs missing_deps
255
254
 
256
- migrate_dependencies = all_deps.keys.select{|d| d.done? }.collect{|d| d.path }
255
+ migrate_dependencies = all_deps.keys.collect{|d| [d] + d.rec_dependencies + d.input_dependencies }.flatten.select{|d| d.done? }.collect{|d| d.path }
257
256
  Log.medium "Migrating #{migrate_dependencies.length} dependencies from #{Misc.fingerprint job_list} to #{ server }"
258
257
  Step.migrate(migrate_dependencies, search_path, :target => server) if migrate_dependencies.any?
259
258
  end
@@ -312,7 +311,7 @@ job.clean
312
311
 
313
312
  workflow_name = job.workflow.to_s
314
313
  remote_workflow = RemoteWorkflow.new("ssh://#{server}:#{workflow_name}", "#{workflow_name}")
315
- inputs = job.recursive_inputs.to_hash.slice(*job.real_inputs.map{|i| i.to_s})
314
+ inputs = IndiferentHash.setup(job.recursive_inputs.to_hash).slice(*job.real_inputs.map{|i| i.to_s})
316
315
  Log.medium "Relaying dependency #{job.workflow}:#{job.short_path} to #{server} (#{inputs.keys * ", "})"
317
316
 
318
317
  rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, inputs)
@@ -331,6 +330,7 @@ job.clean
331
330
  if options[:migrate]
332
331
  rjobs_job.each do |rjob,job|
333
332
  rjob.produce
333
+ iif [:migrate, job]
334
334
  Step.migrate(Rbbt.identify(job.path), 'user', :source => server)
335
335
  end
336
336
  end
@@ -1,6 +1,6 @@
1
1
  class RemoteStep
2
2
  module SSH
3
- attr_accessor :override_dependencies, :run_type, :slurm_options
3
+ attr_accessor :override_dependencies, :run_type, :slurm_options, :produce_dependencies
4
4
 
5
5
  def init_job(cache_type = nil, other_params = {})
6
6
  return self if @url
@@ -52,11 +52,12 @@ class RemoteStep
52
52
  end
53
53
 
54
54
  def _run
55
- RemoteWorkflow::SSH.upload_dependencies(self, @server)
55
+ RemoteWorkflow::SSH.upload_dependencies(self, @server, 'user', @produce_dependencies)
56
56
  RemoteWorkflow::SSH.run_job(File.join(base_url, task.to_s), @input_id, @base_name)
57
57
  end
58
58
 
59
59
  def _run_slurm
60
+ RemoteWorkflow::SSH.upload_dependencies(self, @server, 'user', @produce_dependencies)
60
61
  RemoteWorkflow::SSH.run_slurm_job(File.join(base_url, task.to_s), @input_id, @base_name, @slurm_options || {})
61
62
  end
62
63
 
@@ -115,7 +116,7 @@ class RemoteStep
115
116
  select{|i| Step === i || (defined?(RemoteStep) && RemoteStep === i) } +
116
117
  inputs.values.flatten.
117
118
  select{|dep| Path === dep && Step === dep.resource }.
118
- select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
119
+ #select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
119
120
  collect{|dep| dep.resource }
120
121
  end
121
122
  end
@@ -188,6 +188,7 @@ class RemoteStep < Step
188
188
  end
189
189
 
190
190
  def file(file)
191
+ init_job
191
192
  @adaptor.get_raw(File.join(url, 'file', file.to_s))
192
193
  end
193
194
 
@@ -107,7 +107,7 @@ class Step
107
107
  canfail = ComputeDependency === job && job.canfail?
108
108
  end
109
109
 
110
- raise_dependency_error(job) if job.error? and not canfail
110
+ Step.raise_dependency_error(job) if job.error? and not canfail
111
111
  end
112
112
 
113
113
  def self.raise_dependency_error(job)
@@ -149,7 +149,7 @@ class Step
149
149
  select{|i| Step === i || (defined?(RemoteStep) && RemoteStep === i) } +
150
150
  recursive_inputs.flatten.
151
151
  select{|dep| Path === dep && Step === dep.resource }.
152
- select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
152
+ #select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
153
153
  collect{|dep| dep.resource }
154
154
  end
155
155
 
@@ -193,7 +193,7 @@ class Step
193
193
 
194
194
  if dependency.error?
195
195
  log_dependency_exec(dependency, :error)
196
- raise_dependency_error dependency
196
+ Step.raise_dependency_error dependency
197
197
  end
198
198
 
199
199
  if dependency.streaming?
@@ -382,7 +382,7 @@ class Step
382
382
 
383
383
  def run_dependencies
384
384
 
385
- rec_dependencies = self.rec_dependencies(true) + input_dependencies
385
+ rec_dependencies = self.rec_dependencies(true) + input_dependencies.reject{|d| d.started? }
386
386
 
387
387
  return if rec_dependencies.empty?
388
388
 
@@ -402,7 +402,7 @@ class Step
402
402
  seen_paths << step.path
403
403
 
404
404
  begin
405
- Step.prepare_for_execution(step) unless step == self
405
+ Step.prepare_for_execution(step) unless step == self
406
406
  rescue DependencyError, DependencyRbbtException
407
407
  raise $! unless canfail_paths.include? step.path
408
408
  end
@@ -423,6 +423,7 @@ class Step
423
423
 
424
424
  produced = []
425
425
  (dependencies + input_dependencies).each do |dep|
426
+ next if dep.started?
426
427
  next unless ComputeDependency === dep
427
428
  if dep.compute == :produce
428
429
  dep.produce
@@ -132,7 +132,7 @@ class Step
132
132
  messages
133
133
  else
134
134
  set_info(:messages, []) if self.respond_to?(:set_info)
135
- end
135
+ end || []
136
136
  end
137
137
 
138
138
  def message(message)
@@ -49,9 +49,9 @@ module Workflow
49
49
  when :nofile
50
50
  inputs[input.to_sym] = Open.realpath(file)
51
51
  when :path_array
52
- inputs[input.to_sym] = Open.read(file).strip.split("\n")
52
+ inputs[input.to_sym] = Open.read(file).strip.split("\n").collect{|p| Path.setup(p) }
53
53
  when :path
54
- inputs[input.to_sym] = Open.read(file).strip.split("\n").first
54
+ inputs[input.to_sym] = Path.setup(Open.read(file).strip.split("\n").first)
55
55
  when :io
56
56
  inputs[input.to_sym] = Open.open(Open.realpath(file))
57
57
  when :io_array
@@ -156,7 +156,7 @@ class Step
156
156
  path = path + '.as_path'
157
157
  end
158
158
  when String
159
- if Misc.is_filename?(value, false)
159
+ if Misc.is_filename?(value, true)
160
160
  value = value.dup
161
161
  value.extend Path
162
162
  return save_input(name, value, type, dir)
@@ -175,7 +175,7 @@ class Step
175
175
  path = path + '.as_path_array'
176
176
  end
177
177
  when String
178
- if Misc.is_filename?(value.first, false)
178
+ if Misc.is_filename?(value.first, true)
179
179
  path = path + '.as_path_array'
180
180
  end
181
181
  when IO
@@ -251,5 +251,4 @@ class Step
251
251
 
252
252
  inputs.keys
253
253
  end
254
-
255
254
  end
@@ -57,7 +57,12 @@ class Step
57
57
  end
58
58
 
59
59
  def workflow
60
- @workflow || info[:workflow] || (@task && @task.respond_to?(:workflow) && @task.workflow) || path.split("/")[-3]
60
+ @workflow ||= begin
61
+ wf = info[:workflow]
62
+ wf = nil if wf == ""
63
+ wf ||= @task.workflow if @task && @task.respond_to?(:workflow)
64
+ wf ||= path.split("/")[-3]
65
+ end
61
66
  end
62
67
 
63
68
 
@@ -296,7 +301,7 @@ class Step
296
301
  res = @result
297
302
  else
298
303
  join if not done?
299
- res = @path.exists? ? Persist.load_file(@path, result_type) : exec
304
+ res = @path.exists? ? Persist.load_file(@path, result_type) : run
300
305
  end
301
306
 
302
307
  if result_description
data/lib/rbbt/workflow.rb CHANGED
@@ -486,7 +486,7 @@ module Workflow
486
486
  if dep_basename.include? "."
487
487
  parts = dep_basename.split(".")
488
488
  extension = [parts.pop]
489
- while parts.last.length <= 4
489
+ while parts.length > 1 && parts.last.length <= 4
490
490
  extension << parts.pop
491
491
  end
492
492
  extension = extension.reverse * "."
@@ -84,5 +84,5 @@ if where.nil? || where == 'all' || path.search_paths.include?(where.to_sym)
84
84
  puts location
85
85
  end
86
86
  else
87
- puts RbbtSSH.command(where, $0, ARGV, options.merge("where" => :all)).read
87
+ puts SSHLine.command(where, $0, ARGV, options.merge("where" => :all))
88
88
  end
@@ -86,5 +86,5 @@ if where.nil? || where == 'all' || path.search_paths.include?(where.to_sym)
86
86
 
87
87
  puts location * "\n"
88
88
  else
89
- puts RbbtSSH.command(where, $0, ARGV, options.merge("where" => :all)).read
89
+ puts SSHLine.command(where, $0, ARGV, options.merge("where" => :all))
90
90
  end
@@ -93,6 +93,8 @@ def fix_options(workflow, task, job_options)
93
93
  TrueClass === value or %w(true TRUE T yes).include? value
94
94
  when :float
95
95
  value.to_f
96
+ when :path
97
+ Path.setup(value)
96
98
  when :integer
97
99
  value.to_i
98
100
  when :text
@@ -419,13 +421,6 @@ begin
419
421
  exit 0
420
422
  end
421
423
 
422
- if tasks = options.delete(:produce)
423
- tasks = tasks.split(",")
424
- produce_cpus = (options[:produce_cpus] || 1)
425
- puts Step.produce_dependencies(job, tasks, prepare_cpus)
426
- exit 0
427
- end
428
-
429
424
  def match_dependencies(queries, dependencies)
430
425
  queries = queries.collect{|q| q.include?("#") ? q.split("#") : q }
431
426
 
@@ -443,6 +438,50 @@ begin
443
438
  matched
444
439
  end
445
440
 
441
+ def replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay = false, run_type = :run)
442
+ jobs_to_relay.each do |job|
443
+ ComputeDependency.setup(job, :bootstrap)
444
+ next if job.done?
445
+ Log.low "Relaying #{Misc.fingerprint job} to #{server}"
446
+ jmeta = class << job; self; end
447
+
448
+ job.instance_variable_set(:@job, job)
449
+ job.instance_variable_set(:@host, server)
450
+ job.instance_variable_set(:@produce_dependencies, produce_dependencies_for_relay)
451
+
452
+ jmeta.define_method :run do |*args|
453
+ if done?
454
+ load
455
+ else
456
+ RemoteWorkflow::SSH.relay_job_list([@job], @host, :run_type => run_type, :migrate => true, :produce_dependencies => @produce_dependencies)
457
+ Step.migrate(@job, 'user', :source => @host)
458
+ load
459
+ end
460
+ end
461
+ #job.dependencies = []
462
+
463
+ #([job] + job.rec_dependencies).each do |j|
464
+ # next if job.done?
465
+ # jmeta = class << j; self; end
466
+
467
+ # j.instance_variable_set(:@job, job)
468
+ # j.instance_variable_set(:@host, server)
469
+ # j.instance_variable_set(:@produce_dependencies, produce_dependencies_for_relay)
470
+
471
+ # jmeta.define_method :run do |*args|
472
+ # if done?
473
+ # load
474
+ # else
475
+ # RemoteWorkflow::SSH.relay_job_list([@job], @host, :run_type => run_type, :migrate => true, :produce_dependencies => @produce_dependencies)
476
+ # Step.migrate(@job, 'user', :source => @host)
477
+ # load
478
+ # end
479
+ # end
480
+ #end
481
+ end
482
+ end
483
+
484
+
446
485
  if server = options.delete(:relay)
447
486
  require 'rbbt/workflow/remote_workflow'
448
487
  relay_dependencies = options.delete(:relay_dependencies).split(",")
@@ -451,7 +490,7 @@ begin
451
490
  jobs_to_relay = relay_dependencies ? match_dependencies(relay_dependencies, job.rec_dependencies) : [job]
452
491
  jobs_to_relay.reject!{|d| d.done? }
453
492
 
454
- RemoteWorkflow::SSH.relay_job_list(jobs_to_relay, server, :run_type => :run, :migrate => true, :produce_dependencies => produce_dependencies_for_relay)
493
+ replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay, :run)
455
494
  end
456
495
 
457
496
  if server = options.delete(:slurm_relay)
@@ -461,7 +500,7 @@ begin
461
500
  jobs_to_relay = relay_dependencies ? match_dependencies(relay_dependencies, job.rec_dependencies) : [job]
462
501
  jobs_to_relay.reject!{|d| d.done? }
463
502
 
464
- RemoteWorkflow::SSH.relay_job_list(jobs_to_relay, server, :run_type => :orchestrate, :migrate => true, :produce_dependencies => produce_dependencies_for_relay)
503
+ replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay, :orchestrate)
465
504
  end
466
505
 
467
506
 
@@ -483,6 +522,14 @@ begin
483
522
  end
484
523
  end
485
524
 
525
+ if tasks = options.delete(:produce)
526
+ tasks = tasks.split(",")
527
+ produce_cpus = (options[:produce_cpus] || 1)
528
+ puts Step.produce_dependencies(job, tasks, produce_cpus)
529
+ exit 0
530
+ end
531
+
532
+
486
533
  if do_fork
487
534
  ENV["RBBT_NO_PROGRESS"] = "true"
488
535
  if detach
@@ -7,6 +7,8 @@ require 'test/unit'
7
7
  module TestResource
8
8
  extend Resource
9
9
 
10
+ self.subdir = 'tmp/tmp-share/resource/TestResource/'
11
+
10
12
  claim tmp.test.google, :url, "http://google.com"
11
13
  claim tmp.test.string, :string, "TEST"
12
14
  claim tmp.test.proc, :proc do
@@ -79,8 +81,8 @@ class TestTSV < Test::Unit::TestCase
79
81
  end
80
82
 
81
83
  def test_libdir
82
- assert File.exist?(TestResource[].share.Rlib["util.R"].find(:lib))
83
- assert File.exist?(TestResource[].share.Rlib["util.R"].find)
84
+ assert File.exist?(Rbbt.share.Rlib["util.R"].find(:lib))
85
+ assert File.exist?(Rbbt.share.Rlib["util.R"].find)
84
86
  end
85
87
 
86
88
  def __test_server
@@ -100,6 +102,9 @@ class TestTSV < Test::Unit::TestCase
100
102
  assert_equal 'share/databases/DATABASE/FILE', Rbbt.identify('/usr/local/share/rbbt/databases/DATABASE/FILE')
101
103
  assert_equal 'share/databases/DATABASE/FILE', Rbbt.identify(File.join(ENV["HOME"], '.rbbt/share/databases/DATABASE/FILE'))
102
104
  assert_equal 'share/databases/DATABASE/FILE', Rbbt.identify('/usr/local/share/rbbt/databases/DATABASE/FILE')
105
+
106
+ assert_equal 'etc/somefile', TestResource.identify(TestResource.etc.somefile.find(:user))
107
+ assert_equal 'etc/somefile', TestResource.identify(TestResource.etc.somefile.find(:local))
103
108
  end
104
109
 
105
110
  end
@@ -199,13 +199,30 @@ row3 A|AA|AAA|AAA B Id3 3
199
199
 
200
200
  def test_unzip
201
201
  content =<<-EOF
202
- #Id ValueA ValueB OtherID
203
- row1 a|A b|B Id1|Id2
204
- row2 aa|aa|AA|AA b1|b2|B1|B2 Id1|Id1|Id2|Id2
202
+ #: :type=:list
203
+ #PMID:Sentence number:TF:TG Transcription Factor (Associated Gene Name) Target Gene (Associated Gene Name) Sign Negation PMID
204
+ 24265317:3:NR1H3:FASN NR1H3 FASN 24265317
205
+ 17522048:0:NR1H3:FASN NR1H3 FASN + 17522048
206
+ 19903962:0:NR1H3:FASN NR1H3 FASN 19903962
207
+ 19903962:7:NR1H3:FASN NR1H3 FASN 19903962
208
+ 22183856:4:NR1H3:FASN NR1H3 FASN 22183856
209
+ 22641099:4:NR1H3:FASN NR1H3 FASN + 22641099
210
+ 23499676:8:NR1H3:FASN NR1H3 FASN + 23499676
211
+ 11790787:5:NR1H3:FASN NR1H3 FASN 11790787
212
+ 11790787:7:NR1H3:FASN NR1H3 FASN + 11790787
213
+ 11790787:9:NR1H3:FASN NR1H3 FASN + 11790787
214
+ 11790787:11:NR1H3:FASN NR1H3 FASN 11790787
215
+ 17522048:1:NR1H3:FASN NR1H3 FASN + 17522048
216
+ 17522048:3:NR1H3:FASN NR1H3 FASN 17522048
217
+ 22160584:1:NR1H3:FASN NR1H3 FASN 22160584
218
+ 22160584:5:NR1H3:FASN NR1H3 FASN + 22160584
219
+ 22160584:8:NR1H3:FASN NR1H3 FASN + 22160584
205
220
  EOF
206
221
 
207
222
  TmpFile.with_file(content) do |filename|
208
- tsv = TSV.open(filename, :sep => /\s+/)
223
+ tsv = TSV.open(filename, :key_field => "Transcription Factor (Associated Gene Name)", :fields => ["Target Gene (Associated Gene Name)", "Sign", "PMID"], :merge => true, :type => :double)
224
+ unzip = tsv.unzip(0,true)
225
+ assert_equal unzip["NR1H3:FASN"][0].length, unzip["NR1H3:FASN"][1].length
209
226
  end
210
227
  end
211
228
 
@@ -69,5 +69,33 @@ A B C D E
69
69
  end
70
70
  end
71
71
 
72
+ def test_merge
73
+ content =<<-EOF
74
+ #: :type=:double
75
+ #PMID:Sentence number:TF:TG Transcription Factor (Associated Gene Name) Target Gene (Associated Gene Name) Sign Negation PMID
76
+ 24265317:3:NR1H3:FASN NR1H3 FASN 24265317
77
+ 17522048:0:NR1H3:FASN NR1H3 FASN + 17522048
78
+ 19903962:0:NR1H3:FASN NR1H3 FASN 19903962
79
+ 19903962:7:NR1H3:FASN NR1H3 FASN 19903962
80
+ 22183856:4:NR1H3:FASN NR1H3 FASN 22183856
81
+ 22641099:4:NR1H3:FASN NR1H3 FASN + 22641099
82
+ 23499676:8:NR1H3:FASN NR1H3 FASN + 23499676
83
+ 11790787:5:NR1H3:FASN NR1H3 FASN 11790787
84
+ 11790787:7:NR1H3:FASN NR1H3 FASN + 11790787
85
+ 11790787:9:NR1H3:FASN NR1H3 FASN + 11790787
86
+ 11790787:11:NR1H3:FASN NR1H3 FASN 11790787
87
+ 17522048:1:NR1H3:FASN NR1H3 FASN + 17522048
88
+ 17522048:3:NR1H3:FASN NR1H3 FASN 17522048
89
+ 22160584:1:NR1H3:FASN NR1H3 FASN 22160584
90
+ 22160584:5:NR1H3:FASN NR1H3 FASN + 22160584
91
+ 22160584:8:NR1H3:FASN NR1H3 FASN + 22160584
92
+ EOF
93
+
94
+ TmpFile.with_file(content) do |filename|
95
+ tsv = TSV.open(filename, :key_field => "Transcription Factor (Associated Gene Name)", :fields => ["Target Gene (Associated Gene Name)", "Sign", "PMID"], :merge => true, :type => :double)
96
+ assert_equal 16, tsv["NR1H3"]["Sign"].length
97
+ end
98
+ end
99
+
72
100
  end
73
101
 
@@ -0,0 +1,14 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestIndiferentHash < Test::Unit::TestCase
5
+ def test_recursive
6
+ a = {:a => {:b => 1 } }
7
+ IndiferentHash.setup(a)
8
+
9
+ assert IndiferentHash === a["a"]
10
+ assert_equal 1, a[:a]["b"]
11
+ assert_equal 1, a["a"][:b]
12
+ end
13
+ end
14
+
@@ -39,7 +39,7 @@ class TestCmd < Test::Unit::TestCase
39
39
  assert_nothing_raised ProcessFailed do CMD.cmd('ls -fake_option', :no_fail => true, :pipe => true) end
40
40
 
41
41
  assert_raise ProcessFailed do CMD.cmd('fake-command', :stderr => true, :pipe => true).join end
42
- assert_raise ProcessFailed do CMD.cmd('ls -fake_option', :stderr => true, :pipe => true).join end
42
+ assert_raise ConcurrentStreamProcessFailed do CMD.cmd('ls -fake_option', :stderr => true, :pipe => true).join end
43
43
  end
44
44
 
45
45
  def test_pipes
@@ -78,4 +78,10 @@ line33
78
78
  def test_bash
79
79
  puts CMD.bash("awk 'test'")
80
80
  end
81
+
82
+ def test_cmd_error
83
+ assert_raise ConcurrentStreamProcessFailed do
84
+ CMD.cmd_log("ruby -e 'puts 1; STDERR.puts 1; sleep 2; raise'")
85
+ end
86
+ end
81
87
  end
@@ -98,7 +98,7 @@ class TestOpen < Test::Unit::TestCase
98
98
  4
99
99
  EOF
100
100
  TmpFile.with_file(content) do |file|
101
- `bgzip #{file}`
101
+ `gzip #{file}`
102
102
  assert_equal(content, Open.read(file + '.gz'))
103
103
  puts content
104
104
  FileUtils.rm file + '.gz'
@@ -181,8 +181,8 @@ class TestOpen < Test::Unit::TestCase
181
181
  Misc.consume_stream(StringIO.new(text), false, file)
182
182
 
183
183
  assert_equal text, Open.read(file)
184
- assert !File.exist?(file)
185
- assert Open.exists? file
184
+ assert Open.exists?(file)
185
+ refute File.exist?(file)
186
186
  end
187
187
 
188
188
  end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
2
+ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
3
+
4
+ class TestSSH < Test::Unit::TestCase
5
+ def test_marshal
6
+
7
+ assert TrueClass === SSHLine.rbbt('turbo', 'true')
8
+ end
9
+ end
10
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.38.0
4
+ version: 5.38.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-11 00:00:00.000000000 Z
11
+ date: 2023-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -530,6 +530,7 @@ files:
530
530
  - test/rbbt/util/misc/test_communication.rb
531
531
  - test/rbbt/util/misc/test_development.rb
532
532
  - test/rbbt/util/misc/test_format.rb
533
+ - test/rbbt/util/misc/test_indiferent_hash.rb
533
534
  - test/rbbt/util/misc/test_lock.rb
534
535
  - test/rbbt/util/misc/test_multipart_payload.rb
535
536
  - test/rbbt/util/misc/test_omics.rb
@@ -556,6 +557,7 @@ files:
556
557
  - test/rbbt/util/test_semaphore.rb
557
558
  - test/rbbt/util/test_simpleDSL.rb
558
559
  - test/rbbt/util/test_simpleopt.rb
560
+ - test/rbbt/util/test_ssh.rb
559
561
  - test/rbbt/util/test_tmpfile.rb
560
562
  - test/rbbt/workflow/step/test_dependencies.rb
561
563
  - test/rbbt/workflow/step/test_save_load_inputs.rb
@@ -587,7 +589,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
587
589
  - !ruby/object:Gem::Version
588
590
  version: '0'
589
591
  requirements: []
590
- rubygems_version: 3.4.8
592
+ rubygems_version: 3.4.13
591
593
  signing_key:
592
594
  specification_version: 4
593
595
  summary: Utilities for the Ruby Bioinformatics Toolkit (rbbt)
@@ -608,6 +610,7 @@ test_files:
608
610
  - test/rbbt/util/test_procpath.rb
609
611
  - test/rbbt/util/python/test_util.rb
610
612
  - test/rbbt/util/misc/test_development.rb
613
+ - test/rbbt/util/misc/test_indiferent_hash.rb
611
614
  - test/rbbt/util/misc/test_omics.rb
612
615
  - test/rbbt/util/misc/test_pipes.rb
613
616
  - test/rbbt/util/misc/test_serialize.rb
@@ -630,6 +633,7 @@ test_files:
630
633
  - test/rbbt/util/test_excel2tsv.rb
631
634
  - test/rbbt/util/test_misc.rb
632
635
  - test/rbbt/util/test_open.rb
636
+ - test/rbbt/util/test_ssh.rb
633
637
  - test/rbbt/util/test_simpleopt.rb
634
638
  - test/rbbt/util/simpleopt/test_parse.rb
635
639
  - test/rbbt/util/simpleopt/test_setup.rb