scout-gear 5.1.1 → 6.0.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 +24 -12
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/scout +2 -0
- data/lib/scout/exceptions.rb +14 -2
- data/lib/scout/log/color.rb +34 -10
- data/lib/scout/log/progress/report.rb +5 -4
- data/lib/scout/meta_extension.rb +4 -2
- data/lib/scout/misc/format.rb +16 -4
- data/lib/scout/misc/monitor.rb +41 -0
- data/lib/scout/misc.rb +1 -0
- data/lib/scout/open/stream.rb +31 -0
- data/lib/scout/path/find.rb +2 -1
- data/lib/scout/path.rb +1 -1
- data/lib/scout/persist/serialize.rb +15 -4
- data/lib/scout/resource/path.rb +5 -0
- data/lib/scout/resource/util.rb +48 -0
- data/lib/scout/resource.rb +2 -0
- data/lib/scout/semaphore.rb +148 -0
- data/lib/scout/simple_opt/doc.rb +26 -2
- data/lib/scout/work_queue/socket.rb +119 -0
- data/lib/scout/work_queue/worker.rb +54 -0
- data/lib/scout/work_queue.rb +86 -0
- data/lib/scout/workflow/definition.rb +8 -2
- data/lib/scout/workflow/documentation.rb +32 -26
- data/lib/scout/workflow/step/info.rb +13 -13
- data/lib/scout/workflow/step/load.rb +18 -0
- data/lib/scout/workflow/step.rb +40 -4
- data/lib/scout/workflow/task/inputs.rb +4 -2
- data/lib/scout/workflow/task.rb +15 -1
- data/lib/scout/workflow/usage.rb +96 -76
- data/lib/scout/workflow.rb +1 -0
- data/scout-gear.gemspec +25 -3
- data/scout_commands/workflow/info +29 -0
- data/scout_commands/workflow/list +27 -0
- data/scout_commands/workflow/task +32 -681
- data/scout_commands/workflow/task_old +706 -0
- 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/resource/test_util.rb +27 -0
- data/test/scout/simple_opt/test_doc.rb +16 -0
- data/test/scout/test_meta_extension.rb +9 -0
- data/test/scout/test_semaphore.rb +17 -0
- data/test/scout/test_work_queue.rb +93 -0
- data/test/scout/work_queue/test_socket.rb +46 -0
- data/test/scout/work_queue/test_worker.rb +99 -0
- data/test/scout/workflow/step/test_info.rb +17 -15
- data/test/scout/workflow/step/test_load.rb +65 -0
- data/test/scout/workflow/test_definition.rb +0 -0
- data/test/scout/workflow/test_documentation.rb +30 -0
- data/test/scout/workflow/test_task.rb +1 -0
- data/test/scout/workflow/test_usage.rb +12 -3
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 919678993bd756d6a67712023120e562c01a69942faf8ad23eb088f29559b1fa
|
4
|
+
data.tar.gz: a233c808dc9af64381196bce97c74727c9064c9b1a4c2a129b364a5d776b01e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 842323af61a5c66c7bf4433cbc0d23e6484e562c88601c64ac7a47ea2c1e217e6f7b590bd7d613d62614ebb2ab228246a2ac150d4d263f9425d9c1a2b4333e65
|
7
|
+
data.tar.gz: 2a4a7d00279d0cbc3153d7b116405fb5d02f8656249b4e0bdf417d01599749686242fb30db183b2baff856e92dcd5c83317161e73bb5bb1dbc861ce10d0086de
|
data/.vimproject
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
scout-gear=/$PWD filter="*.rb *.yaml" {
|
2
2
|
Rakefile
|
3
|
-
bin=bin
|
3
|
+
bin=bin filter="*"{
|
4
4
|
scout
|
5
|
-
scout_rbbt
|
6
5
|
}
|
7
6
|
scout_commands=scout_commands filter="*"{
|
7
|
+
rbbt
|
8
|
+
alias
|
8
9
|
find
|
9
10
|
glob
|
10
11
|
workflow=workflow{
|
12
|
+
task_old
|
11
13
|
task
|
14
|
+
list
|
15
|
+
info
|
12
16
|
}
|
13
|
-
alias
|
14
17
|
}
|
15
18
|
lib=lib {
|
16
19
|
scout-gear.rb
|
@@ -26,6 +29,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
26
29
|
insist.rb
|
27
30
|
digest.rb
|
28
31
|
filesystem.rb
|
32
|
+
monitor.rb
|
29
33
|
}
|
30
34
|
indiferent_hash.rb
|
31
35
|
indiferent_hash=indiferent_hash{
|
@@ -73,8 +77,9 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
73
77
|
produce=produce{
|
74
78
|
rake.rb
|
75
79
|
}
|
76
|
-
path.rb
|
77
80
|
scout.rb
|
81
|
+
util.rb
|
82
|
+
path.rb
|
78
83
|
}
|
79
84
|
persist.rb
|
80
85
|
persist=persist{
|
@@ -88,6 +93,7 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
88
93
|
step.rb
|
89
94
|
step=step{
|
90
95
|
info.rb
|
96
|
+
load.rb
|
91
97
|
}
|
92
98
|
task.rb
|
93
99
|
task=task{
|
@@ -97,6 +103,12 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
97
103
|
usage.rb
|
98
104
|
util.rb
|
99
105
|
}
|
106
|
+
semaphore.rb
|
107
|
+
work_queue.rb
|
108
|
+
work_queue=work_queue{
|
109
|
+
socket.rb
|
110
|
+
worker.rb
|
111
|
+
}
|
100
112
|
}
|
101
113
|
}
|
102
114
|
test=test {
|
@@ -218,16 +230,16 @@ scout-gear=/$PWD filter="*.rb *.yaml" {
|
|
218
230
|
concurrency=concurrency{
|
219
231
|
processes.rb
|
220
232
|
threads.rb
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
233
|
+
processes=processes{
|
234
|
+
socket.rb
|
235
|
+
worker.rb
|
236
|
+
}
|
237
|
+
}
|
226
238
|
|
227
|
-
|
239
|
+
procpath.rb
|
228
240
|
|
229
|
-
|
230
|
-
|
241
|
+
migrate.rb
|
242
|
+
}
|
231
243
|
|
232
244
|
monitor.rb
|
233
245
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
6.0.0
|
data/bin/scout
CHANGED
data/lib/scout/exceptions.rb
CHANGED
@@ -71,8 +71,20 @@ end
|
|
71
71
|
|
72
72
|
class LockInterrupted < TryAgain; end
|
73
73
|
|
74
|
-
|
75
|
-
|
74
|
+
class ClosedStream < StandardError; end
|
75
|
+
|
76
|
+
class DoneProcessing < Exception
|
77
|
+
attr_accessor :pid
|
78
|
+
def initialize(pid = Process.pid)
|
79
|
+
@pid = pid
|
80
|
+
end
|
81
|
+
|
82
|
+
def message
|
83
|
+
"Done processing pid #{pid}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
76
88
|
#class OpenGzipError < StandardError; end
|
77
89
|
#
|
78
90
|
#
|
data/lib/scout/log/color.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative 'color_class'
|
|
2
2
|
require_relative '../indiferent_hash'
|
3
3
|
|
4
4
|
require 'term/ansicolor'
|
5
|
+
require 'colorist'
|
5
6
|
|
6
7
|
module Colorize
|
7
8
|
def self.colors=(colors)
|
@@ -9,7 +10,13 @@ module Colorize
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def self.colors
|
12
|
-
@colors ||= IndiferentHash.setup(
|
13
|
+
@colors ||= IndiferentHash.setup(Hash[<<-EOF.split("\n").collect{|l| l.split(" ")}])
|
14
|
+
green #00cd00
|
15
|
+
red #cd0000
|
16
|
+
yellow #ffd700
|
17
|
+
blue #0000cd
|
18
|
+
path blue
|
19
|
+
EOF
|
13
20
|
end
|
14
21
|
|
15
22
|
def self.diverging_colors=(colors)
|
@@ -33,7 +40,6 @@ module Colorize
|
|
33
40
|
EOF
|
34
41
|
end
|
35
42
|
|
36
|
-
|
37
43
|
def self.from_name(color)
|
38
44
|
return color if color =~ /^#?[0-9A-F]+$/i
|
39
45
|
return colors[color.to_s] if colors.include?(color.to_s)
|
@@ -52,7 +58,7 @@ module Colorize
|
|
52
58
|
when 'blue'
|
53
59
|
colors["RoyalBlue"]
|
54
60
|
else
|
55
|
-
colors[color.to_s] || color
|
61
|
+
colors[color.to_s] || color.to_s
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
@@ -134,8 +140,21 @@ module Log
|
|
134
140
|
WHITE, DARK, GREEN, YELLOW, RED = Color::SOLARIZED.values_at :base0, :base00, :green, :yellow, :magenta
|
135
141
|
|
136
142
|
SEVERITY_COLOR = [reset, cyan, green, magenta, blue, yellow, red] #.collect{|e| "\033[#{e}"}
|
143
|
+
CONCEPT_COLORS = IndiferentHash.setup({
|
144
|
+
:title => magenta,
|
145
|
+
:path => blue,
|
146
|
+
:input => blue,
|
147
|
+
:value => green,
|
148
|
+
:integer => green,
|
149
|
+
:negative => red,
|
150
|
+
:float => green,
|
151
|
+
:waiting => yellow,
|
152
|
+
:started => blue,
|
153
|
+
:done => green,
|
154
|
+
:error => red,
|
155
|
+
})
|
137
156
|
HIGHLIGHT = "\033[1m"
|
138
|
-
|
157
|
+
|
139
158
|
def self.uncolor(str)
|
140
159
|
"" << Term::ANSIColor.uncolor(str)
|
141
160
|
end
|
@@ -144,15 +163,20 @@ module Log
|
|
144
163
|
reset
|
145
164
|
end
|
146
165
|
|
147
|
-
def self.color(
|
166
|
+
def self.color(color, str = nil, reset = false)
|
148
167
|
return str.dup || "" if nocolor
|
149
|
-
|
150
|
-
color
|
151
|
-
color
|
168
|
+
|
169
|
+
color = SEVERITY_COLOR[color] if Integer === color
|
170
|
+
color = CONCEPT_COLORS[color] if CONCEPT_COLORS.include?(color)
|
171
|
+
color = Term::ANSIColor.send(color) if Symbol === color and Term::ANSIColor.respond_to?(color)
|
172
|
+
|
173
|
+
return str if Symbol === color
|
174
|
+
color_str = reset ? Term::ANSIColor.reset : ""
|
175
|
+
color_str << color
|
152
176
|
if str.nil?
|
153
|
-
|
177
|
+
color_str
|
154
178
|
else
|
155
|
-
|
179
|
+
color_str + str.to_s + Term::ANSIColor.reset
|
156
180
|
end
|
157
181
|
end
|
158
182
|
|
@@ -195,15 +195,16 @@ module Log
|
|
195
195
|
def done(io = STDERR)
|
196
196
|
done_msg = Log.color(:magenta, "· ") << Log.color(:green, "done")
|
197
197
|
if @start
|
198
|
-
ellapsed = (Time.now - @start)
|
198
|
+
ellapsed = (Time.now - @start)
|
199
199
|
else
|
200
200
|
ellapsed = 0
|
201
201
|
end
|
202
|
-
|
203
|
-
done_msg << " " << Log.color(:blue, (@ticks).to_s) << " #{bytes ? 'bytes' : 'items'} in " << Log.color(:green,
|
202
|
+
ellapsed_str = [ellapsed/3600, ellapsed/60 % 60, ellapsed % 60].map{|t| "%02i" % t }.join(':')
|
203
|
+
done_msg << " " << Log.color(:blue, (@ticks).to_s) << " #{bytes ? 'bytes' : 'items'} in " << Log.color(:green, ellapsed_str)
|
204
204
|
@last_count = 0
|
205
205
|
@last_time = @start
|
206
|
-
|
206
|
+
thr = ellapsed > 0 ? (@ticks / ellapsed).to_i.to_s : 0
|
207
|
+
done_msg << " - " << Log.color(:blue, thr) << " per second"
|
207
208
|
done_msg << Log.color(:magenta, " · " << desc)
|
208
209
|
print(io, Log.up_lines(@depth) << done_msg << Log.down_lines(@depth))
|
209
210
|
|
data/lib/scout/meta_extension.rb
CHANGED
@@ -24,8 +24,10 @@ module MetaExtension
|
|
24
24
|
return if attrs.nil? || attrs.empty?
|
25
25
|
|
26
26
|
if rest.length == 1 && Hash === (rlast = rest.last) &&
|
27
|
-
! (rlkey = rlast.keys.first).nil? &&
|
28
|
-
|
27
|
+
((! (rlkey = rlast.keys.first).nil? && attrs.include?(rlkey.to_sym)) ||
|
28
|
+
(! attrs.length != 1 ))
|
29
|
+
|
30
|
+
|
29
31
|
|
30
32
|
pairs = rlast
|
31
33
|
else
|
data/lib/scout/misc/format.rb
CHANGED
@@ -25,7 +25,14 @@ module Misc
|
|
25
25
|
str
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
|
29
|
+
MAX_WIDTH = 100
|
30
|
+
def self.format_paragraph(text, size = nil, indent = nil, offset = nil)
|
31
|
+
size ||= Log.tty_size || MAX_WIDTH
|
32
|
+
size = MAX_WIDTH if size > MAX_WIDTH
|
33
|
+
indent ||= 0
|
34
|
+
offset ||= 0
|
35
|
+
|
29
36
|
i = 0
|
30
37
|
size = size + offset + indent
|
31
38
|
re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/
|
@@ -55,7 +62,10 @@ module Misc
|
|
55
62
|
end*""
|
56
63
|
end
|
57
64
|
|
58
|
-
def self.format_definition_list_item(dt, dd,
|
65
|
+
def self.format_definition_list_item(dt, dd, indent = nil, size = nil, color = :yellow)
|
66
|
+
size ||= Log.tty_size || MAX_WIDTH
|
67
|
+
size = MAX_WIDTH if size > MAX_WIDTH
|
68
|
+
indent ||= size / 3
|
59
69
|
dd = "" if dd.nil?
|
60
70
|
dt = Log.color color, dt if color
|
61
71
|
dt = dt.to_s unless dd.empty?
|
@@ -73,10 +83,12 @@ module Misc
|
|
73
83
|
text
|
74
84
|
end
|
75
85
|
|
76
|
-
def self.format_definition_list(defs,
|
86
|
+
def self.format_definition_list(defs, indent = nil, size = nil, color = :yellow, sep = "\n\n")
|
87
|
+
size ||= Log.tty_size || MAX_WIDTH
|
88
|
+
indent ||= 30
|
77
89
|
entries = []
|
78
90
|
defs.each do |dt,dd|
|
79
|
-
text = format_definition_list_item(dt,dd,size,
|
91
|
+
text = format_definition_list_item(dt,dd,indent, size,color)
|
80
92
|
entries << text
|
81
93
|
end
|
82
94
|
entries * sep
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Misc
|
2
|
+
def self.benchmark(repeats = 1, message = nil)
|
3
|
+
require 'benchmark'
|
4
|
+
res = nil
|
5
|
+
begin
|
6
|
+
measure = Benchmark.measure do
|
7
|
+
repeats.times do
|
8
|
+
res = yield
|
9
|
+
end
|
10
|
+
end
|
11
|
+
if message
|
12
|
+
puts "#{message }: #{ repeats } repeats"
|
13
|
+
else
|
14
|
+
puts "Benchmark for #{ repeats } repeats"
|
15
|
+
end
|
16
|
+
puts measure
|
17
|
+
rescue Exception
|
18
|
+
puts "Benchmark aborted"
|
19
|
+
raise $!
|
20
|
+
end
|
21
|
+
res
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.profile(options = {})
|
25
|
+
require 'ruby-prof'
|
26
|
+
profiler = RubyProf::Profile.new
|
27
|
+
profiler.start
|
28
|
+
begin
|
29
|
+
res = yield
|
30
|
+
rescue Exception
|
31
|
+
puts "Profiling aborted"
|
32
|
+
raise $!
|
33
|
+
ensure
|
34
|
+
result = profiler.stop
|
35
|
+
printer = RubyProf::FlatPrinter.new(result)
|
36
|
+
printer.print(STDOUT, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
res
|
40
|
+
end
|
41
|
+
end
|
data/lib/scout/misc.rb
CHANGED
data/lib/scout/open/stream.rb
CHANGED
@@ -68,6 +68,7 @@ module Open
|
|
68
68
|
block.call if block_given?
|
69
69
|
|
70
70
|
Log.high "Done consuming stream #{Log.fingerprint io} into #{into_path || into}"
|
71
|
+
c
|
71
72
|
rescue Aborted
|
72
73
|
Log.high "Consume stream Aborted #{Log.fingerprint io} into #{into_path || into}"
|
73
74
|
io.abort $! if io.respond_to? :abort
|
@@ -369,4 +370,34 @@ module Open
|
|
369
370
|
def self.tee_stream(stream)
|
370
371
|
tee_stream_thread(stream)
|
371
372
|
end
|
373
|
+
|
374
|
+
def self.read_stream(stream, size)
|
375
|
+
str = nil
|
376
|
+
Thread.pass while IO.select([stream],nil,nil,1).nil?
|
377
|
+
while not str = stream.read(size)
|
378
|
+
IO.select([stream],nil,nil,1)
|
379
|
+
Thread.pass
|
380
|
+
raise ClosedStream if stream.eof?
|
381
|
+
end
|
382
|
+
|
383
|
+
while str.length < size
|
384
|
+
raise ClosedStream if stream.eof?
|
385
|
+
IO.select([stream],nil,nil,1)
|
386
|
+
if new = stream.read(size-str.length)
|
387
|
+
str << new
|
388
|
+
end
|
389
|
+
end
|
390
|
+
str
|
391
|
+
end
|
392
|
+
|
393
|
+
def self.read_stream(stream, size)
|
394
|
+
str = ""
|
395
|
+
while str.length < size
|
396
|
+
missing = size - str.length
|
397
|
+
more = stream.read(missing)
|
398
|
+
str << more
|
399
|
+
end
|
400
|
+
str
|
401
|
+
end
|
402
|
+
|
372
403
|
end
|
data/lib/scout/path/find.rb
CHANGED
@@ -123,7 +123,7 @@ module Path
|
|
123
123
|
|
124
124
|
def follow(map_name = :default, annotate = true)
|
125
125
|
IndiferentHash.setup(path_maps)
|
126
|
-
map = path_maps[map_name]
|
126
|
+
map = path_maps[map_name] || Path.path_maps[map_name]
|
127
127
|
raise "Map not found #{Log.fingerprint map_name} not in #{Log.fingerprint path_maps.keys}" if map.nil?
|
128
128
|
while Symbol === map
|
129
129
|
map_name = map
|
@@ -163,4 +163,5 @@ module Path
|
|
163
163
|
.collect{|where| find(where) }
|
164
164
|
.select{|file| file.exist? }.uniq
|
165
165
|
end
|
166
|
+
|
166
167
|
end
|
data/lib/scout/path.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative 'open'
|
|
3
3
|
|
4
4
|
module Persist
|
5
5
|
TRUE_STRINGS = Set.new ["true", "True", "TRUE", "t", "T", "1", "yes", "Yes", "YES", "y", "Y", "ON", "on"] unless defined? TRUE_STRINGS
|
6
|
+
SERIALIZER = :json
|
6
7
|
|
7
8
|
class << self
|
8
9
|
attr_accessor :save_drivers, :load_drivers
|
@@ -15,6 +16,8 @@ module Persist
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.serialize(content, type)
|
19
|
+
type = type.to_sym if String === type
|
20
|
+
type = SERIALIZER if type == :serializer
|
18
21
|
case type
|
19
22
|
when nil, :string, :integer, :float, :boolean, :file, :path
|
20
23
|
if IO === content || StringIO === content
|
@@ -28,7 +31,7 @@ module Persist
|
|
28
31
|
content.to_yaml
|
29
32
|
when :json
|
30
33
|
content.to_json
|
31
|
-
when :marshal
|
34
|
+
when :marshal
|
32
35
|
Marshal.dump(content)
|
33
36
|
else
|
34
37
|
if m = type.to_s.match(/(.*)_array/)
|
@@ -41,6 +44,8 @@ module Persist
|
|
41
44
|
end
|
42
45
|
|
43
46
|
def self.deserialize(serialized, type)
|
47
|
+
type = type.to_sym if String === type
|
48
|
+
type = SERIALIZER if type == :serializer
|
44
49
|
case type
|
45
50
|
when nil, :string, :file, :stream
|
46
51
|
serialized
|
@@ -58,7 +63,7 @@ module Persist
|
|
58
63
|
YAML.parse(serialized)
|
59
64
|
when :json
|
60
65
|
JSON.parse(serialized)
|
61
|
-
when :marshal
|
66
|
+
when :marshal
|
62
67
|
Marshal.load(serialized)
|
63
68
|
else
|
64
69
|
if m = type.to_s.match(/(.*)_array/)
|
@@ -73,6 +78,10 @@ module Persist
|
|
73
78
|
|
74
79
|
MEMORY = {}
|
75
80
|
def self.save(content, file, type = :serializer)
|
81
|
+
type = :serializer if type.nil?
|
82
|
+
type = type.to_sym if String === type
|
83
|
+
type = SERIALIZER if type == :serializer
|
84
|
+
type = MEMORY if type == :memory
|
76
85
|
return if content.nil?
|
77
86
|
type = MEMORY if type == :memory
|
78
87
|
type = :serializer if type.nil?
|
@@ -97,16 +106,18 @@ module Persist
|
|
97
106
|
ConcurrentStream.setup copy, :threads => t, :filename => file, :autojoin => true
|
98
107
|
else
|
99
108
|
serialized = serialize(content, type)
|
100
|
-
Open.sensible_write(file, serialized)
|
109
|
+
Open.sensible_write(file, serialized, :force => true)
|
101
110
|
content
|
102
111
|
end
|
103
112
|
end
|
104
113
|
|
105
114
|
def self.load(file, type = :serializer)
|
106
115
|
file = file.find if Path === file
|
116
|
+
type = :serializer if type.nil?
|
117
|
+
type = type.to_sym if String === type
|
118
|
+
type = SERIALIZER if type == :serializer
|
107
119
|
type = MEMORY if type == :memory
|
108
120
|
return unless Hash === type || Open.exist?(file)
|
109
|
-
type = :serializer if type.nil?
|
110
121
|
|
111
122
|
Log.debug "Load #{Log.fingerprint type} on #{file}"
|
112
123
|
if load_drivers[type]
|
data/lib/scout/resource/path.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Resource
|
2
|
+
def identify(path)
|
3
|
+
return path unless path.start_with?("/")
|
4
|
+
path_maps = path.path_maps || self.path_maps || Path.path_maps
|
5
|
+
path = File.expand_path(path)
|
6
|
+
path += "/" if File.directory?(path)
|
7
|
+
|
8
|
+
map_order ||= (path_maps.keys & Path.basic_map_order) + (path_maps.keys - Path.basic_map_order)
|
9
|
+
map_order -= [:current, "current"]
|
10
|
+
map_order << :current
|
11
|
+
|
12
|
+
choices = []
|
13
|
+
map_order.uniq.each do |name|
|
14
|
+
pattern = path_maps[name]
|
15
|
+
pattern = path_maps[pattern] while Symbol === pattern
|
16
|
+
next if pattern.nil?
|
17
|
+
|
18
|
+
pattern = pattern.sub('{PWD}', Dir.pwd)
|
19
|
+
if String === pattern and pattern.include?('{')
|
20
|
+
regexp = "^" + pattern
|
21
|
+
.gsub(/{(TOPLEVEL)}/,'(?<\1>[^/]+)')
|
22
|
+
.gsub(/{([^}]+)}/,'(?<\1>[^/]+)?') +
|
23
|
+
"(?:/(?<REST>.*))?/?$"
|
24
|
+
if m = path.match(regexp)
|
25
|
+
if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] == self.pkgdir
|
26
|
+
unlocated = %w(TOPLEVEL SUBPATH PATH REST).collect{|c|
|
27
|
+
m.named_captures.include?(c) ? m[c] : nil
|
28
|
+
}.compact * "/"
|
29
|
+
unlocated.gsub!(/\/+/,'/')
|
30
|
+
unlocated[self.subdir] = "" if self.subdir
|
31
|
+
choices << self.annotate(unlocated)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
Path.setup(choices.sort_by{|s| s.length }.first, self, nil, path_maps)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.relocate(path)
|
41
|
+
return path if Open.exists?(path)
|
42
|
+
resource = path.pkgdir if Path === path
|
43
|
+
resource = Scout unless Resource === resource
|
44
|
+
unlocated = resource.identify path
|
45
|
+
unlocated.find
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|