From 8a436fdd98c63cc0a7a6d2c642c18d33421dc6ad Mon Sep 17 00:00:00 2001
From: Vipul A M <vipulnsward@gmail.com>
Date: Mon, 25 Jan 2016 01:32:44 +0530
Subject: 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]
---
 railties/lib/rails/tasks/routes.rake   | 32 +++++++++++++++--
 railties/test/application/rake_test.rb | 63 ++++++++++++++++++++++++++++++++--
 2 files changed, 91 insertions(+), 4 deletions(-)

(limited to 'railties')

diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake
index 1815c2fdc7..499c434ffa 100644
--- a/railties/lib/rails/tasks/routes.rake
+++ b/railties/lib/rails/tasks/routes.rake
@@ -1,7 +1,35 @@
-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
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index b979ad64d1..7171aa6e1a 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -141,8 +141,67 @@ module ApplicationTests
         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
 
-- 
cgit v1.2.3