diff options
-rw-r--r-- | actionpack/lib/action_dispatch/routing.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/inspector.rb | 127 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing/inspector_test.rb | 68 | ||||
-rw-r--r-- | guides/source/routing.md | 2 | ||||
-rw-r--r-- | railties/CHANGELOG.md | 19 | ||||
-rw-r--r-- | railties/lib/rails/commands/routes/routes_command.rb | 8 | ||||
-rw-r--r-- | railties/test/application/rake_test.rb | 40 | ||||
-rw-r--r-- | railties/test/commands/routes_test.rb | 47 |
8 files changed, 232 insertions, 82 deletions
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 72f7407c6e..776058d98e 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -243,7 +243,8 @@ module ActionDispatch # # rails routes # - # Target specific controllers by prefixing the command with <tt>-c</tt> option. + # Target specific controllers by prefixing the command with <tt>-c</tt> option. Use + # <tt>--expanded</tt> to turn on the expanded table formatting mode. # module Routing extend ActiveSupport::Autoload diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index 22336c59b6..8c0cf74667 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -126,61 +126,114 @@ module ActionDispatch end class ConsoleFormatter - def initialize - @buffer = [] - end + class Sheet + def initialize + @buffer = [] + end - def result - @buffer.join("\n") - end + def result + @buffer.join("\n") + end - def section_title(title) - @buffer << "\n#{title}:" - end + def section_title(title) + @buffer << "\n#{title}:" + end - def section(routes) - @buffer << draw_section(routes) - end + def section(routes) + @buffer << draw_section(routes) + end - def header(routes) - @buffer << draw_header(routes) - end + def header(routes) + @buffer << draw_header(routes) + end - def no_routes(routes) - @buffer << - if routes.none? - <<~MESSAGE + def no_routes(routes) + @buffer << + if routes.none? + <<~MESSAGE You don't have any routes defined! Please add some routes in config/routes.rb. - MESSAGE - else - "No routes were found for this controller" + MESSAGE + else + "No routes were found for this controller" + end + @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." end - @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." - end - private - def draw_section(routes) - header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length) - name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max) + private + + def draw_section(routes) + header_lengths = ["Prefix", "Verb", "URI Pattern"].map(&:length) + name_width, verb_width, path_width = widths(routes).zip(header_lengths).map(&:max) - routes.map do |r| - "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}" + routes.map do |r| + "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}" + end + end + + def draw_header(routes) + name_width, verb_width, path_width = widths(routes) + + "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action" + end + + def widths(routes) + [routes.map { |r| r[:name].length }.max || 0, + routes.map { |r| r[:verb].length }.max || 0, + routes.map { |r| r[:path].length }.max || 0] end + end + + class Expanded < ConsoleFormatter + def initialize + @buffer = [] end - def draw_header(routes) - name_width, verb_width, path_width = widths(routes) + def result + @buffer.join("") + end + + def section_title(title) + @buffer << "\n#{"[ #{title} ]"}\n" + end - "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action" + def section(routes) + @buffer << draw_expanded_section(routes) end - def widths(routes) - [routes.map { |r| r[:name].length }.max || 0, - routes.map { |r| r[:verb].length }.max || 0, - routes.map { |r| r[:path].length }.max || 0] + def header(routes) + @buffer end + + def no_routes(routes) + @buffer << + if routes.none? + <<~MESSAGE + You don't have any routes defined! + + Please add some routes in config/routes.rb.\n + MESSAGE + else + "No routes were found for this controller\n" + end + @buffer << "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." + end + + private + + def draw_expanded_section(routes) + routes.map.each_with_index do |r, i| + <<~MESSAGE + --[ Route #{i + 1} ]#{'-' * 60} + Prefix | #{r[:name]} + Verb | #{r[:verb]} + URI | #{r[:path]} + Controller#Action | #{r[:reqs]} + MESSAGE + end + end + end end class HtmlTableFormatter diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb index 438a918567..127212b228 100644 --- a/actionpack/test/dispatch/routing/inspector_test.rb +++ b/actionpack/test/dispatch/routing/inspector_test.rb @@ -19,10 +19,10 @@ module ActionDispatch @set = ActionDispatch::Routing::RouteSet.new end - def draw(options = nil, &block) + def draw(options = nil, formater = ActionDispatch::Routing::ConsoleFormatter::Sheet.new, &block) @set.draw(&block) inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes) - inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options).split("\n") + inspector.format(formater, options).split("\n") end def test_displaying_routes_for_engines @@ -321,6 +321,70 @@ module ActionDispatch " DELETE /posts/:id(.:format) posts#destroy"], output end + def test_routes_when_expanded + engine = Class.new(Rails::Engine) do + def self.inspect + "Blog::Engine" + end + end + engine.routes.draw do + get "/cart", to: "cart#show" + end + + output = draw(nil, ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do + get "/custom/assets", to: "custom_assets#show" + get "/custom/furnitures", to: "custom_furnitures#show" + mount engine => "/blog", :as => "blog" + end + + assert_equal ["--[ Route 1 ]------------------------------------------------------------", + "Prefix | custom_assets", + "Verb | GET", + "URI | /custom/assets(.:format)", + "Controller#Action | custom_assets#show", + "--[ Route 2 ]------------------------------------------------------------", + "Prefix | custom_furnitures", + "Verb | GET", + "URI | /custom/furnitures(.:format)", + "Controller#Action | custom_furnitures#show", + "--[ Route 3 ]------------------------------------------------------------", + "Prefix | blog", + "Verb | ", + "URI | /blog", + "Controller#Action | Blog::Engine", + "", + "[ Routes for Blog::Engine ]", + "--[ Route 1 ]------------------------------------------------------------", + "Prefix | cart", + "Verb | GET", + "URI | /cart(.:format)", + "Controller#Action | cart#show"], output + end + + + def test_no_routes_matched_filter_when_expanded + output = draw("rails/dummy", ActionDispatch::Routing::ConsoleFormatter::Expanded.new) do + get "photos/:id" => "photos#show", :id => /[A-Z]\d{5}/ + end + + assert_equal [ + "No routes were found for this controller", + "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." + ], output + end + + def test_not_routes_when_expanded + output = draw("rails/dummy", ActionDispatch::Routing::ConsoleFormatter::Expanded.new) {} + + assert_equal [ + "You don't have any routes defined!", + "", + "Please add some routes in config/routes.rb.", + "", + "For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html." + ], output + end + def test_routes_can_be_filtered_with_namespaced_controllers output = draw("admin/posts") do resources :articles diff --git a/guides/source/routing.md b/guides/source/routing.md index 1e75cbf362..98aa841938 100644 --- a/guides/source/routing.md +++ b/guides/source/routing.md @@ -1183,7 +1183,7 @@ $ bin/rails routes -c Comments $ bin/rails routes -c Articles::CommentsController ``` -TIP: You'll find that the output from `rails routes` is much more readable if you widen your terminal window until the output lines don't wrap. +TIP: You'll find that the output from `rails routes` is much more readable if you widen your terminal window until the output lines don't wrap. You can also use --expanded option to turn on the expanded table formatting mode. ### Testing Routes diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 51f6e1f0ac..a38888afe5 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,5 +1,24 @@ ## Rails 6.0.0.alpha (Unreleased) ## +* Add "rails routes --expanded" option to output routes in expanded mode like + "psql --expanded". Result looks like: + + ``` + $ rails routes --expanded + --[ Route 1 ]------------------------------------------------------------ + Prefix | high_scores + Verb | GET + URI | /high_scores(.:format) + Controller#Action | high_scores#index + --[ Route 2 ]------------------------------------------------------------ + Prefix | new_high_score + Verb | GET + URI | /high_scores/new(.:format) + Controller#Action | high_scores#new + ``` + + *Benoit Tigeot* + * Rails 6 requires Ruby 2.4.1 or newer. *Jeremy Daer* diff --git a/railties/lib/rails/commands/routes/routes_command.rb b/railties/lib/rails/commands/routes/routes_command.rb index c4fd6c7eb5..c4f3717095 100644 --- a/railties/lib/rails/commands/routes/routes_command.rb +++ b/railties/lib/rails/commands/routes/routes_command.rb @@ -7,12 +7,14 @@ module Rails class RoutesCommand < Base # :nodoc: class_option :controller, aliases: "-c", type: :string, desc: "Specifies the controller." class_option :grep_pattern, aliases: "-g", type: :string, desc: "Specifies grep pattern." + class_option :expanded_format, aliases: "--expanded", type: :string, desc: "Turn on expanded format mode." no_commands do def help say "Usage: Print out all defined routes in match order, with names." say "" say "Target specific controller with -c option, or grep routes using -g option" + say "Use expanded format with --expanded option" say "" end end @@ -24,7 +26,11 @@ module Rails all_routes = Rails.application.routes.routes inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes) - say inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, routes_filter) + if options.has_key?("expanded_format") + say inspector.format(ActionDispatch::Routing::ConsoleFormatter::Expanded.new, routes_filter) + else + say inspector.format(ActionDispatch::Routing::ConsoleFormatter::Sheet.new, routes_filter) + end end private diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index f7d301e125..9683230d07 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -122,46 +122,6 @@ module ApplicationTests rails("stats") end - def test_rails_routes_calls_the_route_inspector - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - get '/cart', to: 'cart#show' - end - RUBY - - output = rails("routes") - assert_equal <<~MESSAGE, output - Prefix Verb URI Pattern Controller#Action - cart GET /cart(.:format) cart#show - rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show - rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show - rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show - rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show - update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update - rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create - MESSAGE - end - - def test_singular_resource_output_in_rake_routes - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - resource :post - end - RUBY - - expected_output = [" Prefix Verb URI Pattern Controller#Action", - " new_post GET /post/new(.:format) posts#new", - "edit_post GET /post/edit(.:format) posts#edit", - " post GET /post(.:format) posts#show", - " PATCH /post(.:format) posts#update", - " PUT /post(.:format) posts#update", - " DELETE /post(.:format) posts#destroy", - " POST /post(.:format) posts#create\n"].join("\n") - - output = rails("routes", "-c", "PostController") - assert_equal expected_output, output - end - def test_logger_is_flushed_when_exiting_production_rake_tasks add_to_config <<-RUBY rake_tasks do diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb index 030dcc7217..24af5de73a 100644 --- a/railties/test/commands/routes_test.rb +++ b/railties/test/commands/routes_test.rb @@ -119,6 +119,53 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase MESSAGE end + test "test rails routes with expanded option" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get '/cart', to: 'cart#show' + end + RUBY + + output = rails("routes", "--expanded") + assert_equal <<~MESSAGE, output + --[ Route 1 ]------------------------------------------------------------ + Prefix | cart + Verb | GET + URI | /cart(.:format) + Controller#Action | cart#show + --[ Route 2 ]------------------------------------------------------------ + Prefix | rails_service_blob + Verb | GET + URI | /rails/active_storage/blobs/:signed_id/*filename(.:format) + Controller#Action | active_storage/blobs#show + --[ Route 3 ]------------------------------------------------------------ + Prefix | rails_blob_variation + Verb | GET + URI | /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) + Controller#Action | active_storage/variants#show + --[ Route 4 ]------------------------------------------------------------ + Prefix | rails_blob_preview + Verb | GET + URI | /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) + Controller#Action | active_storage/previews#show + --[ Route 5 ]------------------------------------------------------------ + Prefix | rails_disk_service + Verb | GET + URI | /rails/active_storage/disk/:encoded_key/*filename(.:format) + Controller#Action | active_storage/disk#show + --[ Route 6 ]------------------------------------------------------------ + Prefix | update_rails_disk_service + Verb | PUT + URI | /rails/active_storage/disk/:encoded_token(.:format) + Controller#Action | active_storage/disk#update + --[ Route 7 ]------------------------------------------------------------ + Prefix | rails_direct_uploads + Verb | POST + URI | /rails/active_storage/direct_uploads(.:format) + Controller#Action | active_storage/direct_uploads#create + MESSAGE + end + private def run_routes_command(args = []) |