watchr 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -101,4 +101,6 @@ bugs:: http://github.com/mynyml/watchr/issues
101
101
 
102
102
  === Acknowledgement
103
103
 
104
- * Thanks to macournoyer[http://github.com/macournoyer] for the evented backend idea
104
+ * macournoyer[http://github.com/macournoyer] for the evented backend idea
105
+ * foca[http://github.com/foca] for suggesting automatically picking up watchr
106
+ scripts bundled in gems
data/Rakefile CHANGED
@@ -23,3 +23,27 @@ if defined? YARD
23
23
  t.options = %w( -o doc/yard --readme README.rdoc --files LICENSE,TODO.txt )
24
24
  end
25
25
  end
26
+
27
+ namespace(:test) do
28
+
29
+ desc "Run all tests"
30
+ task(:all) do
31
+ tests = Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
32
+ cmd = "ruby -rubygems -Ilib -e'%w( #{tests.join(' ')} ).each {|file| require file }'"
33
+ puts cmd if ENV['VERBOSE']
34
+ system cmd
35
+ end
36
+
37
+ desc "Run all tests on multiple ruby versions (requires rvm with 1.8.6 and 1.8.7)"
38
+ task(:portability) do
39
+ versions = %w( 1.8.6 1.8.7 )
40
+ versions.each do |version|
41
+ system <<-BASH
42
+ bash -c 'source ~/.rvm/scripts/rvm;
43
+ rvm use #{version};
44
+ echo "--------- `ruby -v` ----------\n";
45
+ rake -s test:all'
46
+ BASH
47
+ end
48
+ end
49
+ end
data/TODO.txt CHANGED
@@ -1,6 +1,5 @@
1
1
 
2
- * refactor Script#parse!
3
- * only accept paths in initialize?
2
+ * 1.9 compatibility
4
3
 
5
4
  * sometimes an action is fired without a file being saved
6
5
  * buffer flushing issue?
@@ -10,7 +9,8 @@
10
9
  * seems like rev/libev drops the file watch
11
10
 
12
11
  * test on other platforms
13
- * mswin
12
+ x mswin
13
+ x cygwin
14
14
  * bsd
15
15
  * osx
16
16
  * solaris
@@ -21,6 +21,7 @@
21
21
  * post main links in readme
22
22
 
23
23
  * eval script within own context?
24
+ * use case: using <tt>path</tt> within script accesses Script#path
24
25
 
25
26
  * respond to different file events?
26
27
  * modified
@@ -28,5 +29,10 @@
28
29
  * deleted
29
30
  * etc.
30
31
  * watch(pattern, EVENT, &action)
32
+ * use case: a script updates a manifest file when a file is deleted
31
33
 
32
34
  * memory profiling / benchmarks
35
+
36
+ * version.watchr
37
+ * sync versions (gemspec & Watchr::VERSION)
38
+
data/bin/watchr CHANGED
@@ -5,15 +5,56 @@ require 'optparse'
5
5
 
6
6
  require 'watchr'
7
7
 
8
- def usage
9
- "Usage: watchr [opts] path/to/script"
10
- end
11
- def version
12
- "watchr version: %s" % Watchr::VERSION
8
+ module Watchr
9
+ # Namespaced to avoid defining global methods
10
+ module Bin #:nodoc:
11
+ extend self
12
+
13
+ def usage
14
+ "Usage: watchr [opts] path/to/script"
15
+ end
16
+
17
+ def version
18
+ "watchr version: %s" % Watchr::VERSION
19
+ end
20
+
21
+ # Find a partial path name in load path
22
+ #
23
+ # ===== Params
24
+ # path<Pathname>:: partial pathname
25
+ #
26
+ # ===== Returns
27
+ # <Pathname>::
28
+ # absolute path of first occurence of partial path in load path, or nil if not found
29
+ #
30
+ def find_in_load_path(path)
31
+ dir = potentially_with_gem( path.basename('.watchr') ) do
32
+ $LOAD_PATH.detect {|p| Pathname(p).join(path).exist? }
33
+ end
34
+ dir ? path.expand_path(dir) : nil
35
+ end
36
+
37
+ private
38
+
39
+ # If the block returns nil, requires gem <tt>name</tt> and tries running the
40
+ # block again. If all fails, returns nil
41
+ #
42
+ # ===== Params
43
+ # name<Pathname,String>:: name of gem to require
44
+ #
45
+ # ===== Returns
46
+ # block's value or nil if gem <tt>name</tt> doesn't exist
47
+ #
48
+ def potentially_with_gem(name)
49
+ yield || (require(name) && yield)
50
+ rescue LoadError
51
+ nil
52
+ end
53
+ end
13
54
  end
14
55
 
15
56
  opts = OptionParser.new do |opts|
16
- opts.banner = usage
57
+ opts.banner = Watchr::Bin.usage
17
58
 
18
59
  opts.on('-d', '--debug', "Print extra debug info while program runs") {
19
60
  Watchr.options.debug = true
@@ -23,16 +64,14 @@ opts = OptionParser.new do |opts|
23
64
  end
24
65
  }
25
66
 
26
- opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
27
- opts.on_tail('-v', '--version', "Print version" ) { puts version; exit }
67
+ opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
68
+ opts.on_tail('-v', '--version', "Print version" ) { puts Watchr::Bin.version; exit }
28
69
 
29
70
  opts.parse! ARGV
30
71
  end
31
72
 
32
- abort(usage) unless ARGV.first
33
-
34
- file = Pathname(ARGV.first).expand_path
35
- abort(%|no script found; file "#{file.to_s}" doesn't exist.|) unless file.exist?
73
+ relative_path = Pathname( ARGV.first ) rescue abort(Watchr::Bin.usage)
74
+ absolute_path = Watchr::Bin.find_in_load_path(relative_path) or abort("no script found; file #{relative_path.to_s.inspect} is not in path.")
36
75
 
37
- Watchr::Controller.new(Watchr::Script.new(file), Watchr.handler.new).run
76
+ Watchr::Controller.new(Watchr::Script.new(absolute_path), Watchr.handler.new).run
38
77
 
@@ -13,16 +13,23 @@ require 'rbconfig'
13
13
  # See README for more details
14
14
  #
15
15
  module Watchr
16
+ begin
17
+ require 'rev'
18
+ HAVE_REV = true
19
+ rescue LoadError, RuntimeError
20
+ HAVE_REV = false
21
+ end
22
+
16
23
  autoload :Script, 'watchr/script'
17
24
  autoload :Controller, 'watchr/controller'
18
25
 
19
26
  module EventHandler
20
27
  autoload :Base, 'watchr/event_handlers/base'
21
- autoload :Unix, 'watchr/event_handlers/unix'
28
+ autoload :Unix, 'watchr/event_handlers/unix' if ::Watchr::HAVE_REV
22
29
  autoload :Portable, 'watchr/event_handlers/portable'
23
30
  end
24
31
 
25
- VERSION = '0.5.5'
32
+ VERSION = '0.5.6'
26
33
 
27
34
  class << self
28
35
  attr_accessor :options
@@ -69,9 +76,6 @@ module Watchr
69
76
 
70
77
  # Detect current OS and return appropriate handler.
71
78
  #
72
- # NOTE temporarily returns Portable handler for all platforms, until
73
- # issue #1 is fixed
74
- #
75
79
  # ===== Examples
76
80
  #
77
81
  # Config::CONFIG['host_os'] #=> 'linux-gnu'
@@ -95,10 +99,10 @@ module Watchr
95
99
  when /mswin|windows|cygwin/i
96
100
  Watchr::EventHandler::Portable
97
101
  when /sunos|solaris|darwin|mach|osx|bsd|linux/i, 'unix'
98
- begin
99
- require 'rev'
102
+ if ::Watchr::HAVE_REV
100
103
  Watchr::EventHandler::Unix
101
- rescue LoadError, RuntimeError
104
+ else
105
+ Watchr.debug "rev not found. `gem install rev` to get evented handler"
102
106
  Watchr::EventHandler::Portable
103
107
  end
104
108
  else
@@ -1,5 +1,3 @@
1
- require 'rev'
2
-
3
1
  module Watchr
4
2
  module EventHandler
5
3
  class Unix
@@ -23,23 +23,16 @@ module Watchr
23
23
  class API #:nodoc:
24
24
  end
25
25
 
26
- # Creates a script object for <tt>file</tt>.
26
+ # Creates a script object for <tt>path</tt>.
27
27
  #
28
28
  # Will also immediatly parse the script so it is ready to be passed to a
29
29
  # controller.
30
30
  #
31
31
  # ===== Parameters
32
- # file<Pathname>:: the path to the script
32
+ # path<Pathname>:: the path to the script
33
33
  #
34
- # ===== TODO
35
- # * only accept Pathname/String
36
- #
37
- #--
38
- # see issue with #parse!
39
- # (update class example when fixed)
40
- #
41
- def initialize(file = StringIO.new)
42
- @file = file
34
+ def initialize(path)
35
+ @path = path
43
36
  @rules = []
44
37
  @default_action = lambda {}
45
38
  parse!
@@ -113,19 +106,23 @@ module Watchr
113
106
 
114
107
  # Eval content of script file.
115
108
  #--
116
- # TODO @file.read will only work with Pathname objects!
117
109
  # TODO fix script file not found error
118
110
  def parse!
119
- Watchr.debug('loading script file %s' % @file.to_s.inspect)
111
+ Watchr.debug('loading script file %s' % @path.to_s.inspect)
120
112
 
121
- @rules.clear
122
- instance_eval(@file.read)
113
+ reset
114
+ instance_eval(@path.read)
123
115
 
124
116
  rescue Errno::ENOENT
125
117
  # TODO figure out why this is happening. still can't reproduce
126
118
  Watchr.debug('script file "not found". wth')
127
119
  sleep(0.3) #enough?
128
- instance_eval(@file.read)
120
+ instance_eval(@path.read)
121
+ end
122
+
123
+ def reset
124
+ @default_action = lambda {}
125
+ @rules.clear
129
126
  end
130
127
 
131
128
  # Find an action corresponding to a path. The returned action is actually a
@@ -159,7 +156,7 @@ module Watchr
159
156
  # path<Pathname>:: path to script file
160
157
  #
161
158
  def path
162
- Pathname(@file.respond_to?(:to_path) ? @file.to_path : @file.to_s).expand_path
159
+ Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
163
160
  end
164
161
 
165
162
  private
@@ -5,18 +5,14 @@
5
5
  # --------------------------------------------------
6
6
  # Convenience Methods
7
7
  # --------------------------------------------------
8
- def all_test_files
9
- Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
10
- end
11
-
12
8
  def run(cmd)
13
9
  puts(cmd)
14
10
  system(cmd)
15
11
  end
16
12
 
17
13
  def run_all_tests
18
- cmd = "ruby -rubygems -Ilib -e'%w( #{all_test_files.join(' ')} ).each {|file| require file }'"
19
- run(cmd)
14
+ # see Rakefile for the definition of the test:all task
15
+ system( "rake -s test:all VERBOSE=true" )
20
16
  end
21
17
 
22
18
  # --------------------------------------------------
@@ -24,6 +20,7 @@ end
24
20
  # --------------------------------------------------
25
21
  watch( '^test.*/test_.*\.rb' ) { |m| run( "ruby -rubygems %s" % m[0] ) }
26
22
  watch( '^lib/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
23
+ watch( '^lib/watchr/(.*)\.rb' ) { |m| run( "ruby -rubygems test/test_%s.rb" % m[1] ) }
27
24
  watch( '^lib/watchr/event_handlers/(.*)\.rb' ) { |m| run( "ruby -rubygems test/event_handlers/test_%s.rb" % m[1] ) }
28
25
  watch( '^test/test_helper\.rb' ) { run_all_tests }
29
26
 
@@ -39,5 +36,3 @@ end
39
36
  # Ctrl-C
40
37
  Signal.trap('INT') { abort("\n") }
41
38
 
42
-
43
- # vim:ft=ruby
@@ -1,3 +1,5 @@
1
+ if Watchr::HAVE_REV
2
+
1
3
  require 'test/test_helper'
2
4
 
3
5
  class UnixEventHandlerTest < Test::Unit::TestCase
@@ -54,3 +56,5 @@ class UnixEventHandlerTest < Test::Unit::TestCase
54
56
  @loop.watchers.every.path.should exclude('bar')
55
57
  end
56
58
  end
59
+
60
+ end # if Watchr::HAVE_REV
@@ -15,7 +15,8 @@ class TestController < Test::Unit::TestCase
15
15
  end
16
16
 
17
17
  def setup
18
- @script = Script.new
18
+ tmpfile = Tempfile.new('foo')
19
+ @script = Script.new( Pathname.new( tmpfile.path ) )
19
20
  @handler = MockHandler.new
20
21
  @controller = Controller.new(@script, @handler)
21
22
  end
@@ -41,10 +42,9 @@ class TestController < Test::Unit::TestCase
41
42
  b/c
42
43
  b/c/y.z
43
44
  ))
44
- script = Script.new
45
- script.watch('.\.z') { :x }
45
+ @script.watch('.\.z') { :x }
46
46
 
47
- contrl = Controller.new(script, MockHandler.new)
47
+ contrl = Controller.new(@script, MockHandler.new)
48
48
  contrl.monitored_paths.should include(to_p('b/x.z'))
49
49
  contrl.monitored_paths.should include(to_p('b/c/y.z'))
50
50
  end
@@ -56,10 +56,9 @@ class TestController < Test::Unit::TestCase
56
56
  b/c
57
57
  b/c/y.z
58
58
  ))
59
- script = Script.new
60
- script.watch('.\.z') { :x }
59
+ @script.watch('.\.z') { :x }
61
60
 
62
- contrl = Controller.new(script, MockHandler.new)
61
+ contrl = Controller.new(@script, MockHandler.new)
63
62
  contrl.monitored_paths.should exclude(to_p('a'))
64
63
  contrl.monitored_paths.should exclude(to_p('b/c'))
65
64
  contrl.monitored_paths.should exclude(to_p('p/q.z'))
@@ -1,5 +1,7 @@
1
1
  require 'pathname'
2
+ require 'tempfile'
2
3
  require 'test/unit'
4
+
3
5
  require 'matchy'
4
6
  require 'mocha'
5
7
  require 'every'
@@ -3,63 +3,79 @@ require 'test/test_helper'
3
3
  class TestScript < Test::Unit::TestCase
4
4
  include Watchr
5
5
 
6
+ def setup
7
+ tmpfile = Tempfile.new('foo')
8
+ @script = Script.new( Pathname.new( tmpfile.path ) )
9
+ end
10
+
6
11
  ## external api
7
12
 
8
13
  test "watch" do
9
- Script.new.watch('pattern')
10
- Script.new.watch('pattern') { nil }
14
+ @script.watch('pattern')
15
+ @script.watch('pattern') { nil }
11
16
  end
12
17
 
13
18
  test "default action" do
14
- Script.new.default_action { nil }
19
+ @script.default_action { nil }
15
20
  end
16
21
 
17
22
  ## functionality
18
23
 
19
24
  test "rule object" do
20
- rule = Script.new.watch('pattern') { nil }
25
+ rule = @script.watch('pattern') { nil }
21
26
  rule.pattern.should be('pattern')
22
27
  rule.action.call.should be(nil)
23
28
  end
24
29
 
25
30
  test "finds action for path" do
26
- script = Script.new
27
- script.watch('abc') { :x }
28
- script.watch('def') { :y }
29
- script.action_for('abc').call.should be(:x)
31
+ @script.watch('abc') { :x }
32
+ @script.watch('def') { :y }
33
+ @script.action_for('abc').call.should be(:x)
30
34
  end
31
35
 
32
36
  test "collects patterns" do
33
- script = Script.new
34
- script.watch('abc')
35
- script.watch('def')
36
- script.patterns.should include('abc')
37
- script.patterns.should include('def')
37
+ @script.watch('abc')
38
+ @script.watch('def')
39
+ @script.patterns.should include('abc')
40
+ @script.patterns.should include('def')
38
41
  end
39
42
 
40
43
  test "parses script file" do
41
- file = StringIO.new(<<-STR)
44
+ file = Pathname( Tempfile.open('bar').path )
45
+ file.open('w') {|f| f.write <<-STR }
42
46
  watch( 'abc' ) { :x }
43
47
  STR
44
48
  script = Script.new(file)
45
49
  script.action_for('abc').call.should be(:x)
46
50
  end
47
51
 
52
+ test "resets state" do
53
+ @script.default_action { 'x' }
54
+ @script.watch('foo') { 'bar' }
55
+ @script.reset
56
+ @script.instance_variable_get(:@default_action).should be_kind_of(Proc)
57
+ @script.instance_variable_get(:@default_action).call.should be(nil)
58
+ @script.instance_variable_get(:@rules).should be([])
59
+ end
60
+
61
+ test "resets state on parse" do
62
+ @script.stubs(:instance_eval)
63
+ @script.expects(:reset)
64
+ @script.parse!
65
+ end
66
+
48
67
  test "actions receive a MatchData object" do
49
- script = Script.new
50
- script.watch('de(.)') {|m| [m[0], m[1]] }
51
- script.action_for('def').call.should be(%w( def f ))
68
+ @script.watch('de(.)') {|m| [m[0], m[1]] }
69
+ @script.action_for('def').call.should be(%w( def f ))
52
70
  end
53
71
 
54
72
  test "rule's default action" do
55
- script = Script.new
56
-
57
- script.watch('abc')
58
- script.action_for('abc').call.should be(nil)
59
- script.default_action { :x }
73
+ @script.watch('abc')
74
+ @script.action_for('abc').call.should be(nil)
75
+ @script.default_action { :x }
60
76
 
61
- script.watch('def')
62
- script.action_for('def').call.should be(:x)
77
+ @script.watch('def')
78
+ @script.action_for('def').call.should be(:x)
63
79
  end
64
80
 
65
81
  test "file path" do
@@ -70,19 +86,15 @@ class TestScript < Test::Unit::TestCase
70
86
  end
71
87
 
72
88
  test "later rules take precedence" do
73
- script = Script.new
89
+ @script.watch('a/(.*)\.x') { :x }
90
+ @script.watch('a/b/(.*)\.x') { :y }
74
91
 
75
- script.watch('a/(.*)\.x') { :x }
76
- script.watch('a/b/(.*)\.x') { :y }
77
-
78
- script.action_for('a/b/c.x').call.should be(:y)
92
+ @script.action_for('a/b/c.x').call.should be(:y)
79
93
  end
80
94
 
81
95
  test "rule patterns match against paths relative to pwd" do
82
- script = Script.new
83
-
84
- script.watch('^abc') { :x }
96
+ @script.watch('^abc') { :x }
85
97
  path = Pathname(Dir.pwd) + 'abc'
86
- script.action_for(path).call.should be(:x)
98
+ @script.action_for(path).call.should be(:x)
87
99
  end
88
100
  end
@@ -26,19 +26,19 @@ class TestWatchr < Test::Unit::TestCase
26
26
 
27
27
  Watchr.handler = nil
28
28
  ENV['HANDLER'] = 'linux'
29
- Watchr.handler.should be(Watchr::EventHandler::Unix)
29
+ Watchr.handler.should be(Watchr::HAVE_REV ? Watchr::EventHandler::Unix : Watchr::EventHandler::Portable)
30
30
 
31
31
  Watchr.handler = nil
32
32
  ENV['HANDLER'] = 'bsd'
33
- Watchr.handler.should be(Watchr::EventHandler::Unix)
33
+ Watchr.handler.should be(Watchr::HAVE_REV ? Watchr::EventHandler::Unix : Watchr::EventHandler::Portable)
34
34
 
35
35
  Watchr.handler = nil
36
36
  ENV['HANDLER'] = 'darwin'
37
- Watchr.handler.should be(Watchr::EventHandler::Unix)
37
+ Watchr.handler.should be(Watchr::HAVE_REV ? Watchr::EventHandler::Unix : Watchr::EventHandler::Portable)
38
38
 
39
39
  Watchr.handler = nil
40
40
  ENV['HANDLER'] = 'unix'
41
- Watchr.handler.should be(Watchr::EventHandler::Unix)
41
+ Watchr.handler.should be(Watchr::HAVE_REV ? Watchr::EventHandler::Unix : Watchr::EventHandler::Portable)
42
42
 
43
43
  Watchr.handler = nil
44
44
  ENV['HANDLER'] = 'mswin'
@@ -1,7 +1,7 @@
1
1
 
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'watchr'
4
- s.version = '0.5.5'
4
+ s.version = '0.5.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: watchr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.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-09-25 00:00:00 -04:00
12
+ date: 2009-09-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency