scout-gear 5.2.0 → 7.1.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.
- checksums.yaml +4 -4
- data/.vimproject +450 -440
- data/VERSION +1 -1
- data/lib/scout/exceptions.rb +22 -2
- data/lib/scout/log/color.rb +61 -10
- data/lib/scout/log/progress/report.rb +5 -4
- data/lib/scout/log/progress/util.rb +2 -0
- data/lib/scout/log/progress.rb +2 -0
- data/lib/scout/log.rb +5 -1
- data/lib/scout/misc/digest.rb +1 -3
- data/lib/scout/misc/monitor.rb +18 -0
- data/lib/scout/open/stream.rb +50 -19
- data/lib/scout/semaphore.rb +148 -0
- data/lib/scout/tsv/parser.rb +144 -0
- data/lib/scout/tsv.rb +14 -0
- data/lib/scout/work_queue/socket.rb +119 -0
- data/lib/scout/work_queue/worker.rb +59 -0
- data/lib/scout/work_queue.rb +113 -0
- data/lib/scout/workflow/step/info.rb +2 -2
- data/lib/scout/workflow/step.rb +2 -1
- data/lib/scout/workflow/task.rb +2 -2
- data/scout-gear.gemspec +18 -3
- data/share/color/color_names +507 -0
- data/share/color/diverging_colors.hex +12 -0
- data/test/scout/log/test_color.rb +0 -0
- data/test/scout/open/test_stream.rb +1 -1
- data/test/scout/test_semaphore.rb +17 -0
- data/test/scout/test_tsv.rb +34 -0
- data/test/scout/test_work_queue.rb +121 -0
- data/test/scout/tsv/test_parser.rb +87 -0
- data/test/scout/work_queue/test_socket.rb +46 -0
- data/test/scout/work_queue/test_worker.rb +147 -0
- metadata +17 -2
@@ -0,0 +1,144 @@
|
|
1
|
+
module TSV
|
2
|
+
def self.cast_value(value, cast)
|
3
|
+
if Array === value
|
4
|
+
value.collect{|e| cast_value(e, cast) }
|
5
|
+
else
|
6
|
+
value.send(cast)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.parse_line(line, type: :list, key: 0, positions: nil, sep: "\t", sep2: "|", cast: nil)
|
11
|
+
items = line.split(sep, -1)
|
12
|
+
|
13
|
+
if positions.nil? && key == 0
|
14
|
+
key = items.shift
|
15
|
+
elsif positions.nil?
|
16
|
+
key = items.delete(key)
|
17
|
+
else
|
18
|
+
key, items = items[key], items.values_at(*positions)
|
19
|
+
end
|
20
|
+
|
21
|
+
items = case type
|
22
|
+
when :list
|
23
|
+
items
|
24
|
+
when :single
|
25
|
+
items.first
|
26
|
+
when :flat
|
27
|
+
[items]
|
28
|
+
when :double
|
29
|
+
items.collect{|i| i.split(sep2, -1) }
|
30
|
+
end
|
31
|
+
|
32
|
+
key = key.partition(sep2).first if type == :double
|
33
|
+
|
34
|
+
if cast
|
35
|
+
items = cast_value(items, cast)
|
36
|
+
end
|
37
|
+
|
38
|
+
[key, items]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.parse_stream(stream, data: nil, merge: true, type: :list, fix: true, bar: false, first_line: nil, **kargs, &block)
|
42
|
+
begin
|
43
|
+
bar = Log::ProgressBar.new_bar(bar) if bar
|
44
|
+
|
45
|
+
data = {} if data.nil?
|
46
|
+
merge = false if type != :double
|
47
|
+
line = first_line || stream.gets
|
48
|
+
while line
|
49
|
+
begin
|
50
|
+
line.strip!
|
51
|
+
line = Misc.fixutf8(line) if fix
|
52
|
+
bar.tick if bar
|
53
|
+
key, items = parse_line(line, type: type, **kargs)
|
54
|
+
|
55
|
+
if block_given?
|
56
|
+
res = block.call(key, items)
|
57
|
+
data[key] = res unless res.nil?
|
58
|
+
next
|
59
|
+
end
|
60
|
+
|
61
|
+
if ! merge || ! data.include?(key)
|
62
|
+
data[key] = items
|
63
|
+
else
|
64
|
+
current = data[key]
|
65
|
+
if merge == :concat
|
66
|
+
items.each_with_index do |new,i|
|
67
|
+
next if new.empty?
|
68
|
+
current[i].concat(new)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
merged = []
|
72
|
+
items.each_with_index do |new,i|
|
73
|
+
next if new.empty?
|
74
|
+
merged[i] = current[i] + new
|
75
|
+
end
|
76
|
+
data[key] = merged
|
77
|
+
end
|
78
|
+
end
|
79
|
+
ensure
|
80
|
+
line = stream.gets
|
81
|
+
end
|
82
|
+
end
|
83
|
+
data
|
84
|
+
ensure
|
85
|
+
Log::ProgressBar.remove_bar(bar) if bar
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.parse_header(stream, fix: true, header_hash: '#', sep: "\n")
|
90
|
+
raise "Closed stream" if IO === stream && stream.closed?
|
91
|
+
|
92
|
+
options = {}
|
93
|
+
preamble = []
|
94
|
+
|
95
|
+
# Get line
|
96
|
+
|
97
|
+
#Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
|
98
|
+
line = stream.gets
|
99
|
+
return {} if line.nil?
|
100
|
+
line = Misc.fixutf8 line.chomp if fix
|
101
|
+
|
102
|
+
# Process options line
|
103
|
+
if line and (String === header_hash && m = line.match(/^#{header_hash}: (.*)/))
|
104
|
+
options = IndiferentHash.string2hash m.captures.first.chomp
|
105
|
+
line = stream.gets
|
106
|
+
line = Misc.fixutf8 line.chomp if line && fix
|
107
|
+
end
|
108
|
+
|
109
|
+
# Determine separator
|
110
|
+
sep = options[:sep] if options[:sep]
|
111
|
+
|
112
|
+
# Process fields line
|
113
|
+
preamble << line if line
|
114
|
+
while line && (TrueClass === header_hash || (String === header_hash && line.start_with?(header_hash)))
|
115
|
+
fields = line.split(sep, -1)
|
116
|
+
key_field = fields.shift
|
117
|
+
key_field = key_field.sub(header_hash, '') if String === header_hash && ! header_hash.empty?
|
118
|
+
|
119
|
+
line = (header_hash != "" ? stream.gets : nil)
|
120
|
+
line = Misc.fixutf8 line.chomp if line
|
121
|
+
preamble << line if line
|
122
|
+
break if TrueClass === header_hash || header_hash == ""
|
123
|
+
end
|
124
|
+
|
125
|
+
preamble = preamble[0..-3] * "\n"
|
126
|
+
|
127
|
+
line ||= stream.gets
|
128
|
+
|
129
|
+
first_line = line
|
130
|
+
|
131
|
+
[options, key_field, fields, first_line, preamble]
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.parse(stream, **kwargs)
|
135
|
+
options, key_field, fields, first_line, preamble = parse_header(stream)
|
136
|
+
|
137
|
+
options.each do |option,value|
|
138
|
+
option = option.to_sym
|
139
|
+
kwargs[option] = value unless kwargs.include?(option)
|
140
|
+
end
|
141
|
+
data = parse_stream(stream, first_line: first_line, **kwargs)
|
142
|
+
TSV.setup data, :key_field => key_field, :fields => fields
|
143
|
+
end
|
144
|
+
end
|
data/lib/scout/tsv.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'meta_extension'
|
2
|
+
require_relative 'tsv/parser'
|
3
|
+
|
4
|
+
module TSV
|
5
|
+
extend MetaExtension
|
6
|
+
extension_attr :key_field, :fields
|
7
|
+
|
8
|
+
def self.open(file, options = {})
|
9
|
+
Open.open(file) do |f|
|
10
|
+
TSV.parse(f,**options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'scout/open'
|
2
|
+
require 'scout/semaphore'
|
3
|
+
require 'scout/exceptions'
|
4
|
+
class WorkQueue
|
5
|
+
class Socket
|
6
|
+
attr_accessor :sread, :swrite, :write_sem, :read_sem, :cleaned
|
7
|
+
def initialize(serializer = nil)
|
8
|
+
@sread, @swrite = Open.pipe
|
9
|
+
|
10
|
+
@serializer = serializer || Marshal
|
11
|
+
|
12
|
+
@key = "/" << rand(1000000000).to_s << '.' << Process.pid.to_s;
|
13
|
+
@write_sem = @key + '.in'
|
14
|
+
@read_sem = @key + '.out'
|
15
|
+
Log.debug "Creating socket semaphores: #{@key}"
|
16
|
+
ScoutSemaphore.create_semaphore(@write_sem,1)
|
17
|
+
ScoutSemaphore.create_semaphore(@read_sem,1)
|
18
|
+
end
|
19
|
+
|
20
|
+
def clean
|
21
|
+
@cleaned = true
|
22
|
+
@sread.close unless @sread.closed?
|
23
|
+
@swrite.close unless @swrite.closed?
|
24
|
+
Log.low "Destroying socket semaphores: #{[@key] * ", "}"
|
25
|
+
ScoutSemaphore.delete_semaphore(@write_sem)
|
26
|
+
ScoutSemaphore.delete_semaphore(@read_sem)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def dump(obj)
|
31
|
+
stream = @swrite
|
32
|
+
obj.concurrent_stream = nil if obj.respond_to?(:concurrent_stream)
|
33
|
+
case obj
|
34
|
+
when Integer
|
35
|
+
size_head = [obj,"I"].pack 'La'
|
36
|
+
str = size_head
|
37
|
+
when nil
|
38
|
+
size_head = [0,"N"].pack 'La'
|
39
|
+
str = size_head
|
40
|
+
when String
|
41
|
+
payload = obj
|
42
|
+
size_head = [payload.bytesize,"C"].pack 'La'
|
43
|
+
str = size_head << payload
|
44
|
+
else
|
45
|
+
payload = @serializer.dump(obj)
|
46
|
+
size_head = [payload.bytesize,"S"].pack 'La'
|
47
|
+
str = size_head << payload
|
48
|
+
end
|
49
|
+
|
50
|
+
write_length = str.length
|
51
|
+
wrote = stream.write(str)
|
52
|
+
while wrote < write_length
|
53
|
+
wrote += stream.write(str[wrote..-1])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def load
|
58
|
+
stream = @sread
|
59
|
+
size_head = Open.read_stream stream, 5
|
60
|
+
|
61
|
+
size, type = size_head.unpack('La')
|
62
|
+
|
63
|
+
return nil if type == "N"
|
64
|
+
return size.to_i if type == "I"
|
65
|
+
begin
|
66
|
+
payload = Open.read_stream stream, size
|
67
|
+
case type
|
68
|
+
when "S"
|
69
|
+
begin
|
70
|
+
@serializer.load(payload)
|
71
|
+
rescue Exception
|
72
|
+
Log.exception $!
|
73
|
+
raise $!
|
74
|
+
end
|
75
|
+
when "C"
|
76
|
+
payload
|
77
|
+
end
|
78
|
+
rescue TryAgain
|
79
|
+
retry
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def closed_read?
|
84
|
+
@sread.closed?
|
85
|
+
end
|
86
|
+
|
87
|
+
def closed_write?
|
88
|
+
@swrite.closed?
|
89
|
+
end
|
90
|
+
|
91
|
+
def close_write
|
92
|
+
self.dump ClosedStream.new
|
93
|
+
@swrite.close unless closed_write?
|
94
|
+
end
|
95
|
+
|
96
|
+
def close_read
|
97
|
+
@sread.close unless closed_read?
|
98
|
+
end
|
99
|
+
|
100
|
+
#{{{ ACCESSOR
|
101
|
+
def push(obj)
|
102
|
+
ScoutSemaphore.synchronize(@write_sem) do
|
103
|
+
self.dump(obj)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def pop
|
108
|
+
ScoutSemaphore.synchronize(@read_sem) do
|
109
|
+
res = self.load
|
110
|
+
raise res if ClosedStream === res
|
111
|
+
res
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
alias write push
|
116
|
+
|
117
|
+
alias read pop
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class WorkQueue
|
2
|
+
class Worker
|
3
|
+
attr_accessor :pid, :ignore_ouput
|
4
|
+
def initialize(ignore_ouput = false)
|
5
|
+
@ignore_output = ignore_ouput
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
@pid = Process.fork do
|
10
|
+
Log.debug "Worker start with #{Process.pid}"
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def process(input, output = nil, &block)
|
16
|
+
run do
|
17
|
+
begin
|
18
|
+
while obj = input.read
|
19
|
+
if DoneProcessing === obj
|
20
|
+
output.write DoneProcessing.new
|
21
|
+
raise obj
|
22
|
+
end
|
23
|
+
res = block.call obj
|
24
|
+
output.write res unless output.nil? || ignore_ouput || res == :ignore
|
25
|
+
end
|
26
|
+
rescue DoneProcessing
|
27
|
+
rescue Interrupt
|
28
|
+
rescue Exception
|
29
|
+
output.write WorkerException.new($!, Process.pid)
|
30
|
+
exit -1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def abort
|
36
|
+
begin
|
37
|
+
Log.log "Aborting worker #{@pid}"
|
38
|
+
Process.kill "INT", @pid
|
39
|
+
rescue Errno::ECHILD
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def join
|
44
|
+
Log.log "Joining worker #{@pid}"
|
45
|
+
Process.waitpid @pid
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.join(workers)
|
49
|
+
workers = [workers] unless Array === workers
|
50
|
+
begin
|
51
|
+
while pid = Process.wait
|
52
|
+
status = $?
|
53
|
+
worker = workers.select{|w| w.pid == pid }.first
|
54
|
+
end
|
55
|
+
rescue Errno::ECHILD
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require_relative 'work_queue/socket'
|
2
|
+
require_relative 'work_queue/worker'
|
3
|
+
|
4
|
+
class WorkQueue
|
5
|
+
attr_accessor :workers, :worker_proc, :callback
|
6
|
+
|
7
|
+
def initialize(workers = 0, &block)
|
8
|
+
@input = WorkQueue::Socket.new
|
9
|
+
@output = WorkQueue::Socket.new
|
10
|
+
@workers = workers.times.collect{ Worker.new }
|
11
|
+
@worker_proc = block
|
12
|
+
@worker_mutex = Mutex.new
|
13
|
+
@removed_workers = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_worker(&block)
|
17
|
+
worker = Worker.new
|
18
|
+
@worker_mutex.synchronize do
|
19
|
+
@workers.push(worker)
|
20
|
+
if block_given?
|
21
|
+
worker.process @input, @output, &block
|
22
|
+
else
|
23
|
+
worker.process @input, @output, &@worker_proc
|
24
|
+
end
|
25
|
+
end
|
26
|
+
worker
|
27
|
+
end
|
28
|
+
|
29
|
+
def ignore_ouput
|
30
|
+
@workers.each{|w| w.ignore_ouput = true }
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_one_worker
|
34
|
+
@input.write DoneProcessing.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_worker(pid)
|
38
|
+
@worker_mutex.synchronize do
|
39
|
+
@workers.delete_if{|w| w.pid == pid }
|
40
|
+
@removed_workers << pid
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def process(&callback)
|
45
|
+
@reader = Thread.new do |parent|
|
46
|
+
begin
|
47
|
+
Thread.current.report_on_exception = false
|
48
|
+
Thread.current["name"] = "Output reader #{Process.pid}"
|
49
|
+
@done_workers ||= []
|
50
|
+
while true
|
51
|
+
obj = @output.read
|
52
|
+
if DoneProcessing === obj
|
53
|
+
done = @worker_mutex.synchronize do
|
54
|
+
Log.low "Worker #{obj.pid} done"
|
55
|
+
@done_workers << obj.pid
|
56
|
+
@done_workers.length == @removed_workers.length + @workers.length
|
57
|
+
end
|
58
|
+
break if done
|
59
|
+
elsif Exception === obj
|
60
|
+
raise obj
|
61
|
+
else
|
62
|
+
callback.call obj if callback
|
63
|
+
end
|
64
|
+
end
|
65
|
+
rescue DoneProcessing
|
66
|
+
rescue Aborted
|
67
|
+
rescue WorkerException
|
68
|
+
Log.error "Exception in worker #{obj.pid} #{Log.fingerprint obj.exception}"
|
69
|
+
self.abort
|
70
|
+
raise obj.exception
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
@workers.each do |w|
|
75
|
+
w.process @input, @output, &@worker_proc
|
76
|
+
end
|
77
|
+
|
78
|
+
Thread.pass until @reader["name"]
|
79
|
+
|
80
|
+
@waiter = Thread.new do
|
81
|
+
begin
|
82
|
+
Thread.current.report_on_exception = false
|
83
|
+
Thread.current["name"] = "Worker waiter #{Process.pid}"
|
84
|
+
while true
|
85
|
+
pid = Process.wait
|
86
|
+
remove_worker(pid)
|
87
|
+
break if workers.empty?
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Thread.pass until @waiter["name"]
|
93
|
+
end
|
94
|
+
|
95
|
+
def write(obj)
|
96
|
+
@input.write obj
|
97
|
+
end
|
98
|
+
|
99
|
+
def abort
|
100
|
+
workers.each{|w| w.abort }
|
101
|
+
end
|
102
|
+
|
103
|
+
def close
|
104
|
+
@worker_mutex.synchronize{ @workers.length }.times do
|
105
|
+
@input.write DoneProcessing.new()
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def join
|
110
|
+
@waiter.join if @waiter
|
111
|
+
@reader.join if @reader
|
112
|
+
end
|
113
|
+
end
|
@@ -55,9 +55,9 @@ class Step
|
|
55
55
|
|
56
56
|
def report_status(status, message = nil)
|
57
57
|
if message.nil?
|
58
|
-
Log.info Log.color(:
|
58
|
+
Log.info Log.color(:status, status, true) + " " + Log.color(:path, path)
|
59
59
|
else
|
60
|
-
Log.info Log.color(:
|
60
|
+
Log.info Log.color(:status, status, true) + " " + Log.color(:path, path) + " " + message
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
data/lib/scout/workflow/step.rb
CHANGED
data/lib/scout/workflow/task.rb
CHANGED
@@ -143,8 +143,8 @@ module Task
|
|
143
143
|
non_default_inputs.concat provided_inputs.keys.select{|k| String === k && k.include?("#") } if Hash === provided_inputs
|
144
144
|
|
145
145
|
if non_default_inputs.any?
|
146
|
-
hash = Misc.digest(:inputs => input_hash, :
|
147
|
-
Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :dependencies => dependencies)}"
|
146
|
+
hash = Misc.digest(:inputs => input_hash, :dependencies => dependencies)
|
147
|
+
Log.debug "Hash #{name} - #{hash}: #{Misc.digest_str(:inputs => inputs, :non_default_inputs => non_default_inputs, :dependencies => dependencies)}"
|
148
148
|
id = [id, hash] * "_"
|
149
149
|
end
|
150
150
|
|
data/scout-gear.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: scout-gear
|
5
|
+
# stub: scout-gear 7.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "scout-gear".freeze
|
9
|
-
s.version = "
|
9
|
+
s.version = "7.1.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Miguel Vazquez".freeze]
|
14
|
-
s.date = "2023-
|
14
|
+
s.date = "2023-05-01"
|
15
15
|
s.description = "Temporary files, logs, etc.".freeze
|
16
16
|
s.email = "mikisvaz@gmail.com".freeze
|
17
17
|
s.executables = ["scout".freeze]
|
@@ -69,6 +69,7 @@ Gem::Specification.new do |s|
|
|
69
69
|
"lib/scout/resource/produce/rake.rb",
|
70
70
|
"lib/scout/resource/scout.rb",
|
71
71
|
"lib/scout/resource/util.rb",
|
72
|
+
"lib/scout/semaphore.rb",
|
72
73
|
"lib/scout/simple_opt.rb",
|
73
74
|
"lib/scout/simple_opt/accessor.rb",
|
74
75
|
"lib/scout/simple_opt/doc.rb",
|
@@ -76,6 +77,11 @@ Gem::Specification.new do |s|
|
|
76
77
|
"lib/scout/simple_opt/parse.rb",
|
77
78
|
"lib/scout/simple_opt/setup.rb",
|
78
79
|
"lib/scout/tmpfile.rb",
|
80
|
+
"lib/scout/tsv.rb",
|
81
|
+
"lib/scout/tsv/parser.rb",
|
82
|
+
"lib/scout/work_queue.rb",
|
83
|
+
"lib/scout/work_queue/socket.rb",
|
84
|
+
"lib/scout/work_queue/worker.rb",
|
79
85
|
"lib/scout/workflow.rb",
|
80
86
|
"lib/scout/workflow/definition.rb",
|
81
87
|
"lib/scout/workflow/documentation.rb",
|
@@ -96,8 +102,11 @@ Gem::Specification.new do |s|
|
|
96
102
|
"scout_commands/workflow/list",
|
97
103
|
"scout_commands/workflow/task",
|
98
104
|
"scout_commands/workflow/task_old",
|
105
|
+
"share/color/color_names",
|
106
|
+
"share/color/diverging_colors.hex",
|
99
107
|
"test/scout/indiferent_hash/test_case_insensitive.rb",
|
100
108
|
"test/scout/indiferent_hash/test_options.rb",
|
109
|
+
"test/scout/log/test_color.rb",
|
101
110
|
"test/scout/log/test_progress.rb",
|
102
111
|
"test/scout/misc/test_digest.rb",
|
103
112
|
"test/scout/misc/test_filesystem.rb",
|
@@ -128,8 +137,14 @@ Gem::Specification.new do |s|
|
|
128
137
|
"test/scout/test_path.rb",
|
129
138
|
"test/scout/test_persist.rb",
|
130
139
|
"test/scout/test_resource.rb",
|
140
|
+
"test/scout/test_semaphore.rb",
|
131
141
|
"test/scout/test_tmpfile.rb",
|
142
|
+
"test/scout/test_tsv.rb",
|
143
|
+
"test/scout/test_work_queue.rb",
|
132
144
|
"test/scout/test_workflow.rb",
|
145
|
+
"test/scout/tsv/test_parser.rb",
|
146
|
+
"test/scout/work_queue/test_socket.rb",
|
147
|
+
"test/scout/work_queue/test_worker.rb",
|
133
148
|
"test/scout/workflow/step/test_info.rb",
|
134
149
|
"test/scout/workflow/step/test_load.rb",
|
135
150
|
"test/scout/workflow/task/test_inputs.rb",
|