rbbt-util 3.2.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/README.rdoc +65 -0
  2. data/bin/run_workflow.rb +142 -69
  3. data/lib/rbbt-util.rb +3 -3
  4. data/lib/rbbt.rb +12 -3
  5. data/lib/rbbt/annotations.rb +215 -0
  6. data/lib/rbbt/{util/fix_width_table.rb → fix_width_table.rb} +17 -13
  7. data/lib/rbbt/persist.rb +164 -0
  8. data/lib/rbbt/persist/tsv.rb +135 -0
  9. data/lib/rbbt/resource.rb +100 -0
  10. data/lib/rbbt/resource/path.rb +180 -0
  11. data/lib/rbbt/resource/rake.rb +48 -0
  12. data/lib/rbbt/resource/util.rb +111 -0
  13. data/lib/rbbt/resource/with_key.rb +28 -0
  14. data/lib/rbbt/tsv.rb +134 -0
  15. data/lib/rbbt/tsv/accessor.rb +345 -0
  16. data/lib/rbbt/tsv/attach.rb +183 -0
  17. data/lib/rbbt/tsv/attach/util.rb +277 -0
  18. data/lib/rbbt/{util/tsv/filters.rb → tsv/filter.rb} +76 -37
  19. data/lib/rbbt/tsv/index.rb +453 -0
  20. data/lib/rbbt/tsv/manipulate.rb +361 -0
  21. data/lib/rbbt/tsv/parser.rb +231 -0
  22. data/lib/rbbt/tsv/serializers.rb +79 -0
  23. data/lib/rbbt/tsv/util.rb +67 -0
  24. data/lib/rbbt/util/R.rb +3 -3
  25. data/lib/rbbt/util/chain_methods.rb +64 -0
  26. data/lib/rbbt/util/cmd.rb +17 -13
  27. data/lib/rbbt/util/excel2tsv.rb +4 -3
  28. data/lib/rbbt/util/log.rb +1 -0
  29. data/lib/rbbt/util/misc.rb +296 -285
  30. data/lib/rbbt/util/open.rb +9 -2
  31. data/lib/rbbt/util/persistence.rb +1 -1
  32. data/lib/rbbt/util/task/job.rb +3 -1
  33. data/lib/rbbt/workflow.rb +193 -0
  34. data/lib/rbbt/workflow/accessor.rb +249 -0
  35. data/lib/rbbt/workflow/annotate.rb +60 -0
  36. data/lib/rbbt/workflow/soap.rb +100 -0
  37. data/lib/rbbt/workflow/step.rb +102 -0
  38. data/lib/rbbt/workflow/task.rb +76 -0
  39. data/test/rbbt/resource/test_path.rb +12 -0
  40. data/test/rbbt/test_annotations.rb +106 -0
  41. data/test/rbbt/{util/test_fix_width_table.rb → test_fix_width_table.rb} +8 -9
  42. data/test/rbbt/test_resource.rb +66 -0
  43. data/test/rbbt/test_tsv.rb +332 -0
  44. data/test/rbbt/test_workflow.rb +102 -0
  45. data/test/rbbt/tsv/test_accessor.rb +163 -0
  46. data/test/rbbt/{util/tsv → tsv}/test_attach.rb +86 -43
  47. data/test/rbbt/{util/tsv/test_filters.rb → tsv/test_filter.rb} +31 -13
  48. data/test/rbbt/tsv/test_index.rb +284 -0
  49. data/test/rbbt/{util/tsv → tsv}/test_manipulate.rb +35 -105
  50. data/test/rbbt/util/test_R.rb +1 -1
  51. data/test/rbbt/util/test_chain_methods.rb +22 -0
  52. data/test/rbbt/util/test_filecache.rb +0 -1
  53. data/test/rbbt/util/test_misc.rb +97 -79
  54. data/test/rbbt/util/test_open.rb +1 -0
  55. data/test/rbbt/util/test_tmpfile.rb +1 -1
  56. data/test/rbbt/workflow/test_soap.rb +103 -0
  57. data/test/rbbt/workflow/test_step.rb +142 -0
  58. data/test/rbbt/workflow/test_task.rb +84 -0
  59. data/test/test_helper.rb +7 -7
  60. metadata +80 -54
  61. data/lib/rbbt/util/rake.rb +0 -176
  62. data/lib/rbbt/util/resource.rb +0 -355
  63. data/lib/rbbt/util/task.rb +0 -183
  64. data/lib/rbbt/util/tc_hash.rb +0 -324
  65. data/lib/rbbt/util/tsv.rb +0 -236
  66. data/lib/rbbt/util/tsv/accessor.rb +0 -312
  67. data/lib/rbbt/util/tsv/attach.rb +0 -416
  68. data/lib/rbbt/util/tsv/index.rb +0 -419
  69. data/lib/rbbt/util/tsv/manipulate.rb +0 -300
  70. data/lib/rbbt/util/tsv/misc.rb +0 -41
  71. data/lib/rbbt/util/tsv/parse.rb +0 -324
  72. data/lib/rbbt/util/tsv/resource.rb +0 -88
  73. data/lib/rbbt/util/workflow.rb +0 -135
  74. data/lib/rbbt/util/workflow/soap.rb +0 -116
  75. data/test/rbbt/util/test_persistence.rb +0 -201
  76. data/test/rbbt/util/test_rake.rb +0 -54
  77. data/test/rbbt/util/test_resource.rb +0 -77
  78. data/test/rbbt/util/test_task.rb +0 -133
  79. data/test/rbbt/util/test_tc_hash.rb +0 -144
  80. data/test/rbbt/util/test_tsv.rb +0 -221
  81. data/test/rbbt/util/test_workflow.rb +0 -135
  82. data/test/rbbt/util/tsv/test_accessor.rb +0 -150
  83. data/test/rbbt/util/tsv/test_index.rb +0 -241
  84. data/test/rbbt/util/tsv/test_parse.rb +0 -87
  85. data/test/rbbt/util/tsv/test_resource.rb +0 -9
@@ -4,15 +4,15 @@ class FixWidthTable
4
4
  def initialize(filename, value_size = nil, range = nil, update = false)
5
5
  @filename = filename
6
6
 
7
- if update or %w(memory stringio).include?(filename.to_s.downcase) or not File.exists? filename
8
- Log.debug "Writing FixWidthTable at #{ @filename.inspect }"
9
- @value_size = value_size
10
- @range = range
7
+ if update or %w(memory stringio).include?(filename.to_s.downcase) or not File.exists?(filename)
8
+ Log.debug "FixWidthTable create: #{ filename }"
9
+ @value_size = value_size
10
+ @range = range
11
11
  @record_size = @value_size + (@range ? 12 : 4)
12
12
 
13
13
  if %w(memory stringio).include? filename.to_s.downcase
14
14
  @filename = :memory
15
- @file = StringIO.new
15
+ @file = StringIO.new
16
16
  else
17
17
  FileUtils.rm @filename if File.exists? @filename
18
18
  @file = File.open(@filename, 'wb')
@@ -22,9 +22,9 @@ class FixWidthTable
22
22
  @file.write [@range ? 1 : 0 ].pack("C")
23
23
  @size = 0
24
24
  else
25
- Log.debug "Reading FixWidthTable at #{ @filename.inspect }"
26
- @file = File.open(@filename, 'r')
27
- @value_size = @file.read(4).unpack("L").first
25
+ Log.debug "FixWidthTable up-to-date: #{ filename }"
26
+ @file = File.open(@filename, 'r')
27
+ @value_size = @file.read(4).unpack("L").first
28
28
  @range = @file.read(1).unpack("C").first == 1
29
29
  @record_size = @value_size + (@range ? 12 : 4)
30
30
  @size = (File.size(@filename) - 5) / (@record_size)
@@ -36,9 +36,7 @@ class FixWidthTable
36
36
  def self.get(filename, value_size = nil, range = nil, update = false)
37
37
  return self.new(filename, value_size, range, update) if filename == :memory
38
38
  case
39
- when (!File.exists?(filename) or update)
40
- CONNECTIONS[filename] = self.new(filename, value_size, range, update)
41
- when (not CONNECTIONS.include?(filename))
39
+ when (!File.exists?(filename) or update or not CONNECTIONS.include?(filename))
42
40
  CONNECTIONS[filename] = self.new(filename, value_size, range, update)
43
41
  end
44
42
 
@@ -48,9 +46,9 @@ class FixWidthTable
48
46
  def format(pos, value)
49
47
  padding = value_size - value.length
50
48
  if range
51
- (pos + [value + "\0" * padding]).pack("llla#{value_size}")
49
+ (pos + [value + ("\0" * padding)]).pack("llla#{value_size}")
52
50
  else
53
- [pos, value + "\0" * padding].pack("la#{value_size}")
51
+ [pos, value + ("\0" * padding)].pack("la#{value_size}")
54
52
  end
55
53
  end
56
54
 
@@ -236,4 +234,10 @@ class FixWidthTable
236
234
  end
237
235
  end
238
236
 
237
+ def values_at(*list)
238
+ list.collect{|pos|
239
+ self[pos]
240
+ }
241
+ end
242
+
239
243
  end
@@ -0,0 +1,164 @@
1
+ require 'digest/md5'
2
+
3
+ require 'rbbt/util/misc'
4
+ require 'rbbt/util/open'
5
+
6
+ require 'rbbt/persist/tsv'
7
+
8
+ module Persist
9
+ CACHEDIR="/tmp/tsv_persistent_cache"
10
+ FileUtils.mkdir CACHEDIR unless File.exist? CACHEDIR
11
+
12
+ def self.cachedir=(cachedir)
13
+ CACHEDIR.replace cachedir
14
+ FileUtils.mkdir_p CACHEDIR unless File.exist? CACHEDIR
15
+ end
16
+
17
+ def self.cachedir
18
+ CACHEDIR
19
+ end
20
+
21
+ def self.newer?(path, file)
22
+ return true if not File.exists? file
23
+ return true if File.mtime(path) < File.mtime(file)
24
+ return false
25
+ end
26
+
27
+ def self.is_persisted?(path, persist_options = {})
28
+ return false if not File.exists? path
29
+ return false if TrueClass === persist_options[:update]
30
+
31
+ check = persist_options[:check]
32
+ if not check.nil?
33
+ if Array === check
34
+ return false if check.select{|file| newer? path, file}.any?
35
+ else
36
+ return false if newer? path, check
37
+ end
38
+ end
39
+
40
+ return true
41
+ end
42
+
43
+ def self.persistence_path(file, persist_options = {}, options = {})
44
+ persistence_file = Misc.process_options persist_options, :file
45
+ return persistence_file if not persistence_file.nil?
46
+
47
+ prefix = Misc.process_options persist_options, :prefix
48
+
49
+ if prefix.nil?
50
+ perfile = file.gsub(/\//, '>')
51
+ else
52
+ perfile = prefix.to_s + ":" + file.gsub(/\//, '>')
53
+ end
54
+
55
+ if options.include? :filters
56
+ options[:filters].each do |match,value|
57
+ perfile = perfile + "&F[#{match}=#{Misc.digest(value.inspect)}]"
58
+ end
59
+ end
60
+
61
+ persistence_dir = Misc.process_options(persist_options, :dir) || CACHEDIR
62
+
63
+ filename = perfile.gsub(/\s/,'_').gsub(/\//,'>')
64
+ options_md5 = Misc.hash2md5 options
65
+ filename << ":" << options_md5 unless options_md5.empty?
66
+
67
+ File.join(persistence_dir, filename)
68
+ end
69
+
70
+ def self.load_file(path, type)
71
+ case (type || "nil").to_sym
72
+ when :nil
73
+ nil
74
+ when :tsv
75
+ TSV.open(path)
76
+ when :marshal_tsv
77
+ TSV.setup(Marshal.load(Open.open(path)))
78
+ when :fwt
79
+ FixWidthTable.get(path)
80
+ when :string, :text
81
+ Open.read(path)
82
+ when :array
83
+ res = Open.read(path).split("\n", -1)
84
+ res.pop
85
+ res
86
+ when :marshal
87
+ Marshal.load(Open.open(path))
88
+ when :yaml
89
+ YAML.load(Open.open(path))
90
+ when :float
91
+ Open.read(path).to_f
92
+ when :integer
93
+ Open.read(path).to_i
94
+ when :tsv
95
+ TSV.open(Open.open(path))
96
+ else
97
+ raise "Unknown persistence: #{ type }"
98
+ end
99
+ end
100
+
101
+ def self.save_file(path, type, content)
102
+
103
+ return if (content.nil? and File.exists? path)
104
+
105
+ case (type || "nil").to_sym
106
+ when :nil
107
+ nil
108
+ when :fwt
109
+ content.file.seek 0
110
+ Open.write(path, content.file.read)
111
+ when :tsv
112
+ Open.write(path, content.to_s)
113
+ when :string, :text
114
+ Open.write(path, content)
115
+ when :array
116
+ Open.write(path, content * "\n" + "\n")
117
+ when :marshal_tsv
118
+ Open.write(path, Marshal.dump(content.dup))
119
+ when :marshal
120
+ Open.write(path, Marshal.dump(content))
121
+ when :yaml
122
+ Open.write(path, YAML.dump(content))
123
+ when :float, :integer, :tsv
124
+ Open.write(path, content.to_s)
125
+ else
126
+ raise "Unknown persistence: #{ type }"
127
+ end
128
+ end
129
+
130
+ def self.persist(name, type = nil, persist_options = {})
131
+ type ||= :marshal
132
+ persist_options = Misc.add_defaults persist_options, :persist => true
133
+
134
+ if persist_options[:persist]
135
+ path = persistence_path(name, persist_options)
136
+ Misc.lock(path) do
137
+ if is_persisted?(path, persist_options)
138
+ Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect}"
139
+ return load_file(path, type)
140
+ else
141
+ Log.debug "Persist create: #{ path } - #{persist_options.inspect}"
142
+ end
143
+ res = yield
144
+ save_file(path, type, res)
145
+ res
146
+ end
147
+ else
148
+ yield
149
+ end
150
+ end
151
+ end
152
+
153
+ module LocalPersist
154
+
155
+ attr_accessor :local_persist_dir
156
+ def local_persist(name, type = nil, options= {}, &block)
157
+ Persist.persist(name, type, options.merge({:dir => @local_persist_dir}), &block)
158
+ end
159
+
160
+ def local_persist_tsv(source, name, opt = {}, options= {}, &block)
161
+ Persist.persist_tsv(source, name, opt, options.merge({:dir => @local_persist_dir}), &block)
162
+ end
163
+
164
+ end
@@ -0,0 +1,135 @@
1
+ require 'tokyocabinet'
2
+
3
+ module Persist
4
+ TC_CONNECTIONS = {}
5
+ def self.open_tokyocabinet(path, write, serializer = nil)
6
+ write = true if not File.exists?(path)
7
+ flags = (write ? TokyoCabinet::HDB::OWRITER | TokyoCabinet::HDB::OCREAT : TokyoCabinet::HDB::OREADER)
8
+
9
+ FileUtils.mkdir_p File.dirname(path) unless File.exists?(File.dirname(path))
10
+
11
+ database = TC_CONNECTIONS[path] ||= TokyoCabinet::HDB.new
12
+ database.close
13
+
14
+ if !database.open(path, flags)
15
+ ecode = database.ecode
16
+ raise "Open error: #{database.errmsg(ecode)}. Trying to open file #{path}"
17
+ end
18
+
19
+ if not database.respond_to? :old_close
20
+ class << database
21
+ attr_accessor :writable, :closed, :persistence_path
22
+
23
+ alias old_close close
24
+ def close
25
+ @closed = true
26
+ old_close
27
+ end
28
+
29
+ def read(force = false)
30
+ return if not write? and not closed and not force
31
+ self.close
32
+ if !self.open(@persistence_path, TokyoCabinet::BDB::OREADER)
33
+ ecode = self.ecode
34
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
35
+ end
36
+ @writable = false
37
+ @closed = false
38
+ self
39
+ end
40
+
41
+ def write(force = true)
42
+ return if write? and not closed and not force
43
+ self.close
44
+ if !self.open(@persistence_path, TokyoCabinet::HDB::OWRITER | TokyoCabinet::HDB::OCREAT)
45
+ ecode = self.ecode
46
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
47
+ end
48
+ @writable = true
49
+ @closed = false
50
+ self
51
+ end
52
+
53
+ def write?
54
+ @writable
55
+ end
56
+
57
+ def collect
58
+ res = []
59
+ each do |key, value|
60
+ res << if block_given?
61
+ yield key, value
62
+ else
63
+ [key, value]
64
+ end
65
+ end
66
+ res
67
+ end
68
+
69
+ def delete(key)
70
+ out(key)
71
+ end
72
+
73
+
74
+ def merge!(hash)
75
+ hash.each do |key,values|
76
+ self[key] = values
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ database.persistence_path ||= path
84
+
85
+ TSV.setup database
86
+ database.serializer = serializer unless serializer.nil?
87
+
88
+ database
89
+ end
90
+
91
+ def self.persist_tsv(source, filename, options, persist_options = {})
92
+ persist_options[:prefix] ||= "TSV"
93
+
94
+ data = case
95
+ when persist_options[:data]
96
+ persist_options[:data]
97
+ when persist_options[:persist]
98
+
99
+ filename ||= source.filename if source.respond_to? :filename
100
+ filename ||= source.object_id.to_s
101
+
102
+ path = persistence_path(filename, persist_options, options)
103
+ if is_persisted? path
104
+ Log.debug "TSV persistence up-to-date: #{ path }"
105
+ return open_tokyocabinet(path, false)
106
+ else
107
+ Log.debug "TSV persistence creating: #{ path }"
108
+ end
109
+
110
+ FileUtils.rm path if File.exists? path
111
+
112
+ data = open_tokyocabinet(path, true)
113
+ data.serializer = :type
114
+ data
115
+ else
116
+ data = {}
117
+ end
118
+
119
+ begin
120
+ yield data
121
+ rescue Exception
122
+ begin
123
+ data.close if data.respondo_to? :close
124
+ rescue
125
+ end
126
+ FileUtils.rm path if path and File.exists? path
127
+ raise $!
128
+ end
129
+
130
+ data.read if data.respond_to? :read and data.respond_to? :write? and data.write?
131
+
132
+ data
133
+ end
134
+
135
+ end
@@ -0,0 +1,100 @@
1
+ require 'rbbt/util/open'
2
+ require 'rbbt/util/log'
3
+ require 'rbbt/util/chain_methods'
4
+ require 'rbbt/resource/path'
5
+ require 'rbbt/resource/rake'
6
+
7
+ module Resource
8
+ extend ChainMethods
9
+ self.chain_prefix = :resource
10
+ def self.extended(base)
11
+ setup_chains(base)
12
+ if not base.respond_to? :pkgdir
13
+ class << base
14
+ attr_accessor :pkgdir, :subdir, :resources, :rake_dirs
15
+ end
16
+
17
+ base.pkgdir = 'rbbt'
18
+ base.subdir = ''
19
+ base.resources = {}
20
+ base.rake_dirs = {}
21
+ end
22
+ base
23
+ end
24
+
25
+ def root()
26
+ Path.setup @subdir || "", @pkgdir, self
27
+ end
28
+
29
+ def resource_method_missing(name, prev = nil, *args)
30
+ # Fix problem with ruby 1.9 calling methods by its own initiative. ARG
31
+ root.send(name, prev, *args)
32
+ end
33
+
34
+ def [](file = nil)
35
+ if file.nil?
36
+ root
37
+ else
38
+ root.send(file)
39
+ end
40
+ end
41
+
42
+ def claim(path, type, content = nil, &block)
43
+ path = path.find if path.respond_to? :find
44
+ if type == :rake
45
+ @rake_dirs[path] = content
46
+ else
47
+ @resources[path] = [type, content || block]
48
+
49
+ if type == :install
50
+ Log.debug "Preparing software: #{path}"
51
+ path.produce
52
+ software_dir = path.resource.root.software.find :user
53
+ set_software_env(software_dir)
54
+ end
55
+ end
56
+ end
57
+
58
+ def produce(path)
59
+ case
60
+ when @resources.include?(path)
61
+ type, content = @resources[path]
62
+ when has_rake(path)
63
+ type = :rake
64
+ rake_dir, content = rake_for(path)
65
+ else
66
+ raise "Resource #{ path } does not seem to be claimed"
67
+ end
68
+
69
+ case type
70
+ when :string
71
+ Open.write(path, content)
72
+ when :url
73
+ Open.write(path, Open.open(content))
74
+ when :proc
75
+ data = content.call
76
+ Open.write(path, data) unless File.exists? path
77
+ when :rake
78
+ run_rake(path, content, rake_dir)
79
+ when :install
80
+ Log.debug "Installing software: #{path}"
81
+ software_dir = path.resource.root.software.find :user
82
+ preamble = <<-EOF
83
+ #!/bin/bash
84
+
85
+ RBBT_SOFTWARE_DIR="#{software_dir}"
86
+
87
+ INSTALL_HELPER_FILE="#{Rbbt.share.install.software.lib.install_helpers.find :lib, caller_lib_dir(__FILE__)}"
88
+ source "$INSTALL_HELPER_FILE"
89
+ EOF
90
+
91
+ CMD.cmd('bash', :in => preamble + "\n" + Open.read(content))
92
+
93
+ set_software_env(software_dir)
94
+ else
95
+ raise "Could not produce #{ resource }. (#{ type }, #{ content })"
96
+ end
97
+
98
+ path
99
+ end
100
+ end