Class: FileWatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/filewatcher.rb

Overview

Simple file watcher. Detect changes in files and directories.

Issues: Currently doesn’t monitor changes in directorynames

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(unexpanded_filenames, print_filelist = false) ⇒ FileWatcher

Returns a new instance of FileWatcher.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/filewatcher.rb', line 10

def initialize(unexpanded_filenames, print_filelist=false)
  @unexpanded_filenames = unexpanded_filenames
  @last_mtimes = { }
  @filenames = expand_directories(@unexpanded_filenames)

  puts "Watching:" if print_filelist
  @filenames.each do |filename|
    raise "File does not exist" unless File.exist?(filename)
    @last_mtimes[filename] = File.stat(filename).mtime
    puts filename if print_filelist
  end
end

Class Method Details

.VERSIONObject



6
7
8
# File 'lib/filewatcher.rb', line 6

def self.VERSION
  return "0.3.4"
end

Instance Method Details

#expand_directories(patterns) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/filewatcher.rb', line 76

def expand_directories(patterns)
  if(!patterns.kind_of?Array)
    patterns = [patterns]
  end
  filenames = []
  patterns.each do |filename|
    if(File.directory?(filename))
      filenames = filenames + find(filename)
    else
      filenames = filenames + find(".", filename, true)
    end
  end

  return filenames.uniq
end

#filesystem_updated?Boolean

Returns:

  • (Boolean)


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/filewatcher.rb', line 34

def filesystem_updated?
  filenames = expand_directories(@unexpanded_filenames)

  if(filenames.size > @filenames.size)
    filename = (filenames - @filenames).first
    @filenames << filename
    @last_mtimes[filename] = File.stat(filename).mtime
    @updated_file = filename
    @event = :new
    return true
  end

  if(filenames.size < @filenames.size)
    filename = (@filenames - filenames).first
    @filenames.delete(filename)
    @last_mtimes.delete(filename)
    @updated_file = filename
    @event = :delete
    return true
  end

  @filenames.each do |filename|
    if(not(File.exists?(filename)))
      @filenames.delete(filename)
      @last_mtimes.delete(filename)
      @updated_file = filename
      @event = :delete
      return true
    end
    mtime = File.stat(filename).mtime
    updated = @last_mtimes[filename] < mtime
    @last_mtimes[filename] = mtime
    if(updated)
      @updated_file = filename
      @event = :changed
      return true
    end
  end

  return false
end

#find(dir, filename = "*.*", subdirs = true) ⇒ Object



92
93
94
# File 'lib/filewatcher.rb', line 92

def find(dir, filename="*.*", subdirs=true)
  Dir[ subdirs ? File.join(dir.split(/\\/), "**", filename) : File.join(dir.split(/\\/), filename) ]
end

#watch(sleep = 1, &on_update) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/filewatcher.rb', line 23

def watch(sleep=1, &on_update)
  loop do
    begin
      Kernel.sleep sleep until filesystem_updated?
    rescue SystemExit,Interrupt
      Kernel.exit
    end
    yield @updated_file, @event
  end
end