rerun 0.7.0.pre3 → 0.7.0.pre4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: