From 4b03c5e2df77d48e18d6eb43414bde0ceee4a999 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 6 Jul 2012 19:32:05 -0700 Subject: [PATCH] Add Middleman::Util.all_files_under to get a recursive listing of files beneath a path, follows symlinks. Fixes #515 --- .../lib/middleman-core/cli/build.rb | 12 ++-- .../core_extensions/external_helpers.rb | 2 +- .../core_extensions/file_watcher.rb | 3 +- middleman-core/lib/middleman-core/util.rb | 15 ++++ .../lib/middleman-more/extensions/gzip.rb | 70 +++++++++---------- 5 files changed, 57 insertions(+), 45 deletions(-) diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 60be95f5..fb1a9b34 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -206,12 +206,12 @@ module Middleman::Cli # @return [void] def queue_current_paths @cleaning_queue = [] - Find.find(@destination) do |path| - next if path.match(/\/\./) && !path.match(/\.htaccess/) - unless path == destination - @cleaning_queue << Pathname.new(path) - end - end if File.exist?(@destination) + return unless File.exist?(@destination) + + paths = ::Middleman::Util.all_files_under(@destination) + @cleaning_queue += paths.select do |path| + !path.to_s.match(/\/\./) || path.to_s.match(/\.htaccess/) + end end # Actually build the app diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index fc0b726c..9b17e37a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -10,7 +10,7 @@ module Middleman def registered(app) # Setup a default helpers paths app.set :helpers_dir, "helpers" - app.set :helpers_filename_glob, "**/*.rb" + app.set :helpers_filename_glob, "**{,/*/**}/*.rb" app.set :helpers_filename_to_module_name_proc, Proc.new { |filename| basename = File.basename(filename, File.extname(filename)) basename.camelcase 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 58473f91..324b6672 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -112,9 +112,8 @@ module Middleman glob = "#{path}**/*" subset = @known_paths.select { |p| p.fnmatch(glob) } - path.find do |filepath| + ::Middleman::Util.all_files_under(path).each do |filepath| full_path = path + filepath - next if full_path.directory? if only_new next if subset.include?(full_path) diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 4a0ef315..c618e452 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -74,6 +74,21 @@ module Middleman File.fnmatch(matcher.to_s, path) end end + + # Get a recusive list of files inside a set of paths. + # Works with symlinks. + # + # @param path A path string or Pathname + # @return [Array] An array of filenames + def self.all_files_under(*paths) + paths.flatten! + paths.map! { |p| Pathname(p) } + files = paths.select { |p| p.file? } + (paths - files).each do |dir| + files << all_files_under(dir.children) + end + files.flatten + end # Simple shared cache implementation class Cache diff --git a/middleman-more/lib/middleman-more/extensions/gzip.rb b/middleman-more/lib/middleman-more/extensions/gzip.rb index 6e574148..a43b0603 100644 --- a/middleman-more/lib/middleman-more/extensions/gzip.rb +++ b/middleman-more/lib/middleman-more/extensions/gzip.rb @@ -19,15 +19,17 @@ module Middleman::Extensions class << self def registered(app, options={}) exts = options[:exts] || %w(.js .css .html .htm) - - app.send :include, InstanceMethods app.after_build do |builder| - Find.find(self.class.inst.build_dir) do |path| - next if File.directory? path - if exts.include? File.extname(path) - new_size = gzip_file(path, builder) - end + + paths = ::Middleman::Util.all_files_under(self.class.inst.build_dir) + paths.each do |path| + next unless exts.include? path.extname + + output_filename, old_size, new_size = Middleman::Extensions::Gzip.gzip_file(path.to_s) + + size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger' + builder.say_status :gzip, "#{output_filename} (#{number_to_human_size((old_size - new_size).abs)} #{size_change_word})" end end end @@ -35,37 +37,33 @@ module Middleman::Extensions alias :included :registered end - module InstanceMethods - def gzip_file(path, builder) - input_file = File.open(path, 'r').read - output_filename = path + '.gz' - input_file_time = File.mtime(path) + def self.gzip_file(path) + input_file = File.open(path, 'r').read + output_filename = path + '.gz' + input_file_time = File.mtime(path) - # Check if the right file's already there - if File.exist?(output_filename) && File.mtime(output_filename) == input_file_time - return - end - - File.open(output_filename, 'w') do |f| - gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION) - gz.mtime = input_file_time.to_i - gz.write input_file - gz.close - end - - # Make the file times match, both for Nginx's gzip_static extension - # and so we can ID existing files. Also, so even if the GZ files are - # wiped out by build --clean and recreated, we won't rsync them over - # again because they'll end up with the same mtime. - File.utime(File.atime(output_filename), input_file_time, output_filename) - - old_size = File.size(path) - new_size = File.size(output_filename) - - size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger' - - builder.say_status :gzip, "#{output_filename} (#{number_to_human_size((old_size - new_size).abs)} #{size_change_word})" + # Check if the right file's already there + if File.exist?(output_filename) && File.mtime(output_filename) == input_file_time + return end + + File.open(output_filename, 'w') do |f| + gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION) + gz.mtime = input_file_time.to_i + gz.write input_file + gz.close + end + + # Make the file times match, both for Nginx's gzip_static extension + # and so we can ID existing files. Also, so even if the GZ files are + # wiped out by build --clean and recreated, we won't rsync them over + # again because they'll end up with the same mtime. + File.utime(File.atime(output_filename), input_file_time, output_filename) + + old_size = File.size(path) + new_size = File.size(output_filename) + + [output_filename, old_size, new_size] end end end