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.
@@ -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 HAML files in my public directory and
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
- === Things to do
81
+ === Recent Changes
82
+
83
+ 1. POC for batch events that occur within a time window
82
84
 
83
- 1. Batch up specs instead of running them individually (not a big deal for jazrb and haml; a big detail for rspec)
85
+ 1. Pass event type to callbacks
84
86
 
85
- 1. Filter spec runs that run as individual commands so they look like a single command (requires batching)
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. Perhaps add the event type to the watch callback, since multiple events can fire now. But haven't neede this.
95
+ 1. Don't swallow config file error messages, particularly on reload. Is this still happening?
94
96
 
95
- 1. Don't swallow config file error messages (particularly on reload)
97
+ 1. Implement some kind of dependence detection (probably starting to get into plugin territory)
data/bin/watchr CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ $VERBOSE = true
4
+
3
5
  require 'pathname'
4
6
  require 'optparse'
5
7
 
@@ -25,9 +25,6 @@ module Watchr
25
25
  end
26
26
 
27
27
  class << self
28
- attr_accessor :options
29
- attr_accessor :handler
30
-
31
28
  # backwards compatibility
32
29
  def version #:nodoc:
33
30
  Watchr::VERSION
@@ -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
- @script.rules.any? {|r| r.match(path) }
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(path, (first_time ? :load : :created) )
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
- SingleFileWatcher.handler.notify(path, type)
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
- SingleFileWatcher.handler.forget self, path
46
- stop_watching
47
- SingleFileWatcher.handler.notify(path, type)
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
- SingleFileWatcher.handler.forget self, path
52
- SingleFileWatcher.handler.notify(path, type)
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
- stop_watching
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
- # @watchers[path].stop
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
@@ -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 = nil, &action)
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.2)
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.action.call(data)
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
 
@@ -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'
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
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-02 00:00:00 -08:00
12
+ date: 2009-11-05 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency