提交 8a436fdd 编写于 作者: V Vipul A M

Add options for rake routes task

Add two options: `-c` and `-g`.
`-g` option returns the urls name, verb and path fields that match the pattern.
`-c` option returns the urls for specific controller.

Fixes #18902, and Fixes #20420

[Anton Davydov & Vipul A M]
上级 25a42755
* Add `-g` and `-c` (short for _grep_ and _controller_ respectively) options
to `bin/rake routes`. These options return the url `name`, `verb` and
`path` field that match the pattern or match a specific controller.
Deprecate `CONTROLLER` env variable in `bin/rake routes`.
See #18902.
*Anton Davydov* & *Vipul A M*
* Response etags to always be weak: Prefixes 'W/' to value returned by
`ActionDispatch::Http::Cache::Response#etag=`, such that etags set in
`fresh_when` and `stale?` are weak.
......
......@@ -239,7 +239,8 @@ module ActionDispatch
#
# rails routes
#
# Target specific controllers by prefixing the command with <tt>CONTROLLER=x</tt>.
# Target specific controllers by prefixing the command with <tt>--controller</tt> option
# - or its <tt>-c</tt> shorthand.
#
module Routing
extend ActiveSupport::Autoload
......
......@@ -60,12 +60,11 @@ def initialize(routes)
end
def format(formatter, filter = nil)
routes_to_display = filter_routes(filter)
filter_options = normalize_filter(filter)
routes_to_display = filter_routes(filter_options)
routes = collect_routes(routes_to_display)
if routes.none?
formatter.no_routes(collect_routes(@routes), filter)
formatter.no_routes(collect_routes(@routes))
return formatter.result
end
......@@ -82,10 +81,21 @@ def format(formatter, filter = nil)
private
def filter_routes(filter)
if filter
filter_name = filter.underscore.sub(/_controller$/, '')
@routes.select { |route| route.defaults[:controller] == filter_name }
def normalize_filter(filter)
if filter.is_a?(Hash) && filter[:controller]
{controller: /#{filter[:controller].downcase.sub(/_?controller\z/, '').sub('::', '/')}/}
elsif filter.is_a?(String)
{controller: /#{filter}/, action: /#{filter}/}
else
nil
end
end
def filter_routes(filter_options)
if filter_options
@routes.select do |route|
filter_options.any? { |default, filter| route.defaults[default] =~ filter }
end
else
@routes
end
......@@ -137,7 +147,7 @@ def header(routes)
@buffer << draw_header(routes)
end
def no_routes(routes, filter)
def no_routes(routes)
@buffer <<
if routes.none?
<<-MESSAGE.strip_heredoc
......@@ -145,8 +155,6 @@ def no_routes(routes, filter)
Please add some routes in config/routes.rb.
MESSAGE
elsif missing_controller?(filter)
"The controller #{filter} does not exist!"
else
"No routes were found for this controller"
end
......@@ -154,10 +162,6 @@ def no_routes(routes, filter)
end
private
def missing_controller?(controller_name)
[ controller_name.camelize, "#{controller_name.camelize}Controller" ].none?(&:safe_constantize)
end
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)
......
......@@ -17,10 +17,10 @@ def setup
@set = ActionDispatch::Routing::RouteSet.new
end
def draw(options = {}, &block)
def draw(options = nil, &block)
@set.draw(&block)
inspector = ActionDispatch::Routing::RoutesInspector.new(@set.routes)
inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options[:filter]).split("\n")
inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options).split("\n")
end
def test_displaying_routes_for_engines
......@@ -297,7 +297,7 @@ def test_redirect
end
def test_routes_can_be_filtered
output = draw(filter: 'posts') do
output = draw('posts') do
resources :articles
resources :posts
end
......@@ -313,6 +313,26 @@ def test_routes_can_be_filtered
" DELETE /posts/:id(.:format) posts#destroy"], output
end
def test_routes_can_be_filtered_with_namespaced_controllers
output = draw('admin/posts') do
resources :articles
namespace :admin do
resources :posts
end
end
assert_equal [" Prefix Verb URI Pattern Controller#Action",
" admin_posts GET /admin/posts(.:format) admin/posts#index",
" POST /admin/posts(.:format) admin/posts#create",
" new_admin_post GET /admin/posts/new(.:format) admin/posts#new",
"edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit",
" admin_post GET /admin/posts/:id(.:format) admin/posts#show",
" PATCH /admin/posts/:id(.:format) admin/posts#update",
" PUT /admin/posts/:id(.:format) admin/posts#update",
" DELETE /admin/posts/:id(.:format) admin/posts#destroy"], output
end
def test_regression_route_with_controller_regexp
output = draw do
get ':controller(/:action)', controller: /api\/[^\/]+/, format: false
......@@ -336,18 +356,18 @@ def test_inspect_routes_shows_resources_route_when_assets_disabled
end
def test_routes_with_undefined_filter
output = draw(:filter => 'Rails::MissingController') do
output = draw(controller: 'Rails::MissingController') do
get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/
end
assert_equal [
"The controller Rails::MissingController does not exist!",
"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_no_routes_matched_filter
output = draw(:filter => 'rails/dummy') do
output = draw('rails/dummy') do
get 'photos/:id' => 'photos#show', :id => /[A-Z]\d{5}/
end
......@@ -358,7 +378,7 @@ def test_no_routes_matched_filter
end
def test_no_routes_were_defined
output = draw(:filter => 'Rails::DummyController') { }
output = draw('Rails::DummyController') {}
assert_equal [
"You don't have any routes defined!",
......
......@@ -1136,10 +1136,21 @@ For example, here's a small section of the `rails routes` output for a RESTful r
edit_user GET /users/:id/edit(.:format) users#edit
```
You may restrict the listing to the routes that map to a particular controller setting the `CONTROLLER` environment variable:
You can search through your routes with the --grep option (-g for short). This outputs any routes that partially match the URL helper method name, the HTTP verb, or the URL path.
```bash
$ CONTROLLER=users bin/rails routes
```
$ bin/rake routes --grep new_comment
$ bin/rake routes -g POST
$ bin/rake routes -g admin
```
If you only want to see the routes that map to a specific controller, there's the --controller option (-c for short).
```
$ bin/rake routes --controller users
$ bin/rake routes --controller admin/users
$ bin/rake routes -c Comments
$ bin/rake 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.
......
desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.'
require 'active_support/deprecation'
require 'active_support/core_ext/string/strip' # for strip_heredoc
require 'optparse'
desc 'Print out all defined routes in match order, with names. Target specific controller with --controller option - or its -c shorthand.'
task routes: :environment do
all_routes = Rails.application.routes.routes
require 'action_dispatch/routing/inspector'
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, ENV['CONTROLLER'])
if ARGV.any?{ |argv| argv.start_with? 'CONTROLLER' }
puts <<-eow.strip_heredoc
Passing `CONTROLLER` to `bin/rake routes` is deprecated and will be removed in Rails 5.1.
Please use `bin/rake routes -c controller_name` instead.
eow
end
routes_filter = nil
routes_filter = {controller: ENV['CONTROLLER']} if ENV['CONTROLLER']
OptionParser.new do |opts|
opts.banner = "Usage: rake routes [options]"
opts.on("-c", "--controller [CONTROLLER]") do |controller|
routes_filter = { controller: controller }
end
opts.on("-g", "--grep [PATTERN]") do |pattern|
routes_filter = pattern
end
end.parse!(ARGV.reject { |x| x == "routes" })
puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, routes_filter)
exit 0 # ensure extra arguments aren't interpreted as Rake tasks
end
......@@ -141,8 +141,67 @@ def test_rake_routes_with_controller_environment
end
RUBY
ENV['CONTROLLER'] = 'cart'
output = Dir.chdir(app_path){ `bin/rails routes` }
output = Dir.chdir(app_path){ `bin/rake routes CONTROLLER=cart` }
assert_equal ["Passing `CONTROLLER` to `bin/rake routes` is deprecated and will be removed in Rails 5.1.",
"Please use `bin/rake routes -c controller_name` instead.",
"Prefix Verb URI Pattern Controller#Action",
" cart GET /cart(.:format) cart#show\n"].join("\n"), output
output = Dir.chdir(app_path){ `bin/rails routes -c cart` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
def test_rake_routes_with_namespaced_controller_environment
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
namespace :admin do
resource :post
end
end
RUBY
expected_output = [" Prefix Verb URI Pattern Controller#Action",
" admin_post POST /admin/post(.:format) admin/posts#create",
" new_admin_post GET /admin/post/new(.:format) admin/posts#new",
"edit_admin_post GET /admin/post/edit(.:format) admin/posts#edit",
" GET /admin/post(.:format) admin/posts#show",
" PATCH /admin/post(.:format) admin/posts#update",
" PUT /admin/post(.:format) admin/posts#update",
" DELETE /admin/post(.:format) admin/posts#destroy\n"].join("\n")
output = Dir.chdir(app_path){ `bin/rails routes -c Admin::PostController` }
assert_equal expected_output, output
output = Dir.chdir(app_path){ `bin/rails routes -c PostController` }
assert_equal expected_output, output
end
def test_rake_routes_with_global_search_key
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get '/cart', to: 'cart#show'
get '/basketball', to: 'basketball#index'
end
RUBY
output = Dir.chdir(app_path){ `bin/rake routes -g show` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
def test_rake_routes_with_controller_search_key
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get '/cart', to: 'cart#show'
get '/basketball', to: 'basketball#index'
end
RUBY
output = Dir.chdir(app_path){ `bin/rake routes -c cart` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
output = Dir.chdir(app_path){ `bin/rake routes -c Cart` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
output = Dir.chdir(app_path){ `bin/rake routes -c CartController` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册