scout-gear 7.1.0 → 7.2.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 (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)