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.1"
end

Instance Method Details

#expand_directories(filenames) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/filewatcher.rb', line 69

def expand_directories(filenames)
  if(filenames.kind_of?String)
    filenames = [filenames]
  end
  files = []
  filenames.each do |filename|
    if(File.directory?(filename))
      files = files + find(filename)
    end
    if(File.file?(filename))
      files << filename
    end
  end
  filenames = files
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
# 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|
    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



85
86
87
# File 'lib/filewatcher.rb', line 85

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