watchr 0.5.5 → 0.5.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.
@@ -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