Class: Middleman::SourceWatcher
- Inherits:
-
Object
- Object
- Middleman::SourceWatcher
- Extended by:
- Forwardable
- Includes:
- Contracts
- Defined in:
- middleman-core/lib/middleman-core/sources/source_watcher.rb
Overview
The default source watcher implementation. Watches a directory on disk and responds to events on changes.
Constant Summary collapse
- IGNORED_DIRECTORIES =
Set.new(%w[.git node_modules .sass-cache vendor/bundle .bundle])
Constants included from Contracts
Instance Attribute Summary collapse
-
#directory ⇒ Object
readonly
Returns the value of attribute directory.
-
#listener ⇒ Object
readonly
Reference to lower level listener.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Instance Method Summary collapse
-
#Any
Stop the listener.
- #exists?(path) ⇒ Boolean
- #files ⇒ Object
- #find(path, glob = false) ⇒ Object
- #find_new_files! ⇒ Object
-
#initialize(parent, type, directory, options_hash = ::Middleman::EMPTY_HASH) ⇒ SourceWatcher
constructor
A new instance of SourceWatcher.
- #listen! ⇒ Object
- #poll_once! ⇒ Object
- #stop_listener! ⇒ Object
-
#to_s ⇒ Object
(also: #inspect)
Work around this bug: http://bugs.ruby-lang.org/issues/4521 where Ruby will call to_s/inspect while printing exception messages, which can take a long time (minutes at full CPU) if the object is huge or has cyclic references, like this.
- #unwatch ⇒ Object
- #update_config(options_hash = ::Middleman::EMPTY_HASH) ⇒ Object
- #update_path(directory) ⇒ Object
Methods included from Contracts
Constructor Details
#initialize(parent, type, directory, options_hash = ::Middleman::EMPTY_HASH) ⇒ SourceWatcher
Returns a new instance of SourceWatcher.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 64 def initialize(parent, type, directory, = ::Middleman::EMPTY_HASH) @parent = parent @options = @type = type @directory = Pathname(directory) @files = {} @extensionless_files = {} @frontmatter = @options.fetch(:frontmatter, true) @binary = @options.fetch(:binary, false) @validator = @options.fetch(:validator, proc { true }) @ignored = @options.fetch(:ignored, proc { false }) @only = Array(@options.fetch(:only, [])) @disable_watcher = app.build? @force_polling = false @latency = nil @wait_for_delay = nil @listener = nil @callbacks = ::Middleman::CallbackManager.new @callbacks.install_methods!(self, [:on_change]) @waiting_for_existence = !@directory.exist? end |
Instance Attribute Details
#directory ⇒ Object (readonly)
Returns the value of attribute directory.
46 47 48 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 46 def directory @directory end |
#listener ⇒ Object (readonly)
Reference to lower level listener
53 54 55 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 53 def listener @listener end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
50 51 52 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 50 def @options end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
42 43 44 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 42 def type @type end |
Instance Method Details
#Any
This method returns an undefined value.
Stop the listener.
120 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 120 Contract Any |
#exists?(path) ⇒ Boolean
166 167 168 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 166 def exists?(path) !find(path).nil? end |
#files ⇒ Object
129 130 131 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 129 def files @files.values end |
#find(path, glob = false) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 139 def find(path, glob = false) path = path.to_s.encode('UTF-8', 'UTF-8-MAC') if RUBY_PLATFORM.match?(/darwin/) p = Pathname(path) return nil if p.absolute? && !p.to_s.start_with?(@directory.to_s) destination_dir = @options[:destination_dir] if !destination_dir.nil? && !destination_dir.empty? && p.to_s.start_with?(destination_dir) path_without_destination_dir = p.to_s[destination_dir.to_s.length + 1..-1] p = Pathname(path_without_destination_dir) end p = @directory + p if p.relative? if glob @extensionless_files[p] else @files[p] end end |
#find_new_files! ⇒ Object
205 206 207 208 209 210 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 205 def find_new_files! new_files = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?)) .reject { |p| @files.key?(p) } update(new_files, []).flatten.map { |s| s[:full_path] } end |
#listen! ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 174 def listen! return if @disable_watcher || @listener || @waiting_for_existence config = { force_polling: @force_polling } 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)) @listener.ignore(/^\.sass-cache/) @listener.ignore(/^node_modules/) @listener.ignore(%r{^vendor/bundle}) @listener.start end |
#poll_once! ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 216 def poll_once! updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?)) removed = @files.keys - updated result = update(updated, removed) if @waiting_for_existence && @directory.exist? @waiting_for_existence = false listen! end result.flatten.map { |s| s[:full_path] } end |
#stop_listener! ⇒ Object
197 198 199 200 201 202 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 197 def stop_listener! return unless @listener @listener.stop @listener = nil end |
#to_s ⇒ Object Also known as: inspect
Work around this bug: http://bugs.ruby-lang.org/issues/4521 where Ruby will call to_s/inspect while printing exception messages, which can take a long time (minutes at full CPU) if the object is huge or has cyclic references, like this.
234 235 236 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 234 def to_s "#<Middleman::SourceWatcher:0x#{object_id} type=#{@type.inspect} directory=#{@directory.inspect}>" end |
#unwatch ⇒ Object
121 122 123 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 121 def unwatch stop_listener! end |
#update_config(options_hash = ::Middleman::EMPTY_HASH) ⇒ Object
108 109 110 111 112 113 114 115 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 108 def update_config( = ::Middleman::EMPTY_HASH) without_listener_running do @disable_watcher = .fetch(:disable_watcher, false) @force_polling = .fetch(:force_polling, false) @latency = .fetch(:latency, nil) @wait_for_delay = .fetch(:wait_for_delay, nil) end end |
#update_path(directory) ⇒ Object
98 99 100 101 102 103 104 105 106 |
# File 'middleman-core/lib/middleman-core/sources/source_watcher.rb', line 98 def update_path(directory) @directory = Pathname(File.(directory, app.root)) without_listener_running do update([], @files.values.map { |source_file| source_file[:full_path] }) end poll_once! end |