rerun 0.7.0.pre3 → 0.7.0.pre4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/rerun/watcher.rb +19 -128
  2. data/rerun.gemspec +1 -1
  3. metadata +2 -2
data/lib/rerun/watcher.rb CHANGED
@@ -5,14 +5,13 @@ Thread.abort_on_exception = true
5
5
  # This class will watch a directory and alert you of
6
6
  # new files, modified files, deleted files.
7
7
  #
8
- # Author: Paul Horman, http://paulhorman.com/filesystemwatcher/
8
+ # Now uses the Listen gem, but spawns its own thread on top.
9
+ # We should probably be accessing the Listen thread directly.
10
+ #
9
11
  # Author: Alex Chaffee
12
+ #
10
13
  module Rerun
11
14
  class Watcher
12
- CREATED = 0
13
- MODIFIED = 1
14
- DELETED = 2
15
-
16
15
  attr_reader :directory, :pattern, :priority
17
16
 
18
17
  # Create a file system watcher. Start it by calling #start.
@@ -32,47 +31,33 @@ module Rerun
32
31
 
33
32
  @pattern = options[:pattern]
34
33
  @directory = options[:directory]
35
- if FileTest.exists?(directory) && FileTest.readable?(directory) then
36
- @directory = Directory.new(directory, @pattern)
37
- else
38
- raise InvalidDirectoryError, "Dir '#{directory}' either doesnt exist or isnt readable"
34
+ @directory.chomp!("/")
35
+ unless FileTest.exists?(@directory) && FileTest.readable?(@directory)
36
+ raise InvalidDirectoryError, "Directory '#{@directory}' either doesnt exist or isnt readable"
39
37
  end
40
38
  @priority = options[:priority]
41
-
42
- @found = nil
43
- @first_time = true
44
39
  @thread = nil
45
40
  end
46
41
 
47
- def prime
48
- @first_time = true
49
- @found = {}
50
- examine
51
- @first_time = false
52
- end
53
-
54
42
  def start
55
43
  if @thread then
56
44
  raise RuntimeError, "already started"
57
45
  end
58
46
 
59
- prime
60
-
61
47
  @thread = Thread.new do
62
48
  # todo: multiple dirs
63
49
 
64
50
  regexp = Glob.new(@pattern).to_regexp
65
- @listener = Listen::Listener.new(@directory.dir, :filter => regexp) do |modified, added, removed|
66
- #d { modified }
67
- #d { added }
68
- #d { removed }
69
- examine
51
+ @listener = Listen::Listener.new(@directory, :filter => regexp) do |modified, added, removed|
52
+ @client_callback.call(:modified => modified, :added => added, :removed => removed)
70
53
  end
71
54
  @listener.start
72
55
  end
73
56
 
74
57
  @thread.priority = @priority
75
58
 
59
+ sleep 0.1 until @listener
60
+
76
61
  at_exit { stop } # try really hard to clean up after ourselves
77
62
  end
78
63
 
@@ -83,116 +68,22 @@ module Rerun
83
68
  end
84
69
  end
85
70
 
86
- # kill the filewatcher thread
71
+ # kill the file watcher thread
87
72
  def stop
73
+ @thread.wakeup rescue ThreadError
88
74
  begin
89
- @thread.wakeup
90
- rescue ThreadError => e
91
- # ignore
92
- end
93
- begin
94
- @thread.kill
95
- rescue ThreadError => e
96
- # ignore
75
+ @listener.stop
76
+ rescue Exception => e
77
+ puts "#{e.class}: #{e.message} stopping listener"
97
78
  end
79
+ @thread.kill rescue ThreadError
98
80
  end
99
81
 
100
- # wait for the filewatcher to finish
82
+ # wait for the file watcher to finish
101
83
  def join
102
- @thread.join() if @thread
84
+ @thread.join if @thread
103
85
  rescue Interrupt => e
104
86
  # don't care
105
87
  end
106
-
107
- private
108
-
109
- def examine
110
-
111
- already_examined = Hash.new()
112
-
113
- examine_files(@directory.files, already_examined)
114
-
115
- # now diff the found files and the examined files to see if
116
- # something has been deleted
117
- all_found_files = @found.keys()
118
- all_examined_files = already_examined.keys()
119
- intersection = all_found_files - all_examined_files
120
-
121
- intersection.each do |file_name|
122
- @client_callback.call(DELETED, file_name)
123
- @found.delete(file_name)
124
- end
125
-
126
- end
127
-
128
- # loops over the file list check for new or modified files
129
- def examine_files(files, already_examined)
130
- files.each do |file_name|
131
- # expand the file name to the fully qual path
132
- full_file_name = File.expand_path(file_name)
133
-
134
- # we cant do much if the file isnt readable anyway
135
- if File.readable?(full_file_name) then
136
- already_examined[full_file_name] = true
137
- stat = File.stat(full_file_name)
138
- mod_time = stat.mtime
139
- size = stat.size
140
-
141
- # on the first iteration just load all of the files into the foundList
142
- if @first_time then
143
- @found[full_file_name] = FoundFile.new(full_file_name, mod_time, size)
144
- else
145
- # see if we have found this file already
146
- found_file = @found[full_file_name]
147
- @found[full_file_name] = FoundFile.new(full_file_name, mod_time, size)
148
-
149
- if found_file
150
- if mod_time > found_file.mod_time || size != found_file.size then
151
- @client_callback.call(MODIFIED, full_file_name)
152
- end
153
- else
154
- @client_callback.call(CREATED, full_file_name)
155
- end
156
- end
157
- end
158
- end
159
- end
160
-
161
- class Directory
162
- attr_reader :dir, :expression
163
-
164
- def initialize(dir, expression)
165
- @dir, @expression = dir, expression
166
- @dir.chop! if @dir =~ %r{/$}
167
- end
168
-
169
- def files
170
- return Dir["#{@dir}/#{@expression}"]
171
- end
172
- end
173
-
174
- class FoundFile
175
- attr_reader :status, :file_name, :mod_time, :size
176
-
177
- def initialize(file_name, mod_time, size)
178
- @file_name, @mod_time, @size = file_name, mod_time, size
179
- end
180
-
181
- def modified(mod_time)
182
- @mod_time = mod_time
183
- end
184
-
185
- def to_s
186
- "FoundFile[file_name=#{file_name}, mod_time=#{mod_time.to_i}, size=#{size}]"
187
- end
188
- end
189
-
190
- # if the directory you want to watch doesnt exist or isn't readable this is thrown
191
- class InvalidDirectoryError < StandardError;
192
- end
193
-
194
- # if the file you want to watch doesnt exist or isn't readable this is thrown
195
- class InvalidFileError < StandardError;
196
- end
197
88
  end
198
89
  end
data/rerun.gemspec CHANGED
@@ -3,7 +3,7 @@ $spec = Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'rerun'
6
- s.version = '0.7.0.pre3'
6
+ s.version = '0.7.0.pre4'
7
7
 
8
8
  s.description = "Restarts your app when a file changes"
9
9
  s.summary = "Launches an app, and restarts it whenever the filesystem changes."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rerun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.pre3
4
+ version: 0.7.0.pre4
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -61,7 +61,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
61
  version: '0'
62
62
  segments:
63
63
  - 0
64
- hash: 3232457078342945302
64
+ hash: -2239978270420892770
65
65
  required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  none: false
67
67
  requirements: