Skip to content

Commit 2675c90

Browse files
authored
Merge pull request rails#47877 from luanzeba/route-source-location
Print source location when inspecting routes
2 parents be287ac + a00e548 commit 2675c90

File tree

7 files changed

+63
-28
lines changed

7 files changed

+63
-28
lines changed

actionpack/lib/action_dispatch/journey/route.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module ActionDispatch
55
module Journey
66
class Route
77
attr_reader :app, :path, :defaults, :name, :precedence, :constraints,
8-
:internal, :scope_options, :ast
8+
:internal, :scope_options, :ast, :source_location
99

1010
alias :conditions :constraints
1111

@@ -53,7 +53,7 @@ def self.verb_matcher(verb)
5353
##
5454
# +path+ is a path constraint.
5555
# +constraints+ is a hash of constraints to be applied to this route.
56-
def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], defaults: {}, request_method_match: nil, precedence: 0, scope_options: {}, internal: false)
56+
def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], defaults: {}, request_method_match: nil, precedence: 0, scope_options: {}, internal: false, source_location: nil)
5757
@name = name
5858
@app = app
5959
@path = path
@@ -69,6 +69,7 @@ def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], d
6969
@path_formatter = @path.build_formatter
7070
@scope_options = scope_options
7171
@internal = internal
72+
@source_location = source_location
7273

7374
@ast = @path.ast.root
7475
@path.ast.route = self

actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@
1313
<td>
1414
<%=simple_format route[:reqs] %>
1515
</td>
16+
<td>
17+
<%=simple_format route[:source_location] %>
18+
</td>
1619
</tr>

actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,10 @@
9090
<th class="http-verb">HTTP Verb</th>
9191
<th>Path</th>
9292
<th>Controller#Action</th>
93+
<th>Source Location</th>
9394
</tr>
9495
<tr>
95-
<th colspan="4" id="search_container"><%= search_field(:query, nil, id: 'search', placeholder: "Search") %></th>
96+
<th colspan="5" id="search_container"><%= search_field(:query, nil, id: 'search', placeholder: "Search") %></th>
9697
</tr>
9798
</thead>
9899
<tbody class='exact_matches' id='exact_matches'>

actionpack/lib/action_dispatch/railtie.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class Railtie < Rails::Railtie # :nodoc:
6767
config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
6868
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
6969

70+
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
71+
ActionDispatch::Routing::Mapper.backtrace_cleaner = Rails.backtrace_cleaner
72+
7073
ActionDispatch.test_app = app
7174
end
7275
end

actionpack/lib/action_dispatch/routing/inspector.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ def collect_routes(routes)
133133
{ name: route.name,
134134
verb: route.verb,
135135
path: route.path,
136-
reqs: route.reqs }
136+
reqs: route.reqs,
137+
source_location: route.source_location }
137138
end
138139
end
139140

@@ -239,13 +240,16 @@ def section(routes)
239240
private
240241
def draw_expanded_section(routes)
241242
routes.map.each_with_index do |r, i|
242-
<<~MESSAGE.chomp
243+
route_rows = <<~MESSAGE.chomp
243244
#{route_header(index: i + 1)}
244245
Prefix | #{r[:name]}
245246
Verb | #{r[:verb]}
246247
URI | #{r[:path]}
247248
Controller#Action | #{r[:reqs]}
248249
MESSAGE
250+
source_location = "\nSource Location | #{r[:source_location]}"
251+
route_rows += source_location if r[:source_location].present?
252+
route_rows
249253
end
250254
end
251255

actionpack/lib/action_dispatch/routing/mapper.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ module Routing
1212
class Mapper
1313
URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]
1414

15+
cattr_accessor :route_source_locations, instance_accessor: false, default: false
16+
cattr_accessor :backtrace_cleaner, instance_accessor: false, default: ActiveSupport::BacktraceCleaner.new
17+
1518
class Constraints < Routing::Endpoint # :nodoc:
1619
attr_reader :app, :constraints
1720

@@ -170,7 +173,7 @@ def make_route(name, precedence)
170173
Journey::Route.new(name: name, app: application, path: path, constraints: conditions,
171174
required_defaults: required_defaults, defaults: defaults,
172175
request_method_match: request_method, precedence: precedence,
173-
scope_options: scope_options, internal: @internal)
176+
scope_options: scope_options, internal: @internal, source_location: route_source_location)
174177
end
175178

176179
def application
@@ -356,6 +359,15 @@ def constraints(options, path_params)
356359
def dispatcher(raise_on_name_error)
357360
Routing::RouteSet::Dispatcher.new raise_on_name_error
358361
end
362+
363+
def route_source_location
364+
if Mapper.route_source_locations
365+
action_dispatch_dir = File.expand_path("..", __dir__)
366+
caller_location = caller_locations.find { |location| !location.path.include?(action_dispatch_dir) }
367+
cleaned_path = Mapper.backtrace_cleaner.clean([caller_location.path]).first
368+
"#{cleaned_path}:#{caller_location.lineno}" if cleaned_path
369+
end
370+
end
359371
end
360372

361373
# Invokes Journey::Router::Utils.normalize_path, then ensures that

actionpack/test/dispatch/routing/inspector_test.rb

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -317,11 +317,14 @@ def test_routes_can_be_filtered
317317
end
318318

319319
def test_routes_when_expanded
320+
ActionDispatch::Routing::Mapper.route_source_locations = true
320321
engine = Class.new(Rails::Engine) do
321322
def self.inspect
322323
"Blog::Engine"
323324
end
324325
end
326+
file_name = ActiveSupport::BacktraceCleaner.new.clean([__FILE__]).first
327+
lineno = __LINE__
325328
engine.routes.draw do
326329
get "/cart", to: "cart#show"
327330
end
@@ -332,28 +335,36 @@ def self.inspect
332335
mount engine => "/blog", :as => "blog"
333336
end
334337

335-
assert_equal ["--[ Route 1 ]----------",
336-
"Prefix | custom_assets",
337-
"Verb | GET",
338-
"URI | /custom/assets(.:format)",
339-
"Controller#Action | custom_assets#show",
340-
"--[ Route 2 ]----------",
341-
"Prefix | custom_furnitures",
342-
"Verb | GET",
343-
"URI | /custom/furnitures(.:format)",
344-
"Controller#Action | custom_furnitures#show",
345-
"--[ Route 3 ]----------",
346-
"Prefix | blog",
347-
"Verb | ",
348-
"URI | /blog",
349-
"Controller#Action | Blog::Engine",
350-
"",
351-
"[ Routes for Blog::Engine ]",
352-
"--[ Route 1 ]----------",
353-
"Prefix | cart",
354-
"Verb | GET",
355-
"URI | /cart(.:format)",
356-
"Controller#Action | cart#show"], output
338+
expected = ["--[ Route 1 ]----------",
339+
"Prefix | custom_assets",
340+
"Verb | GET",
341+
"URI | /custom/assets(.:format)",
342+
"Controller#Action | custom_assets#show",
343+
"Source Location | #{file_name}:#{lineno + 6}",
344+
"--[ Route 2 ]----------",
345+
"Prefix | custom_furnitures",
346+
"Verb | GET",
347+
"URI | /custom/furnitures(.:format)",
348+
"Controller#Action | custom_furnitures#show",
349+
"Source Location | #{file_name}:#{lineno + 7}",
350+
"--[ Route 3 ]----------",
351+
"Prefix | blog",
352+
"Verb | ",
353+
"URI | /blog",
354+
"Controller#Action | Blog::Engine",
355+
"Source Location | #{file_name}:#{lineno + 8}",
356+
"",
357+
"[ Routes for Blog::Engine ]",
358+
"--[ Route 1 ]----------",
359+
"Prefix | cart",
360+
"Verb | GET",
361+
"URI | /cart(.:format)",
362+
"Controller#Action | cart#show",
363+
"Source Location | #{file_name}:#{lineno + 2}"]
364+
365+
assert_equal expected, output
366+
ensure
367+
ActionDispatch::Routing::Mapper.route_source_locations = false
357368
end
358369

359370
def test_no_routes_matched_filter_when_expanded

0 commit comments

Comments
 (0)