From cd8bb8b6ce96cbfbade45cd5845e5862adf21125 Mon Sep 17 00:00:00 2001
From: Jon Moss <me@jonathanmoss.me>
Date: Sat, 13 Feb 2016 22:18:22 -0500
Subject: Add `internal` attribute to routes

This is meant to provide a way for Action Cable, Sprockets, and possibly
other Rack applications to mark themselves as internal, and to exclude
themselves from the routing inspector, and thus `rails routes` / `rake
routes`.

I think this is the only way to have mounted Rack apps be marked as
internal, within AD/Journey. Another option would be to create an array
of regexes for internal apps, and then to iterate over that everytime a
request comes through. Also, I only had the first `add_route` method set
`internal`'s default to false, to avoid littering it all over the
codebase.
---
 actionmailer/lib/action_mailer/railtie.rb          |  4 ++--
 actionpack/lib/action_dispatch/journey/route.rb    |  5 +++--
 .../lib/action_dispatch/routing/inspector.rb       |  2 +-
 actionpack/lib/action_dispatch/routing/mapper.rb   |  4 +++-
 actionpack/test/dispatch/routing/inspector_test.rb | 23 ++++++++++++++++++++++
 railties/lib/rails/application/finisher.rb         |  8 ++++----
 6 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index 22390c4953..6a633e4ce8 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -47,8 +47,8 @@ module ActionMailer
 
         if options.show_previews
           app.routes.prepend do
-            get '/rails/mailers'         => "rails/mailers#index"
-            get '/rails/mailers/*path'   => "rails/mailers#preview"
+            get '/rails/mailers'         => "rails/mailers#index", internal: true
+            get '/rails/mailers/*path'   => "rails/mailers#preview", internal: true
           end
         end
 
diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb
index 35c2b1b86e..fee08fc3db 100644
--- a/actionpack/lib/action_dispatch/journey/route.rb
+++ b/actionpack/lib/action_dispatch/journey/route.rb
@@ -3,7 +3,7 @@ module ActionDispatch
     class Route # :nodoc:
       attr_reader :app, :path, :defaults, :name, :precedence
 
-      attr_reader :constraints
+      attr_reader :constraints, :internal
       alias :conditions :constraints
 
       module VerbMatchers
@@ -55,7 +55,7 @@ module ActionDispatch
       ##
       # +path+ is a path constraint.
       # +constraints+ is a hash of constraints to be applied to this route.
-      def initialize(name, app, path, constraints, required_defaults, defaults, request_method_match, precedence)
+      def initialize(name, app, path, constraints, required_defaults, defaults, request_method_match, precedence, internal = false)
         @name        = name
         @app         = app
         @path        = path
@@ -70,6 +70,7 @@ module ActionDispatch
         @decorated_ast     = nil
         @precedence        = precedence
         @path_formatter    = @path.build_formatter
+        @internal          = internal
       end
 
       def ast
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb
index 983f1daeb3..6f651a5689 100644
--- a/actionpack/lib/action_dispatch/routing/inspector.rb
+++ b/actionpack/lib/action_dispatch/routing/inspector.rb
@@ -41,7 +41,7 @@ module ActionDispatch
       end
 
       def internal?
-        controller.to_s =~ %r{\Arails/(info|mailers|welcome)}
+        internal
       end
 
       def engine?
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index afbaa45d20..16b430c36e 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -107,6 +107,7 @@ module ActionDispatch
           @ast                = ast
           @anchor             = anchor
           @via                = via
+          @internal           = options[:internal]
 
           path_params = ast.find_all(&:symbol?).map(&:to_sym)
 
@@ -148,7 +149,8 @@ module ActionDispatch
                             required_defaults,
                             defaults,
                             request_method,
-                            precedence)
+                            precedence,
+                            @internal)
 
           route
         end
diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb
index f72a87b994..fd85cc6e9f 100644
--- a/actionpack/test/dispatch/routing/inspector_test.rb
+++ b/actionpack/test/dispatch/routing/inspector_test.rb
@@ -389,6 +389,29 @@ module ActionDispatch
         ], output
       end
 
+      def test_displaying_routes_for_internal_engines
+        engine = Class.new(Rails::Engine) do
+          def self.inspect
+            "Blog::Engine"
+          end
+        end
+        engine.routes.draw do
+          get '/cart', to: 'cart#show'
+          post '/cart', to: 'cart#create'
+          patch '/cart', to: 'cart#update'
+        end
+
+        output = draw do
+          get '/custom/assets', to: 'custom_assets#show'
+          mount engine => "/blog", as: "blog", internal: true
+        end
+
+        assert_equal [
+          "       Prefix Verb URI Pattern              Controller#Action",
+          "custom_assets GET  /custom/assets(.:format) custom_assets#show",
+        ], output
+      end
+
     end
   end
 end
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 411cdbad19..64ec539564 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -22,10 +22,10 @@ module Rails
       initializer :add_builtin_route do |app|
         if Rails.env.development?
           app.routes.append do
-            get '/rails/info/properties' => "rails/info#properties"
-            get '/rails/info/routes'     => "rails/info#routes"
-            get '/rails/info'            => "rails/info#index"
-            get '/'                      => "rails/welcome#index"
+            get '/rails/info/properties' => "rails/info#properties", internal: true
+            get '/rails/info/routes'     => "rails/info#routes", internal: true
+            get '/rails/info'            => "rails/info#index", internal: true
+            get '/'                      => "rails/welcome#index", internal: true
           end
         end
       end
-- 
cgit v1.2.3