rbbt-util 5.28.9 → 5.28.10

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbbt/entity.rb +1 -1
  3. data/lib/rbbt/fix_width_table.rb +5 -4
  4. data/lib/rbbt/persist.rb +1 -1
  5. data/lib/rbbt/persist/tsv/adapter.rb +0 -1
  6. data/lib/rbbt/persist/tsv/fix_width_table.rb +5 -3
  7. data/lib/rbbt/tsv/dumper.rb +6 -2
  8. data/lib/rbbt/util/cmd.rb +1 -0
  9. data/lib/rbbt/util/misc/bgzf.rb +1 -1
  10. data/lib/rbbt/util/named_array.rb +1 -1
  11. data/lib/rbbt/util/open.rb +17 -16
  12. data/lib/rbbt/workflow/definition.rb +2 -1
  13. data/lib/rbbt/workflow/integration/ansible.rb +53 -0
  14. data/lib/rbbt/workflow/integration/ansible/workflow.rb +60 -0
  15. data/lib/rbbt/workflow/step.rb +5 -0
  16. data/lib/rbbt/workflow/step/accessor.rb +1 -1
  17. data/lib/rbbt/workflow/util/archive.rb +2 -0
  18. data/lib/rbbt/workflow/util/orchestrator.rb +22 -9
  19. data/share/rbbt_commands/ansible +55 -0
  20. data/share/rbbt_commands/purge_job +0 -1
  21. data/share/rbbt_commands/workflow/forget_deps +9 -0
  22. data/test/rbbt/association/test_index.rb +6 -6
  23. data/test/rbbt/knowledge_base/test_query.rb +3 -3
  24. data/test/rbbt/knowledge_base/test_registry.rb +1 -1
  25. data/test/rbbt/persist/tsv/test_cdb.rb +0 -7
  26. data/test/rbbt/persist/tsv/test_kyotocabinet.rb +2 -8
  27. data/test/rbbt/persist/tsv/test_leveldb.rb +0 -6
  28. data/test/rbbt/persist/tsv/test_lmdb.rb +0 -6
  29. data/test/rbbt/persist/tsv/test_tokyocabinet.rb +15 -14
  30. data/test/rbbt/test_entity.rb +0 -1
  31. data/test/rbbt/test_knowledge_base.rb +3 -4
  32. data/test/rbbt/test_persist.rb +10 -6
  33. data/test/rbbt/test_workflow.rb +17 -16
  34. data/test/rbbt/tsv/test_accessor.rb +11 -0
  35. data/test/rbbt/tsv/test_attach.rb +0 -2
  36. data/test/rbbt/tsv/test_index.rb +6 -7
  37. data/test/rbbt/tsv/test_manipulate.rb +2 -3
  38. data/test/rbbt/util/R/test_model.rb +2 -1
  39. data/test/rbbt/util/R/test_plot.rb +0 -2
  40. data/test/rbbt/util/concurrency/test_processes.rb +1 -1
  41. data/test/rbbt/util/misc/test_bgzf.rb +11 -7
  42. data/test/rbbt/util/misc/test_lock.rb +0 -1
  43. data/test/rbbt/util/misc/test_multipart_payload.rb +1 -1
  44. data/test/rbbt/util/misc/test_pipes.rb +0 -5
  45. data/test/rbbt/util/test_R.rb +1 -0
  46. data/test/rbbt/util/test_log.rb +4 -6
  47. data/test/rbbt/util/test_misc.rb +0 -2
  48. data/test/rbbt/util/test_open.rb +0 -1
  49. data/test/rbbt/util/test_python.rb +17 -1
  50. data/test/rbbt/workflow/test_remote_workflow.rb +1 -1
  51. data/test/rbbt/workflow/test_step.rb +8 -3
  52. data/test/rbbt/workflow/util/test_orchestrator.rb +50 -0
  53. metadata +5 -4
  54. data/test/rbbt/workflow/remote/test_client.rb +0 -56
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fa2f71df9aef8810599ab3660c847c084dea75ccb2485d294cfa1962e341162
4
- data.tar.gz: 7eb004ddf8bcf30b00325dc5251d9ed73a307de433c18c0847eb4d70a4bea1e2
3
+ metadata.gz: 443812f3080048a2e39b95ceda4fda2b3f403788c4d32ae4822b0b6920ac1d1f
4
+ data.tar.gz: e586076cca9dbd72b9dae8ba8be0061269e9bef5d04163f382f2d3b3f353d1b8
5
5
  SHA512:
6
- metadata.gz: 6ba23322f9ac768f1782c4e26605c50171b6d35d1d3c2acc0ef195e26ca39af851a232e1581ca2ec220899b7780f35f8d0d36e1f61f0b0e6500c883999c3760b
7
- data.tar.gz: afa0952f228a951ea78506ad0776fd96dbfbd2b91bac73310ee6807e4a7d0a74c7ca8f582880c5abd28bbf709c8be3d9dff1797056be756962091b2e97031f30
6
+ metadata.gz: ca6ea9a139a48dfcc76fb04b889d45881d023e9f6fda362da0bb7bd4c63b31217ca0a9bb9f4702186c78b741a1eb1b5c7ca2607512e6dced51026081bdcb8aa7
7
+ data.tar.gz: 76f021c8d565e2833506f17fb54436d0fe80d29d8bface099cece0445cb70718f8f2126e6fa6eb139f6555e33fe9382d1401339aacb100073bb4964c62f1a260
@@ -38,7 +38,7 @@ module Entity
38
38
  if value.to_s == k.to_s
39
39
  found = k
40
40
  break
41
- elsif value =~ /\(#{Regexp.quote k}\)/
41
+ elsif value.to_s =~ /\(#{Regexp.quote k}\)/
42
42
  found = k
43
43
  break
44
44
  end
@@ -67,7 +67,7 @@ class FixWidthTable
67
67
 
68
68
  def format(pos, value)
69
69
  padding = value_size - value.length
70
- if range
70
+ if @range
71
71
  (pos + [padding, value + ("\0" * padding)]).pack("llll#{mask}")
72
72
  else
73
73
  [pos, padding, value + ("\0" * padding)].pack("ll#{mask}")
@@ -105,7 +105,7 @@ class FixWidthTable
105
105
 
106
106
  def idx_value(index)
107
107
  return nil if index < 0 or index >= size
108
- @file.seek((range ? 17 : 9 ) + (record_size) * index, IO::SEEK_SET)
108
+ @file.seek((@range ? 17 : 9 ) + (record_size) * index, IO::SEEK_SET)
109
109
  padding = @file.read(4).unpack("l").first+1
110
110
  txt = @file.read(value_size)
111
111
  str = txt.unpack(mask).first
@@ -277,7 +277,8 @@ class FixWidthTable
277
277
 
278
278
  def [](pos)
279
279
  return [] if size == 0
280
- if range
280
+ self.read
281
+ if @range
281
282
  get_range(pos)
282
283
  else
283
284
  get_point(pos)
@@ -286,7 +287,7 @@ class FixWidthTable
286
287
 
287
288
  def overlaps(pos, value = false)
288
289
  return [] if size == 0
289
- idxs = if range
290
+ idxs = if @range
290
291
  get_range(pos, true)
291
292
  else
292
293
  get_point(pos, true)
@@ -25,7 +25,7 @@ module Persist
25
25
  MEMORY = {} unless defined? MEMORY
26
26
  MAX_FILE_LENGTH = 150
27
27
 
28
- # Return non-false if the first file is newer than the second file
28
+ # Is 'file' newer than 'path'? return non-true if path is newer than file
29
29
  def self.newer?(path, file)
30
30
  return true if not Open.exists?(file)
31
31
  path = path.find if Path === path
@@ -52,7 +52,6 @@ module Persist
52
52
  def lock
53
53
  return yield if @locked
54
54
  lock_filename = Persist.persistence_path(persistence_path, {:dir => TSV.lock_dir})
55
- Log.stack caller if $LOG
56
55
  Misc.lock(lock_filename) do
57
56
  begin
58
57
  @locked = true
@@ -52,7 +52,7 @@ module Persist
52
52
  if TSV::ENTRY_KEYS.include? key
53
53
  set_metadata(key, value)
54
54
  else
55
- if range
55
+ if @range
56
56
  add_range_point key, value
57
57
  else
58
58
  add key, value
@@ -61,7 +61,7 @@ module Persist
61
61
  end
62
62
 
63
63
  def add(key, value)
64
- key = pos_function.call(key) if pos_function and not (range and Array === key)
64
+ key = pos_function.call(key) if pos_function and not (@range and Array === key)
65
65
  super(key, value)
66
66
  end
67
67
 
@@ -85,8 +85,10 @@ module Persist
85
85
  end
86
86
 
87
87
  def each
88
+ read
88
89
  @size.times do |i|
89
- yield i, value(i)
90
+ v = idx_value(i)
91
+ yield i, v
90
92
  end
91
93
  end
92
94
 
@@ -32,13 +32,17 @@ module TSV
32
32
  sep + ([""] * fields.length) * sep << "\n"
33
33
  end
34
34
  when Array
35
- if fields.nil? or fields.empty?
35
+ if fields.nil?
36
+ sep + (values.collect{|v| Array === v ? v * "|" : v} * sep) << "\n"
37
+ elsif fields.empty?
36
38
  "\n"
37
39
  else
38
40
  sep + (values.collect{|v| Array === v ? v * "|" : v} * sep) << "\n"
39
41
  end
40
42
  else
41
- if fields.nil? or fields.empty?
43
+ if fields.nil?
44
+ sep + values.to_s + "\n"
45
+ elsif fields.empty?
42
46
  "\n"
43
47
  else
44
48
  sep + values.to_s << "\n"
@@ -98,6 +98,7 @@ module CMD
98
98
  post = options.delete(:post)
99
99
  log = options.delete(:log)
100
100
  no_fail = options.delete(:no_fail)
101
+ no_fail = options.delete(:nofail) if no_fail.nil?
101
102
  no_wait = options.delete(:no_wait)
102
103
 
103
104
  dont_close_in = options.delete(:dont_close_in)
@@ -7,7 +7,7 @@ module Bgzf
7
7
 
8
8
  def self.bgzip_cmd
9
9
  @@bgzip_cmd ||= begin
10
- path = `bash -c "type -p bgzips"`.strip
10
+ path = `bash -c "type -p bgzip"`.strip
11
11
  if path.empty?
12
12
  Rbbt.claim Rbbt.software.opt.htslib, :install, Rbbt.share.install.software.HTSLIB.find(:lib)
13
13
  Rbbt.software.opt.htslib.produce
@@ -117,7 +117,7 @@ module NamedArray
117
117
  #end
118
118
 
119
119
  def each(&block)
120
- if defined?(Entity) and not @fields.nil? and not @fields.empty?
120
+ if defined?(Entity) && ! (@fields.nil? || @fields.empty?)
121
121
  i = 0
122
122
  super do |elem|
123
123
  field = @fields[i]
@@ -16,9 +16,9 @@ module Open
16
16
  GREP_CMD = begin
17
17
  if ENV["GREP_CMD"]
18
18
  ENV["GREP_CMD"]
19
- elsif File.exists?('/bin/grep')
19
+ elsif File.exist?('/bin/grep')
20
20
  "/bin/grep"
21
- elsif File.exists?('/usr/bin/grep')
21
+ elsif File.exist?('/usr/bin/grep')
22
22
  "/usr/bin/grep"
23
23
  else
24
24
  "grep"
@@ -262,7 +262,7 @@ module Open
262
262
  if (dir_sub_path = find_repo_dir(file))
263
263
  remove_from_repo(*dir_sub_path)
264
264
  else
265
- FileUtils.rm(file) if File.exists?(file) or Open.broken_link?(file)
265
+ FileUtils.rm(file) if File.exist?(file) or Open.broken_link?(file)
266
266
  end
267
267
  end
268
268
 
@@ -333,7 +333,7 @@ module Open
333
333
  nil
334
334
  else
335
335
  target = target.find if Path === target
336
- if ! File.exists?(target)
336
+ if ! File.exist?(target)
337
337
  FileUtils.mkdir_p target
338
338
  end
339
339
  end
@@ -344,8 +344,8 @@ module Open
344
344
  target = target.find if Path === target
345
345
 
346
346
  target = File.join(target, File.basename(source)) if File.directory? target
347
- FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
348
- FileUtils.rm target if File.exists?(target)
347
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
348
+ FileUtils.rm target if File.exist?(target)
349
349
  FileUtils.ln_s source, target
350
350
  end
351
351
 
@@ -353,8 +353,8 @@ module Open
353
353
  source = source.find if Path === source
354
354
  target = target.find if Path === target
355
355
 
356
- FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
357
- FileUtils.rm target if File.exists?(target)
356
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
357
+ FileUtils.rm target if File.exist?(target)
358
358
  FileUtils.ln source, target
359
359
  end
360
360
 
@@ -362,8 +362,8 @@ module Open
362
362
  source = source.find if Path === source
363
363
  target = target.find if Path === target
364
364
 
365
- FileUtils.mkdir_p File.dirname(target) unless File.exists?(File.dirname(target))
366
- FileUtils.rm target if File.exists?(target)
365
+ FileUtils.mkdir_p File.dirname(target) unless File.exist?(File.dirname(target))
366
+ FileUtils.rm target if File.exist?(target)
367
367
  begin
368
368
  CMD.cmd("ln -L '#{ source }' '#{ target }'")
369
369
  rescue ProcessFailed
@@ -475,6 +475,7 @@ module Open
475
475
  File.exist?(file) #|| File.symlink?(file)
476
476
  end
477
477
  end
478
+
478
479
  class << self
479
480
  alias exist? exists?
480
481
  end
@@ -747,7 +748,7 @@ module Open
747
748
  if (dir_sub_path = find_repo_dir(path))
748
749
  writable_repo?(*dir_sub_path)
749
750
  else
750
- if File.exists?(path)
751
+ if File.exist?(path)
751
752
  File.writable?(path)
752
753
  else
753
754
  File.writable?(File.dirname(File.expand_path(path)))
@@ -776,14 +777,14 @@ module Open
776
777
  file = file.find if Path === file
777
778
  begin
778
779
  if File.symlink?(file) || File.stat(file).nlink > 1
779
- if File.exists?(file + '.info') && defined?(Step)
780
+ if File.exist?(file + '.info') && defined?(Step)
780
781
  done = Step::INFO_SERIALIZER.load(Open.open(file + '.info'))[:done]
781
782
  return done if done
782
783
  end
783
784
 
784
785
  file = Pathname.new(file).realpath.to_s
785
786
  end
786
- return nil unless File.exists?(file)
787
+ return nil unless File.exist?(file)
787
788
  File.mtime(file)
788
789
  rescue
789
790
  nil
@@ -793,7 +794,7 @@ module Open
793
794
 
794
795
  def self.update_mtime(path, target)
795
796
  if File.symlink?(target) || File.stat(target).nlink > 1
796
- if File.exists?(target + '.info')
797
+ if File.exist?(target + '.info')
797
798
  target = target + '.info'
798
799
  else
799
800
  target = Pathname.new(target).realpath.to_s
@@ -801,7 +802,7 @@ module Open
801
802
  end
802
803
 
803
804
  CMD.cmd("touch -r '#{path}' '#{target}'")
804
- CMD.cmd("touch -r '#{path}.info' '#{target}'") if File.exists?(path + '.info')
805
+ CMD.cmd("touch -r '#{path}.info' '#{target}'") if File.exist?(path + '.info')
805
806
  end
806
807
 
807
808
  def self.atime(file)
@@ -823,7 +824,7 @@ module Open
823
824
  end
824
825
 
825
826
  def self.broken_link?(path)
826
- File.symlink?(path) && ! File.exists?(File.readlink(path))
827
+ File.symlink?(path) && ! File.exist?(File.readlink(path))
827
828
  end
828
829
 
829
830
  def self.download(url, path)
@@ -44,6 +44,7 @@ module Workflow
44
44
 
45
45
  def dep(*dependency, &block)
46
46
  @dependencies ||= []
47
+ dependency = [tasks.keys.last] if dependency.empty? && ! block_given?
47
48
  if block_given?
48
49
  if dependency.any?
49
50
 
@@ -129,7 +130,7 @@ module Workflow
129
130
  :resumable => consume_resumable,
130
131
  :input_options => consume_input_options
131
132
  }
132
-
133
+
133
134
  task_info[:extension] = case task_info[:result_type].to_s
134
135
  when "tsv"
135
136
  "tsv"
@@ -0,0 +1,53 @@
1
+ require_relative 'ansible/workflow'
2
+ require 'rbbt/workflow/usage'
3
+
4
+ module Ansible
5
+ def self.play(playbook, inventory = nil)
6
+ inventory = Rbbt.etc.ansible_inventory.find
7
+ Log.with_severity 0 do
8
+ TmpFile.with_file do |tmp|
9
+ if Hash === playbook
10
+ Open.write(tmp, [playbook].to_yaml)
11
+ playbook = tmp
12
+ end
13
+ CMD.cmd_log("ansible-playbook -i #{inventory} #{playbook}")
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.clean_symbols(hash)
19
+ new = {}
20
+ hash.each do |key,value|
21
+ key = key.to_s
22
+ value = case value
23
+ when Symbol
24
+ value.to_s
25
+ when Hash
26
+ self.clean_symbols(value)
27
+ else
28
+ value
29
+ end
30
+ new[key] = value
31
+ end
32
+ new
33
+ end
34
+
35
+ def self.workflow2playbook(workflow, task, options = {})
36
+ job_options = workflow.get_SOPT(workflow.tasks[task])
37
+
38
+ tasks = workflow.job(task, nil, job_options).exec
39
+
40
+ hosts = options[:hosts] || 'localhost'
41
+
42
+ clean_tasks = tasks.collect{|task| self.clean_symbols task }
43
+ {"hosts" => hosts, "tasks" => clean_tasks}
44
+ end
45
+
46
+ def self.playbook(file, task = nil, options = {})
47
+ task = 'default' if task.nil?
48
+
49
+ workflow = Workflow.require_workflow file
50
+ task = workflow.tasks.keys.last if workflow.tasks[task].nil?
51
+ workflow2playbook workflow, task, options
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ require 'rbbt/workflow'
2
+
3
+ module Ansible
4
+ module AnsibleWorkflow
5
+ def self.extended(object)
6
+ class << object
7
+ attr_accessor :ans_tasks
8
+ end
9
+
10
+ object.helper :register do |task_info|
11
+ desc = task.description if task
12
+ name ||= desc || short_path
13
+ task_info = {"name" => name}.merge(task_info)
14
+ @ans_tasks ||= []
15
+ @ans_tasks << task_info
16
+ task
17
+ end
18
+
19
+ object.helper :ans do |name, info|
20
+ register({ name => info})
21
+ end
22
+
23
+ object.helper :add do |name, info|
24
+ @ans_tasks.last[name.to_s] = info
25
+ end
26
+
27
+ object.helper :shell do |cmd|
28
+ register({"shell" => cmd.strip})
29
+ end
30
+
31
+ object.helper :sudo do |cmd|
32
+ register({"shell" => cmd.strip, "become" => 'yes'})
33
+ end
34
+
35
+ object.helper :singularity do |scmd|
36
+ img = config :singularity_img, :build, :test, :small, :default => '/data/img/singularity/rbbt/rbbt.simg'
37
+ container = config :singularity_container, :build, :test, :small, :default => '/data/img/sandbox/mvazque2/'
38
+ cmd = <<-EOF
39
+ singularity exec -C -H '#{container}' '#{img}' #{scmd}
40
+ EOF
41
+ register({"shell" => cmd.strip, "name" => short_path})
42
+ end
43
+
44
+
45
+ object.helper :produce_task do
46
+ @ans_tasks
47
+ end
48
+ end
49
+
50
+ def play(name = nil, &block)
51
+ name = Misc.snake_case(@description) if name.nil?
52
+ task name => :yaml do |*args|
53
+ self.instance_exec *args, &block
54
+ dependencies.inject([]){|acc,dep| acc += dep.load } + produce_task
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+
@@ -154,6 +154,11 @@ class Step
154
154
  all_inputs
155
155
  end
156
156
 
157
+ def dependencies=(dependencies)
158
+ @dependencies = dependencies
159
+ set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
160
+ end
161
+
157
162
  def recursive_inputs
158
163
  if NamedArray === inputs
159
164
  i = {}
@@ -121,7 +121,7 @@ class Step
121
121
  inputs[name] = value
122
122
  end
123
123
 
124
- if options.include? 'override_dependencies'
124
+ if options && options.include?('override_dependencies')
125
125
  inputs.merge!(:override_dependencies => open[:override_dependencies])
126
126
  input_types = IndiferentHash.setup(input_types.merge(:override_dependencies => :array))
127
127
  end
@@ -67,8 +67,10 @@ class Step
67
67
  next unless File.exists?(step.path)
68
68
  job_files << step.path
69
69
  job_files << step.info_file if File.exists?(step.info_file)
70
+ job_files << Step.md5_file(step.path) if File.exists?(Step.md5_file step.path)
70
71
  job_file_dir_content = Dir.glob(step.files_dir + '/**/*')
71
72
  job_files += job_file_dir_content
73
+ job_files << step.files_dir if File.exists?(step.files_dir)
72
74
  rec_dependencies = Set.new
73
75
 
74
76
  next unless recursive
@@ -143,18 +143,25 @@ module Workflow
143
143
  end
144
144
  end
145
145
 
146
- def erase_job_dependencies(job, rules, workload, top_level_jobs)
146
+ def erase_job_dependencies(job, rules, all_jobs, top_level_jobs)
147
147
  job.dependencies.each do |dep|
148
148
  next if top_level_jobs.include? dep.path
149
149
  next unless Orchestrator.job_rules(rules, dep)["erase"].to_s == 'true'
150
150
 
151
- list = (workload.keys - [job]).collect{|pending| pending.dependencies}.flatten
152
- next if list.include?(dep)
151
+ dep_path = dep.path
152
+ parents = all_jobs.select do |parent|
153
+ paths = parent.info[:dependencies].nil? ? parent.dependencies.collect{|d| d.path } : parent.info[:dependencies].collect{|d| d.last }
154
+ paths.include? dep_path
155
+ end
156
+
157
+ next unless parents.reject{|parent| parent.done? }.empty?
153
158
 
154
- Log.high "Erasing #{dep.path} from #{job.path}"
155
- job.archive_deps
156
- job.copy_files_dir
157
- job.dependencies = job.dependencies - [dep]
159
+ parents.each do |parent|
160
+ Log.high "Erasing #{dep.path} from #{parent.path}"
161
+ parent.archive_deps
162
+ parent.copy_files_dir
163
+ parent.dependencies = parent.dependencies - [dep]
164
+ end
158
165
  dep.clean
159
166
  end
160
167
  end
@@ -162,7 +169,13 @@ module Workflow
162
169
  def process(rules, jobs)
163
170
  begin
164
171
 
165
- workload = jobs.inject({}){|acc,job| acc.merge!(Orchestrator.job_workload(job)) }
172
+ workload = jobs.inject({}) do |acc,job|
173
+ Orchestrator.job_workload(job).each do |j,d|
174
+ acc[j] = d unless acc.keys.collect{|k| k.path }.include? j.path
175
+ end
176
+ acc
177
+ end
178
+ all_jobs = workload.keys
166
179
 
167
180
  top_level_jobs = jobs.collect{|job| job.path }
168
181
  while workload.any?
@@ -187,7 +200,7 @@ module Workflow
187
200
  when job.done?
188
201
  Log.debug "Orchestrator done #{job.path}"
189
202
  release_resources(job)
190
- erase_job_dependencies(job, rules, workload, top_level_jobs)
203
+ erase_job_dependencies(job, rules, all_jobs, top_level_jobs)
191
204
 
192
205
  when job.running?
193
206
  next