rbbt-util 5.11.9 → 5.12.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.
@@ -0,0 +1,90 @@
1
+ require 'net/smtp'
2
+
3
+ module Misc
4
+
5
+ def self.hostname
6
+ @hostanem ||= `hostname`.strip
7
+ end
8
+
9
+ def self.pid_exists?(pid)
10
+ return false if pid.nil?
11
+ begin
12
+ Process.getpgid(pid.to_i)
13
+ true
14
+ rescue Errno::ESRCH
15
+ false
16
+ end
17
+ end
18
+
19
+ def self.send_email(from, to, subject, message, options = {})
20
+ IndiferentHash.setup(options)
21
+ options = Misc.add_defaults options, :from_alias => nil, :to_alias => nil, :server => 'localhost', :port => 25, :user => nil, :pass => nil, :auth => :login
22
+
23
+ server, port, user, pass, from_alias, to_alias, auth = Misc.process_options options, :server, :port, :user, :pass, :from_alias, :to_alias, :auth
24
+
25
+ msg = <<-END_OF_MESSAGE
26
+ From: #{from_alias} <#{from}>
27
+ To: #{to_alias} <#{to}>
28
+ Subject: #{subject}
29
+
30
+ #{message}
31
+ END_OF_MESSAGE
32
+
33
+ Net::SMTP.start(server, port, server, user, pass, auth) do |smtp|
34
+ smtp.send_message msg, from, to
35
+ end
36
+ end
37
+
38
+ def self.env_add(var, value, sep = ":", prepend = true)
39
+ ENV[var] ||= ""
40
+ return if ENV[var] =~ /(#{sep}|^)#{Regexp.quote value}(#{sep}|$)/
41
+ if prepend
42
+ ENV[var] = value + sep + ENV[var]
43
+ else
44
+ ENV[var] += sep + ENV[var]
45
+ end
46
+ end
47
+
48
+ def self.path_relative_to(basedir, path)
49
+ path = File.expand_path(path) unless path[0] == "/"
50
+ basedir = File.expand_path(basedir) unless basedir[0] == "/"
51
+
52
+ if path.index(basedir) == 0
53
+ if basedir[-1] == "/"
54
+ return path[basedir.length..-1]
55
+ else
56
+ return path[basedir.length+1..-1]
57
+ end
58
+ else
59
+ return nil
60
+ end
61
+ end
62
+
63
+ def self.common_path(dir, file)
64
+ file = File.expand_path file
65
+ dir = File.expand_path dir
66
+
67
+ return true if file == dir
68
+ while File.dirname(file) != file
69
+ file = File.dirname(file)
70
+ return true if file == dir
71
+ end
72
+
73
+ return false
74
+ end
75
+
76
+ # WARN: probably not thread safe...
77
+ def self.in_dir(dir)
78
+ old_pwd = FileUtils.pwd
79
+ res = nil
80
+ begin
81
+ FileUtils.mkdir_p dir unless File.exists? dir
82
+ FileUtils.cd dir
83
+ res = yield
84
+ ensure
85
+ FileUtils.cd old_pwd
86
+ end
87
+ res
88
+ end
89
+
90
+ end
data/lib/rbbt/util/tar.rb CHANGED
@@ -43,13 +43,6 @@ module Misc
43
43
 
44
44
  string = tar.string
45
45
 
46
- #chunk_size = 1024
47
- #Zlib::GzipWriter.wrap(gz) do |writer|
48
- # while chunk = tar.read(chunk_size) do
49
- # writer.write chunk
50
- # end
51
- # writer.close
52
- #end
53
46
  z = Zlib::GzipWriter.new(gz)
54
47
  z.write string
55
48
  z.close
@@ -49,9 +49,9 @@ class Step
49
49
  end
50
50
 
51
51
  begin
52
- @info_cache = Misc.insist(2, 1, info_file) do
53
- Misc.insist(2, 0.5, info_file) do
54
- Misc.insist(3, 0.1, info_file) do
52
+ @info_cache = Misc.insist(2, 3, info_file) do
53
+ Misc.insist(2, 1, info_file) do
54
+ Misc.insist(3, 0.2, info_file) do
55
55
  Open.open(info_file) do |file|
56
56
  INFO_SERIALIAZER.load(file) || {}
57
57
  end
@@ -2,6 +2,47 @@ class Step
2
2
 
3
3
  attr_reader :stream
4
4
 
5
+ STREAM_CACHE = {}
6
+ STREAM_CACHE_MUTEX = Mutex.new
7
+ def self.dup_stream(stream)
8
+ case stream
9
+ when IO, File
10
+ return stream if stream.closed?
11
+ STREAM_CACHE_MUTEX.synchronize do
12
+ if STREAM_CACHE[stream].nil?
13
+ STREAM_CACHE[stream] = stream
14
+ else
15
+ Misc.dup_stream(STREAM_CACHE[stream])
16
+ end
17
+ end
18
+ when TSV::Dumper, TSV::Parser
19
+ stream = stream.stream
20
+ return stream if stream.closed?
21
+
22
+ STREAM_CACHE_MUTEX.synchronize do
23
+ if STREAM_CACHE[stream].nil?
24
+ STREAM_CACHE[stream] = stream
25
+ else
26
+ Misc.dup_stream(STREAM_CACHE[stream])
27
+ end
28
+ end
29
+ else
30
+ stream
31
+ end
32
+ end
33
+
34
+ def self.purge_stream_cache
35
+ return
36
+ STREAM_CACHE_MUTEX.synchronize do
37
+ STREAM_CACHE.collect{|k,s|
38
+ Thread.new do
39
+ Misc.consume_stream s
40
+ end
41
+ }
42
+ STREAM_CACHE.clear
43
+ end
44
+ end
45
+
5
46
  def get_stream
6
47
  @mutex.synchronize do
7
48
  @stream = begin
@@ -12,9 +53,16 @@ class Step
12
53
  end
13
54
  end
14
55
 
56
+ def dup_inputs
57
+ @inputs.collect do |input|
58
+ Step.dup_stream input
59
+ end
60
+ end
61
+
15
62
  def _exec
16
63
  @exec = true if @exec.nil?
17
- @task.exec_in((bindings ? bindings : self), *@inputs)
64
+ #@task.exec_in((bindings ? bindings : self), *@inputs)
65
+ @task.exec_in((bindings ? bindings : self), *dup_inputs)
18
66
  end
19
67
 
20
68
  def exec(no_load=false)
@@ -299,26 +347,32 @@ class Step
299
347
 
300
348
  join_stream
301
349
 
302
- return if not Open.exists? info_file
350
+ return self if not Open.exists? info_file
351
+
352
+ return self if info[:joined]
303
353
  pid = @pid
304
354
 
305
355
  Misc.insist [0.1, 0.2, 0.5, 1] do
306
356
  pid ||= info[:pid]
307
357
  end
308
358
 
309
- if pid.nil?
310
- dependencies.each{|dep| dep.join }
311
- self
312
- else
313
- begin
314
- Log.debug{"Waiting for pid: #{pid}"}
315
- Process.waitpid pid
316
- rescue Errno::ECHILD
317
- Log.debug{"Process #{ pid } already finished: #{ path }"}
318
- end if Misc.pid_exists? pid
319
- pid = nil
320
- dependencies.each{|dep| dep.join }
321
- self
359
+ begin
360
+ if pid.nil?
361
+ dependencies.each{|dep| dep.join }
362
+ self
363
+ else
364
+ begin
365
+ Log.debug{"Waiting for pid: #{pid}"}
366
+ Process.waitpid pid
367
+ rescue Errno::ECHILD
368
+ Log.debug{"Process #{ pid } already finished: #{ path }"}
369
+ end if Misc.pid_exists? pid
370
+ pid = nil
371
+ dependencies.each{|dep| dep.join }
372
+ self
373
+ end
374
+ ensure
375
+ set_info :joined, true
322
376
  end
323
377
  self
324
378
  end
@@ -29,15 +29,13 @@ module Task
29
29
  end
30
30
  end
31
31
 
32
- def param_options
33
- end
34
-
35
32
  def take_input_values(input_values)
36
33
  return [] if @inputs.nil?
37
34
  values = []
35
+ defaults = IndiferentHash.setup(@input_defaults || {})
38
36
  @inputs.each do |input|
39
37
  value = input_values[input]
40
- value = IndiferentHash.setup(@input_defaults || {})[input] if value.nil?
38
+ value = defaults[input] if value.nil?
41
39
  values << value
42
40
  end
43
41
  values
@@ -46,7 +44,11 @@ module Task
46
44
  def exec(*args)
47
45
  case
48
46
  when (args.length == 1 and not inputs.nil? and inputs.length > 1 and Hash === args.first)
49
- self.call *take_input_values(IndiferentHash.setup(args.first))
47
+ begin
48
+ self.call *take_input_values(IndiferentHash.setup(args.first))
49
+ ensure
50
+ purge_stream_cache
51
+ end
50
52
  else
51
53
  self.call *args
52
54
  end
@@ -0,0 +1,92 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../..', 'test_helper.rb')
2
+ require 'rbbt/tsv'
3
+ require 'rbbt/tsv/stream'
4
+ require 'rbbt'
5
+
6
+ class TestStream < Test::Unit::TestCase
7
+ def test_collapse_stream
8
+ text=<<-EOF
9
+ #: :sep=" "
10
+ #Row LabelA LabelB LabelC
11
+ row1 A B C
12
+ row1 a b c
13
+ row2 AA BB CC
14
+ row2 aa bb cc
15
+ EOF
16
+
17
+ s = StringIO.new text
18
+ tsv = TSV.open TSV.collapse_stream(s)
19
+ assert_equal ["A", "a"], tsv["row1"][0]
20
+ assert_equal ["BB", "bb"], tsv["row2"][1]
21
+ end
22
+
23
+ def test_paste_stream
24
+ text1=<<-EOF
25
+ #: :sep=" "
26
+ #Row LabelA LabelB LabelC
27
+ row1 A B C
28
+ row2 AA BB CC
29
+ row3 AAA BBB CCC
30
+ EOF
31
+
32
+ text2=<<-EOF
33
+ #: :sep=" "
34
+ #Row Labela Labelb
35
+ row1 a b
36
+ row2 aa bb
37
+ row3 aaa bbb
38
+ EOF
39
+
40
+ text3=<<-EOF
41
+ #: :sep=" "
42
+ #Row LabelC
43
+ row1 c
44
+ row2 cc
45
+ row3 ccc
46
+ EOF
47
+
48
+ s1 = StringIO.new text1
49
+ s2 = StringIO.new text2
50
+ s3 = StringIO.new text3
51
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list)
52
+ assert_equal ["A", "B", "C", "a", "b", "c"], tsv["row1"]
53
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
54
+ assert_equal ["AAA", "BBB", "CCC", "aaa", "bbb", "ccc"], tsv["row3"]
55
+ end
56
+
57
+ def test_paste_stream_sort
58
+ text1=<<-EOF
59
+ #: :sep=" "
60
+ #Row LabelA LabelB LabelC
61
+ row2 AA BB CC
62
+ row1 A B C
63
+ row3 AAA BBB CCC
64
+ EOF
65
+
66
+ text2=<<-EOF
67
+ #: :sep=" "
68
+ #Row Labela Labelb
69
+ row1 a b
70
+ row3 aaa bbb
71
+ row2 aa bb
72
+ EOF
73
+
74
+ text3=<<-EOF
75
+ #: :sep=" "
76
+ #Row Labelc
77
+ row3 ccc
78
+ row1 c
79
+ row2 cc
80
+ EOF
81
+
82
+ s1 = StringIO.new text1
83
+ s2 = StringIO.new text2
84
+ s3 = StringIO.new text3
85
+ tsv = TSV.open TSV.paste_streams([s1,s2,s3], :sep => " ", :type => :list, :sort => true)
86
+ assert_equal "Row", tsv.key_field
87
+ assert_equal %w(LabelA LabelB LabelC Labela Labelb Labelc), tsv.fields
88
+ assert_equal ["A", "B", "C", "a", "b", "c"], tsv["row1"]
89
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
90
+ assert_equal ["AAA", "BBB", "CCC", "aaa", "bbb", "ccc"], tsv["row3"]
91
+ end
92
+ end
@@ -18,12 +18,10 @@ row2 A B Id3
18
18
 
19
19
  assert_equal 2, TSV.field_match_counts(tsv, ["a","A","a","b","Id3"])["ValueA"]
20
20
  assert_equal nil, TSV.field_match_counts(tsv, ["ValueA"])["ValueA"]
21
-
22
21
  end
23
-
24
22
  end
25
23
 
26
- def test_marshal
24
+ def _test_marshal
27
25
  content =<<-EOF
28
26
  #Id ValueA ValueB OtherID
29
27
  row1 a|aa|aaa b Id1|Id2
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../test_helper')
2
+ require 'test/unit'
3
+ require 'rbbt/tsv'
4
+ require 'rbbt/util/misc'
5
+
6
+ class TestMiscPipes < Test::Unit::TestCase
7
+
8
+ def test_collapse_stream
9
+ text=<<-EOF
10
+ row1 A B C
11
+ row1 a b c
12
+ row2 AA BB CC
13
+ row2 aa bb cc
14
+ EOF
15
+
16
+ s = StringIO.new text
17
+ tsv = TSV.open Misc.collapse_stream(s,nil, " "), :sep => " "
18
+ assert_equal ["A", "a"], tsv["row1"][0]
19
+ assert_equal ["BB", "bb"], tsv["row2"][1]
20
+ end
21
+
22
+ def test_paste_stream
23
+ text1=<<-EOF
24
+ row1 A B C
25
+ row2 AA BB CC
26
+ row3 AAA BBB CCC
27
+ EOF
28
+
29
+ text2=<<-EOF
30
+ row1 a b
31
+ row2 aa bb
32
+ EOF
33
+
34
+ text3=<<-EOF
35
+ row1 c
36
+ row2 cc
37
+ row3 ccc
38
+ EOF
39
+
40
+ s1 = StringIO.new text1
41
+ s2 = StringIO.new text2
42
+ s3 = StringIO.new text3
43
+ tsv = TSV.open Misc.paste_streams([s1,s2,s3],nil, " "), :sep => " ", :type => :list
44
+ assert_equal ["A", "B", "C", "a", "b", "c"], tsv["row1"]
45
+ assert_equal ["AA", "BB", "CC", "aa", "bb", "cc"], tsv["row2"]
46
+ assert_equal ["AAA", "BBB", "CCC", "", "", "ccc"], tsv["row3"]
47
+ end
48
+
49
+ def test_sort_stream
50
+ text =<<-EOF
51
+ #: :sep=" "
52
+ #Row LabelA LabelB LabelC
53
+ row2 AA BB CC
54
+ row3 AAA BBB CCC
55
+ row1 A B C
56
+ EOF
57
+ s = StringIO.new text
58
+ sorted = Misc.sort_stream(s)
59
+ assert_equal %w(#: #Row row2 row3 row1), text.split("\n").collect{|l| l.split(" ").first}
60
+ assert_equal %w(#: #Row row1 row2 row3), sorted.read.split("\n").collect{|l| l.split(" ").first}
61
+ end
62
+
63
+ def test_dup_stream
64
+ text =<<-EOF
65
+ #: :sep=" "
66
+ #Row LabelA LabelB LabelC
67
+ row2 AA BB CC
68
+ row3 AAA BBB CCC
69
+ row1 A B C
70
+ EOF
71
+
72
+ TmpFile.with_file(text) do |tmp|
73
+ io = Open.open(tmp)
74
+ dup = Misc.dup_stream(io)
75
+ assert_equal text, dup.read
76
+ assert_equal text, io.read
77
+ end
78
+ end
79
+ end