scout-gear 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +29 -0
  3. data/VERSION +1 -1
  4. data/bin/scout +5 -1
  5. data/lib/rbbt-scout.rb +5 -0
  6. data/lib/scout/concurrent_stream.rb +6 -2
  7. data/lib/scout/config.rb +168 -0
  8. data/lib/scout/exceptions.rb +4 -3
  9. data/lib/scout/indiferent_hash/options.rb +1 -0
  10. data/lib/scout/indiferent_hash.rb +4 -2
  11. data/lib/scout/log/color.rb +3 -1
  12. data/lib/scout/log/progress/report.rb +1 -0
  13. data/lib/scout/log/progress/util.rb +1 -1
  14. data/lib/scout/log/progress.rb +5 -3
  15. data/lib/scout/log.rb +3 -2
  16. data/lib/scout/misc/monitor.rb +3 -0
  17. data/lib/scout/misc/system.rb +15 -0
  18. data/lib/scout/misc.rb +1 -0
  19. data/lib/scout/named_array.rb +68 -0
  20. data/lib/scout/open/stream.rb +38 -7
  21. data/lib/scout/path/find.rb +27 -3
  22. data/lib/scout/path/util.rb +7 -4
  23. data/lib/scout/persist/serialize.rb +7 -14
  24. data/lib/scout/persist.rb +21 -1
  25. data/lib/scout/resource/produce.rb +7 -94
  26. data/lib/scout/resource/software.rb +176 -0
  27. data/lib/scout/tsv/dumper.rb +107 -0
  28. data/lib/scout/tsv/index.rb +49 -0
  29. data/lib/scout/tsv/parser.rb +203 -30
  30. data/lib/scout/tsv/path.rb +13 -0
  31. data/lib/scout/tsv/persist/adapter.rb +348 -0
  32. data/lib/scout/tsv/persist/tokyocabinet.rb +113 -0
  33. data/lib/scout/tsv/persist.rb +15 -0
  34. data/lib/scout/tsv/traverse.rb +48 -0
  35. data/lib/scout/tsv/util.rb +24 -0
  36. data/lib/scout/tsv.rb +16 -3
  37. data/lib/scout/work_queue/worker.rb +3 -3
  38. data/lib/scout/work_queue.rb +22 -7
  39. data/lib/scout/workflow/definition.rb +93 -4
  40. data/lib/scout/workflow/step/config.rb +18 -0
  41. data/lib/scout/workflow/step/dependencies.rb +40 -0
  42. data/lib/scout/workflow/step/file.rb +15 -0
  43. data/lib/scout/workflow/step/info.rb +31 -4
  44. data/lib/scout/workflow/step/provenance.rb +148 -0
  45. data/lib/scout/workflow/step.rb +68 -19
  46. data/lib/scout/workflow/task.rb +3 -2
  47. data/lib/scout/workflow/usage.rb +1 -1
  48. data/lib/scout/workflow.rb +11 -3
  49. data/lib/scout-gear.rb +1 -0
  50. data/lib/scout.rb +1 -0
  51. data/scout-gear.gemspec +34 -3
  52. data/scout_commands/find +1 -1
  53. data/scout_commands/workflow/task +16 -10
  54. data/share/software/install_helpers +523 -0
  55. data/test/scout/log/test_progress.rb +0 -2
  56. data/test/scout/misc/test_system.rb +21 -0
  57. data/test/scout/open/test_stream.rb +159 -0
  58. data/test/scout/path/test_find.rb +14 -7
  59. data/test/scout/resource/test_software.rb +24 -0
  60. data/test/scout/test_config.rb +66 -0
  61. data/test/scout/test_meta_extension.rb +10 -0
  62. data/test/scout/test_named_array.rb +19 -0
  63. data/test/scout/test_persist.rb +35 -0
  64. data/test/scout/test_tmpfile.rb +2 -2
  65. data/test/scout/test_tsv.rb +41 -1
  66. data/test/scout/test_work_queue.rb +40 -13
  67. data/test/scout/tsv/persist/test_adapter.rb +34 -0
  68. data/test/scout/tsv/persist/test_tokyocabinet.rb +92 -0
  69. data/test/scout/tsv/test_dumper.rb +44 -0
  70. data/test/scout/tsv/test_index.rb +64 -0
  71. data/test/scout/tsv/test_parser.rb +86 -0
  72. data/test/scout/tsv/test_persist.rb +36 -0
  73. data/test/scout/tsv/test_traverse.rb +9 -0
  74. data/test/scout/tsv/test_util.rb +0 -0
  75. data/test/scout/work_queue/test_worker.rb +3 -3
  76. data/test/scout/workflow/step/test_dependencies.rb +25 -0
  77. data/test/scout/workflow/step/test_info.rb +15 -17
  78. data/test/scout/workflow/step/test_load.rb +16 -18
  79. data/test/scout/workflow/step/test_provenance.rb +25 -0
  80. data/test/scout/workflow/test_step.rb +206 -10
  81. data/test/scout/workflow/test_task.rb +0 -3
  82. data/test/test_helper.rb +6 -0
  83. metadata +33 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d00b2f7d1a5156c6259729b245722979b34132ca3a66922110662fadfc56b65
4
- data.tar.gz: 057a511570907a68d6ee7d962705bfe3cc92325c1fc026b45c5ff0dfb0634f96
3
+ metadata.gz: de499ccbdffd888298324a025b253f0dd0e359d279d6abe8331acd91fd00cc57
4
+ data.tar.gz: 9643053080da23a98209ebefbcd3b3043b7031374a405ffed112460f1ddcf411
5
5
  SHA512:
6
- metadata.gz: 8ca8280c5f4ac63ca98cc8c2388700e29752ec37b008d3f9b54a7bab13569af24fc94afbbfc60d9e295ca81c9a2e5a64bdab83e6cab7c9dd6d531013d72f6954
7
- data.tar.gz: c056280d255116ed9a3c74ee8c1b4c367f30abf6ec60d278180534afc1728d104f89ac247fa0b1d7fb751692b869e2cf73a6a8ac8b6bef8f07e411a59e476409
6
+ metadata.gz: 73afbf6aeb4032380fc45e2f60e2e9335d763c6837ef3bb8247c83bfaf2cd962a6fdfba767788b988e00f685d0e9bc19927a4e794fc092296cc088f23d4565ee
7
+ data.tar.gz: 309e86afe466c649800fd212fd22e9e183a5e92ba558d88ec0258690a15437952ead3e968c3693b89c036dc2fa9e27f4d129f6be6c001031dc38ab071361ba99
data/.vimproject CHANGED
@@ -18,6 +18,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
18
18
  lib=lib {
19
19
  scout-gear.rb
20
20
  workflow-scout.rb
21
+ rbbt-scout.rb
21
22
  scout.rb
22
23
  scout=scout{
23
24
  meta_extension.rb
@@ -30,7 +31,9 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
30
31
  digest.rb
31
32
  filesystem.rb
32
33
  monitor.rb
34
+ system.rb
33
35
  }
36
+ named_array.rb
34
37
  indiferent_hash.rb
35
38
  indiferent_hash=indiferent_hash{
36
39
  case_insensitive.rb
@@ -77,10 +80,12 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
77
80
  produce=produce{
78
81
  rake.rb
79
82
  }
83
+ software.rb
80
84
  scout.rb
81
85
  util.rb
82
86
  path.rb
83
87
  }
88
+ config.rb
84
89
  persist.rb
85
90
  persist=persist{
86
91
  serialize.rb
@@ -94,6 +99,10 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
94
99
  step=step{
95
100
  info.rb
96
101
  load.rb
102
+ file.rb
103
+ config.rb
104
+ dependencies.rb
105
+ provenance.rb
97
106
  }
98
107
  task.rb
99
108
  task=task{
@@ -112,6 +121,16 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
112
121
  tsv.rb
113
122
  tsv=tsv{
114
123
  parser.rb
124
+ dumper.rb
125
+ persist.rb
126
+ index.rb
127
+ persist=persist{
128
+ adapter.rb
129
+ tokyocabinet.rb
130
+ }
131
+ traverse.rb
132
+ util.rb
133
+ path.rb
115
134
  }
116
135
  }
117
136
  }
@@ -126,6 +145,13 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
126
145
  test_tmpfile.rb
127
146
  }
128
147
  }
148
+ share=share{
149
+ software=software{
150
+ install_helpers
151
+ }
152
+ }
153
+
154
+
129
155
 
130
156
  modules=modules{
131
157
  rbbt-util=rbbt-util filter="*.rb *.rake Rakefile *.rdoc *.R *.sh *.js *.haml *.sass *.txt *.conf LICENSE" {
@@ -386,6 +412,9 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
386
412
  resource.rb
387
413
  resource=resource{
388
414
  path.rb
415
+ path=path{
416
+ refactor.rb
417
+ }
389
418
  util.rb
390
419
  with_key.rb
391
420
  rake.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.1.0
1
+ 7.2.0
data/bin/scout CHANGED
@@ -37,6 +37,11 @@ if dev_dir
37
37
  $LOAD_PATH.unshift f
38
38
  end
39
39
  end
40
+ ['rbbt-*/lib'].each do |pattern|
41
+ Dir.glob(File.join(File.expand_path(dev_dir), pattern)).each do |f|
42
+ $LOAD_PATH.unshift f
43
+ end
44
+ end
40
45
  end
41
46
 
42
47
  Log.nocolor = true if ARGV.include? "--nocolor"
@@ -112,7 +117,6 @@ def commands(prev)
112
117
  end
113
118
 
114
119
  def scout_usage(prev = nil)
115
- puts
116
120
  puts SOPT.doc
117
121
 
118
122
  if prev
data/lib/rbbt-scout.rb ADDED
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift File.join(__dir__, '../modules/rbbt-util/lib')
2
+ module Rbbt
3
+ extend Resource
4
+ self.pkgdir = 'rbbt'
5
+ end
@@ -9,11 +9,11 @@ module AbortedStream
9
9
  end
10
10
 
11
11
  module ConcurrentStream
12
- attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile, :no_fail, :pair, :thread, :stream_exception, :log, :std_err
12
+ attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile, :no_fail, :pair, :thread, :stream_exception, :log, :std_err, :next
13
13
 
14
14
  def self.setup(stream, options = {}, &block)
15
15
 
16
- threads, pids, callback, abort_callback, filename, autojoin, lockfile, no_fail, pair = IndiferentHash.process_options options, :threads, :pids, :callback, :abort_callback, :filename, :autojoin, :lockfile, :no_fail, :pair
16
+ threads, pids, callback, abort_callback, filename, autojoin, lockfile, no_fail, pair, next_stream = IndiferentHash.process_options options, :threads, :pids, :callback, :abort_callback, :filename, :autojoin, :lockfile, :no_fail, :pair, :next
17
17
  stream.extend ConcurrentStream unless ConcurrentStream === stream
18
18
 
19
19
  stream.threads ||= []
@@ -24,6 +24,7 @@ module ConcurrentStream
24
24
  stream.no_fail = no_fail unless no_fail.nil?
25
25
  stream.std_err = ""
26
26
 
27
+ stream.next = next_stream unless next_stream.nil?
27
28
  stream.pair = pair unless pair.nil?
28
29
 
29
30
  callback = block if block_given?
@@ -230,6 +231,9 @@ module ConcurrentStream
230
231
  def read(*args)
231
232
  begin
232
233
  super(*args)
234
+ rescue
235
+ raise stream_exception if stream_exception
236
+ raise $!
233
237
  ensure
234
238
  begin
235
239
  close unless closed?
@@ -0,0 +1,168 @@
1
+ require_relative 'path'
2
+ require_relative 'resource'
3
+ require_relative 'resource/scout'
4
+
5
+ module Scout::Config
6
+
7
+ CACHE = IndiferentHash.setup({})
8
+
9
+ GOT_KEYS=[]
10
+
11
+ def self.add_entry(key, value, tokens)
12
+ tokens = [tokens] unless Array === tokens
13
+ tokens << "key:#{key}" unless tokens.include?("key:#{key}")
14
+ CACHE[key.to_s] ||= []
15
+ CACHE[key.to_s] << [tokens, value]
16
+ end
17
+
18
+ def self.load_file(file)
19
+ Log.debug "Loading config file: #{ file }"
20
+ TSV.traverse file, :type => :array do |line|
21
+ next if line =~ /^#/
22
+ key, value, *tokens = line.strip.split(/\s/)
23
+
24
+ self.add_entry(key, value, tokens) if key
25
+ end
26
+ end
27
+
28
+ def self.load_config
29
+ Scout.etc.config.find_all.reverse.each do |file|
30
+ self.load_file(file)
31
+ end
32
+ end
33
+
34
+ def self.set(values, *tokens)
35
+ if not Hash === values
36
+ values = {values => tokens.shift}
37
+ end
38
+
39
+ values.each do |key,value|
40
+ add_entry key, value, tokens
41
+ end
42
+ end
43
+
44
+ def self.token_priority(token)
45
+ token, _sep, priority = token.to_s.partition("::")
46
+
47
+ if priority.nil? || priority.empty?
48
+ type, _sep, rest = token.partition(":")
49
+ priority = case type
50
+ when "workflow"
51
+ 4
52
+ when "task"
53
+ 3
54
+ when "file"
55
+ 2
56
+ when "line"
57
+ 1
58
+ when "key"
59
+ 20
60
+ else
61
+ 10
62
+ end
63
+ else
64
+ priority = priority.to_i
65
+ end
66
+
67
+ [token, priority]
68
+ end
69
+
70
+ def self.match(entries, give_token)
71
+ priorities = {}
72
+ entries.each do |tokens, value|
73
+ best_prio = nil
74
+ tokens = [tokens] unless Array === tokens
75
+ tokens.each do |tok|
76
+ tok, prio = token_priority tok
77
+ next unless tok == give_token
78
+
79
+ best_prio = prio if best_prio.nil? or best_prio > prio
80
+ next if prio > best_prio
81
+
82
+ priorities[prio] ||= []
83
+ priorities[prio].unshift value
84
+ end
85
+ end if entries
86
+ priorities
87
+ end
88
+
89
+ # For equal priorities the matching prioritizes tokens ealier in the list
90
+ def self.get(key, *tokens)
91
+ options = tokens.pop if Hash === tokens.last
92
+ default = options.nil? ? nil : options[:default]
93
+
94
+ tokens = ["key:" + key] if tokens.empty?
95
+
96
+ tokens = tokens.flatten
97
+ file, _sep, line = caller.reject{|l|
98
+ l =~ /rbbt\/(?:resource\.rb|workflow\.rb)/ or
99
+ l =~ /rbbt\/resource\/path\.rb/ or
100
+ l =~ /rbbt\/util\/misc\.rb/ or
101
+ l =~ /accessor\.rb/ or
102
+ l =~ /progress-monitor\.rb/
103
+ }.first.partition(":")
104
+
105
+ File.expand_path(file)
106
+
107
+ tokens << ("file:" << file)
108
+ tokens << ("line:" << file << ":" << line.sub(/:in \`.*/,''))
109
+
110
+ entries = CACHE[key.to_s]
111
+ priorities = {}
112
+ tokens.each do |token|
113
+ token_prio = match entries, token.to_s
114
+ token_prio.each do |prio, values|
115
+ priorities[prio] ||= []
116
+ priorities[prio].concat(values)
117
+ end
118
+ end
119
+
120
+ value = priorities.empty? ? default : priorities.collect{|p| p }.sort_by{|p,v| p}.first.last.first
121
+ value = false if value == 'false'
122
+
123
+ Log.debug "Value #{value.inspect} for config key '#{ key }': #{tokens * ", "}"
124
+ GOT_KEYS << [key, value, tokens]
125
+
126
+ if String === value && m = value.match(/^env:(.*)/)
127
+ variable = m.captures.first
128
+ ENV[variable]
129
+ elsif value == 'nil'
130
+ nil
131
+ else
132
+ value
133
+ end
134
+ end
135
+
136
+ def self.with_config
137
+ saved_config = {}
138
+ CACHE.each do |k,v|
139
+ saved_config[k] = v.dup
140
+ end
141
+ saved_got_keys = GOT_KEYS.dup
142
+ begin
143
+ yield
144
+ ensure
145
+ CACHE.replace(saved_config)
146
+ GOT_KEYS.replace(saved_got_keys)
147
+ end
148
+ end
149
+
150
+ def self.process_config(config)
151
+ if Misc.is_filename?(config) && File.exist?(config)
152
+ Scout::Config.load_file(config)
153
+ elsif Scout.etc.config_profile[config].exists?
154
+ Scout::Config.load_file(Scout.etc.config_profile[config].find)
155
+ else
156
+ key, value, *tokens = config.split(/\s/)
157
+ tokens = tokens.collect do |tok|
158
+ tok, _sep, prio = tok.partition("::")
159
+ prio = "0" if prio.nil? or prio.empty?
160
+ [tok, prio] * "::"
161
+ end
162
+ Scout::Config.set({key => value}, *tokens)
163
+ end
164
+ end
165
+
166
+
167
+ self.load_config
168
+ end
@@ -85,9 +85,9 @@ class DoneProcessing < Exception
85
85
  end
86
86
 
87
87
  class WorkerException < ScoutException
88
- attr_accessor :exception, :pid
89
- def initialize(exception, pid)
90
- @exception = exception
88
+ attr_accessor :worker_exception, :pid
89
+ def initialize(worker_exception, pid)
90
+ @worker_exception = worker_exception
91
91
  @pid = pid
92
92
  end
93
93
  end
@@ -137,3 +137,4 @@ end
137
137
  #
138
138
  #
139
139
  #
140
+ class ResourceNotFound < ScoutException; end
@@ -29,6 +29,7 @@ module IndiferentHash
29
29
 
30
30
  def self.pull_keys(hash, prefix)
31
31
  new = {}
32
+ prefix = prefix.to_s
32
33
  hash.keys.each do |key|
33
34
  if key.to_s =~ /#{ prefix }_(.*)/
34
35
  case
@@ -58,9 +58,11 @@ module IndiferentHash
58
58
  def delete(key)
59
59
  case key
60
60
  when Symbol, Module
61
- super(key) || super(key.to_s)
61
+ v = super(key)
62
+ v.nil? ? super(key.to_s) : v
62
63
  when String
63
- super(key) || super(key.to_sym)
64
+ v = super(key)
65
+ v.nil? ? super(key.to_sym) : v
64
66
  else
65
67
  super(key)
66
68
  end
@@ -185,8 +185,10 @@ module Log
185
185
  :red
186
186
  when :waiting, :queued
187
187
  :yellow
188
- when :started, :start, :streamming
188
+ when :started, :streamming
189
189
  :cyan
190
+ when :start
191
+ :title
190
192
  else
191
193
  :cyan
192
194
  end
@@ -2,6 +2,7 @@ require 'yaml'
2
2
  module Log
3
3
  class ProgressBar
4
4
  def print(io, str)
5
+ return if self.severity && self.severity < Log.severity
5
6
  return if Log.no_bar
6
7
  STDERR.print str
7
8
  Log.logfile.puts str unless Log.logfile.nil?
@@ -81,7 +81,7 @@ module Log
81
81
  Log::ProgressBar.remove_bar self, error
82
82
  end
83
83
 
84
- def self.with_bar(max, options = {})
84
+ def self.with_bar(max = nil, options = {})
85
85
  bar = new_bar(max, options)
86
86
  begin
87
87
  error = false
@@ -15,20 +15,22 @@ module Log
15
15
 
16
16
  class << self
17
17
  attr_accessor :default_file
18
+ attr_accessor :default_severity
18
19
  end
19
20
 
20
21
  attr_accessor :max, :ticks, :frequency, :depth, :desc, :file, :bytes, :process, :callback, :severity
21
22
 
22
23
  def initialize(max = nil, options = {})
23
- depth, desc, file, bytes, frequency, process, callback =
24
- IndiferentHash.process_options options, :depth, :desc, :file, :bytes, :frequency, :process, :callback,
25
- :depth => 0, :frequency => 2
24
+ depth, desc, file, bytes, frequency, process, callback, severity =
25
+ IndiferentHash.process_options options, :depth, :desc, :file, :bytes, :frequency, :process, :callback, :severity,
26
+ :depth => 0, :frequency => 2, :severity => Log::ProgressBar.default_severity
26
27
 
27
28
  max = nil if TrueClass === max
28
29
 
29
30
  @max = max
30
31
  @ticks = 0
31
32
  @frequency = frequency
33
+ @severity = severity
32
34
  @last_time = nil
33
35
  @last_count = nil
34
36
  @last_percent = nil
data/lib/scout/log.rb CHANGED
@@ -186,11 +186,12 @@ module Log
186
186
 
187
187
  def self.exception(e)
188
188
  stack = caller
189
+ backtrace = e.backtrace || []
189
190
  if ENV["RBBT_ORIGINAL_STACK"] == 'true'
190
191
  error([e.class.to_s, e.message].compact * ": " )
191
- error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(e.backtrace)*"\n")
192
+ error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(backtrace)*"\n")
192
193
  else
193
- error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(e.backtrace.reverse)*"\n")
194
+ error("BACKTRACE [#{Process.pid}]: " << Log.last_caller(stack) << "\n" + color_stack(backtrace.reverse)*"\n")
194
195
  error([e.class.to_s, e.message].compact * ": " )
195
196
  end
196
197
  end
@@ -1,4 +1,7 @@
1
1
  module Misc
2
+ def self.pid_alive?(pid)
3
+ !! Process.kill(0, pid) rescue false
4
+ end
2
5
  def self.benchmark(repeats = 1, message = nil)
3
6
  require 'benchmark'
4
7
  res = nil
@@ -0,0 +1,15 @@
1
+ module Misc
2
+ def self.env_add(var, value, sep = ":", prepend = true)
3
+ if ENV[var].nil?
4
+ ENV[var] = value
5
+ elsif ENV[var] =~ /(#{sep}|^)#{Regexp.quote value}(#{sep}|$)/
6
+ return
7
+ else
8
+ if prepend
9
+ ENV[var] = value + sep + ENV[var]
10
+ else
11
+ ENV[var] += sep + value
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/scout/misc.rb CHANGED
@@ -3,6 +3,7 @@ require_relative 'misc/insist'
3
3
  require_relative 'misc/digest'
4
4
  require_relative 'misc/filesystem'
5
5
  require_relative 'misc/monitor'
6
+ require_relative 'misc/system'
6
7
 
7
8
  module Misc
8
9
  end
@@ -0,0 +1,68 @@
1
+ require_relative 'meta_extension'
2
+ module NamedArray
3
+ extend MetaExtension
4
+ extension_attr :fields
5
+
6
+ def self.identify_name(names, selected)
7
+ res = (Array === selected ? selected : [selected]).collect do |field|
8
+ case field
9
+ when nil
10
+ 0
11
+ when Integer
12
+ field
13
+ when Symbol
14
+ field == :key ? field : identify_name(names, field.to_s)
15
+ when (names.nil? and String)
16
+ if field =~ /^\d+$/
17
+ identify_field(key_field, fields, field.to_i)
18
+ else
19
+ raise "No name information available and specified name not numeric: #{ field }"
20
+ end
21
+ when Symbol
22
+ names.index{|f| f.to_s == field.to_s }
23
+ when String
24
+ pos = names.index{|f| f.to_s == field }
25
+ next pos if pos
26
+ if field =~ /^\d+$/
27
+ next identify_names(names, field.to_i)
28
+ end
29
+ pos = names.index{|name| name.start_with?(field) }
30
+ next pos if pos
31
+ nil
32
+ else
33
+ raise "Field '#{ Log.fingerprint field }' was not understood. Options: (#{ Log.fingerprint names })"
34
+ end
35
+ end
36
+
37
+ Array === selected ? res : res.first
38
+ end
39
+
40
+ def positions(fields)
41
+ if Array == fields
42
+ fields.collect{|field|
43
+ NamedArray.identify_name(@fields, field)
44
+ }
45
+ else
46
+ NamedArray.identify_name(@fields, fields)
47
+ end
48
+ end
49
+
50
+ def [](key)
51
+ pos = NamedArray.identify_name(@fields, key)
52
+ super(pos)
53
+ end
54
+
55
+ def concat(other)
56
+ super(other)
57
+ self.fields.concat(other.fields) if NamedArray === other
58
+ self
59
+ end
60
+
61
+ def to_hash
62
+ hash = {}
63
+ self.fields.zip(self) do |field,value|
64
+ hash[field] = value
65
+ end
66
+ IndiferentHash.setup hash
67
+ end
68
+ end
@@ -1,5 +1,5 @@
1
1
  module Open
2
- BLOCK_SIZE = 1024
2
+ BLOCK_SIZE = 1024 * 8
3
3
 
4
4
  class << self
5
5
  attr_accessor :sensible_write_lock_dir
@@ -52,9 +52,7 @@ module Open
52
52
  into_path, into = into, File.open(into, 'w')
53
53
  end
54
54
 
55
- into.sync = true if IO === into
56
55
  into_close = false unless into.respond_to? :close
57
- io.sync = true
58
56
 
59
57
  begin
60
58
  while c = io.readpartial(BLOCK_SIZE)
@@ -77,7 +75,7 @@ module Open
77
75
  FileUtils.rm into_path if into_path and File.exist?(into_path)
78
76
  rescue Exception
79
77
  Log.low "Consume stream Exception reading #{Log.fingerprint io} into #{into_path || into} - #{$!.message}"
80
- exception = io.stream_exception || $!
78
+ exception = (io.respond_to?(:stream_exception) && io.stream_exception) ? io.stream_exception : $!
81
79
  io.abort exception if io.respond_to? :abort
82
80
  into.close if into.respond_to?(:closed?) && ! into.closed?
83
81
  into_path = into if into_path.nil? && String === into
@@ -110,7 +108,7 @@ module Open
110
108
  Log.warn "Path exists in sensible_write, not forcing update: #{ path }"
111
109
  Open.consume_stream content
112
110
  else
113
- FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory? File.dirname(tmp_path)
111
+ FileUtils.mkdir_p File.dirname(tmp_path) unless File.directory?(File.dirname(tmp_path))
114
112
  FileUtils.rm_f tmp_path if File.exist? tmp_path
115
113
  begin
116
114
 
@@ -121,7 +119,7 @@ module Open
121
119
  File.open(tmp_path, 'wb') do |f| f.write content end
122
120
  when (IO === content or StringIO === content or File === content)
123
121
  Open.write(tmp_path) do |f|
124
- f.sync = true
122
+ #f.sync = true
125
123
  begin
126
124
  while block = content.readpartial(BLOCK_SIZE)
127
125
  f.write block
@@ -345,7 +343,6 @@ module Open
345
343
  end
346
344
  end
347
345
 
348
-
349
346
  out_pipes.each do |sout|
350
347
  ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :pair => stream
351
348
  end
@@ -400,5 +397,39 @@ module Open
400
397
  end
401
398
  str
402
399
  end
400
+
401
+ def self.sort_stream(stream, header_hash = "#", cmd_args = "-u")
402
+ Open.open_pipe do |sin|
403
+ line = stream.gets
404
+ while line =~ /^#{header_hash}/ do
405
+ sin.puts line
406
+ line = stream.gets
407
+ end
408
+
409
+ line_stream = Open.open_pipe do |line_stream_in|
410
+ line_stream_in.puts line
411
+ begin
412
+ Open.consume_stream(stream, false, line_stream_in)
413
+ rescue
414
+ raise $!
415
+ end
416
+ end
417
+
418
+ sorted = CMD.cmd("env LC_ALL=C sort #{cmd_args || ""}", :in => line_stream, :pipe => true)
419
+
420
+ begin
421
+ Open.consume_stream(sorted, false, sin)
422
+ rescue
423
+ Log.exception $!
424
+ begin
425
+ sorted.raise($!) if sorted.respond_to? :raise
426
+ stream.raise($!) if stream.respond_to? :raise
427
+ ensure
428
+ raise $!
429
+ end
430
+ end
431
+ end
432
+ end
433
+
403
434
 
404
435
  end
@@ -9,7 +9,8 @@ module Path
9
9
  break unless file =~ /(?:scout|rbbt)\/(?:resource\.rb|workflow\.rb)/ or
10
10
  file =~ /(?:scout|rbbt)\/(?:.*\/)?path\.rb/ or
11
11
  file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
12
- file =~ /(?:scout|rbbt)\/persist.rb/
12
+ file =~ /(?:scout|rbbt)\/persist.rb/ or
13
+ file =~ /modules\/rbbt-util/
13
14
  end
14
15
  file = file.sub(/\.rb[^\w].*/,'.rb')
15
16
  end
@@ -136,15 +137,38 @@ module Path
136
137
  found
137
138
  end
138
139
 
140
+ def self.exists_file_or_alternatives(file)
141
+ return file if File.exist?(file) or File.directory?(file)
142
+ %w(gz bgz zip).each do |extension|
143
+ alt_file = file + '.' + extension
144
+ return alt_file if File.exist?(alt_file) or File.directory?(alt_file)
145
+ end
146
+ nil
147
+ end
148
+
139
149
  def find(where = nil)
140
- return self if located?
150
+ if located?
151
+ if File.exist?(self)
152
+ return self if located?
153
+ else
154
+ found = Path.exists_file_or_alternatives(self)
155
+ if found
156
+ return self.annotate(found)
157
+ else
158
+ return self if located?
159
+ end
160
+ end
161
+ end
162
+
141
163
  return find_all if where == 'all' || where == :all
164
+
142
165
  return follow(where) if where
143
166
 
144
167
  map_order.each do |map_name|
145
168
  found = follow(map_name, false)
146
169
 
147
- return annotate_found_where(found, map_name) if File.exist?(found) || File.directory?(found)
170
+ found = Path.exists_file_or_alternatives(found)
171
+ return annotate_found_where(found, map_name) if found
148
172
  end
149
173
 
150
174
  return follow(:default)