smparkes-watchr 0.5.7.4 → 0.5.7.6
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.
- 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
|