scout-gear 10.1.0 → 10.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab089af23ec3cb6d23db1190f712d2a981db96e818572aa5b561227a9601b9b8
4
- data.tar.gz: d72662def6d6b7207d015d7cea613a1882578efe201ed391f79d37027ab7c70e
3
+ metadata.gz: 2a7adf9c59ab3ce69e89dd2e02089b5287605a1b74c6a435a5bfa4ece17c1f75
4
+ data.tar.gz: 65f9fa08d1b4a99e973d33eb5a7c0ddab85a98b5d6a675f8a2f5cfe381e664aa
5
5
  SHA512:
6
- metadata.gz: d5b67fdc030ad2ed3dd4d9da47d7f12068b71f14a1ae390f65c411bc2e835ac2da1648fccb554cbda4a3a56bdf6b16fc63080620453e75481590622cfd883247
7
- data.tar.gz: 97fa38ef8db895d3a8aa05d2e4e521bb98d28924b389429994f6e98bceb7bfa7ad74920676c17b8b124bf288700e80078909ea20a84c3c0b24efd0cf7b0632cb
6
+ metadata.gz: cd78580f6d0fd2a417f15f425602131d4e3150fc8a0f35a1d2f63f5868e29cae8a9f59244a2fdc5d642441051b8528bcd2f8596aaf4bc11414437e6d4dc4cd14
7
+ data.tar.gz: ad61b8616e5029ff0ee748b48ef78928dc862bfbb0ba763610ad9f89f7e865975d816318ea388d30d774f1088894b9c2a3d42487b9a3c01c795c45cd5b37f2d7
data/.vimproject CHANGED
@@ -8,6 +8,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
8
8
  alias
9
9
  find
10
10
  glob
11
+ log
11
12
  doc
12
13
  update
13
14
  template
@@ -16,7 +17,14 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
16
17
  task
17
18
  list
18
19
  info
20
+ write_info
19
21
  install
22
+ trace
23
+ prov
24
+ }
25
+ batch=batch{
26
+ list
27
+ clean
20
28
  }
21
29
  resource=resource{
22
30
  produce
@@ -72,6 +80,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
72
80
  unzip.rb
73
81
  reorder.rb
74
82
  sort.rb
83
+ melt.rb
75
84
  }
76
85
  parser.rb
77
86
  dumper.rb
@@ -80,9 +89,8 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
80
89
  persist=persist{
81
90
  adapter.rb
82
91
  serialize.rb
83
- sdbm.rb
84
- tkrzw.rb
85
92
  tokyocabinet.rb
93
+ tkrzw.rb
86
94
  fix_width_table.rb
87
95
  }
88
96
  index.rb
@@ -122,6 +130,10 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
122
130
  test_tsv.rb
123
131
  test_work_queue.rb
124
132
  test_workflow.rb
133
+ work_queue=work_queue{
134
+ test_socket.rb
135
+ test_worker.rb
136
+ }
125
137
  workflow=workflow{
126
138
  test_definition.rb
127
139
  test_documentation.rb
@@ -140,10 +152,42 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
140
152
  test_dependencies.rb
141
153
  test_inputs.rb
142
154
  }
155
+ deployment=deployment{
156
+ test_orchestrator.rb
157
+ }
143
158
  }
144
- indiferent_hash=indiferent_hash{
145
- test_case_insensitive.rb
146
- test_options.rb
159
+ tsv=tsv{
160
+ test_attach.rb
161
+ test_change_id.rb
162
+ test_dumper.rb
163
+ test_index.rb
164
+ test_open.rb
165
+ test_parser.rb
166
+ test_persist.rb
167
+ test_stream.rb
168
+ test_transformer.rb
169
+ test_traverse.rb
170
+ test_util.rb
171
+ util=util{
172
+ test_filter.rb
173
+ test_melt.rb
174
+ test_process.rb
175
+ test_reorder.rb
176
+ test_select.rb
177
+ test_sort.rb
178
+ test_unzip.rb
179
+ }
180
+ persist=persist{
181
+ test_adapter.rb
182
+ test_fix_width_table.rb
183
+ test_tokyocabinet.rb
184
+ }
185
+ }
186
+ offsite=offsite{
187
+ test_ssh.rb
188
+ test_step.rb
189
+ test_sync.rb
190
+ test_task.rb
147
191
  }
148
192
  }
149
193
  }
@@ -524,6 +568,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
524
568
  test_filter.rb
525
569
  test_index.rb
526
570
  test_manipulate.rb
571
+ test_marshal.rb
527
572
  test_matrix.rb
528
573
  test_parallel.rb
529
574
  test_parser.rb
data/VERSION CHANGED
@@ -1 +1 @@
1
- 10.1.0
1
+ 10.3.0
@@ -0,0 +1,84 @@
1
+ require 'tkrzw'
2
+ require_relative 'adapter'
3
+
4
+ module ScoutTKRZW
5
+ attr_accessor :persistence_path, :persistence_class, :open_options
6
+
7
+ def self.open(path, write = true, persistence_class = 'tkh', options = {})
8
+ open_options = IndiferentHash.add_defaults options, truncate: true, num_buckets: 100, dbm: "HashDBM", sync_hard: true, encoding: "UTF-8"
9
+
10
+ path = path.find if Path === path
11
+
12
+ dir = File.dirname(File.expand_path(path))
13
+ Open.mkdir(dir) unless File.exist?(dir)
14
+
15
+ database = Persist::CONNECTIONS[[persistence_class, path]*":"] ||= Tkrzw::DBM.new
16
+
17
+ database.close if database.open?
18
+
19
+ database.open(path, write, open_options)
20
+
21
+ database.extend ScoutTKRZW
22
+ database.persistence_path ||= path
23
+ database.open_options = open_options
24
+
25
+ #Persist::CONNECTIONS[[persistence_class, path]*":"] = database
26
+
27
+ database
28
+ end
29
+
30
+ def close
31
+ @closed = true
32
+ @writable = false
33
+ super
34
+ end
35
+
36
+ def read(force = false)
37
+ return if open? && ! writable? && ! force
38
+ self.close if open?
39
+ if !self.open(@persistence_path, false, @open_options)
40
+ ecode = self.ecode
41
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
42
+ end
43
+
44
+ @writable = false
45
+ @closed = false
46
+
47
+ self
48
+ end
49
+
50
+ def write(force = true)
51
+ return if open? && writable? && ! force
52
+ self.close if self.open?
53
+
54
+ if !self.open(@persistence_path, true, @open_options)
55
+ ecode = self.ecode
56
+ raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
57
+ end
58
+
59
+ @writable = true
60
+ @closed = false
61
+
62
+ self
63
+ end
64
+
65
+ def keys
66
+ search("contain", "")
67
+ end
68
+ end
69
+
70
+ Persist.save_drivers[:tkh] = proc do |file, content|
71
+ data = ScoutTKRZW.open(file, true, "tkh")
72
+ content.annotate(data)
73
+ data.extend TSVAdapter
74
+ data.merge!(content)
75
+ data.close
76
+ data.read
77
+ data
78
+ end
79
+
80
+ Persist.load_drivers[:tkh] = proc do |file|
81
+ data = ScoutTKRZW.open(file, false, "tkh")
82
+ data.extend TSVAdapter unless TSVAdapter === data
83
+ data
84
+ end
@@ -1,6 +1,15 @@
1
1
  require 'scout/persist'
2
2
  require_relative 'persist/adapter'
3
- require_relative 'persist/tokyocabinet'
3
+
4
+ begin
5
+ require_relative 'persist/tokyocabinet'
6
+ rescue
7
+ end
8
+
9
+ begin
10
+ require_relative 'persist/tkrzw'
11
+ rescue
12
+ end
4
13
 
5
14
  Persist.save_drivers[:tsv] = proc do |file,content|
6
15
  stream = if IO === content
@@ -2,15 +2,16 @@ module TSV
2
2
  class Transformer
3
3
  attr_accessor :unnamed, :parser, :dumper
4
4
 
5
- def initialize(parser, dumper = nil, unnamed: false)
5
+ def initialize(parser, dumper = nil, unnamed: nil)
6
6
  if TSV::Parser === parser
7
7
  @parser = parser
8
8
  elsif TSV === parser
9
9
  @parser = parser
10
+ @unnamed = parser.unnamed
10
11
  else
11
12
  @parser = TSV::Parser.new parser
12
13
  end
13
- @unnamed = unnamed
14
+ @unnamed = unnamed unless unnamed.nil?
14
15
  if dumper.nil?
15
16
  @dumper = TSV::Dumper.new(@parser)
16
17
  @dumper.sep = "\t"
@@ -70,7 +71,7 @@ module TSV
70
71
  @dumper.init if @dumper.respond_to?(:init) && ! @dumper.initialized
71
72
  Log.debug "Transform #{Log.fingerprint @parser} into #{Log.fingerprint @dumper}"
72
73
  Open.traverse(@parser, *args, **kwargs) do |k,v|
73
- NamedArray.setup(v, @parser.fields, k) unless @unnamed
74
+ NamedArray.setup(v, @parser.fields, k) unless @unnamed || @parser.fields.nil?
74
75
  block.call k, v
75
76
  end
76
77
  end
@@ -112,16 +113,18 @@ module TSV
112
113
 
113
114
  def to_list
114
115
  res = self.annotate({})
115
- transformer = Transformer.new self, res
116
- transformer.type = :list
117
- transformer.traverse do |k,v|
118
- case self.type
119
- when :single
120
- [k, [v]]
121
- when :double
122
- [k, v.collect{|v| v.first }]
123
- when :flat
124
- [k, v.slice(0,1)]
116
+ self.with_unnamed do
117
+ transformer = Transformer.new self, res
118
+ transformer.type = :list
119
+ transformer.traverse do |k,v|
120
+ case self.type
121
+ when :single
122
+ [k, [v]]
123
+ when :double
124
+ [k, v.collect{|v| v.first }]
125
+ when :flat
126
+ [k, v.slice(0,1)]
127
+ end
125
128
  end
126
129
  end
127
130
  res
@@ -131,6 +134,7 @@ module TSV
131
134
  res = self.annotate({})
132
135
  transformer = Transformer.new self, res
133
136
  transformer.type = :single
137
+ transformer.unnamed = true
134
138
  transformer.traverse do |k,v|
135
139
  v = v.first while Array === v
136
140
  [k, v]
@@ -0,0 +1,13 @@
1
+ module TSV
2
+ def melt_columns(value_field, column_field)
3
+ target = TSV.setup({}, :key_field => "ID", :fields => [key_field, value_field, column_field], :type => :list, :cast => cast)
4
+ each do |k,values|
5
+ i = 0
6
+ values.zip(fields).each do |v,f|
7
+ target["#{k}:#{i}"] = [k,v,f]
8
+ i+=1
9
+ end
10
+ end
11
+ target
12
+ end
13
+ end
@@ -7,6 +7,7 @@ require_relative 'util/select'
7
7
  require_relative 'util/reorder'
8
8
  require_relative 'util/unzip'
9
9
  require_relative 'util/sort'
10
+ require_relative 'util/melt'
10
11
  module TSV
11
12
  def self.identify_field(key_field, fields, name, strict: nil)
12
13
  return :key if name == :key || (! strict && NamedArray.field_match(key_field, name))
data/lib/scout/tsv.rb CHANGED
@@ -34,11 +34,23 @@ module TSV
34
34
  end
35
35
 
36
36
  def self.open(file, options = {})
37
- persist, type, grep, invert_grep = IndiferentHash.process_options options, :persist, :persist_type, :grep, :invert_grep, :persist => false, :persist_type => "HDB"
38
- type = type.to_sym if type
37
+ grep, invert_grep = IndiferentHash.process_options options, :grep, :invert_grep, :persist => false
38
+
39
+ persist_options = IndiferentHash.pull_keys options, :persist
40
+ persist_options = IndiferentHash.add_defaults persist_options, :prefix => "TSV", :type => :HDB
41
+
39
42
  file = StringIO.new file if String === file && ! (Path === file) && file.index("\n")
40
- Persist.persist(file, type, options.merge(:persist => persist, :prefix => "Tsv", :other_options => options)) do |filename|
41
- data = filename ? ScoutCabinet.open(filename, true, type) : nil
43
+ Persist.persist(file, persist_options[:type], persist_options.merge(:other_options => options)) do |filename|
44
+ if filename
45
+ data = case persist_options[:type]
46
+ when :HDB, :BDB
47
+ ScoutCabinet.open(filename, true, persist_options[:type])
48
+ when :tkh, :tkt, :tks
49
+ ScoutTKRZW.open(filename, true, persist_options[:type])
50
+ end
51
+ else
52
+ data = nil
53
+ end
42
54
  options[:data] = data if data
43
55
  options[:filename] = file
44
56
 
@@ -84,8 +84,10 @@ module Workflow
84
84
  annotate_next_task :deps, [workflow, task, options, block, args]
85
85
  end
86
86
 
87
- def input(*args)
88
- annotate_next_task(:inputs, args)
87
+ def input(name, type = nil, *rest)
88
+ name = name.to_sym
89
+ type = type.to_sym if type
90
+ annotate_next_task(:inputs, [name, type] + rest)
89
91
  end
90
92
 
91
93
  def desc(description)
@@ -102,8 +104,10 @@ module Workflow
102
104
 
103
105
  def task(name_and_type, &block)
104
106
  name, type = name_and_type.collect.first
107
+ type = type.to_sym if String === type
108
+ name = name.to_sym if String === name
105
109
  @tasks ||= IndiferentHash.setup({})
106
- block = self.method(name) if block.nil?
110
+ block = lambda &self.method(name) if block.nil?
107
111
  begin
108
112
  @annotate_next_task ||= {}
109
113
  @annotate_next_task[:extension] ||=
@@ -132,8 +136,10 @@ module Workflow
132
136
  def task_alias(name, workflow, oname, *rest, &block)
133
137
  dep(workflow, oname, *rest, &block)
134
138
  extension :dep_task unless @extension
135
- returns workflow.tasks[oname].returns if @returns.nil?
136
- type = workflow.tasks[oname].type
139
+ task_proc = workflow.tasks[oname]
140
+ raise "Task #{oname} not found" if task_proc.nil?
141
+ returns task_proc.returns if @returns.nil?
142
+ type = task_proc.type
137
143
  task name => type do
138
144
  raise RbbtException, "dep_task does not have any dependencies" if dependencies.empty?
139
145
  Step.wait_for_jobs dependencies.select{|d| d.streaming? }
@@ -5,7 +5,7 @@ class Step
5
5
  next if seen.include? dep.path
6
6
  next if connected && dep.done? && dep.updated?
7
7
  direct_deps << dep
8
- end
8
+ end if dependencies
9
9
  seen.concat direct_deps.collect{|d| d.path }
10
10
  direct_deps.inject(direct_deps){|acc,d| acc.concat(d.rec_dependencies(connected, seen)); acc }
11
11
  end
@@ -12,9 +12,10 @@ class Step
12
12
  end
13
13
  end
14
14
 
15
- def file(file)
15
+ def file(file = nil)
16
16
  dir = files_dir
17
17
  Path.setup(dir) unless Path === dir
18
+ return dir if file.nil?
18
19
  dir[file]
19
20
  end
20
21
 
@@ -68,7 +68,7 @@ class Step
68
68
  $inputs.each do |input|
69
69
  value = job_inputs[input]
70
70
  next if value.nil?
71
- value_str = Misc.fingerprint(value)
71
+ value_str = Log.fingerprint(value)
72
72
  str << "\t#{Log.color :magenta, input}=#{value_str}"
73
73
  end
74
74
  end
@@ -78,7 +78,7 @@ class Step
78
78
  IndiferentHash.setup(info)
79
79
  value = info[field]
80
80
  next if value.nil?
81
- value_str = Misc.fingerprint(value)
81
+ value_str = Log.fingerprint(value)
82
82
  str << "\t#{Log.color :magenta, field}=#{value_str}"
83
83
  end
84
84
  end
@@ -27,10 +27,10 @@ class Step
27
27
  @result = nil
28
28
  @info = nil
29
29
  @info_load_time = nil
30
- Open.rm path if Open.exist?(path)
31
- Open.rm tmp_path if Open.exist?(tmp_path)
32
- Open.rm info_file if Open.exist?(info_file)
33
- Open.rm_rf files_dir if Open.exist?(files_dir)
30
+ Open.rm path if Open.exist_or_link?(path)
31
+ Open.rm tmp_path if Open.exist_or_link?(tmp_path)
32
+ Open.rm info_file if Open.exist_or_link?(info_file)
33
+ Open.rm_rf files_dir if Open.exist_or_link?(files_dir)
34
34
  self
35
35
  end
36
36
 
@@ -76,10 +76,14 @@ class Step
76
76
 
77
77
  def task_name
78
78
  @task_name ||= @task.name if @task.respond_to?(:name)
79
+ @task_name ||= info[:task_name] if Open.exist?(info_file)
80
+ @task_name ||= path.split("/")[-2]
79
81
  end
80
82
 
81
83
  def workflow
82
- @task.workflow if @task
84
+ @workflow ||= @task.workflow if Task === @task
85
+ @workflow ||= info[:workflow] if Open.exist?(info_file)
86
+ @workflow ||= path.split("/")[-3]
83
87
  end
84
88
 
85
89
  def exec
@@ -130,6 +134,7 @@ class Step
130
134
  input_names = (task.respond_to?(:inputs) && task.inputs) ? task.inputs.collect{|name,_| name} : []
131
135
  merge_info :status => :start, :start => Time.now,
132
136
  :pid => Process.pid, :pid_hostname => Misc.hostname,
137
+ :task_name => task_name, :workflow => workflow.to_s,
133
138
  :inputs => MetaExtension.purge(inputs), :input_names => input_names, :type => type,
134
139
  :dependencies => dependencies.collect{|d| d.path }
135
140
 
@@ -232,11 +237,14 @@ class Step
232
237
  while @result && streaming? && stream = self.stream
233
238
  threads << Open.consume_stream(stream, true)
234
239
  end
240
+
241
+ threads.compact!
242
+
235
243
  threads.each do |t|
236
244
  begin
237
245
  t.join
238
246
  rescue Exception
239
- threads.each{|t| t.raise(Aborted); t.join }
247
+ threads.compact.each{|t| t.raise(Aborted); t.join }
240
248
  raise $!
241
249
  end
242
250
  end
@@ -252,6 +260,7 @@ class Step
252
260
  while ! present?
253
261
  sleep 0.1
254
262
  end
263
+ self
255
264
  end
256
265
 
257
266
  def terminated?
@@ -19,7 +19,7 @@ module Task
19
19
  step_inputs.each do |k,v|
20
20
  if Symbol === v
21
21
  input_dep = dependencies.select{|d| d.task_name == v }.first
22
- resolved_inputs[k] = input_dep || step_inputs[v] || k
22
+ resolved_inputs[k] = input_dep || provided_inputs[v] || step_inputs[v] || k
23
23
  else
24
24
  resolved_inputs[k] = v
25
25
  end
@@ -79,7 +79,7 @@ module Task
79
79
  when Step
80
80
  dep = res
81
81
  dependencies << dep
82
- dep_non_default_inputs = find_dep_non_default_inputs.call(dep, block_options)
82
+ dep_non_default_inputs = find_dep_non_default_inputs.call(dep, definition_options)
83
83
  non_default_inputs.concat(dep_non_default_inputs)
84
84
  when Hash
85
85
  step_options = block_options.merge(res)
@@ -3,7 +3,7 @@ module Task
3
3
  def self.format_input(value, type, options = {})
4
4
  return value if IO === value || StringIO === value || Step === value
5
5
 
6
- if String === value && ! [:path, :file, :folder, :binary].include?(type) && ! (options && (options[:noload] || options[:stream] || options[:nofile]))
6
+ if String === value && ! [:path, :file, :folder, :binary, :tsv].include?(type) && ! (options && (options[:noload] || options[:stream] || options[:nofile]))
7
7
  if Open.exists?(value) && ! Open.directory?(value)
8
8
  Persist.load(value, type)
9
9
  else
@@ -85,8 +85,12 @@ module Task
85
85
  input_file = File.join(directory, name.to_s)
86
86
 
87
87
  if Path.is_filename?(value)
88
- relative_file = save_file_input(value, directory)
89
- Open.write(input_file + ".as_file", relative_file)
88
+ if type == :path
89
+ Open.write(input_file + ".as_path", value)
90
+ else
91
+ relative_file = save_file_input(value, directory)
92
+ Open.write(input_file + ".as_file", relative_file)
93
+ end
90
94
  elsif Step === value
91
95
  Open.write(input_file + ".as_step", value.short_path)
92
96
  elsif type == :file
@@ -52,8 +52,9 @@ module Task
52
52
  inputs = task.inputs.reject{|name, _| seen.include? name }
53
53
  inputs = task.inputs.reject{|name, _| options.include? name }
54
54
  next unless inputs.any?
55
- task.inputs.select{|name, _| inputs.include? name }.each do |name,_,_,_,options|
56
- selects << [i, options[:select_options]] if options[:select_options]
55
+ input_names = inputs.collect{|name,_| name }
56
+ task.inputs.select{|name,_| input_names.include? name }.each do |name,_,_,_,options|
57
+ selects << [name, options[:select_options]] if options && options[:select_options]
57
58
  end
58
59
 
59
60
  dep = workflow.nil? || dep_workflow.name != workflow.name ? ["#{dep_workflow.name}", task_name.to_s] *"#" : task_name.to_s
@@ -291,6 +292,7 @@ module Workflow
291
292
  prov_tree = prov_tree(dep_tree)
292
293
  if prov_tree && ! prov_tree.empty? && prov_tree.split("\n").length > 2
293
294
 
295
+ str.puts
294
296
  str.puts Log.color :magenta, "## DEPENDENCY GRAPH (abridged)"
295
297
  str.puts
296
298
  prov_tree.split("\n").each do |line|
@@ -7,5 +7,10 @@ module Workflow
7
7
  mod.instance_eval(&block)
8
8
  mod
9
9
  end
10
+
11
+ def find_in_dependencies(name, dependencies)
12
+ name = name.to_sym
13
+ dependencies.select{|dep| dep.task_name.to_sym == name }
14
+ end
10
15
  end
11
16
 
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 10.1.0 ruby lib
5
+ # stub: scout-gear 10.3.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "10.1.0"
9
+ s.version = "10.3.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-07-07"
14
+ s.date = "2023-08-01"
15
15
  s.description = "Temporary files, logs, path, resources, persistence, workflows, TSV, etc.".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.executables = ["scout".freeze]
@@ -51,12 +51,14 @@ Gem::Specification.new do |s|
51
51
  "lib/scout/tsv/persist/adapter.rb",
52
52
  "lib/scout/tsv/persist/fix_width_table.rb",
53
53
  "lib/scout/tsv/persist/serialize.rb",
54
+ "lib/scout/tsv/persist/tkrzw.rb",
54
55
  "lib/scout/tsv/persist/tokyocabinet.rb",
55
56
  "lib/scout/tsv/stream.rb",
56
57
  "lib/scout/tsv/transformer.rb",
57
58
  "lib/scout/tsv/traverse.rb",
58
59
  "lib/scout/tsv/util.rb",
59
60
  "lib/scout/tsv/util/filter.rb",
61
+ "lib/scout/tsv/util/melt.rb",
60
62
  "lib/scout/tsv/util/process.rb",
61
63
  "lib/scout/tsv/util/reorder.rb",
62
64
  "lib/scout/tsv/util/select.rb",
@@ -89,9 +91,12 @@ Gem::Specification.new do |s|
89
91
  "lib/workflow-scout.rb",
90
92
  "scout-gear.gemspec",
91
93
  "scout_commands/alias",
94
+ "scout_commands/batch/clean",
95
+ "scout_commands/batch/list",
92
96
  "scout_commands/doc",
93
97
  "scout_commands/find",
94
98
  "scout_commands/glob",
99
+ "scout_commands/log",
95
100
  "scout_commands/offsite",
96
101
  "scout_commands/rbbt",
97
102
  "scout_commands/resource/produce",
@@ -100,7 +105,10 @@ Gem::Specification.new do |s|
100
105
  "scout_commands/workflow/info",
101
106
  "scout_commands/workflow/install",
102
107
  "scout_commands/workflow/list",
108
+ "scout_commands/workflow/prov",
103
109
  "scout_commands/workflow/task",
110
+ "scout_commands/workflow/trace",
111
+ "scout_commands/workflow/write_info",
104
112
  "share/color/color_names",
105
113
  "share/color/diverging_colors.hex",
106
114
  "share/software/install_helpers",
@@ -117,6 +125,7 @@ Gem::Specification.new do |s|
117
125
  "test/scout/test_workflow.rb",
118
126
  "test/scout/tsv/persist/test_adapter.rb",
119
127
  "test/scout/tsv/persist/test_fix_width_table.rb",
128
+ "test/scout/tsv/persist/test_tkrzw.rb",
120
129
  "test/scout/tsv/persist/test_tokyocabinet.rb",
121
130
  "test/scout/tsv/test_attach.rb",
122
131
  "test/scout/tsv/test_change_id.rb",
@@ -130,6 +139,7 @@ Gem::Specification.new do |s|
130
139
  "test/scout/tsv/test_traverse.rb",
131
140
  "test/scout/tsv/test_util.rb",
132
141
  "test/scout/tsv/util/test_filter.rb",
142
+ "test/scout/tsv/util/test_melt.rb",
133
143
  "test/scout/tsv/util/test_process.rb",
134
144
  "test/scout/tsv/util/test_reorder.rb",
135
145
  "test/scout/tsv/util/test_select.rb",