rbbt-util 5.11.9 → 5.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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