aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/sprockets
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/sprockets')
-rw-r--r--actionpack/lib/sprockets/assets.rake67
-rw-r--r--actionpack/lib/sprockets/bootstrap.rb37
-rw-r--r--actionpack/lib/sprockets/compressors.rb46
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb24
-rw-r--r--actionpack/lib/sprockets/railtie.rb61
-rw-r--r--actionpack/lib/sprockets/static_compiler.rb52
6 files changed, 190 insertions, 97 deletions
diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake
index 9b2f3a3f94..bb5cf6740a 100644
--- a/actionpack/lib/sprockets/assets.rake
+++ b/actionpack/lib/sprockets/assets.rake
@@ -6,58 +6,55 @@ namespace :assets do
if ENV["RAILS_GROUPS"].to_s.empty? || ENV["RAILS_ENV"].to_s.empty?
ENV["RAILS_GROUPS"] ||= "assets"
ENV["RAILS_ENV"] ||= "production"
- Kernel.exec $0, *ARGV
+ ruby $0, *ARGV
else
- Rake::Task["environment"].invoke
+ require "fileutils"
Rake::Task["tmp:cache:clear"].invoke
+ Rake::Task["assets:environment"].invoke
- # Ensure that action view is loaded and the appropriate sprockets hooks get executed
- ActionView::Base
-
- # Always compile files
- Rails.application.config.assets.compile = true
+ unless Rails.application.config.assets.enabled
+ raise "Cannot precompile assets if sprockets is disabled. Please set config.assets.enabled to true"
+ end
- # Always ignore asset host
- Rails.application.config.action_controller.asset_host = nil
+ # Ensure that action view is loaded and the appropriate sprockets hooks get executed
+ _ = ActionView::Base
config = Rails.application.config
+ config.assets.compile = true
+ config.assets.digest = false if ENV["RAILS_ASSETS_NONDIGEST"]
+
env = Rails.application.assets
- target = Pathname.new(File.join(Rails.public_path, config.assets.prefix))
- manifest = {}
+
+ # Always compile files and avoid use of existing precompiled assets
+ config.assets.compile = true
+ config.assets.digests = {}
+
+ target = File.join(Rails.public_path, config.assets.prefix)
+ static_compiler = Sprockets::StaticCompiler.new(env, target, :digest => config.assets.digest)
+
+ manifest = static_compiler.precompile(config.assets.precompile)
manifest_path = config.assets.manifest || target
+ FileUtils.mkdir_p(manifest_path)
- config.assets.precompile.each do |path|
- env.each_logical_path do |logical_path|
- if path.is_a?(Regexp)
- next unless path.match(logical_path)
- elsif path.is_a?(Proc)
- next unless path.call(logical_path)
- else
- next unless File.fnmatch(path.to_s, logical_path)
- end
-
- if asset = env.find_asset(logical_path)
- asset_path = config.assets.digest ? asset.digest_path : logical_path
- manifest[logical_path] = asset_path
- filename = target.join(asset_path)
-
- mkdir_p filename.dirname
- asset.write_to(filename)
- asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
- end
+ unless ENV["RAILS_ASSETS_NONDIGEST"]
+ File.open("#{manifest_path}/manifest.yml", 'wb') do |f|
+ YAML.dump(manifest, f)
end
- end
-
- File.open("#{manifest_path}/manifest.yml", 'wb') do |f|
- YAML.dump(manifest, f)
+ ENV["RAILS_ASSETS_NONDIGEST"] = "true"
+ ruby $0, *ARGV
end
end
end
desc "Remove compiled assets"
- task :clean => [:environment, 'tmp:cache:clear'] do
+ task :clean => ['assets:environment', 'tmp:cache:clear'] do
config = Rails.application.config
public_asset_path = File.join(Rails.public_path, config.assets.prefix)
rm_rf public_asset_path, :secure => true
end
+
+ task :environment do
+ Rails.application.initialize!(:assets)
+ Sprockets::Bootstrap.new(Rails.application).run
+ end
end
diff --git a/actionpack/lib/sprockets/bootstrap.rb b/actionpack/lib/sprockets/bootstrap.rb
new file mode 100644
index 0000000000..395b264fe7
--- /dev/null
+++ b/actionpack/lib/sprockets/bootstrap.rb
@@ -0,0 +1,37 @@
+module Sprockets
+ class Bootstrap
+ def initialize(app)
+ @app = app
+ end
+
+ # TODO: Get rid of config.assets.enabled
+ def run
+ app, config = @app, @app.config
+ return unless app.assets
+
+ config.assets.paths.each { |path| app.assets.append_path(path) }
+
+ if config.assets.compress
+ # temporarily hardcode default JS compressor to uglify. Soon, it will work
+ # the same as SCSS, where a default plugin sets the default.
+ unless config.assets.js_compressor == false
+ app.assets.js_compressor = LazyCompressor.new { Sprockets::Compressors.registered_js_compressor(config.assets.js_compressor || :uglifier) }
+ end
+
+ unless config.assets.css_compressor == false
+ app.assets.css_compressor = LazyCompressor.new { Sprockets::Compressors.registered_css_compressor(config.assets.css_compressor) }
+ end
+ end
+
+ if config.assets.compile
+ app.routes.prepend do
+ mount app.assets => config.assets.prefix
+ end
+ end
+
+ if config.assets.digest
+ app.assets = app.assets.index
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/sprockets/compressors.rb b/actionpack/lib/sprockets/compressors.rb
index 351eff1085..cb3e13314b 100644
--- a/actionpack/lib/sprockets/compressors.rb
+++ b/actionpack/lib/sprockets/compressors.rb
@@ -1,4 +1,50 @@
module Sprockets
+ module Compressors
+ @@css_compressors = {}
+ @@js_compressors = {}
+ @@default_css_compressor = nil
+ @@default_js_compressor = nil
+
+ def self.register_css_compressor(name, klass, options = {})
+ @@default_css_compressor = name.to_sym if options[:default] || @@default_css_compressor.nil?
+ @@css_compressors[name.to_sym] = {:klass => klass.to_s, :require => options[:require]}
+ end
+
+ def self.register_js_compressor(name, klass, options = {})
+ @@default_js_compressor = name.to_sym if options[:default] || @@default_js_compressor.nil?
+ @@js_compressors[name.to_sym] = {:klass => klass.to_s, :require => options[:require]}
+ end
+
+ def self.registered_css_compressor(name)
+ if name.respond_to?(:to_sym)
+ compressor = @@css_compressors[name.to_sym] || @@css_compressors[@@default_css_compressor]
+ require compressor[:require] if compressor[:require]
+ compressor[:klass].constantize.new
+ else
+ name
+ end
+ end
+
+ def self.registered_js_compressor(name)
+ if name.respond_to?(:to_sym)
+ compressor = @@js_compressors[name.to_sym] || @@js_compressors[@@default_js_compressor]
+ require compressor[:require] if compressor[:require]
+ compressor[:klass].constantize.new
+ else
+ name
+ end
+ end
+
+ # The default compressors must be registered in default plugins (ex. Sass-Rails)
+ register_css_compressor(:scss, 'Sass::Rails::Compressor', :require => 'sass/rails/compressor', :default => true)
+ register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier', :default => true)
+
+ # Automaticaly register some compressors
+ register_css_compressor(:yui, 'YUI::CssCompressor', :require => 'yui/compressor')
+ register_js_compressor(:closure, 'Closure::Compiler', :require => 'closure-compiler')
+ register_js_compressor(:yui, 'YUI::JavaScriptCompressor', :require => 'yui/compressor')
+ end
+
# An asset compressor which does nothing.
#
# This compressor simply returns the asset as-is, without any compression
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 457ab93ae3..e1d8fccf04 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -13,7 +13,6 @@ module Sprockets
controller = self.controller if respond_to?(:controller)
paths = RailsHelper::AssetPaths.new(config, controller)
paths.asset_environment = asset_environment
- paths.asset_prefix = asset_prefix
paths.asset_digests = asset_digests
paths.compile_assets = compile_assets?
paths.digest_assets = digest_assets?
@@ -57,10 +56,25 @@ module Sprockets
def asset_path(source, options = {})
source = source.logical_path if source.respond_to?(:logical_path)
- path = asset_paths.compute_public_path(source, 'assets', options.merge(:body => true))
+ path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true))
options[:body] ? "#{path}?body=1" : path
end
+ def image_path(source)
+ asset_path(source)
+ end
+ alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
+
+ def javascript_path(source)
+ asset_path(source)
+ end
+ alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with an javascript_path named route
+
+ def stylesheet_path(source)
+ asset_path(source)
+ end
+ alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with an stylesheet_path named route
+
private
def debug_assets?
compile_assets? && (Rails.application.config.assets.debug || params[:debug_assets])
@@ -102,10 +116,6 @@ module Sprockets
class AssetNotPrecompiledError < StandardError; end
- def compute_public_path(source, dir, options = {})
- super(source, asset_prefix, options)
- end
-
# Return the filesystem path for the source
def compute_source_path(source, ext)
asset_for(source, ext)
@@ -119,7 +129,7 @@ module Sprockets
end
def digest_for(logical_path)
- if asset_digests && (digest = asset_digests[logical_path])
+ if digest_assets && asset_digests && (digest = asset_digests[logical_path])
return digest
end
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index f05d835554..6b67fb1d2d 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -1,7 +1,10 @@
module Sprockets
- autoload :Helpers, "sprockets/helpers"
+ autoload :Bootstrap, "sprockets/bootstrap"
+ autoload :Helpers, "sprockets/helpers"
+ autoload :Compressors, "sprockets/compressors"
autoload :LazyCompressor, "sprockets/compressors"
autoload :NullCompressor, "sprockets/compressors"
+ autoload :StaticCompiler, "sprockets/static_compiler"
# TODO: Get rid of config.assets.enabled
class Railtie < ::Rails::Railtie
@@ -11,7 +14,7 @@ module Sprockets
load "sprockets/assets.rake"
end
- initializer "sprockets.environment" do |app|
+ initializer "sprockets.environment", :group => :assets do |app|
config = app.config
next unless config.assets.enabled
@@ -50,59 +53,7 @@ module Sprockets
# are compiled, and so that other Railties have an opportunity to
# register compressors.
config.after_initialize do |app|
- next unless app.assets
- config = app.config
-
- config.assets.paths.each { |path| app.assets.append_path(path) }
-
- if config.assets.compress
- # temporarily hardcode default JS compressor to uglify. Soon, it will work
- # the same as SCSS, where a default plugin sets the default.
- unless config.assets.js_compressor == false
- app.assets.js_compressor = LazyCompressor.new { expand_js_compressor(config.assets.js_compressor || :uglifier) }
- end
-
- unless config.assets.css_compressor == false
- app.assets.css_compressor = LazyCompressor.new { expand_css_compressor(config.assets.css_compressor) }
- end
- end
-
- if config.assets.compile
- app.routes.prepend do
- mount app.assets => config.assets.prefix
- end
- end
-
- if config.assets.digest
- app.assets = app.assets.index
- end
+ Sprockets::Bootstrap.new(app).run
end
-
- protected
- def expand_js_compressor(sym)
- case sym
- when :closure
- require 'closure-compiler'
- Closure::Compiler.new
- when :uglifier
- require 'uglifier'
- Uglifier.new
- when :yui
- require 'yui/compressor'
- YUI::JavaScriptCompressor.new
- else
- sym
- end
- end
-
- def expand_css_compressor(sym)
- case sym
- when :yui
- require 'yui/compressor'
- YUI::CssCompressor.new
- else
- sym
- end
- end
end
end
diff --git a/actionpack/lib/sprockets/static_compiler.rb b/actionpack/lib/sprockets/static_compiler.rb
new file mode 100644
index 0000000000..4a0078be46
--- /dev/null
+++ b/actionpack/lib/sprockets/static_compiler.rb
@@ -0,0 +1,52 @@
+require 'fileutils'
+
+module Sprockets
+ class StaticCompiler
+ attr_accessor :env, :target, :digest
+
+ def initialize(env, target, options = {})
+ @env = env
+ @target = target
+ @digest = options.key?(:digest) ? options.delete(:digest) : true
+ end
+
+ def precompile(paths)
+ Rails.application.config.assets.digest = digest
+ manifest = {}
+
+ env.each_logical_path do |logical_path|
+ next unless precompile_path?(logical_path, paths)
+ if asset = env.find_asset(logical_path)
+ manifest[logical_path] = compile(asset)
+ end
+ end
+ manifest
+ end
+
+ def compile(asset)
+ asset_path = digest_asset(asset)
+ filename = File.join(target, asset_path)
+ FileUtils.mkdir_p File.dirname(filename)
+ asset.write_to(filename)
+ asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
+ asset_path
+ end
+
+ def precompile_path?(logical_path, paths)
+ paths.each do |path|
+ if path.is_a?(Regexp)
+ return true if path.match(logical_path)
+ elsif path.is_a?(Proc)
+ return true if path.call(logical_path)
+ else
+ return true if File.fnmatch(path.to_s, logical_path)
+ end
+ end
+ false
+ end
+
+ def digest_asset(asset)
+ digest ? asset.digest_path : asset.logical_path
+ end
+ end
+end