Skip to content

Commit

Permalink
Avoid unnecessary add_setup calls (#926)
Browse files Browse the repository at this point in the history
  • Loading branch information
numbata authored Apr 30, 2024
1 parent 37fa45f commit 0b969bc
Showing 1 changed file with 34 additions and 29 deletions.
63 changes: 34 additions & 29 deletions lib/grape-swagger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module SwaggerRouting
private

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

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

@target_class.combined_routes[resource] << route
combined_routes[resource] << route
end
end

def determine_namespaced_routes(name, parent_route)
def determine_namespaced_routes(name, parent_route, routes)
if parent_route.nil?
@target_class.combined_routes.values.flatten
routes.values.flatten
else
parent_route.reject do |route|
!route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
end
end
end

def combine_namespace_routes(namespaces)
def combine_namespace_routes(namespaces, routes)
combined_namespace_routes = {}
# iterate over each single namespace
namespaces.each_key do |name, _|
# get the parent route for the namespace
parent_route_name = extract_parent_route(name)
parent_route = @target_class.combined_routes[parent_route_name]
parent_route = routes[parent_route_name]
# fetch all routes that are within the current namespace
namespace_routes = determine_namespaced_routes(name, parent_route)
namespace_routes = determine_namespaced_routes(name, parent_route, routes)

# default case when not explicitly specified or nested == true
standalone_namespaces = namespaces.reject do |_, ns|
Expand All @@ -76,12 +77,13 @@ def combine_namespace_routes(namespaces)
# rubocop:disable Style/Next
if parent_standalone_namespaces.empty?
# default option, append namespace methods to parent route
parent_route = @target_class.combined_namespace_routes.key?(parent_route_name)
@target_class.combined_namespace_routes[parent_route_name] = [] unless parent_route
@target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
combined_namespace_routes[parent_route_name] ||= []
combined_namespace_routes[parent_route_name].push(*namespace_routes)
end
# rubocop:enable Style/Next
end

combined_namespace_routes
end

def extract_parent_route(name)
Expand Down Expand Up @@ -110,7 +112,7 @@ def route_path_start_with?(route, name)
end

module SwaggerDocumentationAdder
attr_accessor :combined_namespaces, :combined_namespace_identifiers, :combined_routes, :combined_namespace_routes
attr_accessor :combined_namespaces, :combined_routes, :combined_namespace_routes

include SwaggerRouting

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

@target_class.combined_routes = {}
combine_routes(@target_class, documentation_class)

@target_class.combined_namespaces = {}
combine_namespaces(@target_class)
combined_routes = combine_routes(@target_class, documentation_class)
combined_namespaces = combine_namespaces(@target_class)
combined_namespace_routes = combine_namespace_routes(combined_namespaces, combined_routes)
exclusive_route_keys = combined_routes.keys - combined_namespaces.keys
@target_class.combined_namespace_routes = combined_namespace_routes.merge(
combined_routes.slice(*exclusive_route_keys)
)
@target_class.combined_routes = combined_routes
@target_class.combined_namespaces = combined_namespaces

@target_class.combined_namespace_routes = {}
@target_class.combined_namespace_identifiers = {}
combine_namespace_routes(@target_class.combined_namespaces)

exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys
exclusive_route_keys.each do |key|
@target_class.combined_namespace_routes[key] = @target_class.combined_routes[key]
end
documentation_class
end

Expand All @@ -151,17 +149,24 @@ def version_for(options)
end

def combine_namespaces(app)
app.endpoints.each do |endpoint|
combined_namespaces = {}
endpoints = app.endpoints.clone

while endpoints.any?
endpoint = endpoints.shift

endpoints.push(*endpoint.options[:app].endpoints) if endpoint.options[:app]
ns = endpoint.namespace_stackable(:namespace).last
next unless ns

# use the full namespace here (not the latest level only)
# and strip leading slash
mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '')
@target_class.combined_namespaces[full_namespace] = ns if ns

combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
combined_namespaces[full_namespace] = ns
end

combined_namespaces
end

def create_documentation_class
Expand Down

0 comments on commit 0b969bc

Please sign in to comment.