diff options
author | Benoit Tigeot <benoit@hopsandfork.com> | 2018-02-25 18:25:55 +0100 |
---|---|---|
committer | Benoit Tigeot <benoit@hopsandfork.com> | 2018-02-28 22:32:34 +0100 |
commit | c6d928f3cae28e3b531d3cc4bcde2ddca0323f11 (patch) | |
tree | 3dd6a24b71abb5b9902a462c70d2d44aef94e099 | |
parent | 39d2cde65919729ec1ca3663d7872adf8036fd58 (diff) | |
download | rails-c6d928f3cae28e3b531d3cc4bcde2ddca0323f11.tar.gz rails-c6d928f3cae28e3b531d3cc4bcde2ddca0323f11.tar.bz2 rails-c6d928f3cae28e3b531d3cc4bcde2ddca0323f11.zip |
Add --expanded option to "rails routes"
When using rails routes with small terminal or complicated routes it can be
very difficult to understand where is the element listed in header. psql
had the same issue, that's why they created "expanded mode" you can
switch using `\x` or by starting psql with
```
-x
--expanded
Turn on the expanded table formatting mode. This is equivalent to the \x command.
```
The output is similar to one implemented here for rails routes:
db_user-# \du
List of roles
-[ RECORD 1 ]----------------------------------------------
Role name | super
Attributes | Superuser, Create role, Create DB
Member of | {}
-[ RECORD 2 ]----------------------------------------------
Role name | role
Attributes | Superuser, Create role, Create DB, Replication
Member of | {}
-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 = []) |