Remove the ability for engines to serve assets from the public directory.

This commit is contained in:
José Valim 2011-04-15 19:57:52 +02:00
parent d84b2f37d0
commit afc828828f
11 changed files with 19 additions and 429 deletions

@ -16,14 +16,6 @@ def self.with(app)
if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers
klass.helper :all
end
if app.config.serve_static_assets && namespace
paths = namespace._railtie.config.paths
klass.config.assets_dir = paths["public"].first
klass.config.javascripts_dir = paths["public/javascripts"].first
klass.config.stylesheets_dir = paths["public/stylesheets"].first
end
end
end
end

@ -30,9 +30,6 @@ def compute_public_path(source, dir, ext = nil, include_host = true)
source = rewrite_extension(source, dir, ext) if ext
source = "/#{dir}/#{source}" unless source[0] == ?/
if controller.respond_to?(:env) && controller.env["action_dispatch.asset_path"]
source = rewrite_asset_path(source, controller.env["action_dispatch.asset_path"])
end
source = rewrite_asset_path(source, config.asset_path)
has_request = controller.respond_to?(:request)

@ -121,7 +121,6 @@ def env_config
@env_config ||= super.merge({
"action_dispatch.parameter_filter" => config.filter_parameters,
"action_dispatch.secret_token" => config.secret_token,
"action_dispatch.asset_path" => nil,
"action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions
})
end
@ -149,10 +148,6 @@ def build_asset_environment
@assets = env
end
def default_asset_path
nil
end
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
if rack_cache = config.action_controller.perform_caching && config.action_dispatch.rack_cache
@ -166,8 +161,7 @@ def default_middleware_stack
end
if config.serve_static_assets
asset_paths = ActiveSupport::OrderedHash[config.static_asset_paths.to_a.reverse]
middleware.use ::ActionDispatch::Static, asset_paths
middleware.use ::ActionDispatch::Static, "/" => paths["public"].first
end
middleware.use ::Rack::Lock unless config.allow_concurrency

@ -4,13 +4,12 @@
module Rails
class Application
class Configuration < ::Rails::Engine::Configuration
attr_accessor :allow_concurrency, :asset_host, :cache_classes, :cache_store,
:encoding, :consider_all_requests_local, :dependency_loading,
:filter_parameters, :helpers_paths, :logger,
:preload_frameworks, :reload_plugins,
:secret_token, :serve_static_assets, :session_options,
:time_zone, :whiny_nils, :force_ssl,
:assets
attr_accessor :allow_concurrency, :asset_host, :asset_path, :assets,
:cache_classes, :cache_store, :consider_all_requests_local,
:dependency_loading, :encoding, :filter_parameters,
:force_ssl, :helpers_paths, :logger, :preload_frameworks,
:reload_plugins, :secret_token, :serve_static_assets,
:session_options, :time_zone, :whiny_nils
attr_writer :log_level
@ -63,6 +62,9 @@ def paths
paths.add "config/environment", :with => "config/environment.rb"
paths.add "lib/templates"
paths.add "log", :with => "log/#{Rails.env}.log"
paths.add "public"
paths.add "public/javascripts"
paths.add "public/stylesheets"
paths.add "tmp"
paths.add "tmp/cache"
paths

@ -171,32 +171,6 @@ module Rails
#
# Now, +Engine+ will get only requests that were not handled by +Application+.
#
# == Asset path
#
# When you use +Engine+ with its own public directory, you will probably want to copy or symlink it
# to application's public directory. To simplify generating paths for assets, you can set <tt>asset_path</tt>
# for an engine:
#
# module MyEngine
# class Engine < Rails::Engine
# config.asset_path = "/my_engine/%s"
# end
# end
#
# With such a config, asset paths will be automatically modified inside +Engine+:
#
# image_path("foo.jpg") #=> "/my_engine/images/foo.jpg"
#
# == Serving static files
#
# By default, Rails uses <tt>ActionDispatch::Static</tt> to serve static files in development mode. This is ok
# while you develop your application, but when you want to deploy it, assets from an engine will not be
# served by default. You should choose one of the two following strategies:
#
# * enable serving static files by setting config.serve_static_assets to true
# * copy engine's public files to application's public folder with <tt>rake ENGINE_NAME:install:assets</tt>, for example
# <tt>rake my_engine:install:assets</tt>
#
# == Engine name
#
# There are some places where an Engine's name is used:
@ -427,8 +401,7 @@ def call(env)
def env_config
@env_config ||= {
'action_dispatch.routes' => routes,
'action_dispatch.asset_path' => config.asset_path
'action_dispatch.routes' => routes
}
end
@ -509,16 +482,7 @@ def load_seed
require environment if environment
end
initializer :append_asset_paths do
config.asset_path ||= default_asset_path
public_path = paths["public"].first
if config.compiled_asset_path && File.exist?(public_path)
config.static_asset_paths[config.compiled_asset_path] = public_path
end
end
initializer :append_app_assets_path do |app|
initializer :append_assets_path do |app|
app.config.assets.paths.unshift *paths["vendor/assets"].existent
app.config.assets.paths.unshift *paths["app/assets"].existent
end
@ -542,30 +506,14 @@ def load_seed
rake_tasks do
next if self.is_a?(Rails::Application)
next unless has_migrations? or has_public?
next unless has_migrations?
namespace railtie_name do
desc "Shortcut for copying migrations and assets from #{railtie_name}"
task :install do
Rake::Task["#{railtie_name}:install:migrations"].invoke if has_migrations?
Rake::Task["#{railtie_name}:install:public"].invoke if has_public?
end
namespace :install do
if has_migrations?
desc "Copy migrations from #{railtie_name} to application"
task :migrations do
ENV["FROM"] = railtie_name
Rake::Task["railties:install:migrations"].invoke
end
end
if has_public?
desc "Copy public from #{railtie_name} to application"
task :public do
ENV["FROM"] = railtie_name
Rake::Task["railties:install:public"].invoke
end
desc "Copy migrations from #{railtie_name} to application"
task :migrations do
ENV["FROM"] = railtie_name
Rake::Task["railties:install:migrations"].invoke
end
end
end
@ -573,10 +521,6 @@ def load_seed
protected
def default_asset_path
"/#{railtie_name}%s"
end
def routes?
defined?(@routes)
end
@ -585,10 +529,6 @@ def has_migrations?
paths["db/migrate"].first.present?
end
def has_public?
paths["public"].first.present?
end
def find_root_with_flag(flag, default=nil)
root_path = self.class.called_from

@ -5,7 +5,7 @@ class Engine
class Configuration < ::Rails::Railtie::Configuration
attr_reader :root
attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths
attr_accessor :plugins, :asset_path
attr_accessor :plugins
def initialize(root=nil)
super()
@ -56,9 +56,6 @@ def paths
paths.add "db"
paths.add "db/migrate"
paths.add "db/seeds", :with => "db/seeds.rb"
paths.add "public"
paths.add "public/javascripts"
paths.add "public/stylesheets"
paths.add "vendor", :load_path => true
paths.add "vendor/assets", :glob => "*"
paths.add "vendor/plugins"
@ -81,10 +78,6 @@ def autoload_once_paths
def autoload_paths
@autoload_paths ||= paths.autoload_paths
end
def compiled_asset_path
asset_path % "" if asset_path
end
end
end
end

@ -67,13 +67,6 @@ def respond_to?(name)
super || @@options.key?(name.to_sym)
end
# static_asset_paths is a Hash containing asset_paths
# with associated public folders, like:
# { "/" => "/app/public", "/my_engine" => "app/engines/my_engine/public" }
def static_asset_paths
@@static_asset_paths ||= ActiveSupport::OrderedHash.new
end
private
def method_missing(name, *args, &blk)

@ -12,7 +12,6 @@
routes
statistics
tmp
railties
).each do |task|
load "rails/tasks/#{task}.rake"
end

@ -1,29 +0,0 @@
namespace :railties do
namespace :install do
# desc "Copies missing assets from Railties (e.g. plugins, engines). You can specify Railties to use with FROM=railtie1,railtie2"
task :public => :rails_env do
require 'rails/generators/base'
Rails.application.initialize!
to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map {|n| n.strip }
app_public_path = Rails.application.paths["public"].first
Rails.application.railties.all do |railtie|
next unless to_load == :all || to_load.include?(railtie.railtie_name)
if railtie.respond_to?(:paths) && (path = railtie.paths["public"].first) &&
(assets_dir = railtie.config.compiled_asset_path) && File.exist?(path)
Rails::Generators::Base.source_root(path)
copier = Rails::Generators::Base.new
Dir[File.join(path, "**/*")].each do |file|
relative = file.gsub(/^#{path}\//, '')
if File.file?(file)
copier.copy_file relative, File.join(app_public_path, assets_dir, relative)
end
end
end
end
end
end
end

@ -187,6 +187,7 @@ class Engine < ::Rails::Engine
end
RUBY
require "rack/file"
boot_rails
env = Rack::MockRequest.env_for("/")
@ -198,195 +199,6 @@ class Engine < ::Rails::Engine
assert_equal Rails.application.routes, env['action_dispatch.routes']
end
test "it allows to set asset_path" do
add_to_config("config.assets.enabled = false")
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
class Engine < ::Rails::Engine
end
end
RUBY
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
match "/foo" => "foo#index"
end
RUBY
@plugin.write "app/controllers/foo_controller.rb", <<-RUBY
class FooController < ActionController::Base
def index
render :index
end
end
RUBY
@plugin.write "app/views/foo/index.html.erb", <<-ERB
<%= image_path("foo.png") %>
<%= javascript_include_tag("foo") %>
<%= stylesheet_link_tag("foo") %>
ERB
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
mount Bukkits::Engine => "/bukkits"
end
RUBY
add_to_config 'config.asset_path = "/omg%s"'
boot_rails
# should set asset_path with engine name by default
assert_equal "/bukkits_engine%s", ::Bukkits::Engine.config.asset_path
::Bukkits::Engine.config.asset_path = "/bukkits%s"
get("/bukkits/foo")
stripped_body = last_response.body.split("\n").map(&:strip).join
expected = "/omg/bukkits/images/foo.png" +
"<script src=\"/omg/bukkits/javascripts/foo.js\" type=\"text/javascript\"></script>" +
"<link href=\"/omg/bukkits/stylesheets/foo.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
assert_equal expected, stripped_body
end
test "default application's asset_path" do
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
match "/foo" => "foo#index"
end
RUBY
@plugin.write "app/controllers/foo_controller.rb", <<-RUBY
class FooController < ActionController::Base
def index
render :inline => '<%= image_path("foo.png") %>'
end
end
RUBY
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do
mount Bukkits::Engine => "/bukkits"
end
RUBY
boot_rails
get("/bukkits/foo")
assert_equal "/bukkits/images/foo.png", last_response.body.strip
end
test "engine's files are served via ActionDispatch::Static" do
add_to_config "config.serve_static_assets = true"
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
class Engine < ::Rails::Engine
engine_name :bukkits
end
end
RUBY
@plugin.write "public/bukkits.html", "/bukkits/bukkits.html"
app_file "public/app.html", "/app.html"
app_file "public/bukkits/file_from_app.html", "/bukkits/file_from_app.html"
boot_rails
get("/app.html")
assert_equal File.read(File.join(app_path, "public/app.html")), last_response.body
get("/bukkits/bukkits.html")
assert_equal File.read(File.join(@plugin.path, "public/bukkits.html")), last_response.body
get("/bukkits/file_from_app.html")
assert_equal File.read(File.join(app_path, "public/bukkits/file_from_app.html")), last_response.body
end
test "an applications files are given priority over an engines files when served via ActionDispatch::Static" do
add_to_config "config.serve_static_assets = true"
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
class Engine < ::Rails::Engine
engine_name :bukkits
end
end
RUBY
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do
mount Bukkits::Engine => "/bukkits"
end
RUBY
@plugin.write "public/bukkits.html", "in engine"
app_file "public/bukkits/bukkits.html", "in app"
boot_rails
get('/bukkits/bukkits.html')
assert_equal 'in app', last_response.body.strip
end
test "shared engine should include application's helpers and own helpers" do
app_file "config/routes.rb", <<-RUBY
AppTemplate::Application.routes.draw do
match "/foo" => "bukkits/foo#index", :as => "foo"
match "/foo/show" => "bukkits/foo#show"
match "/foo/bar" => "bukkits/foo#bar"
end
RUBY
app_file "app/helpers/some_helper.rb", <<-RUBY
module SomeHelper
def something
"Something... Something... Something..."
end
end
RUBY
@plugin.write "app/helpers/bar_helper.rb", <<-RUBY
module BarHelper
def bar
"It's a bar."
end
end
RUBY
@plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY
class Bukkits::FooController < ActionController::Base
def index
render :inline => "<%= something %>"
end
def show
render :text => foo_path
end
def bar
render :inline => "<%= bar %>"
end
end
RUBY
boot_rails
get("/foo")
assert_equal "Something... Something... Something...", last_response.body
get("/foo/show")
assert_equal "/foo", last_response.body
get("/foo/bar")
assert_equal "It's a bar.", last_response.body
end
test "isolated engine should include only its own routes and helpers" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
@ -772,71 +584,6 @@ class Engine < ::Rails::Engine
assert_equal Bukkits::Engine.instance, Rails::Engine.find(engine_path)
end
test "ensure that engine properly sets assets directories" do
add_to_config("config.action_dispatch.show_exceptions = false")
add_to_config("config.serve_static_assets = true")
add_to_config("config.assets.enabled = false")
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
class Engine < ::Rails::Engine
isolate_namespace Bukkits
end
end
RUBY
@plugin.write "public/stylesheets/foo.css", ""
@plugin.write "public/javascripts/foo.js", ""
@plugin.write "app/views/layouts/bukkits/application.html.erb", <<-RUBY
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :all %>
<%= yield %>
RUBY
@plugin.write "app/controllers/bukkits/home_controller.rb", <<-RUBY
module Bukkits
class HomeController < ActionController::Base
def index
render :text => "Good morning!", :layout => "bukkits/application"
end
end
end
RUBY
@plugin.write "config/routes.rb", <<-RUBY
Bukkits::Engine.routes.draw do
match "/home" => "home#index"
end
RUBY
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
mount Bukkits::Engine => "/bukkits"
end
RUBY
require 'rack/test'
extend Rack::Test::Methods
boot_rails
require "#{rails_root}/config/environment"
assert_equal File.join(@plugin.path, "public"), Bukkits::HomeController.assets_dir
assert_equal File.join(@plugin.path, "public/stylesheets"), Bukkits::HomeController.stylesheets_dir
assert_equal File.join(@plugin.path, "public/javascripts"), Bukkits::HomeController.javascripts_dir
assert_equal File.join(app_path, "public"), ActionController::Base.assets_dir
assert_equal File.join(app_path, "public/stylesheets"), ActionController::Base.stylesheets_dir
assert_equal File.join(app_path, "public/javascripts"), ActionController::Base.javascripts_dir
get "/bukkits/home"
assert_match %r{bukkits/stylesheets/foo.css}, last_response.body
assert_match %r{bukkits/javascripts/foo.js}, last_response.body
end
private
def app
Rails.application

@ -10,44 +10,6 @@ def app
@app ||= Rails.application
end
def test_install_migrations_and_assets
@plugin.write "public/javascripts/foo.js", "doSomething()"
@plugin.write "db/migrate/1_create_users.rb", <<-RUBY
class CreateUsers < ActiveRecord::Migration
end
RUBY
app_file "db/migrate/1_create_sessions.rb", <<-RUBY
class CreateSessions < ActiveRecord::Migration
end
RUBY
add_to_config "ActiveRecord::Base.timestamped_migrations = false"
Dir.chdir(app_path) do
`rake bukkits:install`
assert File.exists?("#{app_path}/db/migrate/2_create_users.rb")
assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
end
end
def test_copying_public
@plugin.write "public/javascripts/foo.js", "doSomething()"
@plugin.write "public/stylesheets/foo.css", "h1 { font-size: 10000px }"
@plugin.write "public/images/img.png", ""
Dir.chdir(app_path) do
`rake bukkits:install:public --trace`
assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
assert_equal "doSomething()\n", File.read(app_path("public/bukkits/javascripts/foo.js"))
assert File.exists?(app_path("public/bukkits/stylesheets/foo.css"))
assert_equal "h1 { font-size: 10000px }\n", File.read(app_path("public/bukkits/stylesheets/foo.css"))
assert File.exists?(app_path("public/bukkits/images/img.png"))
end
end
def test_serving_sprockets_assets
@plugin.write "app/assets/javascripts/engine.js.coffee", "square = (x) -> x * x"