From 604c0e2b5d2c17a4fee85f8fd80d62cacd1f1652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kla=C4=8Dan?= Date: Mon, 31 Oct 2016 18:50:03 +0100 Subject: [PATCH] Fix source watcher configuration (#1999) * Fix source watcher configuration * Keep old Sources#initialize signature * Poll source on path change --- .../lib/middleman-core/application.rb | 1 + .../core_extensions/file_watcher.rb | 12 ++++-- middleman-core/lib/middleman-core/sources.rb | 6 +-- .../middleman-core/sources/source_watcher.rb | 41 +++++++++++++++---- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index fb1ab93f..52b31c92 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -203,6 +203,7 @@ module Middleman define_setting :watcher_disable, false, 'If the Listen watcher should not run' define_setting :watcher_force_polling, false, 'If the Listen watcher should run in polling mode' define_setting :watcher_latency, nil, 'The Listen watcher latency' + define_setting :watcher_wait_for_delay, 0.5, 'The Listen watcher delay between calls when changes exist' # Delegate convenience methods off to their implementations def_delegator :"::Middleman::Logger", :singleton, :logger 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 82df8f73..6fd16ae9 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -28,10 +28,7 @@ module Middleman super # Setup source collection. - @sources = ::Middleman::Sources.new(app, - disable_watcher: app.config[:watcher_disable], - force_polling: app.config[:watcher_force_polling], - latency: app.config[:watcher_latency]) + @sources = ::Middleman::Sources.new(app) # Add default ignores. IGNORES.each do |key, value| @@ -55,6 +52,13 @@ module Middleman # @return [void] Contract Any def after_configuration + @watcher.update_config( + disable_watcher: app.config[:watcher_disable], + force_polling: app.config[:watcher_force_polling], + latency: app.config[:watcher_latency], + wait_for_delay: app.config[:watcher_wait_for_delay] + ) + if @original_source_dir != app.config[:source] @watcher.update_path(app.config[:source]) end diff --git a/middleman-core/lib/middleman-core/sources.rb b/middleman-core/lib/middleman-core/sources.rb index d2f64a40..ced46227 100644 --- a/middleman-core/lib/middleman-core/sources.rb +++ b/middleman-core/lib/middleman-core/sources.rb @@ -56,15 +56,13 @@ module Middleman # @param [Hash] options Global options. # @param [Array] watchers Default watchers. Contract IsA['Middleman::Application'], Maybe[Hash], Maybe[Array] => Any - def initialize(app, options={}, watchers=[]) + def initialize(app, _options={}, watchers=[]) @app = app @watchers = watchers @sorted_watchers = @watchers.dup.freeze ::Middleman::Sources.file_cache = {} - @options = options - # Set of procs wanting to be notified of changes @on_change_callbacks = ::Hamster::Vector.empty @@ -172,7 +170,7 @@ module Middleman # @return [Middleman::Sources] Contract Symbol => ::Middleman::Sources def by_type(type) - self.class.new @app, @options, watchers.select { |d| d.type == type } + self.class.new @app, nil, watchers.select { |d| d.type == type } end # Get all files for this collection of watchers. diff --git a/middleman-core/lib/middleman-core/sources/source_watcher.rb b/middleman-core/lib/middleman-core/sources/source_watcher.rb index 88d75f3f..8e3a3550 100644 --- a/middleman-core/lib/middleman-core/sources/source_watcher.rb +++ b/middleman-core/lib/middleman-core/sources/source_watcher.rb @@ -75,9 +75,10 @@ module Middleman @ignored = options.fetch(:ignored, proc { false }) @only = Array(options.fetch(:only, [])) - @disable_watcher = app.build? || @parent.options.fetch(:disable_watcher, false) - @force_polling = @parent.options.fetch(:force_polling, false) - @latency = @parent.options.fetch(:latency, nil) + @disable_watcher = app.build? + @force_polling = false + @latency = nil + @wait_for_delay = nil @listener = nil @@ -95,13 +96,20 @@ module Middleman def update_path(directory) @directory = Pathname(File.expand_path(directory, app.root)) - stop_listener! if @listener - - update([], @files.values.map { |source_file| source_file[:full_path] }) + without_listener_running do + update([], @files.values.map { |source_file| source_file[:full_path] }) + end poll_once! + end - listen! unless @disable_watcher + def update_config(options={}) + without_listener_running do + @disable_watcher = options.fetch(:disable_watcher, false) + @force_polling = options.fetch(:force_polling, false) + @latency = options.fetch(:latency, nil) + @wait_for_delay = options.fetch(:wait_for_delay, nil) + end end # Stop watching. @@ -160,10 +168,10 @@ module Middleman config = { force_polling: @force_polling, - wait_for_delay: 0.5 } - config[:latency] = @latency.to_i if @latency + config[:wait_for_delay] = @wait_for_delay.try(:to_f) || 0.5 + config[:latency] = @latency.to_f if @latency @listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change)) @@ -343,5 +351,20 @@ module Middleman @only.any? { |reg| file[:relative_path].to_s =~ reg } end end + + private + + def without_listener_running + listener_running = @listener && @listener.processing? + + stop_listener! if listener_running + + yield + + if listener_running + poll_once! + listen! + end + end end end