joshbuddy-usher 0.3.6 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -3
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/lib/usher/grapher.rb +0 -1
- data/lib/usher/interface/rack_interface.rb +1 -1
- data/lib/usher/interface/rails2_interface/mapper.rb +2 -2
- data/lib/usher/node.rb +45 -7
- data/lib/usher/route/variable.rb +5 -4
- data/lib/usher/route.rb +7 -6
- data/lib/usher/splitter.rb +35 -15
- data/lib/usher.rb +21 -18
- data/spec/recognize_spec.rb +44 -0
- data/spec/split_spec.rb +6 -1
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -67,7 +67,7 @@ Sections of a route can be marked as "one and only one" by surrounding it with b
|
|
67
67
|
|
68
68
|
== Rack
|
69
69
|
|
70
|
-
===
|
70
|
+
=== config.ru
|
71
71
|
|
72
72
|
require 'usher'
|
73
73
|
app = proc do |env|
|
@@ -82,8 +82,10 @@ Sections of a route can be marked as "one and only one" by surrounding it with b
|
|
82
82
|
]
|
83
83
|
end
|
84
84
|
|
85
|
-
routes = Usher::Interface.for(:rack)
|
86
|
-
|
85
|
+
routes = Usher::Interface.for(:rack) do
|
86
|
+
add('/hello/:name').to(app)
|
87
|
+
end
|
88
|
+
|
87
89
|
run routes
|
88
90
|
|
89
91
|
------------
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
s.homepage = "http://github.com/joshbuddy/usher"
|
10
10
|
s.authors = ["Joshua Hull"]
|
11
11
|
s.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"]
|
12
|
-
s.add_dependency 'joshbuddy-fuzzy_hash', '>=0.0.
|
12
|
+
s.add_dependency 'joshbuddy-fuzzy_hash', '>=0.0.3'
|
13
13
|
end
|
14
14
|
rescue LoadError
|
15
15
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
data/VERSION.yml
CHANGED
data/lib/usher/grapher.rb
CHANGED
@@ -7,7 +7,7 @@ class Usher
|
|
7
7
|
@set = set
|
8
8
|
end
|
9
9
|
|
10
|
-
def connect(path, options =
|
10
|
+
def connect(path, options = nil)
|
11
11
|
@set.add_route(path, options)
|
12
12
|
end
|
13
13
|
|
@@ -21,7 +21,7 @@ class Usher
|
|
21
21
|
named_route(:root, '/', options)
|
22
22
|
end
|
23
23
|
|
24
|
-
def named_route(name, path, options =
|
24
|
+
def named_route(name, path, options = nil)
|
25
25
|
@set.add_named_route(name, path, options)
|
26
26
|
end
|
27
27
|
|
data/lib/usher/node.rb
CHANGED
@@ -14,10 +14,14 @@ class Usher
|
|
14
14
|
def initialize(parent, value)
|
15
15
|
@parent = parent
|
16
16
|
@value = value
|
17
|
-
@lookup =
|
17
|
+
@lookup = Hash.new
|
18
18
|
@exclusive_type = nil
|
19
19
|
end
|
20
20
|
|
21
|
+
def upgrade_lookup
|
22
|
+
@lookup = FuzzyHash.new(@lookup)
|
23
|
+
end
|
24
|
+
|
21
25
|
def depth
|
22
26
|
@depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
|
23
27
|
end
|
@@ -54,6 +58,7 @@ class Usher
|
|
54
58
|
key = parts.shift
|
55
59
|
target_node = case key
|
56
60
|
when Route::RequestMethod
|
61
|
+
current_node.upgrade_lookup if key.value.is_a?(Regexp)
|
57
62
|
if current_node.exclusive_type == key.type
|
58
63
|
current_node.lookup[key.value] ||= Node.new(current_node, key)
|
59
64
|
elsif current_node.lookup.empty?
|
@@ -64,7 +69,15 @@ class Usher
|
|
64
69
|
current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
|
65
70
|
end
|
66
71
|
else
|
67
|
-
|
72
|
+
if !key.is_a?(Route::Variable)
|
73
|
+
current_node.upgrade_lookup if key.is_a?(Regexp)
|
74
|
+
current_node.lookup[key] ||= Node.new(current_node, key)
|
75
|
+
elsif key.regex_matcher
|
76
|
+
current_node.upgrade_lookup
|
77
|
+
current_node.lookup[key.regex_matcher] ||= Node.new(current_node, key)
|
78
|
+
else
|
79
|
+
current_node.lookup[nil] ||= Node.new(current_node, key)
|
80
|
+
end
|
68
81
|
end
|
69
82
|
current_node = target_node
|
70
83
|
end
|
@@ -86,20 +99,45 @@ class Usher
|
|
86
99
|
if terminates?
|
87
100
|
Response.new(terminates, params)
|
88
101
|
elsif params.last.is_a?(Array) && @lookup[nil]
|
89
|
-
|
102
|
+
if @lookup[nil].exclusive_type
|
103
|
+
@lookup[nil].find(request, path, params)
|
104
|
+
else
|
105
|
+
Response.new(@lookup[nil].terminates, params)
|
106
|
+
end
|
90
107
|
end
|
91
108
|
elsif next_part = @lookup[part]
|
92
|
-
next_part.find(request, path, params)
|
93
|
-
elsif next_part = @lookup[nil]
|
94
109
|
if next_part.value.is_a?(Route::Variable)
|
95
110
|
part = next_part.value.transform!(part)
|
96
111
|
next_part.value.valid!(part)
|
112
|
+
var = next_part.value
|
113
|
+
params << [next_part.value.name, part]
|
114
|
+
until (path.first == var.look_ahead) || path.empty?
|
115
|
+
params.last.last << path.shift.to_s
|
116
|
+
end
|
117
|
+
next_part.find(request, path, params)
|
118
|
+
else
|
119
|
+
next_part.find(request, path, params)
|
120
|
+
end
|
121
|
+
elsif next_part = @lookup[part] || next_part = @lookup[nil]
|
122
|
+
if next_part.value.is_a?(Route::Variable)
|
97
123
|
case next_part.value.type
|
98
124
|
when :*
|
99
125
|
params << [next_part.value.name, []] unless params.last && params.last.first == next_part.value.name
|
100
|
-
|
101
|
-
|
126
|
+
if next_part.value.look_ahead === part
|
127
|
+
path.unshift(part)
|
128
|
+
path.unshift(next_part.parent.value) if next_part.parent.value.is_a?(Symbol)
|
129
|
+
next_part.find(request, path, params)
|
130
|
+
else
|
131
|
+
unless part.is_a?(Symbol)
|
132
|
+
part = next_part.value.transform!(part)
|
133
|
+
next_part.value.valid!(part)
|
134
|
+
params.last.last << part
|
135
|
+
end
|
136
|
+
find(request, path, params)
|
137
|
+
end
|
102
138
|
when :':'
|
139
|
+
part = next_part.value.transform!(part)
|
140
|
+
next_part.value.valid!(part)
|
103
141
|
var = next_part.value
|
104
142
|
params << [next_part.value.name, part]
|
105
143
|
until (path.first == var.look_ahead) || path.empty?
|
data/lib/usher/route/variable.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
class Usher
|
2
2
|
class Route
|
3
3
|
class Variable
|
4
|
-
attr_reader :type, :name, :validator, :transformer
|
4
|
+
attr_reader :type, :name, :validator, :transformer, :regex_matcher
|
5
5
|
attr_accessor :look_ahead
|
6
6
|
|
7
|
-
def initialize(type, name,
|
7
|
+
def initialize(type, name, validator = nil, transformer = nil, regex_matcher = nil)
|
8
8
|
@type = type
|
9
9
|
@name = :"#{name}"
|
10
|
-
@validator =
|
11
|
-
@transformer =
|
10
|
+
@validator = validator
|
11
|
+
@transformer = transformer
|
12
|
+
@regex_matcher = regex_matcher
|
12
13
|
end
|
13
14
|
|
14
15
|
def to_s
|
data/lib/usher/route.rb
CHANGED
@@ -8,14 +8,15 @@ class Usher
|
|
8
8
|
class Route
|
9
9
|
attr_reader :paths, :original_path, :requirements, :conditions, :params, :primary_path
|
10
10
|
|
11
|
-
def initialize(original_path, router, options =
|
11
|
+
def initialize(original_path, router, options = nil) # :nodoc:
|
12
12
|
@original_path = original_path
|
13
13
|
@router = router
|
14
|
-
@requirements = options.delete(:requirements)
|
15
|
-
@conditions = options.delete(:conditions)
|
16
|
-
@transformers = options.delete(:transformers)
|
14
|
+
@requirements = options && options.delete(:requirements)
|
15
|
+
@conditions = options && options.delete(:conditions)
|
16
|
+
@transformers = options && options.delete(:transformers)
|
17
17
|
@paths = @router.splitter.split(@original_path, @requirements, @transformers).collect {|path| Path.new(self, path)}
|
18
18
|
@primary_path = @paths.first
|
19
|
+
#FIXME params is poorly named. this shouldn't be an array
|
19
20
|
@params = []
|
20
21
|
end
|
21
22
|
|
@@ -27,8 +28,8 @@ class Usher
|
|
27
28
|
# route = set.add_route('/test')
|
28
29
|
# route.to(:controller => 'testing', :action => 'index')
|
29
30
|
# set.recognize(Request.new('/test')).first.params => {:controller => 'testing', :action => 'index'}
|
30
|
-
def to(options)
|
31
|
-
@params << options
|
31
|
+
def to(options = nil, &block)
|
32
|
+
@params << (block_given? ? block : options)
|
32
33
|
self
|
33
34
|
end
|
34
35
|
|
data/lib/usher/splitter.rb
CHANGED
@@ -8,7 +8,7 @@ class Usher
|
|
8
8
|
|
9
9
|
SplitterInstance.new(
|
10
10
|
delimiters,
|
11
|
-
Regexp.new('((:|\*)?[0-9A-Za-z\$\-_\+!\*\',]+|' + delimiters_regex + '|\(|\)
|
11
|
+
Regexp.new('((:|\*)?[0-9A-Za-z\$\-_\+!\*\',]+|' + delimiters_regex + '|\(|\)|\||\{)'),
|
12
12
|
Regexp.new(delimiters_regex + '|[0-9A-Za-z\$\-_\+!\*\',]+')
|
13
13
|
)
|
14
14
|
end
|
@@ -40,7 +40,7 @@ class Usher
|
|
40
40
|
parts
|
41
41
|
end
|
42
42
|
|
43
|
-
def split(path, requirements =
|
43
|
+
def split(path, requirements = nil, transformers = nil)
|
44
44
|
parts = Group.new(:all, nil)
|
45
45
|
ss = StringScanner.new(path)
|
46
46
|
current_group = parts
|
@@ -48,8 +48,32 @@ class Usher
|
|
48
48
|
part = ss.scan(@split_regex)
|
49
49
|
case part[0]
|
50
50
|
when ?*, ?:
|
51
|
-
type =
|
52
|
-
current_group << Usher::Route::Variable.new(type, part,
|
51
|
+
type = part.slice!(0).chr.to_sym
|
52
|
+
current_group << Usher::Route::Variable.new(type, part, requirements && requirements[part.to_sym], transformers && transformers[part.to_sym])
|
53
|
+
when ?{
|
54
|
+
pattern = ''
|
55
|
+
count = 1
|
56
|
+
variable = ss.scan(/:([^,]+),/)
|
57
|
+
until count.zero?
|
58
|
+
regex_part = ss.scan(/\{|\}|[^\{\}]+/)
|
59
|
+
case regex_part[0]
|
60
|
+
when ?{
|
61
|
+
count += 1
|
62
|
+
when ?}
|
63
|
+
count -= 1
|
64
|
+
end
|
65
|
+
pattern << regex_part
|
66
|
+
end
|
67
|
+
pattern.slice!(pattern.size - 1)
|
68
|
+
regex = Regexp.new(pattern)
|
69
|
+
if variable
|
70
|
+
variable_type = variable.slice!(0).chr.to_sym
|
71
|
+
variable_name = variable[0, variable.size - 1].to_sym
|
72
|
+
current_group << Usher::Route::Variable.new(variable_type, variable_name, requirements && requirements[variable_name], transformers && transformers[variable_name], regex)
|
73
|
+
else
|
74
|
+
current_group << regex
|
75
|
+
end
|
76
|
+
|
53
77
|
when ?(
|
54
78
|
new_group = Group.new(:any, current_group)
|
55
79
|
current_group << new_group
|
@@ -75,20 +99,16 @@ class Usher
|
|
75
99
|
end unless !path || path.empty?
|
76
100
|
paths = calc_paths(parts)
|
77
101
|
paths.each do |path|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if last_variable
|
86
|
-
last_variable.look_ahead = last_delimiter || @delimiters.first.to_sym
|
102
|
+
path.each_with_index do |part, index|
|
103
|
+
if part.is_a?(Usher::Route::Variable)
|
104
|
+
case part.type
|
105
|
+
when :*
|
106
|
+
part.look_ahead = path[index + 1, path.size].find{|p| !p.is_a?(Symbol) && !p.is_a?(Usher::Route::Variable)} || nil
|
107
|
+
when :':'
|
108
|
+
part.look_ahead = path[index + 1, path.size].find{|p| p.is_a?(Symbol)} || @delimiters.first.to_sym
|
87
109
|
end
|
88
|
-
last_variable = part
|
89
110
|
end
|
90
111
|
end
|
91
|
-
last_variable.look_ahead = last_delimiter || @delimiters.first.to_sym if last_variable
|
92
112
|
end
|
93
113
|
paths
|
94
114
|
end
|
data/lib/usher.rb
CHANGED
@@ -45,9 +45,9 @@ class Usher
|
|
45
45
|
# The +request_methods+ are methods that are called against the request object in order to
|
46
46
|
# enforce the +conditions+ segment of the routes. For HTTP routes (and in fact the default), those
|
47
47
|
# methods are <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method]</tt>.
|
48
|
-
def initialize(options =
|
49
|
-
@delimiters = options.delete(:options) || ['/', '.']
|
50
|
-
@request_methods = options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
48
|
+
def initialize(options = nil)
|
49
|
+
@delimiters = options && options.delete(:options) || ['/', '.']
|
50
|
+
@request_methods = options && options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
51
51
|
@splitter = Splitter.for_delimiters(@delimiters)
|
52
52
|
reset!
|
53
53
|
end
|
@@ -56,7 +56,7 @@ class Usher
|
|
56
56
|
#
|
57
57
|
# set = Usher.new
|
58
58
|
# set.add_named_route(:test_route, '/test')
|
59
|
-
def add_named_route(name, path, options =
|
59
|
+
def add_named_route(name, path, options = nil)
|
60
60
|
add_route(path, options).name(name)
|
61
61
|
end
|
62
62
|
|
@@ -113,19 +113,20 @@ class Usher
|
|
113
113
|
# * +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
114
114
|
# * +conditions+ - Accepts any of the +request_methods+ specificied in the construction of Usher. This can be either a <tt>string</tt> or a regular expression.
|
115
115
|
# * Any other key is interpreted as a requirement for the variable of its name.
|
116
|
-
def add_route(path, options =
|
117
|
-
transformers = options.delete(:transformers) || {}
|
118
|
-
conditions = options.delete(:conditions) || {}
|
119
|
-
requirements = options.delete(:requirements) || {}
|
120
|
-
options
|
121
|
-
|
122
|
-
|
123
|
-
|
116
|
+
def add_route(path, options = nil)
|
117
|
+
transformers = options && options.delete(:transformers) || {}
|
118
|
+
conditions = options && options.delete(:conditions) || {}
|
119
|
+
requirements = options && options.delete(:requirements) || {}
|
120
|
+
if options
|
121
|
+
options.delete_if do |k, v|
|
122
|
+
if v.is_a?(Regexp) || v.is_a?(Proc)
|
123
|
+
requirements[k] = v
|
124
|
+
true
|
125
|
+
end
|
124
126
|
end
|
125
127
|
end
|
126
|
-
|
127
128
|
route = Route.new(path, self, {:transformers => transformers, :conditions => conditions, :requirements => requirements})
|
128
|
-
route.to(options)
|
129
|
+
route.to(options) if options && !options.empty?
|
129
130
|
|
130
131
|
@tree.add(route)
|
131
132
|
@routes << route
|
@@ -160,10 +161,10 @@ class Usher
|
|
160
161
|
# set.generate_url(nil, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
161
162
|
# set.generate_url(:test_route, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
162
163
|
# set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
163
|
-
def generate_url(route, params =
|
164
|
-
check_variables = options.key?(:check_variables) ? options.delete(:check_variables) : false
|
165
|
-
delimiter = options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
|
166
|
-
extra_params = options.key?(:extra_params) ? options.delete(:extra_params) : {}
|
164
|
+
def generate_url(route, params = nil, options = nil)
|
165
|
+
check_variables = options && options.key?(:check_variables) ? options.delete(:check_variables) : false
|
166
|
+
delimiter = options && options.key?(:delimiter) ? options.delete(:delimiter) : @delimiters.first
|
167
|
+
extra_params = options && options.key?(:extra_params) ? options.delete(:extra_params) : {}
|
167
168
|
|
168
169
|
path = case route
|
169
170
|
when Symbol
|
@@ -183,6 +184,8 @@ class Usher
|
|
183
184
|
path.dynamic_parts.collect{|k| params_hash.delete(k.name) {|el| raise MissingParameterException.new(k.name)} }
|
184
185
|
when Array
|
185
186
|
path.dynamic_parts.size == params.size ? params : raise(MissingParameterException.new("got #{params.size} arguments, expected #{path.dynamic_parts.size}"))
|
187
|
+
when nil
|
188
|
+
nil
|
186
189
|
else
|
187
190
|
Array(params)
|
188
191
|
end
|
data/spec/recognize_spec.rb
CHANGED
@@ -40,6 +40,50 @@ describe "Usher route recognition" do
|
|
40
40
|
route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'})).params.should == [[:format, ['html', 'json', 'apple']]]
|
41
41
|
end
|
42
42
|
|
43
|
+
it "should recgonize only a glob-style variable" do
|
44
|
+
target_route = route_set.add_route('/*format')
|
45
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple'}))
|
46
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
47
|
+
response.path.route.should == target_route
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should recgonize a regex static part" do
|
51
|
+
target_route = route_set.add_route('/test/part/{one|two}')
|
52
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/one'})).path.route.should == target_route
|
53
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/two'})).path.route.should == target_route
|
54
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/three'})).should == nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should recgonize a regex static part containing {}'s" do
|
58
|
+
target_route = route_set.add_route('/test/part/{^o{2,3}$}')
|
59
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oo'})).path.route.should == target_route
|
60
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/ooo'})).path.route.should == target_route
|
61
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/oooo'})).should == nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should recgonize a regex static part containing {}'s" do
|
65
|
+
target_route = route_set.add_route('/test/part/{:test,hello|again}')
|
66
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).path.route.should == target_route
|
67
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/hello'})).params.should == [[:test, 'hello']]
|
68
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).path.route.should == target_route
|
69
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/again'})).params.should == [[:test, 'again']]
|
70
|
+
route_set.recognize(build_request({:method => 'get', :path => '/test/part/world'})).should == nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should recgonize two glob-style variables separated by a static part" do
|
74
|
+
target_route = route_set.add_route('/*format/innovate/*onemore')
|
75
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/innovate/apple'}))
|
76
|
+
response.params.should == [[:format, ['sample', 'html']], [:onemore, ['apple']]]
|
77
|
+
response.path.route.should == target_route
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should recgonize only a glob-style variable with a condition" do
|
81
|
+
target_route = route_set.add_route('/*format', :conditions => {:domain => 'test-domain'})
|
82
|
+
response = route_set.recognize(build_request({:method => 'get', :path => '/sample/html/json/apple', :domain => 'test-domain'}))
|
83
|
+
response.params.should == [[:format, ['sample', 'html', 'json', 'apple']]]
|
84
|
+
response.path.route.should == target_route
|
85
|
+
end
|
86
|
+
|
43
87
|
it "should recognize a format-style literal" do
|
44
88
|
target_route = route_set.add_route('/:action.html', :controller => 'sample', :action => 'action')
|
45
89
|
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == Usher::Node::Response.new(target_route.paths.first, [[:action , 'sample']])
|
data/spec/split_spec.rb
CHANGED
@@ -6,6 +6,11 @@ describe "Usher route tokenizing" do
|
|
6
6
|
it "should split / delimited routes" do
|
7
7
|
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this/split').should == [[:/, 'test', :/,'this', :/, 'split']]
|
8
8
|
end
|
9
|
+
|
10
|
+
it "should split / delimited routes with a regex in it" do
|
11
|
+
Usher::Splitter.for_delimiters(['/', '.']).
|
12
|
+
split('/test/{this}/split').should == [[:/, 'test', :/, /this/, :/, 'split']]
|
13
|
+
end
|
9
14
|
|
10
15
|
it "should split on ' ' delimited routes as well" do
|
11
16
|
Usher::Splitter.for_delimiters([' ']).split('test this split').should == [['test', :' ', 'this', :' ', 'split']]
|
@@ -50,7 +55,7 @@ describe "Usher route tokenizing" do
|
|
50
55
|
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split(.:format))') == [
|
51
56
|
[:/, "test", :/, "this"],
|
52
57
|
[:/, "test", :/, "this", :/, "split"],
|
53
|
-
[:/, "test", :/, "this", :/, "split", '.', Usher::Route::Variable.new(:':', :format)]
|
58
|
+
[:/, "test", :/, "this", :/, "split", :'.', Usher::Route::Variable.new(:':', :format)]
|
54
59
|
]
|
55
60
|
end
|
56
61
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshbuddy-usher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-09 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.
|
23
|
+
version: 0.0.3
|
24
24
|
version:
|
25
25
|
description: A general purpose routing library
|
26
26
|
email: joshbuddy@gmail.com
|