smparkes-watchr 0.5.7.4 → 0.5.7.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +8 -6
- data/bin/watchr +2 -0
- data/lib/watchr.rb +0 -3
- data/lib/watchr/controller.rb +12 -3
- data/lib/watchr/event_handlers/em.rb +47 -13
- data/lib/watchr/script.rb +59 -6
- data/watchr.gemspec +1 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -62,7 +62,7 @@ while looking at file paths: only directories will get watches put on
|
|
62
62
|
them. (Otherwise <tt>%r(.*)</tt> would put watches on every
|
63
63
|
file/directory in the tree, which seems kinda bad.)
|
64
64
|
|
65
|
-
The second watch looks for
|
65
|
+
The second watch looks for Haml files in my public directory and
|
66
66
|
automatically converts them to HTML. These are static files, not
|
67
67
|
served by an app server like Rails: even with static files, I hate
|
68
68
|
writing raw HTML. The extension here is that instead of a single event
|
@@ -78,11 +78,13 @@ interested). This case is similar to the previous but also adds the
|
|
78
78
|
seen after watchr starts. This allows watchr to run all the specs when
|
79
79
|
first started, similar to what autotest does.
|
80
80
|
|
81
|
-
===
|
81
|
+
=== Recent Changes
|
82
|
+
|
83
|
+
1. POC for batch events that occur within a time window
|
82
84
|
|
83
|
-
1.
|
85
|
+
1. Pass event type to callbacks
|
84
86
|
|
85
|
-
|
87
|
+
=== Things to do
|
86
88
|
|
87
89
|
1. Integrate upstream (if they want it)
|
88
90
|
|
@@ -90,6 +92,6 @@ first started, similar to what autotest does.
|
|
90
92
|
|
91
93
|
1. Handle user interrupt processing more systematically
|
92
94
|
|
93
|
-
1.
|
95
|
+
1. Don't swallow config file error messages, particularly on reload. Is this still happening?
|
94
96
|
|
95
|
-
1.
|
97
|
+
1. Implement some kind of dependence detection (probably starting to get into plugin territory)
|
data/bin/watchr
CHANGED
data/lib/watchr.rb
CHANGED
data/lib/watchr/controller.rb
CHANGED
@@ -28,7 +28,7 @@ module Watchr
|
|
28
28
|
end
|
29
29
|
@handler
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
# Creates a controller object around given <tt>script</tt>
|
33
33
|
#
|
34
34
|
# ===== Parameters
|
@@ -83,11 +83,20 @@ module Watchr
|
|
83
83
|
#
|
84
84
|
def monitored_paths
|
85
85
|
paths = Dir['**/*'].select do |path|
|
86
|
-
|
86
|
+
watch = false
|
87
|
+
@script.rules.reverse.each do |r|
|
88
|
+
rule_watches = r.watch(path)
|
89
|
+
if false
|
90
|
+
$stderr.print "watch ", path, " ", rule_watches, "\n"
|
91
|
+
end
|
92
|
+
next if rule_watches.nil?
|
93
|
+
watch = rule_watches
|
94
|
+
break
|
95
|
+
end
|
96
|
+
watch
|
87
97
|
end
|
88
98
|
paths.push(@script.path).compact!
|
89
99
|
paths.map {|path| Pathname(path).expand_path }
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
93
|
-
|
@@ -27,8 +27,9 @@ module Watchr
|
|
27
27
|
|
28
28
|
def init first_time
|
29
29
|
# p "w", path, first_time,(first_time ? :load : :created)
|
30
|
+
# $stderr.puts "#{signature}: #{pathname}"
|
30
31
|
update_reference_times
|
31
|
-
SingleFileWatcher.handler.notify(
|
32
|
+
SingleFileWatcher.handler.notify(pathname, (first_time ? :load : :created) )
|
32
33
|
end
|
33
34
|
|
34
35
|
# File's path as a Pathname
|
@@ -37,23 +38,45 @@ module Watchr
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def file_modified
|
40
|
-
|
41
|
+
# p "mod", pathname, type
|
42
|
+
SingleFileWatcher.handler.notify(pathname, type)
|
41
43
|
update_reference_times
|
42
44
|
end
|
43
45
|
|
44
46
|
def file_moved
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
# p "mov", pathname
|
48
|
+
SingleFileWatcher.handler.forget self, pathname
|
49
|
+
begin
|
50
|
+
# $stderr.puts "stop.fm #{signature}: #{pathname}"
|
51
|
+
stop_watching
|
52
|
+
rescue Exception => e
|
53
|
+
$stderr.puts "exception while attempting to stop_watching in file_moved: #{e}"
|
54
|
+
end
|
55
|
+
SingleFileWatcher.handler.notify(pathname, type)
|
48
56
|
end
|
49
57
|
|
50
58
|
def file_deleted
|
51
|
-
|
52
|
-
|
59
|
+
# p "del", pathname
|
60
|
+
# $stderr.puts "stop.fd #{signature}: #{pathname} #{type}"
|
61
|
+
SingleFileWatcher.handler.forget self, pathname
|
62
|
+
SingleFileWatcher.handler.notify(pathname, :deleted)
|
63
|
+
if type == :modified
|
64
|
+
# There's a race condition here ... the directory should have gotten mod'ed, but we'll get the
|
65
|
+
# delete after the directory scan, so we won't watch the new file. This isn't the cleanest way to
|
66
|
+
# handle this, but should work for now ...
|
67
|
+
SingleFileWatcher.handler.watch pathname
|
68
|
+
else
|
69
|
+
end
|
53
70
|
end
|
54
71
|
|
55
72
|
def stop
|
56
|
-
|
73
|
+
# p "stop", pathname
|
74
|
+
begin
|
75
|
+
# $stderr.puts "stop.s #{signature}: #{pathname}"
|
76
|
+
stop_watching
|
77
|
+
rescue Exception => e
|
78
|
+
$stderr.puts "exception while attempting to stop_watching in stop: #{e}"
|
79
|
+
end
|
57
80
|
end
|
58
81
|
|
59
82
|
private
|
@@ -122,12 +145,25 @@ module Watchr
|
|
122
145
|
"warning: no/wrong watcher to forget for #{path}: #{@watchers[path]} vs #{connection}"
|
123
146
|
end
|
124
147
|
@watchers.delete path
|
148
|
+
raise "hell: #{path}" if !@old_paths.include? Pathname(path)
|
149
|
+
@old_paths.delete Pathname(path)
|
125
150
|
end
|
126
151
|
|
152
|
+
def watch path
|
153
|
+
begin
|
154
|
+
::EM.watch_file path.to_s, SingleFileWatcher do |watcher|
|
155
|
+
watcher.init @first_time
|
156
|
+
@watchers[path] = watcher
|
157
|
+
end
|
158
|
+
@old_paths << path
|
159
|
+
rescue Errno::ENOENT; end
|
160
|
+
end
|
161
|
+
|
127
162
|
private
|
128
163
|
|
129
164
|
# Binds all <tt>monitored_paths</tt> to the listening loop.
|
130
165
|
def attach
|
166
|
+
# p "scan"
|
131
167
|
@monitored_paths = @monitored_paths.uniq
|
132
168
|
new_paths = @monitored_paths - @old_paths
|
133
169
|
remove_paths = @old_paths - @monitored_paths
|
@@ -138,12 +174,9 @@ module Watchr
|
|
138
174
|
new_paths.each do |path|
|
139
175
|
if @watchers[path]
|
140
176
|
$stderr.puts "warning: replacing (ignoring) watcher for #{path}"
|
141
|
-
|
142
|
-
end
|
143
|
-
::EM.watch_file path.to_s, SingleFileWatcher do |watcher|
|
144
|
-
watcher.init @first_time
|
145
|
-
@watchers[path] = watcher
|
177
|
+
@watchers[path].stop
|
146
178
|
end
|
179
|
+
watch path
|
147
180
|
end
|
148
181
|
remove_paths.each do |path|
|
149
182
|
watcher = @watchers[path]
|
@@ -159,5 +192,6 @@ module Watchr
|
|
159
192
|
@loop.watchers.each {|watcher| watcher.detach }
|
160
193
|
end
|
161
194
|
end
|
195
|
+
|
162
196
|
end
|
163
197
|
end
|
data/lib/watchr/script.rb
CHANGED
@@ -10,6 +10,31 @@ module Watchr
|
|
10
10
|
class Script
|
11
11
|
DEFAULT_EVENT_TYPE = :modified
|
12
12
|
|
13
|
+
class Batch
|
14
|
+
def initialize rule
|
15
|
+
@timer = nil
|
16
|
+
@rule = rule
|
17
|
+
@events = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def call data, event
|
21
|
+
if @timer
|
22
|
+
@timer.cancel
|
23
|
+
end
|
24
|
+
@timer = EM::Timer.new(0.001) do
|
25
|
+
deliver
|
26
|
+
end
|
27
|
+
@events << [ data, event ]
|
28
|
+
end
|
29
|
+
|
30
|
+
def deliver
|
31
|
+
events = @events
|
32
|
+
@timer = nil
|
33
|
+
@events = []
|
34
|
+
@rule.action.call [events]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
13
38
|
# Convenience type. Provides clearer and simpler access to rule properties.
|
14
39
|
#
|
15
40
|
# ===== Examples
|
@@ -18,15 +43,38 @@ module Watchr
|
|
18
43
|
# rule.pattern #=> 'lib/.*\.rb'
|
19
44
|
# rule.action.call #=> 'ohaie'
|
20
45
|
#
|
21
|
-
Rule = Struct.new(:pattern, :event_types, :predicate, :action)
|
46
|
+
Rule = Struct.new(:pattern, :event_types, :predicate, :options, :action, :batch)
|
22
47
|
|
23
48
|
class Rule
|
49
|
+
|
50
|
+
def call data, event
|
51
|
+
if options[:batch]
|
52
|
+
self.batch ||= Batch.new self
|
53
|
+
batch.call data, event
|
54
|
+
else
|
55
|
+
action.call data, event
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def watch path
|
60
|
+
watch = nil
|
61
|
+
pattern = self.pattern
|
62
|
+
( pattern.class == String ) and ( pattern = Regexp.new pattern )
|
63
|
+
md = pattern.match(path)
|
64
|
+
if md
|
65
|
+
watch = self.predicate.nil? || self.predicate.call(md)
|
66
|
+
end
|
67
|
+
return watch
|
68
|
+
end
|
69
|
+
|
24
70
|
def match path
|
25
71
|
pattern = self.pattern
|
26
72
|
( pattern.class == String ) and ( pattern = Regexp.new pattern )
|
73
|
+
# p path, pattern, pattern.match(path)
|
27
74
|
( md = pattern.match(path) ) &&
|
28
75
|
( self.predicate == nil || self.predicate.call(md) )
|
29
76
|
end
|
77
|
+
|
30
78
|
end
|
31
79
|
|
32
80
|
# TODO eval context
|
@@ -87,9 +135,9 @@ module Watchr
|
|
87
135
|
# ===== Returns
|
88
136
|
# rule<Rule>:: rule created by the method
|
89
137
|
#
|
90
|
-
def watch(pattern, event_type = DEFAULT_EVENT_TYPE, predicate
|
138
|
+
def watch(pattern, event_type = DEFAULT_EVENT_TYPE, predicate = nil, options = {}, &action)
|
91
139
|
event_types = Array(event_type)
|
92
|
-
@rules << Rule.new(pattern, event_types, predicate, action || @default_action)
|
140
|
+
@rules << Rule.new(pattern, event_types, predicate, options, action || @default_action)
|
93
141
|
@rules.last
|
94
142
|
end
|
95
143
|
|
@@ -137,8 +185,8 @@ module Watchr
|
|
137
185
|
(1..10).each do
|
138
186
|
old_v = v
|
139
187
|
v = @path.read
|
140
|
-
break if v && v == old_v
|
141
|
-
sleep(0.
|
188
|
+
break if v != "" && v == old_v
|
189
|
+
sleep(0.3)
|
142
190
|
end
|
143
191
|
|
144
192
|
instance_eval(@path.read)
|
@@ -173,7 +221,7 @@ module Watchr
|
|
173
221
|
types.each do |rule_event_type|
|
174
222
|
if ( rule_event_type.nil? && ( event_type != :load ) ) || ( rule_event_type == event_type )
|
175
223
|
data = path.match(rule.pattern)
|
176
|
-
return rule.
|
224
|
+
return rule.call(data, event_type)
|
177
225
|
end
|
178
226
|
end
|
179
227
|
end
|
@@ -215,6 +263,11 @@ module Watchr
|
|
215
263
|
# rules<Array(Rule)>:: rules corresponding to <tt>path</tt>
|
216
264
|
#
|
217
265
|
def rules_for(path)
|
266
|
+
@rules.reverse.select do |rule|
|
267
|
+
# p "K", path, rule.pattern, path.match(rule.pattern)
|
268
|
+
path.match(rule.pattern)
|
269
|
+
end
|
270
|
+
# p "KK", path, @rules.reverse.select {|rule| path.match(rule.pattern) }
|
218
271
|
@rules.reverse.select {|rule| path.match(rule.pattern) }
|
219
272
|
end
|
220
273
|
|
data/watchr.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'smparkes-watchr'
|
4
|
-
s.version = '0.5.7.
|
4
|
+
s.version = '0.5.7.6'
|
5
5
|
s.summary = "Modern continious testing (flexible alternative to autotest)"
|
6
6
|
s.description = "Modern continious testing (flexible alternative to autotest)."
|
7
7
|
s.author = "mynyml"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smparkes-watchr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.7.
|
4
|
+
version: 0.5.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mynyml
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-05 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|