scout-gear 10.8.2 → 10.8.4

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: a469436e6ab560158eead4f0fae044ebddebe65d611a97a69837ab7884cad3e4
4
- data.tar.gz: a60763c026694b77083f23cf14784e4e6575bd34886980c4af28ead001f8590e
3
+ metadata.gz: 97c074aa2b85744eccbcba77c7be3eaa733d7280f6c5875211a3a1b771234e04
4
+ data.tar.gz: c284bf58c6954699fdc0b0742f6331ea1af7db7188b76b99325ad561e19de6cf
5
5
  SHA512:
6
- metadata.gz: 5620d8f89b1c5b7bff57c21c2fb28bac8c31168220a7fd8b9804179e9381b75603e9844440e233f07c0d80ebc7de8f684235a34297263ca927679a4f08aa348c
7
- data.tar.gz: b91fb51fec1e97b351a2d7a91b07186498b49d2b8bdf4561bb806b7b38cf45c2c2239642830bc1bfb9909b2f5ed7f173b3ce3707ca2f9fd799fd89d246217fa3
6
+ metadata.gz: f381c4c3167580d337ec5ac43bec9e12e8db0b4b423603fe134b8751d3a9aa8b9930797c87daa9cd0b7cf7f9c24c60ece3c00b2b4b70aec03aa71eae7bcef091
7
+ data.tar.gz: f39b067a52e6724302dc92d1eeb4dac3c22ce07e25c4e986d9a3018c92dcfdd79441d23bd2c9f0dca90a7a39d6ca95bc52fab92b0b4999cc003e48767e26bce8
data/.vimproject CHANGED
@@ -5,6 +5,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
5
5
  }
6
6
  lib=lib {
7
7
  scout=scout{
8
+ monitor.rb
8
9
  workflow.rb
9
10
  workflow=workflow{
10
11
  exceptions.rb
@@ -171,6 +172,9 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
171
172
  produce
172
173
  sync
173
174
  }
175
+ system=system{
176
+ clean
177
+ }
174
178
  }
175
179
  test=test {
176
180
  test_helper.rb
data/Rakefile CHANGED
@@ -24,6 +24,7 @@ Juwelier::Tasks.new do |gem|
24
24
  gem.add_runtime_dependency 'net-ssh'
25
25
  gem.add_runtime_dependency 'matrix'
26
26
  gem.add_runtime_dependency 'RubyInline'
27
+ gem.add_runtime_dependency 'csv'
27
28
  #gem.add_runtime_dependency 'tokyocabinet'
28
29
 
29
30
  gem.add_development_dependency "juwelier", "~> 2.1.0"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 10.8.2
1
+ 10.8.4
@@ -0,0 +1,296 @@
1
+ require 'scout'
2
+
3
+ module Scout
4
+
5
+ LOCK_DIRS = Scout.tmp.tsv_open_locks.find_all + Scout.tmp.persist_locks.find_all + Scout.tmp.sensiblewrite_locks.find_all +
6
+ Scout.tmp.produce_locks.find_all + Scout.tmp.step_info_locks.find_all
7
+
8
+ SENSIBLE_WRITE_DIRS = Open.sensible_write_dir.find_all
9
+
10
+ PERSIST_DIRS = Scout.share.find_all + Scout.var.cache.persistence.find_all
11
+
12
+ JOB_DIRS = Scout.var.jobs.find_all
13
+
14
+ MUTEX_FOR_THREAD_EXCLUSIVE = Mutex.new
15
+
16
+ def self.dump_memory(file, obj = nil)
17
+ Log.info "Dumping #{obj} objects into #{ file }"
18
+ Thread.new do
19
+ while true
20
+ Open.write(file) do |f|
21
+ MUTEX_FOR_THREAD_EXCLUSIVE.synchronize do
22
+ GC.start
23
+ ObjectSpace.each_object(obj) do |o|
24
+ f.puts "---"
25
+ f.puts(String === o ? o : o.inspect)
26
+ end
27
+ end
28
+ end
29
+ FileUtils.cp file, file + '.save'
30
+ sleep 3
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.file_time(file)
36
+ info = {}
37
+ begin
38
+ info[:ctime] = File.ctime file
39
+ info[:atime] = File.atime file
40
+ info[:elapsed] = Time.now - info[:ctime]
41
+ rescue Exception
42
+ end
43
+ info[:ctime] = Time.now - 999
44
+ info
45
+ end
46
+
47
+ #{{{ LOCKS
48
+
49
+ def self.locks(dirs = LOCK_DIRS)
50
+ dirs.collect do |dir|
51
+ next unless Open.exists? dir
52
+ `find -L "#{ dir }" -name "*.lock" 2>/dev/null`.split "\n"
53
+ end.compact.flatten
54
+ end
55
+
56
+ def self.lock_info(dirs = LOCK_DIRS)
57
+ lock_info = {}
58
+ locks(dirs).each do |f|
59
+ lock_info[f] = {}
60
+ begin
61
+ lock_info[f].merge!(file_time(f))
62
+ if File.size(f) > 0
63
+ info = Open.open(f) do |s|
64
+ Open.yaml(s)
65
+ end
66
+ IndiferentHash.setup(info)
67
+ lock_info[f][:pid] = info[:pid]
68
+ lock_info[f][:ppid] = info[:ppid]
69
+ end
70
+ rescue Exception
71
+ Log.exception $!
72
+ end
73
+ end
74
+ lock_info
75
+ end
76
+
77
+ #{{{ SENSIBLE WRITES
78
+
79
+ def self.sensiblewrites(dirs = SENSIBLE_WRITE_DIRS)
80
+ dirs.collect do |dir|
81
+ next unless Open.exists? dir
82
+ `find -L "#{ dir }" -not -name "*.lock" -not -type d 2>/dev/null`.split "\n"
83
+ end.compact.flatten
84
+ end
85
+
86
+ def self.sensiblewrite_info(dirs = SENSIBLE_WRITE_DIRS)
87
+ info = {}
88
+ sensiblewrites(dirs).each do |f|
89
+ begin
90
+ i = file_time(f)
91
+ info[f] = i
92
+ rescue
93
+ Log.exception $!
94
+ end
95
+ end
96
+ info
97
+ end
98
+
99
+ # PERSISTS
100
+
101
+ def self.persists(dirs = PERSIST_DIRS)
102
+ dirs.collect do |dir|
103
+ next unless Open.exists? dir
104
+ `find -L "#{ dir }" -name "*.persist" 2>/dev/null`.split "\n"
105
+ end.compact.flatten
106
+ end
107
+
108
+ def self.persist_info(dirs = PERSIST_DIRS)
109
+ info = {}
110
+ persists(dirs).each do |f|
111
+ begin
112
+ i = file_time(f)
113
+ info[f] = i
114
+ rescue
115
+ Log.exception $!
116
+ end
117
+ end
118
+ info
119
+ end
120
+
121
+ # PERSISTS
122
+
123
+ def self.job_info(workflows = nil, tasks = nil, dirs = JOB_DIRS)
124
+ require 'rbbt/workflow/step'
125
+
126
+ workflows = [workflows] if workflows and not Array === workflows
127
+ workflows = workflows.collect{|w| w.to_s} if workflows
128
+
129
+ tasks = [tasks] if tasks and not Array === tasks
130
+ tasks = tasks.collect{|w| w.to_s} if tasks
131
+
132
+ jobs = {}
133
+ seen = Set.new
134
+ _files = Set.new
135
+ dirs.collect do |dir|
136
+ next unless Open.exists? dir
137
+
138
+ task_dir_workflows = {}
139
+ tasks_dirs = if dir == '.'
140
+ ["."]
141
+ else
142
+ #workflowdirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
143
+ # repo_dir, sub_path = dir_sub_path
144
+ # Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
145
+ # else
146
+ # dir.glob("*")
147
+ # end
148
+
149
+ workflowdirs = dir.glob("*")
150
+
151
+ workflowdirs.collect do |workflowdir|
152
+ workflow = File.basename(workflowdir)
153
+ next if workflows and not workflows.include? workflow
154
+
155
+ #task_dirs = if (dir_sub_path = Open.find_repo_dir(workflowdir))
156
+ # repo_dir, sub_path = dir_sub_path
157
+ # Open.list_repo_files(*dir_sub_path).collect{|f| f.split("/").first}.uniq.collect{|f| File.join(repo_dir, f)}.uniq
158
+ # else
159
+ # workflowdir.glob("*")
160
+ # end
161
+
162
+ task_dirs = workflowdir.glob("*")
163
+
164
+ task_dirs.each do |tasks_dir|
165
+ task_dir_workflows[tasks_dir] = workflow
166
+ end
167
+ end.compact.flatten
168
+ end
169
+
170
+ tasks_dirs.collect do |taskdir|
171
+ task = File.basename(taskdir)
172
+ next if tasks and not tasks.include? task
173
+
174
+
175
+ #files = if (dir_sub_path = Open.find_repo_dir(taskdir))
176
+ # repo_dir, sub_path = dir_sub_path
177
+ # Open.list_repo_files(*dir_sub_path).reject do |f|
178
+ # f.include?("/.info/") ||
179
+ # f.include?(".files/") ||
180
+ # f.include?(".pid/") ||
181
+ # File.directory?(f)
182
+ # end.collect do |f|
183
+ # File.join(repo_dir, f)
184
+ # end
185
+ # else
186
+ # #cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.notify' -not -name '\\.*' 2>/dev/null"
187
+ # cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/.info/*\" -prune \\) -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.md5' -not -name '*.notify' -not -name '\\.*' \\( -not -type d -o -name '*.files' \\) 2>/dev/null"
188
+
189
+ # CMD.cmd(cmd, :pipe => true).read.split("\n")
190
+ # end
191
+
192
+ files = begin
193
+ cmd = "find -L '#{ taskdir }/' -not \\( -path \"#{taskdir}/.info/*\" -prune \\) -not \\( -path \"#{taskdir}/*.files/*\" -prune \\) -not -name '*.pid' -not -name '*.md5' -not -name '*.notify' -not -name '\\.*' \\( -not -type d -o -name '*.files' \\) 2>/dev/null"
194
+
195
+ CMD.cmd(cmd, :pipe => true).read.split("\n")
196
+ end
197
+
198
+ files = files.sort_by{|f| Open.mtime(f) || Time.now}
199
+ workflow = task_dir_workflows[taskdir]
200
+ TSV.traverse files, :type => :array, :into => jobs, :_bar => "Finding jobs in #{ taskdir }" do |file|
201
+ _files << file
202
+ if m = file.match(/(.*)\.(info|pid|files)$/)
203
+ file = m[1]
204
+ end
205
+ next if seen.include? file
206
+ seen << file
207
+
208
+ name = file[taskdir.length+1..-1]
209
+ info_file = file + '.info'
210
+
211
+ info = {}
212
+
213
+ info[:workflow] = workflow
214
+ info[:task] = task
215
+ info[:name] = name
216
+
217
+ if Open.exists? file
218
+ info = info.merge(file_time(file))
219
+ info[:done] = true
220
+ info[:info_file] = Open.exist?(info_file) ? info_file : nil
221
+ else
222
+ info = info.merge({:info_file => info_file, :done => false})
223
+ end
224
+
225
+ [file, info]
226
+ end
227
+
228
+ end.compact.flatten
229
+ end.compact.flatten
230
+ jobs
231
+ end
232
+
233
+ # REST
234
+
235
+ def self.__jobs(dirs = JOB_DIRS)
236
+ job_files = {}
237
+ dirs.each do |dir|
238
+ workflow_dirs = dir.glob("*").each do |wdir|
239
+ workflow = File.basename(wdir)
240
+ job_files[workflow] = {}
241
+ task_dirs = wdir.glob('*')
242
+ task_dirs.each do |tdir|
243
+ task = File.basename(tdir)
244
+ job_files[workflow][task] = tdir.glob('*')
245
+ end
246
+ end
247
+ end
248
+ jobs = {}
249
+ job_files.each do |workflow,task_jobs|
250
+ jobs[workflow] ||= {}
251
+ task_jobs.each do |task, files|
252
+ jobs[workflow][task] ||= {}
253
+ files.each do |f|
254
+ next if f =~ /\.lock$/
255
+ job = f.sub(/\.(info|files)/,'')
256
+
257
+ jobs[workflow][task][job] ||= {}
258
+ if jobs[workflow][task][job][:status].nil?
259
+ status = nil
260
+ status = :done if Open.exists? job
261
+ if status.nil? and f=~/\.info/
262
+ info = begin
263
+ Step::INFO_SERIALIZER.load(Open.read(f, :mode => 'rb'))
264
+ rescue
265
+ {}
266
+ end
267
+ status = info[:status]
268
+ pid = info[:pid]
269
+ end
270
+
271
+ jobs[workflow][task][job][:pid] = pid if pid
272
+ jobs[workflow][task][job][:status] = status if status
273
+ end
274
+ end
275
+ end
276
+ end
277
+ jobs
278
+ end
279
+
280
+ def self.load_lock(lock)
281
+ begin
282
+ info = Misc.insist 3 do
283
+ Open.yaml(lock)
284
+ end
285
+ info.values_at "pid", "ppid", "time"
286
+ rescue Exception
287
+ time = begin
288
+ File.atime(lock)
289
+ rescue Exception
290
+ Time.now
291
+ end
292
+ [nil, nil, time]
293
+ end
294
+ end
295
+
296
+ end
@@ -191,6 +191,7 @@ module Workflow
191
191
  def process(rules, jobs = nil)
192
192
  jobs, rules = rules, {} if jobs.nil?
193
193
  jobs = [jobs] if Step === jobs
194
+ failed_jobs = []
194
195
  begin
195
196
 
196
197
  workload = Orchestrator.workload(jobs)
@@ -199,7 +200,6 @@ module Workflow
199
200
  all_jobs.each{|job| job.clean unless (job.done? && job.updated?) || (job.error? && ! job.recoverable_error?) }
200
201
 
201
202
  top_level_jobs = jobs.collect{|job| job.path }
202
- failed_jobs = []
203
203
  while workload.any?
204
204
 
205
205
  candidates = resources_used.keys + Orchestrator.candidates(workload, rules)
@@ -2,7 +2,7 @@ module Workflow
2
2
  attr_accessor :title, :description
3
3
 
4
4
  def self.doc_parse_first_line(str)
5
- if str.match(/^([^\n]*)\n\n(.*)/sm)
5
+ if str.match(/^([^\n]*)\n\n(.*)/smu)
6
6
  str.replace $2
7
7
  $1
8
8
  else
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.8.2 ruby lib
5
+ # stub: scout-gear 10.8.4 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-gear".freeze
9
- s.version = "10.8.2".freeze
9
+ s.version = "10.8.4".freeze
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 = "2025-06-13"
14
+ s.date = "1980-01-02"
15
15
  s.description = "Scout gear: workflow, TSVs, persistence, entities, associations, and knowledge_bases.".freeze
16
16
  s.email = "mikisvaz@gmail.com".freeze
17
17
  s.executables = ["scout".freeze]
@@ -51,6 +51,7 @@ Gem::Specification.new do |s|
51
51
  "lib/scout/knowledge_base/query.rb",
52
52
  "lib/scout/knowledge_base/registry.rb",
53
53
  "lib/scout/knowledge_base/traverse.rb",
54
+ "lib/scout/monitor.rb",
54
55
  "lib/scout/persist/engine.rb",
55
56
  "lib/scout/persist/engine/fix_width_table.rb",
56
57
  "lib/scout/persist/engine/packed_index.rb",
@@ -143,6 +144,7 @@ Gem::Specification.new do |s|
143
144
  "scout_commands/rbbt",
144
145
  "scout_commands/resource/produce",
145
146
  "scout_commands/resource/sync",
147
+ "scout_commands/system/clean",
146
148
  "scout_commands/template",
147
149
  "scout_commands/update",
148
150
  "scout_commands/workflow/cmd",
@@ -250,7 +252,7 @@ Gem::Specification.new do |s|
250
252
  ]
251
253
  s.homepage = "http://github.com/mikisvaz/scout-gear".freeze
252
254
  s.licenses = ["MIT".freeze]
253
- s.rubygems_version = "3.6.6".freeze
255
+ s.rubygems_version = "3.6.7".freeze
254
256
  s.summary = "basic gear for scouts".freeze
255
257
 
256
258
  s.specification_version = 4
@@ -259,6 +261,7 @@ Gem::Specification.new do |s|
259
261
  s.add_runtime_dependency(%q<net-ssh>.freeze, [">= 0".freeze])
260
262
  s.add_runtime_dependency(%q<matrix>.freeze, [">= 0".freeze])
261
263
  s.add_runtime_dependency(%q<RubyInline>.freeze, [">= 0".freeze])
264
+ s.add_runtime_dependency(%q<csv>.freeze, [">= 0".freeze])
262
265
  s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0".freeze])
263
266
  end
264
267
 
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'scout'
4
+ require 'scout/monitor'
5
+
6
+ $0 = "scout #{$previous_commands*""} #{ File.basename(__FILE__) }" if $previous_commands
7
+
8
+ options = SOPT.setup <<EOF
9
+
10
+ Clean orphaned files
11
+
12
+ $ rbbt system clean <workflow> <task>
13
+
14
+ Specify workflow '.' and no task to examine the jobs of the current directory (usefull for web-server cache).
15
+
16
+ -a--all Apply to all jobs, not only uncompleted
17
+ -o--older* Clean jobs not access in some time
18
+ -f--force Remove locks and files regardless of been active
19
+ -q--quick Quick check
20
+ -d--dirty Clean dirty jobs
21
+ -h--help Print this help
22
+ EOF
23
+
24
+ scout_usage and exit 0 if options[:help]
25
+
26
+ workflow, task = ARGV
27
+
28
+ workflow = workflow.split "," if workflow
29
+ task = task.split "," if task
30
+
31
+ all = options.delete :all
32
+ force = options.delete :force
33
+ dirty = options.delete :dirty
34
+ time = options.delete :older
35
+
36
+ ENV["SCOUT_DEBUG_CLEAN"] = 'false'
37
+ ENV["SCOUT_UPDATE"] = 'true' if dirty
38
+
39
+ time = Misc.timespan time, 'd' if time
40
+
41
+ puts Log.color(:magenta, "# System clean")
42
+
43
+ locks = Scout.lock_info
44
+ if locks.any?
45
+ puts
46
+ puts Log.color(:magenta, "Locks:")
47
+ locks.each do |file,info|
48
+ if force or (info[:pid] && ! Misc.pid_alive?(info[:pid]))
49
+ puts " Removing #{ file }"
50
+ File.unlink file
51
+ end
52
+ end
53
+ end
54
+
55
+ persists = Scout.persist_info
56
+ if persists.any?
57
+ puts
58
+ puts Log.color(:magenta, "Persist:")
59
+ persists.each do |file,info|
60
+ if force or (info[:pid] and Misc.pid_alive? info[:pid])
61
+ puts " Removing #{ file }"
62
+ File.unlink file
63
+ end
64
+ end
65
+ end
66
+
67
+ sensiblewrites = Scout.sensiblewrite_info
68
+ if sensiblewrites.any?
69
+ puts
70
+ puts Log.color(:magenta, "Writes:")
71
+ sensiblewrites.each do |file,info|
72
+ if force or (info[:pid] and Misc.pid_alive? info[:pid])
73
+ puts " Removing #{ file }"
74
+ File.unlink file
75
+ end
76
+ end
77
+ end
78
+
79
+ exit 0 if workflow.nil?
80
+ workflow = nil if workflow == ["all"]
81
+
82
+ puts
83
+ puts Log.color(:magenta, "# Workflow clean")
84
+ puts
85
+
86
+ if workflow === ['.']
87
+ jobs = Scout.job_info ["all"], task, ['.']
88
+ else
89
+ jobs = Scout.job_info workflow, task
90
+ end
91
+
92
+ workflows = {}
93
+
94
+ TSV.traverse jobs do |file,i|
95
+ if options[:quick] and i[:done]
96
+ status = 'done'
97
+ else
98
+ info = begin
99
+ Open.open(i[:info_file]) do |f|
100
+ Step.load_info(f)
101
+ end
102
+ rescue
103
+ {:status => :noinfo}
104
+ end
105
+
106
+ done = Open.exists?(file) && ! Open.broken_link?(file)
107
+ pid = info[:pid] || (Open.exists?(file + '.pid') && Open.read(file + '.pid')) unless done
108
+
109
+ status = info[:status].to_s
110
+ if status != "noinfo"
111
+ status = :missing if status == "done" and not done
112
+ status = :nopid if status != "done" and pid.nil?
113
+ status = :dead if status != "done" and pid and not Misc.pid_alive?(pid)
114
+ status = :sync if status != "done" and done
115
+ end
116
+
117
+ status = :dirty if info[:status].to_s == "done" and dirty and Workflow.load_step(file).dirty?
118
+ if info[:status] == :error
119
+ begin
120
+ exception = info[:exception][:class]
121
+ Kernel.const_get exception
122
+ status = :non_recoverable if exception.superclass === ScoutException
123
+ rescue
124
+ end
125
+ end
126
+
127
+ status = status.to_s
128
+ end
129
+
130
+ if time and Open.exists?(file)
131
+ old = Time.now - Open.atime(file)
132
+ if old > time
133
+ status = 'old'
134
+ end
135
+ end
136
+
137
+ if (force && status !~ /done/) or
138
+ status =~ /\b(old|dirty|nopid|error|missing|aborted|dead|sync|waiting)$/ or
139
+ (status == "noinfo" and not done) or
140
+ status == ""
141
+
142
+ puts " Removing #{ file } - #{status}"
143
+ Step.clean(file)
144
+ end
145
+ end
146
+
@@ -115,7 +115,7 @@ else
115
115
  when "serial"
116
116
  job.run(true)
117
117
  when "local"
118
- refresh = Scout::Config.get :refresh, :deploy, :local, :orchestrator, default: 3
118
+ refresh = Scout::Config.get :refresh, :deploy, :local, :orchestrator, default: 0.5
119
119
  orchestrator = Workflow::Orchestrator.new refresh.to_f, "cpus" => Misc.processors
120
120
  orchestrator.process({}, job)
121
121
  when "slurm"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout-gear
3
3
  version: !ruby/object:Gem::Version
4
- version: 10.8.2
4
+ version: 10.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: scout-essentials
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: csv
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: juwelier
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +134,7 @@ files:
120
134
  - lib/scout/knowledge_base/query.rb
121
135
  - lib/scout/knowledge_base/registry.rb
122
136
  - lib/scout/knowledge_base/traverse.rb
137
+ - lib/scout/monitor.rb
123
138
  - lib/scout/persist/engine.rb
124
139
  - lib/scout/persist/engine/fix_width_table.rb
125
140
  - lib/scout/persist/engine/packed_index.rb
@@ -212,6 +227,7 @@ files:
212
227
  - scout_commands/rbbt
213
228
  - scout_commands/resource/produce
214
229
  - scout_commands/resource/sync
230
+ - scout_commands/system/clean
215
231
  - scout_commands/template
216
232
  - scout_commands/update
217
233
  - scout_commands/workflow/cmd
@@ -334,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
334
350
  - !ruby/object:Gem::Version
335
351
  version: '0'
336
352
  requirements: []
337
- rubygems_version: 3.6.6
353
+ rubygems_version: 3.6.7
338
354
  specification_version: 4
339
355
  summary: basic gear for scouts
340
356
  test_files: []