class Filewatcher
Simple file watcher. Detect changes in files and directories.
Issues: Currently doesn't monitor changes in directorynames
Constants
- VERSION
Attributes
interval[RW]
keep_watching[R]
Public Class Methods
new(unexpanded_filenames, options = {})
click to toggle source
# File lib/filewatcher.rb, line 20 def initialize(unexpanded_filenames, options = {}) @unexpanded_filenames = unexpanded_filenames @unexpanded_excluded_filenames = options[:exclude] @keep_watching = false @pausing = false @immediate = options[:immediate] @show_spinner = options[:spinner] @interval = options.fetch(:interval, 0.5) @every = options[:every] end
Public Instance Methods
finalize(&on_update)
click to toggle source
Calls the update block repeatedly until all changes in the current snapshot are dealt with
# File lib/filewatcher.rb, line 75 def finalize(&on_update) on_update = @on_update unless block_given? while filesystem_updated?(@end_snapshot || mtime_snapshot) update_spinner('Finalizing') trigger_changes(on_update) end @end_snapshot = nil end
last_found_filenames()
click to toggle source
# File lib/filewatcher.rb, line 84 def last_found_filenames last_snapshot.keys end
pause()
click to toggle source
# File lib/filewatcher.rb, line 48 def pause @pausing = true update_spinner('Initiating pause') # Ensure we wait long enough to enter pause loop in #watch sleep @interval end
resume()
click to toggle source
# File lib/filewatcher.rb, line 55 def resume if !@keep_watching || !@pausing raise "Can't resume unless #watch and #pause were first called" end @last_snapshot = mtime_snapshot # resume with fresh snapshot @pausing = false update_spinner('Resuming') sleep @interval # Wait long enough to exit pause loop in #watch end
stop()
click to toggle source
Ends the watch, allowing any remaining changes to be finalized. Used mainly in multi-threaded situations.
# File lib/filewatcher.rb, line 67 def stop @keep_watching = false update_spinner('Stopping') nil end
update_spinner(label)
click to toggle source
# File lib/filewatcher.rb, line 14 def update_spinner(label) return unless @show_spinner @spinner ||= %w[\\ | / -] print "#{' ' * 30}\r#{label} #{@spinner.rotate!.first}\r" end
watch() { |'', ''| ... }
click to toggle source
# File lib/filewatcher.rb, line 31 def watch(&on_update) ## The set of available signals depends on the OS ## Windows doesn't support `HUP` signal, for example (%w[HUP INT TERM] & Signal.list.keys).each do |signal| trap(signal) { exit } end @on_update = on_update @keep_watching = true yield('', '') if @immediate main_cycle @end_snapshot = mtime_snapshot finalize(&on_update) end
Private Instance Methods
expand_directories(patterns)
click to toggle source
# File lib/filewatcher.rb, line 125 def expand_directories(patterns) patterns = Array(patterns) unless patterns.is_a? Array expanded_patterns = patterns.map do |pattern| pattern = File.expand_path(pattern) Dir[ File.directory?(pattern) ? File.join(pattern, '**', '*') : pattern ] end expanded_patterns.flatten! expanded_patterns.uniq! expanded_patterns end
filesystem_updated?(snapshot = mtime_snapshot)
click to toggle source
# File lib/filewatcher.rb, line 110 def filesystem_updated?(snapshot = mtime_snapshot) @changes = {} (snapshot.to_a - last_snapshot.to_a).each do |file, _mtime| @changes[file] = last_snapshot[file] ? :updated : :created end (last_snapshot.keys - snapshot.keys).each do |file| @changes[file] = :deleted end @last_snapshot = snapshot @changes.any? end
last_snapshot()
click to toggle source
# File lib/filewatcher.rb, line 90 def last_snapshot @last_snapshot ||= mtime_snapshot end
mtime_snapshot()
click to toggle source
Takes a snapshot of the current status of watched files. (Allows avoidance of potential race condition during finalize
)
# File lib/filewatcher.rb, line 96 def mtime_snapshot snapshot = {} filenames = expand_directories(@unexpanded_filenames) # Remove files in the exclude filenames list filenames -= expand_directories(@unexpanded_excluded_filenames) filenames.each do |filename| mtime = File.exist?(filename) ? File.mtime(filename) : Time.new(0) snapshot[filename] = mtime end snapshot end