From 67689e60d24677ac3c38678df3abc287dc2ac341 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 18 Mar 2014 21:17:50 -0700 Subject: [PATCH] Prevent the file watcher from recursively enumerating into paths that it should ignore. This should fix the issue in #1197 as well as provide a performance boost when starting 'middleman server'. --- .../core_extensions/file_watcher.rb | 21 ++++++----- .../lib/middleman-core/preview_server.rb | 2 ++ middleman-core/lib/middleman-core/util.rb | 36 +++++++++++-------- 3 files changed, 33 insertions(+), 26 deletions(-) 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 fbe39c1f..14cac4ae 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -7,12 +7,12 @@ module Middleman module FileWatcher IGNORE_LIST = [ - /^bin\//, - /^\.bundle\//, - /^vendor\//, - /^\.sass-cache\//, - /^\.cache\//, - /^\.git\//, + /^bin(\/|$)/, + /^\.bundle(\/|$)/, + /^vendor(\/|$)/, + /^\.sass-cache(\/|$)/, + /^\.cache(\/|$)/, + /^\.git(\/|$)/, /^\.gitignore$/, /\.DS_Store/, /^\.rbenv-.*$/, @@ -38,7 +38,7 @@ module Middleman end app.after_configuration do - config[:file_watcher_ignore] << %r{^#{config[:build_dir]}\/} + config[:file_watcher_ignore] << %r{^#{config[:build_dir]}(\/|$)} end # After config, load everything else @@ -99,7 +99,6 @@ module Middleman # @return [void] def did_change(path) path = Pathname(path) - return if ignored?(path) logger.debug "== File Change: #{path}" @known_paths << path self.run_callbacks(path, :changed) @@ -111,7 +110,6 @@ module Middleman # @return [void] def did_delete(path) path = Pathname(path) - return if ignored?(path) logger.debug "== File Deletion: #{path}" @known_paths.delete(path) self.run_callbacks(path, :deleted) @@ -131,7 +129,7 @@ module Middleman glob = (path + '**').to_s subset = @known_paths.select { |p| p.fnmatch(glob) } - ::Middleman::Util.all_files_under(path).each do |filepath| + ::Middleman::Util.all_files_under(path, &method(:ignored?)).each do |filepath| next if only_new && subset.include?(filepath) subset.delete(filepath) @@ -156,7 +154,6 @@ module Middleman @known_paths.include?(p) end - protected # Whether this path is ignored # @param [Pathname] path # @return [Boolean] @@ -165,6 +162,8 @@ module Middleman app.config[:file_watcher_ignore].any? { |r| path =~ r } end + protected + # Notify callbacks for a file given an array of callbacks # # @param [Pathname] path The file that was changed diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 0fceb8ea..9ce1248b 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -133,10 +133,12 @@ module Middleman @webrick.stop else added_and_modified.each do |path| + next if app.files.ignored?(path) app.files.did_change(path) end removed.each do |path| + next if app.files.ignored?(path) app.files.did_delete(path) end end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 02892775..102b51e7 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -28,7 +28,7 @@ module Middleman return false if Tilt.registered?(ext.sub('.', '')) dot_ext = (ext.to_s[0] == ?.) ? ext.dup : ".#{ext}" - + if mime = ::Rack::Mime.mime_type(dot_ext, nil) !nonbinary_mime?(mime) else @@ -113,21 +113,27 @@ module Middleman end end - # Get a recusive list of files inside a set of paths. + # Get a recusive list of files inside a path. # Works with symlinks. # - # @param paths Some paths string or Pathname - # @return [Array] An array of filenames - def all_files_under(*paths) - paths.flat_map do |p| - path = Pathname(p) + # @param path Some path string or Pathname + # @param ignore A proc/block that returns true if a given path should be ignored - if a path + # is ignored, nothing below it will be searched either. + # @return [Array] An array of Pathnames for each file (no directories) + def all_files_under(path, &ignore) + path = Pathname(path) - if path.directory? - all_files_under(*path.children) - elsif path.file? - path - end - end.compact + return [] if ignore && ignore.call(path) + + if path.directory? + path.children.flat_map do |child| + all_files_under(child, &ignore) + end.compact + elsif path.file? + [path] + else + [] + end end # Given a source path (referenced either absolutely or relatively) @@ -248,7 +254,7 @@ module Middleman s.each_byte do |c| return true if binary_bytes.include?(c) end - + false end @@ -278,4 +284,4 @@ module Middleman end end end -end \ No newline at end of file +end