Skip to content

Commit 0b969bc

Browse files
authored
Avoid unnecessary add_setup calls (#926)
1 parent 37fa45f commit 0b969bc

File tree

1 file changed

+34
-29
lines changed

1 file changed

+34
-29
lines changed

lib/grape-swagger.rb

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module SwaggerRouting
2424
private
2525

2626
def combine_routes(app, doc_klass)
27-
app.routes.each do |route|
27+
app.routes.each_with_object({}) do |route, combined_routes|
2828
route_path = route.path
2929
route_match = route_path.split(/^.*?#{route.prefix}/).last
3030
next unless route_match
@@ -37,31 +37,32 @@ def combine_routes(app, doc_klass)
3737

3838
resource = route_match.captures.first
3939
resource = '/' if resource.empty?
40-
@target_class.combined_routes[resource] ||= []
40+
combined_routes[resource] ||= []
4141
next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
4242

43-
@target_class.combined_routes[resource] << route
43+
combined_routes[resource] << route
4444
end
4545
end
4646

47-
def determine_namespaced_routes(name, parent_route)
47+
def determine_namespaced_routes(name, parent_route, routes)
4848
if parent_route.nil?
49-
@target_class.combined_routes.values.flatten
49+
routes.values.flatten
5050
else
5151
parent_route.reject do |route|
5252
!route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
5353
end
5454
end
5555
end
5656

57-
def combine_namespace_routes(namespaces)
57+
def combine_namespace_routes(namespaces, routes)
58+
combined_namespace_routes = {}
5859
# iterate over each single namespace
5960
namespaces.each_key do |name, _|
6061
# get the parent route for the namespace
6162
parent_route_name = extract_parent_route(name)
62-
parent_route = @target_class.combined_routes[parent_route_name]
63+
parent_route = routes[parent_route_name]
6364
# fetch all routes that are within the current namespace
64-
namespace_routes = determine_namespaced_routes(name, parent_route)
65+
namespace_routes = determine_namespaced_routes(name, parent_route, routes)
6566

6667
# default case when not explicitly specified or nested == true
6768
standalone_namespaces = namespaces.reject do |_, ns|
@@ -76,12 +77,13 @@ def combine_namespace_routes(namespaces)
7677
# rubocop:disable Style/Next
7778
if parent_standalone_namespaces.empty?
7879
# default option, append namespace methods to parent route
79-
parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
80-
@target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
81-
@target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
80+
combined_namespace_routes[parent_route_name] ||= []
81+
combined_namespace_routes[parent_route_name].push(*namespace_routes)
8282
end
8383
# rubocop:enable Style/Next
8484
end
85+
86+
combined_namespace_routes
8587
end
8688

8789
def extract_parent_route(name)
@@ -110,7 +112,7 @@ def route_path_start_with?(route, name)
110112
end
111113

112114
module SwaggerDocumentationAdder
113-
attr_accessor :combined_namespaces, :combined_namespace_identifiers, :combined_routes, :combined_namespace_routes
115+
attr_accessor :combined_namespaces, :combined_routes, :combined_namespace_routes
114116

115117
include SwaggerRouting
116118

@@ -127,20 +129,16 @@ def add_swagger_documentation(options = {})
127129
documentation_class.setup(options)
128130
mount(documentation_class)
129131

130-
@target_class.combined_routes = {}
131-
combine_routes(@target_class, documentation_class)
132-
133-
@target_class.combined_namespaces = {}
134-
combine_namespaces(@target_class)
132+
combined_routes = combine_routes(@target_class, documentation_class)
133+
combined_namespaces = combine_namespaces(@target_class)
134+
combined_namespace_routes = combine_namespace_routes(combined_namespaces, combined_routes)
135+
exclusive_route_keys = combined_routes.keys - combined_namespaces.keys
136+
@target_class.combined_namespace_routes = combined_namespace_routes.merge(
137+
combined_routes.slice(*exclusive_route_keys)
138+
)
139+
@target_class.combined_routes = combined_routes
140+
@target_class.combined_namespaces = combined_namespaces
135141

136-
@target_class.combined_namespace_routes = {}
137-
@target_class.combined_namespace_identifiers = {}
138-
combine_namespace_routes(@target_class.combined_namespaces)
139-
140-
exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys
141-
exclusive_route_keys.each do |key|
142-
@target_class.combined_namespace_routes[key] = @target_class.combined_routes[key]
143-
end
144142
documentation_class
145143
end
146144

@@ -151,17 +149,24 @@ def version_for(options)
151149
end
152150

153151
def combine_namespaces(app)
154-
app.endpoints.each do |endpoint|
152+
combined_namespaces = {}
153+
endpoints = app.endpoints.clone
154+
155+
while endpoints.any?
156+
endpoint = endpoints.shift
157+
158+
endpoints.push(*endpoint.options[:app].endpoints) if endpoint.options[:app]
155159
ns = endpoint.namespace_stackable(:namespace).last
160+
next unless ns
156161

157162
# use the full namespace here (not the latest level only)
158163
# and strip leading slash
159164
mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
160165
full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '')
161-
@target_class.combined_namespaces[full_namespace] = ns if ns
162-
163-
combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
166+
combined_namespaces[full_namespace] = ns
164167
end
168+
169+
combined_namespaces
165170
end
166171

167172
def create_documentation_class

0 commit comments

Comments
 (0)