rack-mount 0.6.1 → 0.6.2
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.
- data/lib/rack/mount.rb +3 -13
- data/lib/rack/mount/analysis/frequency.rb +0 -2
- data/lib/rack/mount/analysis/splitting.rb +2 -2
- data/lib/rack/mount/code_generation.rb +113 -0
- data/lib/rack/mount/generatable_regexp.rb +1 -1
- data/lib/rack/mount/route.rb +69 -5
- data/lib/rack/mount/route_set.rb +289 -46
- data/lib/rack/mount/strexp.rb +53 -50
- data/lib/rack/mount/utils.rb +7 -7
- data/lib/rack/mount/vendor/reginald/reginald.rb +2 -1
- data/lib/rack/mount/vendor/reginald/reginald/alternation.rb +11 -1
- data/lib/rack/mount/vendor/reginald/reginald/atom.rb +17 -5
- data/lib/rack/mount/vendor/reginald/reginald/character.rb +11 -2
- data/lib/rack/mount/vendor/reginald/reginald/character_class.rb +8 -20
- data/lib/rack/mount/vendor/reginald/reginald/collection.rb +10 -6
- data/lib/rack/mount/vendor/reginald/reginald/expression.rb +30 -20
- data/lib/rack/mount/vendor/reginald/reginald/group.rb +22 -8
- data/lib/rack/mount/vendor/reginald/reginald/options.rb +47 -0
- data/lib/rack/mount/vendor/reginald/reginald/parser.rb +137 -273
- data/lib/rack/mount/vendor/reginald/reginald/tokenizer.rb +1 -1
- data/lib/rack/mount/vendor/reginald/reginald/version.rb +3 -0
- data/lib/rack/mount/version.rb +1 -1
- metadata +6 -10
- data/lib/rack/mount/exceptions.rb +0 -3
- data/lib/rack/mount/generation/route.rb +0 -59
- data/lib/rack/mount/generation/route_set.rb +0 -200
- data/lib/rack/mount/mixover.rb +0 -60
- data/lib/rack/mount/recognition/code_generation.rb +0 -124
- data/lib/rack/mount/recognition/route.rb +0 -62
- data/lib/rack/mount/recognition/route_set.rb +0 -121
@@ -140,7 +140,7 @@ class Parser < Racc::Parser
|
|
140
140
|
action { [:NEGATE, text] }
|
141
141
|
|
142
142
|
when (text = @ss.scan(/:(alnum|alpha|ascii|blank|cntrl|digit|graph|lower|print|punct|space|upper|word|xdigit):/))
|
143
|
-
action { [
|
143
|
+
action { [:CTYPE, text] }
|
144
144
|
|
145
145
|
when (text = @ss.scan(/\\-/))
|
146
146
|
action { [:CHAR, text] }
|
data/lib/rack/mount/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
8
|
+
- 2
|
9
|
+
version: 0.6.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joshua Peek
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-13 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -32,16 +32,10 @@ files:
|
|
32
32
|
- lib/rack/mount/analysis/frequency.rb
|
33
33
|
- lib/rack/mount/analysis/histogram.rb
|
34
34
|
- lib/rack/mount/analysis/splitting.rb
|
35
|
-
- lib/rack/mount/
|
35
|
+
- lib/rack/mount/code_generation.rb
|
36
36
|
- lib/rack/mount/generatable_regexp.rb
|
37
|
-
- lib/rack/mount/generation/route.rb
|
38
|
-
- lib/rack/mount/generation/route_set.rb
|
39
|
-
- lib/rack/mount/mixover.rb
|
40
37
|
- lib/rack/mount/multimap.rb
|
41
38
|
- lib/rack/mount/prefix.rb
|
42
|
-
- lib/rack/mount/recognition/code_generation.rb
|
43
|
-
- lib/rack/mount/recognition/route.rb
|
44
|
-
- lib/rack/mount/recognition/route_set.rb
|
45
39
|
- lib/rack/mount/regexp_with_named_groups.rb
|
46
40
|
- lib/rack/mount/route.rb
|
47
41
|
- lib/rack/mount/route_set.rb
|
@@ -63,8 +57,10 @@ files:
|
|
63
57
|
- lib/rack/mount/vendor/reginald/reginald/collection.rb
|
64
58
|
- lib/rack/mount/vendor/reginald/reginald/expression.rb
|
65
59
|
- lib/rack/mount/vendor/reginald/reginald/group.rb
|
60
|
+
- lib/rack/mount/vendor/reginald/reginald/options.rb
|
66
61
|
- lib/rack/mount/vendor/reginald/reginald/parser.rb
|
67
62
|
- lib/rack/mount/vendor/reginald/reginald/tokenizer.rb
|
63
|
+
- lib/rack/mount/vendor/reginald/reginald/version.rb
|
68
64
|
- lib/rack/mount/version.rb
|
69
65
|
has_rdoc: true
|
70
66
|
homepage: http://github.com/josh/rack-mount
|
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'rack/mount/utils'
|
2
|
-
|
3
|
-
module Rack::Mount
|
4
|
-
module Generation
|
5
|
-
module Route #:nodoc:
|
6
|
-
def initialize(*args)
|
7
|
-
super
|
8
|
-
|
9
|
-
@has_significant_params = @conditions.any? { |method, condition|
|
10
|
-
(condition.respond_to?(:required_params) && condition.required_params.any?) ||
|
11
|
-
(condition.respond_to?(:required_defaults) && condition.required_defaults.any?)
|
12
|
-
}
|
13
|
-
end
|
14
|
-
|
15
|
-
def generation_keys
|
16
|
-
@conditions.inject({}) { |keys, (method, condition)|
|
17
|
-
if condition.respond_to?(:required_defaults)
|
18
|
-
keys.merge!(condition.required_defaults)
|
19
|
-
else
|
20
|
-
keys
|
21
|
-
end
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
def significant_params?
|
26
|
-
@has_significant_params
|
27
|
-
end
|
28
|
-
|
29
|
-
def generate(method, params = {}, recall = {}, options = {})
|
30
|
-
if method.nil?
|
31
|
-
result = @conditions.inject({}) { |h, (method, condition)|
|
32
|
-
if condition.respond_to?(:generate)
|
33
|
-
h[method] = condition.generate(params, recall, options)
|
34
|
-
end
|
35
|
-
h
|
36
|
-
}
|
37
|
-
return nil if result.values.compact.empty?
|
38
|
-
else
|
39
|
-
result = generate_method(method, params, recall, options)
|
40
|
-
end
|
41
|
-
|
42
|
-
if result
|
43
|
-
@defaults.each do |key, value|
|
44
|
-
params.delete(key) if params[key] == value
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
result
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
def generate_method(method, params, recall, options)
|
53
|
-
if condition = @conditions[method]
|
54
|
-
condition.generate(params, recall, options)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,200 +0,0 @@
|
|
1
|
-
require 'rack/mount/utils'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
module Rack::Mount
|
5
|
-
module Generation
|
6
|
-
module RouteSet
|
7
|
-
# Adds generation related concerns to RouteSet.new.
|
8
|
-
def initialize(*args)
|
9
|
-
@named_routes = {}
|
10
|
-
@generation_key_analyzer = Analysis::Frequency.new
|
11
|
-
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
# Adds generation aspects to RouteSet#add_route.
|
16
|
-
def add_route(*args)
|
17
|
-
route = super
|
18
|
-
@named_routes[route.name] = route if route.name
|
19
|
-
@generation_key_analyzer << route.generation_keys
|
20
|
-
route
|
21
|
-
end
|
22
|
-
|
23
|
-
# Generates a url from Rack env and identifiers or significant keys.
|
24
|
-
#
|
25
|
-
# To generate a url by named route, pass the name in as a +Symbol+.
|
26
|
-
# url(env, :dashboard) # => "/dashboard"
|
27
|
-
#
|
28
|
-
# Additional parameters can be passed in as a hash
|
29
|
-
# url(env, :people, :id => "1") # => "/people/1"
|
30
|
-
#
|
31
|
-
# If no name route is given, it will fall back to a slower
|
32
|
-
# generation search.
|
33
|
-
# url(env, :controller => "people", :action => "show", :id => "1")
|
34
|
-
# # => "/people/1"
|
35
|
-
def url(env, *args)
|
36
|
-
named_route, params = nil, {}
|
37
|
-
|
38
|
-
case args.length
|
39
|
-
when 2
|
40
|
-
named_route, params = args[0], args[1].dup
|
41
|
-
when 1
|
42
|
-
if args[0].is_a?(Hash)
|
43
|
-
params = args[0].dup
|
44
|
-
else
|
45
|
-
named_route = args[0]
|
46
|
-
end
|
47
|
-
else
|
48
|
-
raise ArgumentError
|
49
|
-
end
|
50
|
-
|
51
|
-
only_path = params.delete(:only_path)
|
52
|
-
recall = env[@parameters_key] || {}
|
53
|
-
|
54
|
-
unless result = generate(:all, named_route, params, recall,
|
55
|
-
:parameterize => lambda { |name, param| Utils.escape_uri(param) })
|
56
|
-
return
|
57
|
-
end
|
58
|
-
|
59
|
-
parts, params = result
|
60
|
-
return unless parts
|
61
|
-
|
62
|
-
params.each do |k, v|
|
63
|
-
if v
|
64
|
-
params[k] = v
|
65
|
-
else
|
66
|
-
params.delete(k)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
req = stubbed_request_class.new(env)
|
71
|
-
req._stubbed_values = parts.merge(:query_string => Utils.build_nested_query(params))
|
72
|
-
only_path ? req.fullpath : req.url
|
73
|
-
end
|
74
|
-
|
75
|
-
def generate(method, *args) #:nodoc:
|
76
|
-
raise 'route set not finalized' unless @generation_graph
|
77
|
-
|
78
|
-
method = nil if method == :all
|
79
|
-
named_route, params, recall, options = extract_params!(*args)
|
80
|
-
merged = recall.merge(params)
|
81
|
-
route = nil
|
82
|
-
|
83
|
-
if named_route
|
84
|
-
if route = @named_routes[named_route.to_sym]
|
85
|
-
recall = route.defaults.merge(recall)
|
86
|
-
url = route.generate(method, params, recall, options)
|
87
|
-
[url, params]
|
88
|
-
else
|
89
|
-
raise RoutingError, "#{named_route} failed to generate from #{params.inspect}"
|
90
|
-
end
|
91
|
-
else
|
92
|
-
keys = @generation_keys.map { |key|
|
93
|
-
if k = merged[key]
|
94
|
-
k.to_s
|
95
|
-
else
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
}
|
99
|
-
@generation_graph[*keys].each do |r|
|
100
|
-
next unless r.significant_params?
|
101
|
-
if url = r.generate(method, params, recall, options)
|
102
|
-
return [url, params]
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
raise RoutingError, "No route matches #{params.inspect}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def rehash #:nodoc:
|
111
|
-
@generation_keys = build_generation_keys
|
112
|
-
@generation_graph = build_generation_graph
|
113
|
-
|
114
|
-
super
|
115
|
-
end
|
116
|
-
|
117
|
-
private
|
118
|
-
def expire!
|
119
|
-
@generation_keys = @generation_graph = nil
|
120
|
-
@generation_key_analyzer.expire!
|
121
|
-
super
|
122
|
-
end
|
123
|
-
|
124
|
-
def flush!
|
125
|
-
@generation_key_analyzer = nil
|
126
|
-
super
|
127
|
-
end
|
128
|
-
|
129
|
-
def build_generation_graph
|
130
|
-
build_nested_route_set(@generation_keys) { |k, i|
|
131
|
-
throw :skip unless @routes[i].significant_params?
|
132
|
-
|
133
|
-
if k = @generation_key_analyzer.possible_keys[i][k]
|
134
|
-
k.to_s
|
135
|
-
else
|
136
|
-
nil
|
137
|
-
end
|
138
|
-
}
|
139
|
-
end
|
140
|
-
|
141
|
-
def build_generation_keys
|
142
|
-
@generation_key_analyzer.report
|
143
|
-
end
|
144
|
-
|
145
|
-
def extract_params!(*args)
|
146
|
-
case args.length
|
147
|
-
when 4
|
148
|
-
named_route, params, recall, options = args
|
149
|
-
when 3
|
150
|
-
if args[0].is_a?(Hash)
|
151
|
-
params, recall, options = args
|
152
|
-
else
|
153
|
-
named_route, params, recall = args
|
154
|
-
end
|
155
|
-
when 2
|
156
|
-
if args[0].is_a?(Hash)
|
157
|
-
params, recall = args
|
158
|
-
else
|
159
|
-
named_route, params = args
|
160
|
-
end
|
161
|
-
when 1
|
162
|
-
if args[0].is_a?(Hash)
|
163
|
-
params = args[0]
|
164
|
-
else
|
165
|
-
named_route = args[0]
|
166
|
-
end
|
167
|
-
else
|
168
|
-
raise ArgumentError
|
169
|
-
end
|
170
|
-
|
171
|
-
named_route ||= nil
|
172
|
-
params ||= {}
|
173
|
-
recall ||= {}
|
174
|
-
options ||= {}
|
175
|
-
|
176
|
-
[named_route, params.dup, recall.dup, options.dup]
|
177
|
-
end
|
178
|
-
|
179
|
-
def instance_variables_to_serialize
|
180
|
-
super - [:@stubbed_request_class]
|
181
|
-
end
|
182
|
-
|
183
|
-
def stubbed_request_class
|
184
|
-
@stubbed_request_class ||= begin
|
185
|
-
klass = Class.new(@request_class)
|
186
|
-
klass.public_instance_methods.each do |method|
|
187
|
-
next if method =~ /^__|object_id/
|
188
|
-
klass.class_eval <<-RUBY
|
189
|
-
def #{method}(*args, &block)
|
190
|
-
@_stubbed_values[:#{method}] || super
|
191
|
-
end
|
192
|
-
RUBY
|
193
|
-
end
|
194
|
-
klass.class_eval { attr_accessor :_stubbed_values }
|
195
|
-
klass
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
data/lib/rack/mount/mixover.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
module Rack::Mount
|
2
|
-
# A mixin that changes the behavior of +include+. Instead of modules
|
3
|
-
# being chained as a superclass, they are mixed into the objects
|
4
|
-
# metaclass. This allows mixins to be stacked ontop of the instance
|
5
|
-
# methods.
|
6
|
-
module Mixover
|
7
|
-
def self.extended(klass)
|
8
|
-
klass.instance_eval do
|
9
|
-
@extended_modules = []
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module InstanceMethods #:nodoc:
|
14
|
-
def dup
|
15
|
-
obj = super
|
16
|
-
included_modules = (class << self; included_modules; end) - (class << obj; included_modules; end)
|
17
|
-
included_modules.reverse.each { |mod| obj.extend(mod) }
|
18
|
-
obj
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Replaces include with a lazy version.
|
23
|
-
def include(*mod)
|
24
|
-
extended_modules.push(*mod)
|
25
|
-
end
|
26
|
-
|
27
|
-
def extended_modules
|
28
|
-
Thread.current[extended_modules_thread_local_key] || @extended_modules
|
29
|
-
end
|
30
|
-
|
31
|
-
def new(*args, &block) #:nodoc:
|
32
|
-
obj = allocate
|
33
|
-
obj.extend(InstanceMethods)
|
34
|
-
extended_modules.each { |mod| obj.extend(mod) }
|
35
|
-
obj.send(:initialize, *args, &block)
|
36
|
-
obj
|
37
|
-
end
|
38
|
-
|
39
|
-
# Create a new class without an included module.
|
40
|
-
def new_without_module(mod, *args, &block)
|
41
|
-
(Thread.current[extended_modules_thread_local_key] = extended_modules.dup).delete(mod)
|
42
|
-
new(*args, &block)
|
43
|
-
ensure
|
44
|
-
Thread.current[extended_modules_thread_local_key] = nil
|
45
|
-
end
|
46
|
-
|
47
|
-
# Create a new class temporarily with a module.
|
48
|
-
def new_with_module(mod, *args, &block)
|
49
|
-
(Thread.current[extended_modules_thread_local_key] = extended_modules.dup).push(*mod)
|
50
|
-
new(*args, &block)
|
51
|
-
ensure
|
52
|
-
Thread.current[extended_modules_thread_local_key] = nil
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
def extended_modules_thread_local_key
|
57
|
-
"mixover_extended_modules_#{object_id}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
module Rack::Mount
|
2
|
-
module Recognition
|
3
|
-
module CodeGeneration #:nodoc:
|
4
|
-
def initialize(*args)
|
5
|
-
@optimized_recognize_defined = false
|
6
|
-
super
|
7
|
-
end
|
8
|
-
|
9
|
-
def _expired_recognize(env) #:nodoc:
|
10
|
-
raise 'route set not finalized'
|
11
|
-
end
|
12
|
-
|
13
|
-
def rehash
|
14
|
-
super
|
15
|
-
optimize_recognize!
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
def instance_variables_to_serialize
|
20
|
-
super - [:@optimized_recognize_defined]
|
21
|
-
end
|
22
|
-
|
23
|
-
def expire!
|
24
|
-
if @optimized_recognize_defined
|
25
|
-
remove_metaclass_method :recognize
|
26
|
-
|
27
|
-
class << self
|
28
|
-
alias_method :recognize, :_expired_recognize
|
29
|
-
end
|
30
|
-
|
31
|
-
@optimized_recognize_defined = false
|
32
|
-
end
|
33
|
-
|
34
|
-
super
|
35
|
-
end
|
36
|
-
|
37
|
-
def optimize_container_iterator(container)
|
38
|
-
body = []
|
39
|
-
|
40
|
-
container.each_with_index { |route, i|
|
41
|
-
body << "route = self[#{i}]"
|
42
|
-
body << 'matches = {}'
|
43
|
-
body << 'params = route.defaults.dup'
|
44
|
-
|
45
|
-
conditions = []
|
46
|
-
route.conditions.each do |method, condition|
|
47
|
-
b = []
|
48
|
-
if condition.is_a?(Regexp)
|
49
|
-
b << "if m = obj.#{method}.match(#{condition.inspect})"
|
50
|
-
b << "matches[:#{method}] = m"
|
51
|
-
if (named_captures = route.named_captures[method]) && named_captures.any?
|
52
|
-
b << 'captures = m.captures'
|
53
|
-
b << 'p = nil'
|
54
|
-
b << named_captures.map { |k, j| "params[#{k.inspect}] = p if p = captures[#{j}]" }.join('; ')
|
55
|
-
end
|
56
|
-
else
|
57
|
-
b << "if m = obj.#{method} == route.conditions[:#{method}]"
|
58
|
-
end
|
59
|
-
b << 'true'
|
60
|
-
b << 'end'
|
61
|
-
conditions << "(#{b.join('; ')})"
|
62
|
-
end
|
63
|
-
|
64
|
-
body << <<-RUBY
|
65
|
-
if #{conditions.join(' && ')}
|
66
|
-
yield route, matches, params
|
67
|
-
end
|
68
|
-
RUBY
|
69
|
-
}
|
70
|
-
|
71
|
-
container.instance_eval(<<-RUBY, __FILE__, __LINE__)
|
72
|
-
def optimized_each(obj)
|
73
|
-
#{body.join("\n")}
|
74
|
-
nil
|
75
|
-
end
|
76
|
-
RUBY
|
77
|
-
end
|
78
|
-
|
79
|
-
def optimize_recognize!
|
80
|
-
keys = @recognition_keys.map { |key|
|
81
|
-
if key.respond_to?(:call_source)
|
82
|
-
key.call_source(:cache, :obj)
|
83
|
-
else
|
84
|
-
"obj.#{key}"
|
85
|
-
end
|
86
|
-
}.join(', ')
|
87
|
-
|
88
|
-
@optimized_recognize_defined = true
|
89
|
-
|
90
|
-
remove_metaclass_method :recognize
|
91
|
-
|
92
|
-
instance_eval(<<-RUBY, __FILE__, __LINE__)
|
93
|
-
def recognize(obj)
|
94
|
-
cache = {}
|
95
|
-
container = @recognition_graph[#{keys}]
|
96
|
-
optimize_container_iterator(container) unless container.respond_to?(:optimized_each)
|
97
|
-
|
98
|
-
if block_given?
|
99
|
-
container.optimized_each(obj) do |route, matches, params|
|
100
|
-
yield route, matches, params
|
101
|
-
end
|
102
|
-
else
|
103
|
-
container.optimized_each(obj) do |route, matches, params|
|
104
|
-
return route, matches, params
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
nil
|
109
|
-
end
|
110
|
-
RUBY
|
111
|
-
end
|
112
|
-
|
113
|
-
# method_defined? can't distinguish between instance
|
114
|
-
# and meta methods. So we have to rescue if the method
|
115
|
-
# has not been defined in the metaclass yet.
|
116
|
-
def remove_metaclass_method(symbol)
|
117
|
-
metaclass = class << self; self; end
|
118
|
-
metaclass.send(:remove_method, symbol)
|
119
|
-
rescue NameError => e
|
120
|
-
nil
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|