Skip to content
This repository
Browse code

Read digests of assets from manifest.yml if config.assets.manifest is on

  • Loading branch information...
commit af0f14e6de3e2cdd2e0ad895edf8c34440c2764f 1 parent c4ce550
Guillermo Iguaran authored August 29, 2011
10  actionpack/lib/sprockets/assets.rake
@@ -18,7 +18,8 @@ namespace :assets do
18 18
 
19 19
       config = Rails.application.config
20 20
       env    = Rails.application.assets
21  
-      target = Rails.root.join("public#{config.assets.prefix}")
  21
+      target = Pathname.new(File.join(Rails.public_path, config.assets.prefix))
  22
+      manifest = {}
22 23
 
23 24
       if env.respond_to?(:each_logical_path)
24 25
         config.assets.precompile.each do |path|
@@ -30,6 +31,7 @@ namespace :assets do
30 31
             end
31 32
 
32 33
             if asset = env.find_asset(logical_path)
  34
+              manifest[logical_path] = asset.digest_path
33 35
               filename = target.join(asset.digest_path)
34 36
               mkdir_p filename.dirname
35 37
               asset.write_to(filename)
@@ -43,6 +45,12 @@ namespace :assets do
43 45
         assets << {:to => target}
44 46
         env.precompile(*assets)
45 47
       end
  48
+
  49
+      if config.assets.manifest
  50
+        File.open("#{target}/manifest.yml", 'w') do |f|
  51
+          YAML.dump(manifest, f)
  52
+        end
  53
+      end
46 54
     end
47 55
   end
48 56
 
17  actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -14,6 +14,7 @@ def asset_paths
14 14
           paths = RailsHelper::AssetPaths.new(config, controller)
15 15
           paths.asset_environment = asset_environment
16 16
           paths.asset_prefix      = asset_prefix
  17
+          paths.asset_digests     = asset_digests
17 18
           paths
18 19
         end
19 20
       end
@@ -87,6 +88,10 @@ def asset_prefix
87 88
         Rails.application.config.assets.prefix
88 89
       end
89 90
 
  91
+      def asset_digests
  92
+        Rails.application.config.assets.digests
  93
+      end
  94
+
90 95
       # Override to specify an alternative asset environment for asset
91 96
       # path generation. The environment should already have been mounted
92 97
       # at the prefix returned by +asset_prefix+.
@@ -95,7 +100,9 @@ def asset_environment
95 100
       end
96 101
 
97 102
       class AssetPaths < ::ActionView::AssetPaths #:nodoc:
98  
-        attr_accessor :asset_environment, :asset_prefix
  103
+        attr_accessor :asset_environment, :asset_prefix, :asset_digests
  104
+
  105
+        class AssetNotPrecompiledError < StandardError; end
99 106
 
100 107
         def compute_public_path(source, dir, ext=nil, include_host=true, protocol=nil)
101 108
           super(source, asset_prefix, ext, include_host, protocol)
@@ -114,6 +121,14 @@ def asset_for(source, ext)
114 121
         end
115 122
 
116 123
         def digest_for(logical_path)
  124
+          if asset_digests && (digest = asset_digests[logical_path])
  125
+            return digest
  126
+          end
  127
+
  128
+          if digest.nil? && Rails.application.config.assets.precompile_only
  129
+            raise AssetNotPrecompiledError
  130
+          end
  131
+
117 132
           if asset = asset_environment[logical_path]
118 133
             return asset.digest_path
119 134
           end
6  actionpack/lib/sprockets/railtie.rb
@@ -26,6 +26,12 @@ class Railtie < ::Rails::Railtie
26 26
         end
27 27
       end
28 28
 
  29
+      if config.assets.manifest
  30
+        if File.exist?(path = File.join(Rails.public_path, config.assets.prefix, "manifest.yml"))
  31
+          config.assets.digests = YAML.load_file(path)
  32
+        end
  33
+      end
  34
+
29 35
       ActiveSupport.on_load(:action_view) do
30 36
         include ::Sprockets::Helpers::RailsHelper
31 37
 
9  railties/lib/rails/application/configuration.rb
@@ -40,10 +40,11 @@ def initialize(*)
40 40
         @assets.version         = ''
41 41
         @assets.debug           = false
42 42
         @assets.allow_debugging = false
43  
-
44  
-        @assets.cache_store    = [ :file_store, "#{root}/tmp/cache/assets/" ]
45  
-        @assets.js_compressor  = nil
46  
-        @assets.css_compressor = nil
  43
+        @assets.manifest        = true
  44
+        @assets.precompile_only = false
  45
+        @assets.cache_store     = [ :file_store, "#{root}/tmp/cache/assets/" ]
  46
+        @assets.js_compressor   = nil
  47
+        @assets.css_compressor  = nil
47 48
       end
48 49
 
49 50
       def compiled_asset_path
4  railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -52,6 +52,10 @@ class Application < Rails::Application
52 52
 <% unless options.skip_sprockets? -%>
53 53
     # Enable the asset pipeline
54 54
     config.assets.enabled = true
  55
+
  56
+    # Create a manifest with the hashes of your assets when you run "rake assets:precompile".
  57
+    # Use this if you don't have a JavaScript engine in your production servers
  58
+    config.assets.manifest = true
55 59
 <% end -%>
56 60
   end
57 61
 end
65  railties/test/application/assets_test.rb
@@ -62,6 +62,71 @@ def app
62 62
       end
63 63
     end
64 64
 
  65
+    test "precompile don't create a manifest file when manifest option is off" do
  66
+      app_file "app/assets/javascripts/application.js", "alert();"
  67
+      app_file "config/initializers/manifest.rb", "Rails.application.config.assets.manifest = false"
  68
+
  69
+      capture(:stdout) do
  70
+        Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
  71
+      end
  72
+
  73
+      assert !File.exist?("#{app_path}/public/assets/manifest.yml")
  74
+    end
  75
+
  76
+    test "precompile creates a manifest file with all the assets listed when manifest option is on" do
  77
+      app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
  78
+      app_file "app/assets/javascripts/application.js", "alert();"
  79
+
  80
+      capture(:stdout) do
  81
+        Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
  82
+      end
  83
+
  84
+      manifest = "#{app_path}/public/assets/manifest.yml"
  85
+
  86
+      assets = YAML.load_file(manifest)
  87
+      assert_match /application-([0-z]+)\.js/, assets["application.js"]
  88
+      assert_match /application-([0-z]+)\.css/, assets["application.css"]
  89
+    end
  90
+
  91
+    test "assets do not require any assets group gem when manifest option is on and manifest file is present" do
  92
+      app_file "app/assets/javascripts/application.js", "alert();"
  93
+
  94
+      ENV["RAILS_ENV"] = "production"
  95
+      capture(:stdout) do
  96
+        Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
  97
+      end
  98
+      manifest = "#{app_path}/public/assets/manifest.yml"
  99
+      assets = YAML.load_file(manifest)
  100
+      asset_path = assets["application.js"]
  101
+
  102
+      require "#{app_path}/config/environment"
  103
+
  104
+      # Checking if Uglifier is defined we can know if Sprockets was reached or not
  105
+      assert !defined?(Uglifier)
  106
+      get "/assets/#{asset_path}"
  107
+      assert_match "alert()", last_response.body
  108
+      assert !defined?(Uglifier)
  109
+    end
  110
+
  111
+    test "assets raise AssetNotPrecompiledError if config.assets.precompile_only is on and file isn't precompiled" do
  112
+      app_file "app/assets/javascripts/app.js", "alert();"
  113
+      app_file "app/views/posts/index.html.erb", "<%= javascript_include_tag 'app' %>"
  114
+      app_file "config/initializers/precompile_only.rb", "Rails.application.config.assets.precompile_only = true"
  115
+
  116
+      app_file "config/routes.rb", <<-RUBY
  117
+        AppTemplate::Application.routes.draw do
  118
+          match '/posts', :to => "posts#index"
  119
+        end
  120
+      RUBY
  121
+
  122
+      ENV["RAILS_ENV"] = "production"
  123
+      require "#{app_path}/config/environment"
  124
+      class ::PostsController < ActionController::Base ; end
  125
+
  126
+      get '/posts'
  127
+      assert_match /AssetNotPrecompiledError/, last_response.body
  128
+    end
  129
+
65 130
     test "precompile appends the md5 hash to files referenced with asset_path and run in the provided RAILS_ENV" do
66 131
       app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
67 132
 

0 notes on commit af0f14e

Please sign in to comment.
Something went wrong with that request. Please try again.