diff --git a/middleman-core/lib/middleman-core/core_extensions/assets.rb b/middleman-core/lib/middleman-core/core_extensions/assets.rb index d2592f7f..ad2f0527 100644 --- a/middleman-core/lib/middleman-core/core_extensions/assets.rb +++ b/middleman-core/lib/middleman-core/core_extensions/assets.rb @@ -29,7 +29,7 @@ module Middleman::CoreExtensions::Assets else # rewrite paths to use their destination path path = File.join(prefix, path) if resource = sitemap.find_resource_by_path(path) - path = resource.path + path = resource.destination_path end File.join(http_prefix, path) diff --git a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb index 8348d8ad..b165a1b1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -1,5 +1,6 @@ require "find" require "middleman-core/watcher" +require "set" # API for watching file change events module Middleman::CoreExtensions::FileWatcher @@ -54,7 +55,7 @@ module Middleman::CoreExtensions::FileWatcher # Initialize api and internal path cache def initialize - self.known_paths = [] + self.known_paths = Set.new end # Add callback to be run on file change @@ -83,7 +84,7 @@ module Middleman::CoreExtensions::FileWatcher # @return [void] def did_change(path) puts "== File Change: #{path}" if instance.logging? && !::Middleman::Watcher.ignore_list.any? { |r| path.match(r) } - self.known_paths << path unless self.known_paths.include?(path) + self.known_paths << path self.run_callbacks(path, :changed) end @@ -93,7 +94,7 @@ module Middleman::CoreExtensions::FileWatcher # @return [void] def did_delete(path) puts "== File Deletion: #{path}" if instance.logging? && !::Middleman::Watcher.ignore_list.any? { |r| path.match(r) } - self.known_paths.delete(path) if self.known_paths.include?(path) + self.known_paths.delete(path) self.run_callbacks(path, :deleted) end @@ -132,4 +133,4 @@ module Middleman::CoreExtensions::FileWatcher end end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 05102d1b..d8e89331 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -1,3 +1,5 @@ +require 'set' + module Middleman::Sitemap::Extensions class OnDisk @@ -8,12 +10,8 @@ module Middleman::Sitemap::Extensions @sitemap = sitemap @app = @sitemap.app - @file_paths_on_disk = [] + @file_paths_on_disk = Set.new - # Cleanup paths - # static_path = @app.source_dir.sub(@app.root, "").sub(/^\//, "") - # sitemap_regex = static_path.empty? ? // : (%r{^#{static_path + "/"}}) - scoped_self = self @waiting_for_ready = true @@ -38,26 +36,28 @@ module Middleman::Sitemap::Extensions # @return [Boolean] def touch_file(file, rebuild=true) return false if file == @app.source_dir || File.directory?(file) - + path = file_to_path(file) return false unless path - - return false if @app.ignored_sitemap_matchers.any? do |name, callback| + + ignored = @app.ignored_sitemap_matchers.any? do |name, callback| callback.call(file, path) end - - if !@file_paths_on_disk.include?(file) - @file_paths_on_disk << file - @sitemap.rebuild_resource_list!(:added_file) if rebuild - end + + @file_paths_on_disk << file unless ignored + + # Rebuild the sitemap any time a file is touched + # in case one of the other manipulators + # (like asset_hash) cares about the contents of this file, + # whether or not it belongs in the sitemap (like a partial) + @sitemap.rebuild_resource_list!(:touched_file) if rebuild end # Remove a file from the store # @param [String] file # @return [void] def remove_file(file, rebuild=true) - if @file_paths_on_disk.include?(file) - @file_paths_on_disk.delete(file) + if @file_paths_on_disk.delete?(file) @sitemap.rebuild_resource_list!(:removed_file) if rebuild end end @@ -117,4 +117,4 @@ module Middleman::Sitemap::Extensions path end end -end \ No newline at end of file +end diff --git a/middleman-more/lib/middleman-more/extensions/asset_hash.rb b/middleman-more/lib/middleman-more/extensions/asset_hash.rb index c5c2f18c..e880973c 100755 --- a/middleman-more/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-more/lib/middleman-more/extensions/asset_hash.rb @@ -5,32 +5,11 @@ module Middleman::Extensions def registered(app, options) exts = options[:exts] || %w(.ico .manifest .jpg .jpeg .png .gif .js .css) - app.after_configuration do - sitemap.reroute do |destination, page| - if exts.include? page.ext - # figure out the path Sprockets would use for this asset - if page.ext == '.js' - sprockets_path = page.path.sub(js_dir,'').sub(/^\//,'') - elsif page.ext == '.css' - sprockets_path = page.path.sub(css_dir,'').sub(/^\//,'') - end - - # See if Sprockets knows about the file - asset = sprockets.find_asset(sprockets_path) if sprockets_path - - if asset # if it's a Sprockets asset, ask sprockets for its digest - digest = asset.digest[0..7] - elsif page.template? # if it's a template, render it out - digest = Digest::SHA1.hexdigest(page.render)[0..7] - else # if it's a static file, just hash it - digest = Digest::SHA1.file(page.source_file).hexdigest[0..7] - end - - destination.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } - else - destination - end - end + app.ready do + sitemap.register_resource_list_manipulator( + :asset_hash, + AssetHashManager.new(self, exts) + ) use Middleware, :exts => exts, :middleman_app => self end @@ -38,6 +17,43 @@ module Middleman::Extensions alias :included :registered end + class AssetHashManager + def initialize(app, exts) + @app = app + @exts = exts + end + + # Update the main sitemap resource list + # @return [void] + def manipulate_resource_list(resources) + resources.each do |resource| + if @exts.include? resource.ext + # figure out the path Sprockets would use for this asset + if resource.ext == '.js' + sprockets_path = resource.path.sub(@app.js_dir,'').sub(/^\//,'') + elsif resource.ext == '.css' + sprockets_path = resource.path.sub(@app.css_dir,'').sub(/^\//,'') + end + + # See if Sprockets knows about the file + asset = @app.sprockets.find_asset(sprockets_path) if sprockets_path + + if asset # if it's a Sprockets asset, ask sprockets for its digest + digest = asset.digest[0..7] + elsif resource.template? # if it's a template, render it out + digest = Digest::SHA1.hexdigest(resource.render)[0..7] + else # if it's a static file, just hash it + digest = Digest::SHA1.file(resource.source_file).hexdigest[0..7] + end + + resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } + end + end + end + end + + # The asset hash middleware is responsible for rewriting references to + # assets to include their new, hashed name. class Middleware def initialize(app, options={}) @rack_app = app @@ -63,7 +79,7 @@ module Middleman::Extensions asset_path = dirpath.join(asset_path).to_s if relative_path - if asset_page = @middleman_app.sitemap.find_page_by_path(asset_path) + if asset_page = @middleman_app.sitemap.find_resource_by_path(asset_path) replacement_path = "/#{asset_page.destination_path}" replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path