Class: Middleman::SourceWatcher
- Inherits:
-
Object
- Object
- Middleman::SourceWatcher
- Extended by:
- Forwardable
- Includes:
- Contracts
- Defined in:
- 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 = {}) ⇒ 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_path(directory) ⇒ Object
Methods included from Contracts
Constructor Details
#initialize(parent, type, directory, options = {}) ⇒ SourceWatcher
Returns a new instance of SourceWatcher.
62 63 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 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 62 def initialize(parent, type, directory, ={}) @parent = parent @options = @type = type @directory = Pathname(directory) @files = {} @extensionless_files = {} @frontmatter = .fetch(:frontmatter, true) @binary = .fetch(:binary, false) @validator = .fetch(:validator, proc { true }) @ignored = .fetch(:ignored, proc { false }) @only = Array(.fetch(:only, [])) @disable_watcher = app.build? || @parent..fetch(:disable_watcher, false) @force_polling = @parent..fetch(:force_polling, false) @latency = @parent..fetch(:latency, 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.
44 45 46 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 44 def directory @directory end |
#listener ⇒ Object (readonly)
Reference to lower level listener
51 52 53 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 51 def listener @listener end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
48 49 50 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 48 def @options end |
#type ⇒ Object (readonly)
Returns the value of attribute type.
40 41 42 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 40 def type @type end |
Instance Method Details
#Any
This method returns an undefined value.
Stop the listener.
110 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 110 Contract Any |
#exists?(path) ⇒ Boolean
150 151 152 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 150 def exists?(path) !find(path).nil? end |
#files ⇒ Object
119 120 121 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 119 def files @files.values end |
#find(path, glob = false) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 129 def find(path, glob=false) path = path.to_s.encode!('UTF-8', 'UTF-8-MAC') if RUBY_PLATFORM =~ /darwin/ p = Pathname(path) return nil if p.absolute? && !p.to_s.start_with?(@directory.to_s) p = @directory + p if p.relative? if glob @extensionless_files[p] else @files[p] end end |
#find_new_files! ⇒ Object
189 190 191 192 193 194 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 189 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
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 158 def listen! return if @disable_watcher || @listener || @waiting_for_existence config = { force_polling: @force_polling, wait_for_delay: 0.5 } config[:latency] = @latency if @latency @listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change)) @listener.ignore(/^\.sass-cache/) @listener.ignore(/^node_modules/) @listener.ignore(/^vendor\/bundle/) @listener.start end |
#poll_once! ⇒ Object
200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 200 def poll_once! updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?)) removed = @files.keys.reject { |p| updated.include?(p) } 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
181 182 183 184 185 186 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 181 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.
218 219 220 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 218 def to_s "#<Middleman::SourceWatcher:0x#{object_id} type=#{@type.inspect} directory=#{@directory.inspect}>" end |
#unwatch ⇒ Object
111 112 113 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 111 def unwatch stop_listener! end |
#update_path(directory) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/middleman-core/sources/source_watcher.rb', line 95 def update_path(directory) @directory = Pathname(File.(directory, app.root)) stop_listener! if @listener update([], @files.values.map { |source_file| source_file[:full_path] }) poll_once! listen! unless @disable_watcher end |