scout-essentials 1.7.1 → 1.8.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 +200 -47
- data/README.md +136 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/doc/Annotation.md +352 -0
- data/doc/CMD.md +203 -0
- data/doc/ConcurrentStream.md +163 -0
- data/doc/IndiferentHash.md +240 -0
- data/doc/Log.md +235 -0
- data/doc/NamedArray.md +174 -0
- data/doc/Open.md +331 -0
- data/doc/Path.md +217 -0
- data/doc/Persist.md +214 -0
- data/doc/Resource.md +229 -0
- data/doc/SimpleOPT.md +236 -0
- data/doc/TmpFile.md +154 -0
- data/lib/scout/annotation/annotated_object.rb +8 -0
- data/lib/scout/annotation/annotation_module.rb +1 -0
- data/lib/scout/cmd.rb +19 -12
- data/lib/scout/concurrent_stream.rb +3 -1
- data/lib/scout/config.rb +2 -2
- data/lib/scout/indiferent_hash/options.rb +2 -2
- data/lib/scout/indiferent_hash.rb +16 -0
- data/lib/scout/log/color.rb +5 -3
- data/lib/scout/log/fingerprint.rb +8 -8
- data/lib/scout/log/progress/report.rb +6 -6
- data/lib/scout/log.rb +7 -7
- data/lib/scout/misc/digest.rb +11 -13
- data/lib/scout/misc/format.rb +2 -2
- data/lib/scout/misc/system.rb +5 -0
- data/lib/scout/open/final.rb +16 -1
- data/lib/scout/open/remote.rb +0 -1
- data/lib/scout/open/stream.rb +30 -5
- data/lib/scout/open/util.rb +32 -0
- data/lib/scout/path/digest.rb +12 -2
- data/lib/scout/path/find.rb +19 -6
- data/lib/scout/path/util.rb +37 -1
- data/lib/scout/persist/open.rb +2 -0
- data/lib/scout/persist.rb +7 -1
- data/lib/scout/resource/path.rb +2 -2
- data/lib/scout/resource/util.rb +18 -4
- data/lib/scout/resource.rb +15 -1
- data/lib/scout/simple_opt/parse.rb +2 -0
- data/lib/scout/tmpfile.rb +1 -1
- data/scout-essentials.gemspec +19 -6
- data/test/scout/misc/test_hook.rb +2 -2
- data/test/scout/open/test_stream.rb +43 -15
- data/test/scout/path/test_find.rb +1 -1
- data/test/scout/path/test_util.rb +11 -0
- data/test/scout/test_path.rb +4 -4
- data/test/scout/test_persist.rb +10 -1
- metadata +31 -5
- data/README.rdoc +0 -18
|
@@ -120,18 +120,18 @@ module Log
|
|
|
120
120
|
str = Log.color(:magenta, "·")
|
|
121
121
|
if @ticks == 0
|
|
122
122
|
if @max
|
|
123
|
-
return str
|
|
123
|
+
return str + " " << Log.color(:magenta, "waiting on #{@max} #{bytes ? 'bytes' : 'items'}") << Log.color(:magenta, " · " + desc)
|
|
124
124
|
else
|
|
125
|
-
return str
|
|
125
|
+
return str + " " << Log.color(:magenta, "waiting - PID: #{Process.pid}") << Log.color(:magenta, " · " + desc)
|
|
126
126
|
end
|
|
127
127
|
end
|
|
128
|
-
str
|
|
128
|
+
str += " " + thr_msg
|
|
129
129
|
if max
|
|
130
130
|
str << Log.color(:blue, " -- ") << eta_msg
|
|
131
131
|
else
|
|
132
132
|
str << Log.color(:blue, " -- ") << ticks.to_s << " #{bytes ? 'bytes' : 'items'}"
|
|
133
133
|
end
|
|
134
|
-
str << Log.color(:magenta, " · "
|
|
134
|
+
str << Log.color(:magenta, " · " + desc)
|
|
135
135
|
str
|
|
136
136
|
end
|
|
137
137
|
|
|
@@ -208,8 +208,8 @@ module Log
|
|
|
208
208
|
@last_count = 0
|
|
209
209
|
@last_time = @start
|
|
210
210
|
thr = ellapsed > 0 ? (@ticks / ellapsed).to_i.to_s : 0
|
|
211
|
-
done_msg << " - "
|
|
212
|
-
done_msg << Log.color(:magenta, " · "
|
|
211
|
+
done_msg << " - " + Log.color(:blue, thr) << " per second"
|
|
212
|
+
done_msg << Log.color(:magenta, " · " + desc)
|
|
213
213
|
print(io, Log.up_lines(@depth) << done_msg << Log.down_lines(@depth))
|
|
214
214
|
|
|
215
215
|
FileUtils.rm file if file and File.exist?(file)
|
data/lib/scout/log.rb
CHANGED
|
@@ -59,7 +59,7 @@ module Log
|
|
|
59
59
|
IO.console.winsize.last
|
|
60
60
|
rescue Exception
|
|
61
61
|
begin
|
|
62
|
-
res = `tput
|
|
62
|
+
res = `tput cols`
|
|
63
63
|
res = nil if res == ""
|
|
64
64
|
res || ENV["TTY_SIZE"] || 80
|
|
65
65
|
rescue Exception
|
|
@@ -165,7 +165,7 @@ module Log
|
|
|
165
165
|
end
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
-
LAST = "log"
|
|
168
|
+
LAST = "log".dup
|
|
169
169
|
def self.logn(message = nil, severity = MEDIUM, &block)
|
|
170
170
|
return if severity < self.severity
|
|
171
171
|
message ||= block.call if block_given?
|
|
@@ -180,8 +180,8 @@ module Log
|
|
|
180
180
|
else
|
|
181
181
|
prefix = time << color(severity) << "[" << sev_str << "]" << color(0)
|
|
182
182
|
end
|
|
183
|
-
message =
|
|
184
|
-
str = prefix
|
|
183
|
+
message = [highlight, message, color(0)].join if severity >= INFO
|
|
184
|
+
str = prefix + " " + message.to_s
|
|
185
185
|
|
|
186
186
|
log_write str
|
|
187
187
|
|
|
@@ -288,9 +288,9 @@ module Log
|
|
|
288
288
|
end
|
|
289
289
|
|
|
290
290
|
def self.tsv(tsv, example = false)
|
|
291
|
-
log_puts Log.color :magenta, "TSV log: "
|
|
292
|
-
log_puts Log.color(:blue, "=> "
|
|
293
|
-
log_puts Log.color(:cyan, "=> "
|
|
291
|
+
log_puts Log.color :magenta, "TSV log: " + Log.last_caller(caller).gsub('`',"'")
|
|
292
|
+
log_puts Log.color(:blue, "=> " + Log.fingerprint(tsv), true)
|
|
293
|
+
log_puts Log.color(:cyan, "=> " + tsv.summary)
|
|
294
294
|
if example && ! tsv.empty?
|
|
295
295
|
key = case example
|
|
296
296
|
when TrueClass, :first, "first"
|
data/lib/scout/misc/digest.rb
CHANGED
|
@@ -8,15 +8,7 @@ module Misc
|
|
|
8
8
|
case obj
|
|
9
9
|
when String
|
|
10
10
|
if Path.is_filename?(obj) && Open.exists?(obj)
|
|
11
|
-
|
|
12
|
-
if Path === obj
|
|
13
|
-
"Directory MD5: #{digest_str(obj.glob("*"))}"
|
|
14
|
-
else
|
|
15
|
-
"Directory MD5: #{digest_str(Dir.glob(File.join(obj, "*")))}"
|
|
16
|
-
end
|
|
17
|
-
else
|
|
18
|
-
"File MD5: #{Misc.digest_file(obj)}"
|
|
19
|
-
end
|
|
11
|
+
Path.setup(obj).digest_str
|
|
20
12
|
else
|
|
21
13
|
obj.dup
|
|
22
14
|
end
|
|
@@ -27,12 +19,12 @@ module Misc
|
|
|
27
19
|
length = obj.length
|
|
28
20
|
mid = length/2
|
|
29
21
|
sample_pos = [1, 2, mid, length-2, length-1]
|
|
30
|
-
"[#{length}:"
|
|
22
|
+
"[#{length}:" + obj.values_at(*sample_pos).inject(""){|acc,o| acc.empty? ? Misc.digest_str(o) : acc << ', ' << Misc.digest_str(o) } << ']'
|
|
31
23
|
else
|
|
32
|
-
'['
|
|
24
|
+
'[' + obj.inject("".dup){|acc,o| acc.empty? ? Misc.digest_str(o) : acc << ', ' << Misc.digest_str(o) } << ']'
|
|
33
25
|
end
|
|
34
26
|
when Hash
|
|
35
|
-
'{'
|
|
27
|
+
'{' + obj.inject(""){|acc,p| s = Misc.digest_str(p.first) + "=" << Misc.digest_str(p.last); acc.empty? ? s : acc << ', ' << s } << '}'
|
|
36
28
|
when Integer
|
|
37
29
|
obj.to_s
|
|
38
30
|
when Float
|
|
@@ -49,6 +41,8 @@ module Misc
|
|
|
49
41
|
"true"
|
|
50
42
|
when FalseClass
|
|
51
43
|
"false"
|
|
44
|
+
when Proc
|
|
45
|
+
Misc.digest obj.source_location
|
|
52
46
|
else
|
|
53
47
|
obj.inspect
|
|
54
48
|
end
|
|
@@ -63,7 +57,11 @@ module Misc
|
|
|
63
57
|
def self.file_md5(file)
|
|
64
58
|
file = file.find if Path === file
|
|
65
59
|
file = File.expand_path(file)
|
|
66
|
-
|
|
60
|
+
begin
|
|
61
|
+
Digest::MD5.file(file).hexdigest
|
|
62
|
+
rescue
|
|
63
|
+
Digest::MD5.hexdigest(file)
|
|
64
|
+
end
|
|
67
65
|
end
|
|
68
66
|
|
|
69
67
|
def self.fast_file_md5(file, sample = 3_000_000)
|
data/lib/scout/misc/format.rb
CHANGED
|
@@ -44,7 +44,7 @@ module Misc
|
|
|
44
44
|
offset ||= 0
|
|
45
45
|
|
|
46
46
|
i = 0
|
|
47
|
-
size = size + offset + indent
|
|
47
|
+
#size = size + offset + indent
|
|
48
48
|
re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/
|
|
49
49
|
text.split(re).collect do |paragraph|
|
|
50
50
|
i += 1
|
|
@@ -74,7 +74,7 @@ module Misc
|
|
|
74
74
|
|
|
75
75
|
def self.format_definition_list_item(dt, dd, indent = nil, size = nil, color: :yellow)
|
|
76
76
|
if size.nil?
|
|
77
|
-
base_size = MAX_TTY_LINE_WIDTH
|
|
77
|
+
base_size = Log.tty_size || MAX_TTY_LINE_WIDTH
|
|
78
78
|
base_indent = indent || (base_size / 3)
|
|
79
79
|
size = base_size - base_indent
|
|
80
80
|
end
|
data/lib/scout/misc/system.rb
CHANGED
data/lib/scout/open/final.rb
CHANGED
|
@@ -70,6 +70,12 @@ module Open
|
|
|
70
70
|
notify_write(file)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
def append(file, content, options = {})
|
|
74
|
+
options = IndiferentHash.setup options
|
|
75
|
+
options[:mode] = "a"
|
|
76
|
+
write(file, content, options)
|
|
77
|
+
end
|
|
78
|
+
|
|
73
79
|
def self.mv(source, target, options = {})
|
|
74
80
|
target = target.find if Path === target
|
|
75
81
|
source = source.find if Path === source
|
|
@@ -81,6 +87,7 @@ module Open
|
|
|
81
87
|
end
|
|
82
88
|
|
|
83
89
|
def self.rm(file)
|
|
90
|
+
file = file.find if Path === file
|
|
84
91
|
FileUtils.rm(file) if File.exist?(file) || Open.broken_link?(file)
|
|
85
92
|
end
|
|
86
93
|
|
|
@@ -101,6 +108,14 @@ module Open
|
|
|
101
108
|
end
|
|
102
109
|
end
|
|
103
110
|
|
|
111
|
+
def self.mkfiledir(target)
|
|
112
|
+
target = target.find if Path === target
|
|
113
|
+
dir = File.dirname(target)
|
|
114
|
+
if ! File.exist?(dir)
|
|
115
|
+
FileUtils.mkdir_p dir
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
104
119
|
def self.cp(source, target, options = {})
|
|
105
120
|
source = source.find if Path === source
|
|
106
121
|
target = target.find if Path === target
|
|
@@ -188,7 +203,7 @@ module Open
|
|
|
188
203
|
begin
|
|
189
204
|
Open.ln(source, target, options)
|
|
190
205
|
rescue
|
|
191
|
-
Log.debug "Could not make regular link, trying symbolic: #{
|
|
206
|
+
Log.debug "Could not make regular link, trying symbolic: #{Log.fingerprint(source)} -> #{Log.fingerprint(target)}"
|
|
192
207
|
Open.ln_s(source, target, options)
|
|
193
208
|
end
|
|
194
209
|
nil
|
data/lib/scout/open/remote.rb
CHANGED
data/lib/scout/open/stream.rb
CHANGED
|
@@ -204,6 +204,7 @@ module Open
|
|
|
204
204
|
|
|
205
205
|
def self.purge_pipes(*save)
|
|
206
206
|
PIPE_MUTEX.synchronize do
|
|
207
|
+
save = save.flatten
|
|
207
208
|
OPEN_PIPE_IN.each do |pipe|
|
|
208
209
|
next if save.include? pipe
|
|
209
210
|
pipe.close unless pipe.closed?
|
|
@@ -361,7 +362,7 @@ module Open
|
|
|
361
362
|
end
|
|
362
363
|
|
|
363
364
|
main_pipe.abort_callback = proc do |exception|
|
|
364
|
-
stream.abort(exception)
|
|
365
|
+
stream.abort(exception) if ConcurrentStream === stream
|
|
365
366
|
out_pipes[1..-1].each do |sout|
|
|
366
367
|
sout.abort(exception)
|
|
367
368
|
end
|
|
@@ -398,10 +399,11 @@ module Open
|
|
|
398
399
|
end
|
|
399
400
|
|
|
400
401
|
def self.read_stream(stream, size)
|
|
401
|
-
str = ""
|
|
402
|
+
str = "".dup
|
|
402
403
|
while str.length < size
|
|
403
404
|
missing = size - str.length
|
|
404
405
|
more = stream.read(missing)
|
|
406
|
+
raise ClosedStream if more.nil?
|
|
405
407
|
str << more
|
|
406
408
|
end
|
|
407
409
|
str
|
|
@@ -464,15 +466,15 @@ module Open
|
|
|
464
466
|
if compact
|
|
465
467
|
current_parts[i] = part.dup
|
|
466
468
|
else
|
|
467
|
-
current_parts[i] = "|"
|
|
469
|
+
current_parts[i] = "|" + part
|
|
468
470
|
end
|
|
469
471
|
else
|
|
470
|
-
current_parts[i] = current_parts[i]
|
|
472
|
+
current_parts[i] = current_parts[i] + "|" << part
|
|
471
473
|
end
|
|
472
474
|
end
|
|
473
475
|
|
|
474
476
|
(parts.length..current_parts.length-1).to_a.each do |pos|
|
|
475
|
-
current_parts[pos] = current_parts[pos]
|
|
477
|
+
current_parts[pos] = current_parts[pos] + "|" << ""
|
|
476
478
|
end
|
|
477
479
|
when current_key.nil?
|
|
478
480
|
current_key = key
|
|
@@ -498,4 +500,27 @@ module Open
|
|
|
498
500
|
end unless current_key.nil?
|
|
499
501
|
end
|
|
500
502
|
end
|
|
503
|
+
|
|
504
|
+
def self.line_monitor_stream(stream, &block)
|
|
505
|
+
monitor, out = tee_stream stream
|
|
506
|
+
monitor_thread = Thread.new do
|
|
507
|
+
begin
|
|
508
|
+
while line = monitor.gets
|
|
509
|
+
block.call line
|
|
510
|
+
end
|
|
511
|
+
rescue
|
|
512
|
+
monitor.abort $!
|
|
513
|
+
monitor.close unless monitor.closed?
|
|
514
|
+
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
|
515
|
+
out.raise $! if out.respond_to?(:raise)
|
|
516
|
+
ensure
|
|
517
|
+
monitor.close unless monitor.closed?
|
|
518
|
+
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
monitor_thread.report_on_exception = false
|
|
522
|
+
|
|
523
|
+
stream.annotate out if stream.respond_to? :annotate
|
|
524
|
+
ConcurrentStream.setup out, :threads => monitor_thread
|
|
525
|
+
end
|
|
501
526
|
end
|
data/lib/scout/open/util.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'pathname'
|
|
1
2
|
module Open
|
|
2
3
|
GREP_CMD = begin
|
|
3
4
|
if ENV["GREP_CMD"]
|
|
@@ -129,4 +130,35 @@ module Open
|
|
|
129
130
|
file = file.produce_and_find if Path === file
|
|
130
131
|
Open.read(file).split("\n")
|
|
131
132
|
end
|
|
133
|
+
|
|
134
|
+
def self.wait_for(path, timeout: 10)
|
|
135
|
+
return if Open.exists?(path)
|
|
136
|
+
|
|
137
|
+
path = path.find if Path === path
|
|
138
|
+
|
|
139
|
+
require 'listen'
|
|
140
|
+
require 'timeout'
|
|
141
|
+
|
|
142
|
+
dir = File.dirname(path)
|
|
143
|
+
name = File.basename(path)
|
|
144
|
+
|
|
145
|
+
queue = Queue.new
|
|
146
|
+
listener = Listen.to(dir) do |_modified, added, _removed|
|
|
147
|
+
queue << :found if added.include?(path)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
listener.start
|
|
151
|
+
|
|
152
|
+
begin
|
|
153
|
+
Timeout.timeout(timeout) do
|
|
154
|
+
# This blocks until something is pushed to the queue
|
|
155
|
+
queue.pop
|
|
156
|
+
end
|
|
157
|
+
true
|
|
158
|
+
rescue Timeout::Error
|
|
159
|
+
false
|
|
160
|
+
ensure
|
|
161
|
+
listener.stop
|
|
162
|
+
end
|
|
163
|
+
end
|
|
132
164
|
end
|
data/lib/scout/path/digest.rb
CHANGED
|
@@ -3,11 +3,21 @@ module Path
|
|
|
3
3
|
def digest_str
|
|
4
4
|
case
|
|
5
5
|
when File.directory?(self)
|
|
6
|
-
|
|
6
|
+
files = self.glob("*")
|
|
7
|
+
|
|
8
|
+
files = files.reject{|f| File.directory?(f) }
|
|
9
|
+
|
|
10
|
+
files = Annotation.purge files
|
|
11
|
+
|
|
12
|
+
if files.length > 10
|
|
13
|
+
"Directory MD5: #{files.length} #{Misc.digest_str(files*"\n")}"
|
|
14
|
+
else
|
|
15
|
+
"Directory MD5: #{Misc.digest_str(files)}"
|
|
16
|
+
end
|
|
7
17
|
when self.located? && File.exist?(self)
|
|
8
18
|
"File MD5: #{Misc.digest_file(self)}"
|
|
9
19
|
else
|
|
10
|
-
'\''
|
|
20
|
+
'\'' + self << '\''
|
|
11
21
|
end
|
|
12
22
|
end
|
|
13
23
|
end
|
data/lib/scout/path/find.rb
CHANGED
|
@@ -6,12 +6,15 @@ module Path
|
|
|
6
6
|
caller_dup = caller.dup
|
|
7
7
|
while file = caller_dup.shift
|
|
8
8
|
break unless file =~ /(?:scout|rbbt)\/(?:resource\.rb|workflow\.rb)/ or
|
|
9
|
-
file =~ /(?:scout|rbbt)\/(?:.*\/)?(path|open|final|tsv|refactor)\.rb/ or
|
|
9
|
+
file =~ /(?:scout|rbbt)\/(?:.*\/)?(path|open|final|tsv|refactor|hook|parser)\.rb/ or
|
|
10
10
|
file =~ /(?:scout|rbbt)\/(?:.*\/)?path\/(?:find|refactor|util)\.rb/ or
|
|
11
11
|
file =~ /(?:scout|rbbt)\/persist.rb/ or
|
|
12
|
+
file =~ /(?:scout|rbbt)\/(persist|workflow)\// or
|
|
12
13
|
file =~ /scout\/resource\/produce.rb/ or
|
|
13
|
-
file =~ /modules\/rbbt-util/
|
|
14
|
+
file =~ /modules\/rbbt-util/ or
|
|
15
|
+
file =~ /^<internal:/
|
|
14
16
|
end
|
|
17
|
+
|
|
15
18
|
return nil if file.nil?
|
|
16
19
|
file = file.sub(/\.rb[^\w].*/,'.rb')
|
|
17
20
|
end
|
|
@@ -65,6 +68,8 @@ module Path
|
|
|
65
68
|
sub('{REMOVE}/', '').
|
|
66
69
|
sub('{REMOVE}', '')
|
|
67
70
|
|
|
71
|
+
file.sub!(/\/$/,'') if path._subpath.nil?
|
|
72
|
+
|
|
68
73
|
while true
|
|
69
74
|
file.gsub!(/\{(.+)(?<!\\)\/(.+)(?<!\\)\/(.+)\}/) do |m|
|
|
70
75
|
key, orig, replace = m.split(/(?<!\\)\//).collect{|p| p.gsub('\/','/') }
|
|
@@ -281,10 +286,18 @@ module Path
|
|
|
281
286
|
.select{|file| file.exist? }.uniq
|
|
282
287
|
end
|
|
283
288
|
|
|
284
|
-
def find_with_extension(extension, *args)
|
|
289
|
+
def find_with_extension(extension, *args, produce: true)
|
|
285
290
|
found = self.find(*args)
|
|
286
|
-
return found if found.exists?
|
|
287
|
-
|
|
288
|
-
|
|
291
|
+
return found if found.exists?(produce: produce) && ! found.directory?
|
|
292
|
+
if Array === extension
|
|
293
|
+
extension.each do |ext|
|
|
294
|
+
found_with_extension = self.set_extension(ext).find
|
|
295
|
+
return found_with_extension if found_with_extension.exists?(produce: produce)
|
|
296
|
+
end
|
|
297
|
+
else
|
|
298
|
+
found_with_extension = self.set_extension(extension).find
|
|
299
|
+
return found_with_extension if found_with_extension.exists?(produce: produce)
|
|
300
|
+
end
|
|
301
|
+
return found
|
|
289
302
|
end
|
|
290
303
|
end
|
data/lib/scout/path/util.rb
CHANGED
|
@@ -15,6 +15,14 @@ module Path
|
|
|
15
15
|
return false
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def self.can_read?(string)
|
|
19
|
+
return true if Open.remote?(string)
|
|
20
|
+
return false unless Path.is_filename?(string)
|
|
21
|
+
string = string.find if Path === string
|
|
22
|
+
return false if File.directory?(string)
|
|
23
|
+
return true
|
|
24
|
+
end
|
|
25
|
+
|
|
18
26
|
def self.sanitize_filename(filename, length = 254)
|
|
19
27
|
if filename.length > length
|
|
20
28
|
if filename =~ /(\..{2,9})$/
|
|
@@ -37,6 +45,14 @@ module Path
|
|
|
37
45
|
File.directory?(self.find)
|
|
38
46
|
end
|
|
39
47
|
|
|
48
|
+
def realpath
|
|
49
|
+
File.realpath(self.find)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def relative_to(dir)
|
|
53
|
+
Misc.path_relative_to(File.expand_path(dir), self.find)
|
|
54
|
+
end
|
|
55
|
+
|
|
40
56
|
def sub(*args)
|
|
41
57
|
self.annotate super(*args)
|
|
42
58
|
end
|
|
@@ -71,12 +87,17 @@ module Path
|
|
|
71
87
|
end
|
|
72
88
|
end
|
|
73
89
|
|
|
90
|
+
def glob_names(...)
|
|
91
|
+
glob(...).collect{|f| f.basename }
|
|
92
|
+
end
|
|
93
|
+
|
|
74
94
|
def glob_all(pattern = nil, caller_lib = nil, search_paths = nil)
|
|
75
95
|
search_paths ||= self.path_maps || Path.path_maps
|
|
76
96
|
search_paths = search_paths.dup
|
|
77
97
|
|
|
78
98
|
search_paths.keys.collect do |where|
|
|
79
99
|
found = find(where)
|
|
100
|
+
next unless found.located?
|
|
80
101
|
|
|
81
102
|
paths = pattern ? found.glob(pattern) : found.glob
|
|
82
103
|
|
|
@@ -135,8 +156,17 @@ module Path
|
|
|
135
156
|
self.annotate(new_path)
|
|
136
157
|
end
|
|
137
158
|
|
|
159
|
+
def newer_files(*files)
|
|
160
|
+
files.flatten.select do |file|
|
|
161
|
+
Path.newer?(self, file)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
138
164
|
|
|
139
|
-
|
|
165
|
+
def outdated?(...)
|
|
166
|
+
newer_files(...).any?
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Is 'file' newer than 'path'? return false if path is newer than file
|
|
140
170
|
def self.newer?(path, file, by_link = false)
|
|
141
171
|
return true if not Open.exists?(file)
|
|
142
172
|
path = path.find if Path === path
|
|
@@ -153,4 +183,10 @@ module Path
|
|
|
153
183
|
return diff if diff < 0
|
|
154
184
|
return false
|
|
155
185
|
end
|
|
186
|
+
|
|
187
|
+
def final_pkgdir
|
|
188
|
+
final_pkgdir = self.pkgdir
|
|
189
|
+
final_pkgdir = final_pkgdir.pkgdir while final_pkgdir.respond_to?(:pkgdir)
|
|
190
|
+
final_pkgdir
|
|
191
|
+
end
|
|
156
192
|
end
|
data/lib/scout/persist/open.rb
CHANGED
|
@@ -4,10 +4,12 @@ require 'yaml'
|
|
|
4
4
|
|
|
5
5
|
module Open
|
|
6
6
|
def self.json(file)
|
|
7
|
+
file = file.find_with_extension :json if Path === file
|
|
7
8
|
Open.open(file){|f| JSON.load(f) }
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def self.yaml(file)
|
|
12
|
+
file = file.find_with_extension :yaml if Path === file
|
|
11
13
|
Open.open(file){|f| YAML.unsafe_load(f) }
|
|
12
14
|
end
|
|
13
15
|
|
data/lib/scout/persist.rb
CHANGED
|
@@ -8,6 +8,7 @@ module Persist
|
|
|
8
8
|
def cache_dir=(cache_dir)
|
|
9
9
|
@cache_dir = Path === cache_dir ? cache_dir : Path.setup(cache_dir)
|
|
10
10
|
end
|
|
11
|
+
|
|
11
12
|
def cache_dir
|
|
12
13
|
@cache_dir ||= Path.setup("var/cache/persistence")
|
|
13
14
|
end
|
|
@@ -34,11 +35,16 @@ module Persist
|
|
|
34
35
|
|
|
35
36
|
file = persist_options[:path] || options[:path] || persistence_path(name, options)
|
|
36
37
|
data = persist_options[:data] || options[:data]
|
|
38
|
+
check = persist_options[:check] || options[:check]
|
|
37
39
|
no_load = persist_options[:no_load] || options[:no_load]
|
|
38
40
|
|
|
39
41
|
update = options[:update] || persist_options[:update]
|
|
40
42
|
update = Open.mtime(update) if Path === update
|
|
41
|
-
|
|
43
|
+
|
|
44
|
+
update = true if file.outdated?(check) if Path === file && check
|
|
45
|
+
file_mtime = Open.mtime(file)
|
|
46
|
+
update = file_mtime >= update ? false : true if file_mtime && Time === update
|
|
47
|
+
update = file_mtime >= (Time.now - update) ? false : true if file_mtime && Numeric === update
|
|
42
48
|
|
|
43
49
|
if type == :memory
|
|
44
50
|
repo = options[:memory] || options[:repo] || MEMORY_CACHE
|
data/lib/scout/resource/path.rb
CHANGED
data/lib/scout/resource/util.rb
CHANGED
|
@@ -15,6 +15,8 @@ module Resource
|
|
|
15
15
|
path = File.expand_path(path) if path.start_with?('/')
|
|
16
16
|
path += "/" if File.directory?(path) and not path.end_with?('/')
|
|
17
17
|
|
|
18
|
+
self_pkgdir = self.final_pkgdir
|
|
19
|
+
|
|
18
20
|
choices = []
|
|
19
21
|
map_order.uniq.each do |name|
|
|
20
22
|
pattern = path_maps[name]
|
|
@@ -31,7 +33,7 @@ module Resource
|
|
|
31
33
|
.gsub(/\/{([^}]+)}/,'(?:/(?<\1>[^/]+))?') +
|
|
32
34
|
"(?:/(?<REST>.+))?/?$"
|
|
33
35
|
if m = path.match(regexp)
|
|
34
|
-
if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] ==
|
|
36
|
+
if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] == self_pkgdir
|
|
35
37
|
|
|
36
38
|
unlocated = %w(TOPLEVEL SUBPATH PATH REST).collect{|c|
|
|
37
39
|
m.named_captures.include?(c) ? m[c] : nil
|
|
@@ -40,10 +42,11 @@ module Resource
|
|
|
40
42
|
if self.subdir && ! self.subdir.empty?
|
|
41
43
|
subdir = self.subdir
|
|
42
44
|
subdir += "/" unless subdir.end_with?("/")
|
|
43
|
-
unlocated[subdir] = ""
|
|
45
|
+
unlocated[subdir] = ""
|
|
44
46
|
end
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
unlocated = path.annotate(unlocated) if Path === path
|
|
49
|
+
choices << unlocated
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
end
|
|
@@ -51,13 +54,24 @@ module Resource
|
|
|
51
54
|
|
|
52
55
|
identified = choices.sort_by{|s| s.length }.first
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
identified ||= path
|
|
58
|
+
|
|
59
|
+
home = ENV['HOME']
|
|
60
|
+
if home
|
|
61
|
+
home += home[0..-2] if home.end_with?('/')
|
|
62
|
+
identified = identified.sub(/^#{home}(\/|$)/, '~\1')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
Path.setup(identified, self, nil, path_maps) unless Path === identified
|
|
66
|
+
|
|
67
|
+
identified
|
|
55
68
|
end
|
|
56
69
|
|
|
57
70
|
def self.identify(path)
|
|
58
71
|
resource = path.pkgdir if Path === path
|
|
59
72
|
resource = Resource.default_resource unless Resource === resource
|
|
60
73
|
unlocated = resource.identify path
|
|
74
|
+
unlocated
|
|
61
75
|
end
|
|
62
76
|
|
|
63
77
|
def self.relocate(path)
|
data/lib/scout/resource.rb
CHANGED
|
@@ -33,7 +33,21 @@ module Resource
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def path_maps
|
|
36
|
-
@path_maps ||= Path.path_maps
|
|
36
|
+
@path_maps ||= Path.path_maps.dup
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def map_order
|
|
40
|
+
@map_order ||= Path.map_order.dup
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def prepend_path(name, map)
|
|
44
|
+
path_maps[name] = map
|
|
45
|
+
map_order.unshift(name.to_sym)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def append_path(name, map)
|
|
49
|
+
path_maps[name] = map
|
|
50
|
+
map_order.push(name.to_sym)
|
|
37
51
|
end
|
|
38
52
|
|
|
39
53
|
def subdir
|
data/lib/scout/tmpfile.rb
CHANGED
|
@@ -124,7 +124,7 @@ module TmpFile
|
|
|
124
124
|
|
|
125
125
|
filename = filename[0..MAX_FILE_LENGTH] << Misc.digest(filename[MAX_FILE_LENGTH+1..-1]) if filename.length > MAX_FILE_LENGTH + 10
|
|
126
126
|
|
|
127
|
-
filename += ":"
|
|
127
|
+
filename += ":" + Misc.digest(clean_options) unless clean_options.empty?
|
|
128
128
|
|
|
129
129
|
persistence_dir[filename]
|
|
130
130
|
end
|