nestor 0.1.0

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.
Files changed (48) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +34 -0
  5. data/Rakefile +76 -0
  6. data/VERSION +1 -0
  7. data/bin/nestor +3 -0
  8. data/doc/.gitignore +3 -0
  9. data/doc/state-diagram.graffle +3870 -0
  10. data/doc/state-diagram.png +0 -0
  11. data/lib/nestor/cli.rb +52 -0
  12. data/lib/nestor/machine.rb +161 -0
  13. data/lib/nestor/strategies/test/unit.rb +116 -0
  14. data/lib/nestor/strategies.rb +18 -0
  15. data/lib/nestor/watchers/rails.rb +56 -0
  16. data/lib/nestor/watchers/rails_script.rb +83 -0
  17. data/lib/nestor/watchers.rb +1 -0
  18. data/lib/nestor.rb +11 -0
  19. data/spec/machine_spec.rb +56 -0
  20. data/spec/spec_helper.rb +9 -0
  21. data/vendor/watchr-0.5.7/.gitignore +5 -0
  22. data/vendor/watchr-0.5.7/History.txt +32 -0
  23. data/vendor/watchr-0.5.7/LICENSE +19 -0
  24. data/vendor/watchr-0.5.7/Manifest +27 -0
  25. data/vendor/watchr-0.5.7/README.rdoc +108 -0
  26. data/vendor/watchr-0.5.7/Rakefile +49 -0
  27. data/vendor/watchr-0.5.7/TODO.txt +40 -0
  28. data/vendor/watchr-0.5.7/bin/watchr +77 -0
  29. data/vendor/watchr-0.5.7/docs.watchr +26 -0
  30. data/vendor/watchr-0.5.7/gem.watchr +32 -0
  31. data/vendor/watchr-0.5.7/lib/watchr/controller.rb +81 -0
  32. data/vendor/watchr-0.5.7/lib/watchr/event_handlers/base.rb +48 -0
  33. data/vendor/watchr-0.5.7/lib/watchr/event_handlers/portable.rb +55 -0
  34. data/vendor/watchr-0.5.7/lib/watchr/event_handlers/unix.rb +97 -0
  35. data/vendor/watchr-0.5.7/lib/watchr/script.rb +203 -0
  36. data/vendor/watchr-0.5.7/lib/watchr.rb +113 -0
  37. data/vendor/watchr-0.5.7/manifest.watchr +70 -0
  38. data/vendor/watchr-0.5.7/specs.watchr +38 -0
  39. data/vendor/watchr-0.5.7/test/README +11 -0
  40. data/vendor/watchr-0.5.7/test/event_handlers/test_base.rb +24 -0
  41. data/vendor/watchr-0.5.7/test/event_handlers/test_portable.rb +58 -0
  42. data/vendor/watchr-0.5.7/test/event_handlers/test_unix.rb +162 -0
  43. data/vendor/watchr-0.5.7/test/test_controller.rb +103 -0
  44. data/vendor/watchr-0.5.7/test/test_helper.rb +52 -0
  45. data/vendor/watchr-0.5.7/test/test_script.rb +123 -0
  46. data/vendor/watchr-0.5.7/test/test_watchr.rb +60 -0
  47. data/vendor/watchr-0.5.7/watchr.gemspec +60 -0
  48. metadata +152 -0
Binary file
data/lib/nestor/cli.rb ADDED
@@ -0,0 +1,52 @@
1
+ require "nestor"
2
+ require "thor"
3
+
4
+ module Nestor
5
+ class Cli < Thor # :nodoc:
6
+ desc("start", <<-EODESC.gsub(/^\s{6}/, ""))
7
+ Starts a continuous test server.
8
+ EODESC
9
+ method_options :strategy => "test/unit", :watcher => "rails", :script => nil, :debug => false, :include => []
10
+ def start
11
+ puts "Using #{options[:strategy].inspect} strategy"
12
+ begin
13
+ # Try the internal version
14
+ require "nestor/strategies/#{options[:strategy]}"
15
+ rescue LoadError
16
+ # Else fallback to something I'm not aware of right now
17
+ require options[:strategy]
18
+ end
19
+
20
+ puts "Using #{options[:watcher].inspect} watcher"
21
+ begin
22
+ require "nestor/watchers/#{options[:watcher]}"
23
+ rescue LoadError
24
+ # Fallback to something external again
25
+ require options[:watcher]
26
+ end
27
+
28
+ Watchr.options.debug = options[:debug]
29
+
30
+ if options[:script] then
31
+ puts "Launching with custom script #{options[:script].inspect}"
32
+ else
33
+ puts "Launching..."
34
+ end
35
+ Nestor::Watchers::Rails.run(:script => Pathname.new(options[:script]))
36
+ end
37
+
38
+ desc("customize PATH", <<-EODESC.gsub(/^\s{6}/, ""))
39
+ Copies the named script file to PATH to allow customizing.
40
+ EODESC
41
+ method_options :strategy => "test/unit", :watcher => "rails"
42
+ def customize(path)
43
+ puts "Using #{options[:watcher].inspect} watcher"
44
+ require "nestor/watchers/#{options[:watcher]}"
45
+
46
+ raise "Destination #{path.inspect} already exists: will not overwrite" if File.file?(path)
47
+ FileUtils.cp(Nestor::Watchers::Rails.path_to_script, path)
48
+
49
+ puts "Wrote #{options[:watcher]} script to #{path.inspect}"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,161 @@
1
+ require "state_machine"
2
+
3
+ module Nestor
4
+ # Implements the state machine that is at the heart of Nestor.
5
+ #
6
+ # == Usage
7
+ #
8
+ # In the Watchr script, use +@strategy+ to access an instance of this class.
9
+ #
10
+ # The available events you may call are:
11
+ #
12
+ # <tt>ready!</tt>:: Machine instances start in the +booting+ state. Once the boot is complete,
13
+ # call +ready+ to indicate you are ready to process events. The default
14
+ # rails template calls #ready when +test/test_helper.rb+ is loaded.
15
+ #
16
+ # <tt>changed!</tt>:: Tells the Machine a file changed. The Watchr script and Strategy are
17
+ # responsible for assigning meaning to the file. The default Watchr
18
+ # script knows how to map model, controller and view files to given
19
+ # tests, and the script thus only tells the Machine about test files.
20
+ # Nothing prevents another implementation from providing the actual
21
+ # implementation files and letting the Strategy decide later what to
22
+ # do about those.
23
+ #
24
+ # <tt>run_successful!</tt>:: Tells the Machine that the last build was successful. This
25
+ # does not necessarily indicate a a completely green build: only
26
+ # that the last run was successful, given the focused files.
27
+ #
28
+ # <tt>run_failed!</tt>:: Tells the Machine there were one or more test failures or errors.
29
+ # Again, this doesn't mean the whole build failed: only the last couple
30
+ # of files had something that caused a failure.
31
+ #
32
+ # <tt>run!</tt>:: Tells the machine to tell the +#strategy+ to run the tests, given the current
33
+ # state of affairs. This might be running all tests, or a subset if the Machine
34
+ # is currently focusing on some items. A separate event is required by the
35
+ # Machine to allow coalescing multiple change events together.
36
+ #
37
+ class Machine
38
+ # The Machine actually delegates running the tests to another object, and this is it's reference.
39
+ attr_reader :strategy # :nodoc:
40
+
41
+ # The list of files we are focusing on, as received by #changed!
42
+ attr_reader :focused_files # :nodoc:
43
+
44
+ # The last changed file. Set by #changed!
45
+ attr_reader :changed_file # :nodoc:
46
+
47
+ # The list of failing tests or examples being focused on right now
48
+ attr_reader :focuses # :nodoc:
49
+
50
+ # +strategy+ is required, and must implement a couple of methods. See Nestor::Strategies for the required calls.
51
+ def initialize(strategy)
52
+ super() # Have to specify no-args, or else it'll raise an ArgumentError
53
+
54
+ @strategy = strategy
55
+ @focused_files, @focuses = [], []
56
+
57
+ log_state_change
58
+ end
59
+
60
+ state_machine :initial => :booting do
61
+ event :ready do
62
+ transition any => :running_all
63
+ end
64
+
65
+ event :failed do
66
+ transition [:running_all, :running_multi, :running_focused] => :run_focused
67
+ end
68
+
69
+ event :successful do
70
+ transition :running_focused => :running_multi
71
+ transition :running_multi => :running_all
72
+ transition :running_all => :green
73
+ end
74
+
75
+ event :file_changed do
76
+ transition [:run_focused, :run_focused_pending] => :run_focused_pending, :if => :changed_file_in_focused_files?
77
+ transition [:run_focused_pending, :run_multi_pending, :run_focused] => :run_multi_pending
78
+ transition :green => :run_multi_pending
79
+ end
80
+
81
+ event :run do
82
+ transition :run_focused_pending => :running_focused
83
+ transition :run_multi_pending => :running_multi
84
+ end
85
+
86
+ after_transition any => any, :do => :log_state_change
87
+ after_transition :to => :running_all, :do => :run_all_tests
88
+ after_transition :to => :running_focused, :do => :run_focused_tests
89
+ after_transition :to => :running_multi, :do => :run_multi_tests
90
+ before_transition :to => :run_focused, :do => :log_focus
91
+ before_transition :to => [:run_focused_pending, :run_multi_pending],
92
+ :do => :log_pending_run
93
+ after_transition :on => :file_changed, :do => :add_changed_file_to_focused_files
94
+ end
95
+
96
+ # Indicates the run was succesful: a green build. This does not indicate that the
97
+ # whole build was successful: only that the files that ran last were successful.
98
+ def run_successful!(files, tests)
99
+ successful!
100
+ end
101
+
102
+ # Indicates there were one or more failures. +files+ lists the actual files
103
+ # that failed, while +tests+ indicates the test names or examples that failed.
104
+ def run_failed!(files, tests)
105
+ @focused_files, @focuses = files, tests
106
+ failed!
107
+ end
108
+
109
+ # Notifies the Machine that a file changed. This might trigger a state change and schedule a build.
110
+ def changed!(file)
111
+ @changed_file = file
112
+ file_changed!
113
+ end
114
+
115
+ private
116
+
117
+ def run_all_tests
118
+ reset_focused_files
119
+ reset_focuses
120
+ @strategy.run_all
121
+ end
122
+
123
+ def run_multi_tests
124
+ reset_focuses
125
+ @strategy.run(focused_files)
126
+ end
127
+
128
+ def run_focused_tests
129
+ @strategy.run(focused_files, focuses)
130
+ end
131
+
132
+ def reset_focused_files
133
+ @focused_files.clear
134
+ end
135
+
136
+ def add_changed_file_to_focused_files
137
+ @focused_files << @changed_file unless @focused_files.include?(@changed_file)
138
+ end
139
+
140
+ def changed_file_in_focused_files?
141
+ @strategy.log("changed_file #{changed_file}, in focused_files? #{focused_files.inspect}")
142
+ focused_files.include?(changed_file)
143
+ end
144
+
145
+ def reset_focuses
146
+ focuses.clear
147
+ end
148
+
149
+ def log_state_change
150
+ @strategy.log("Machine entering state: #{state.inspect}")
151
+ end
152
+
153
+ def log_focus
154
+ @strategy.log("Focusing on #{focuses.inspect}")
155
+ end
156
+
157
+ def log_pending_run
158
+ @strategy.log("Run pending... Waiting for go ahead")
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,116 @@
1
+ require "yaml"
2
+ require "pathname"
3
+ require "test/unit/ui/console/testrunner"
4
+
5
+ module Nestor
6
+ module Strategies
7
+ module Test
8
+ class Unit
9
+ def initialize(root)
10
+ @root = Pathname.new(root).realpath
11
+ end
12
+
13
+ # Logs a message to STDOUT. This implementation forks, so the #log method also
14
+ # provides the PID of the logger.
15
+ def log(message)
16
+ STDOUT.printf "[%d] %s - %s\n", Process.pid, Time.now.strftime("%H:%M:%S"), message
17
+ STDOUT.flush
18
+ end
19
+
20
+ # Runs absolutely all tests as found by walking test/.
21
+ def run_all
22
+ fork do
23
+ log "Run all tests"
24
+ test_files = Dir["test/**/*_test.rb"]
25
+ test_files.each {|f| log(f); load f}
26
+
27
+ ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
28
+ test_runner = ::Nestor::Strategies::Test::TestRunner.new(nil)
29
+ result = ::Test::Unit::AutoRunner.run(false, nil, []) do |autorunner|
30
+ autorunner.runner = lambda { test_runner }
31
+ end
32
+
33
+ report(test_runner, test_files)
34
+ end
35
+ end
36
+
37
+ # Runs only the named files, and optionally focuses on only a couple of tests
38
+ # within the loaded test cases.
39
+ def run(test_files, focuses=[])
40
+ fork do
41
+ log "Running #{focuses.length} focused tests"
42
+ test_files.each {|f| log(f); load f}
43
+
44
+ ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
45
+ test_runner = ::Nestor::Strategies::Test::TestRunner.new(nil)
46
+ result = ::Test::Unit::AutoRunner.run(false, nil, []) do |autorunner|
47
+ autorunner.runner = lambda { test_runner }
48
+ autorunner.filters << proc{|t| focuses.include?(t.method_name)} unless focuses.empty?
49
+ end
50
+
51
+ report(test_runner, test_files)
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ # Since we forked, we can't call into the Machine from the child process. Upstream
58
+ # communications is implemented by writing new files to the filesystem and letting
59
+ # the parent process catch the changes.
60
+ def report(test_runner, test_files)
61
+ info = {"status" => test_runner.passed? ? "successful" : "failed", "failures" => {}}
62
+ failures = info["failures"]
63
+ test_runner.faults.each do |failure|
64
+ filename = if failure.respond_to?(:location) then
65
+ failure.location.detect do |loc|
66
+ filename = loc.split(":", 2).first
67
+ test_files.detect {|tf| filename.include?(tf)}
68
+ end
69
+ elsif failure.respond_to?(:exception) then
70
+ failure.exception.backtrace.detect do |loc|
71
+ filename = loc.split(":", 2).first
72
+ test_files.detect {|tf| filename.include?(tf)}
73
+ end
74
+ else
75
+ raise "Unknown object type received as failure: #{failure.inspect} doesn't have #exception or #location methods."
76
+ end
77
+
78
+ test_name = failure.test_name.split("(", 2).first.strip
79
+ if filename.nil? then
80
+ log("Could not map #{failure.test_name.inspect} to a specific test file: mapping to #{test_files.length}")
81
+ test_files.each do |tf|
82
+ failures[test_name] = tf
83
+ end
84
+ else
85
+ log("Failed #{failure.test_name.inspect} in #{filename.inspect}")
86
+ failures[test_name] = filename
87
+ end
88
+ end
89
+
90
+ File.open("tmp/nestor-results.yml", "w") {|io| io.write(info.to_yaml) }
91
+ log "Wrote #{failures.length} failure(s) to tmp/nestor-results.yml"
92
+ end
93
+ end
94
+
95
+ # A helper class that allows me to get more information from the build.
96
+ #
97
+ # This is something that definitely will change when Nestor is tested on Ruby 1.9.
98
+ class TestRunner < ::Test::Unit::UI::Console::TestRunner #:nodoc:
99
+ attr_reader :faults
100
+
101
+ # This is a duck-typing method. Test::Unit's design requiers a #run method,
102
+ # but it is implemented as a class method. I fake it here to allow me to
103
+ # pass an instance and have the actual TestRunner instance available afterwards.
104
+ def run(suite, output_level=NORMAL)
105
+ @suite = suite.respond_to?(:suite) ? suite.suite : suite
106
+ start
107
+ end
108
+
109
+ # Returns pass/fail status.
110
+ def passed?
111
+ @faults.empty?
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,18 @@
1
+ module Nestor
2
+ # Nestor::Cli will require a file named +nestor/strategies/#{strategy_name}+. If you want
3
+ # to provide custom strategies, make it available to Nestor using the correct path.
4
+ #
5
+ # Strategies are simple objects that implement the following protocol:
6
+ #
7
+ # <tt>log(message)</tt>:: Logs a simple message, either to the console or a logfile.
8
+ # The Machine will use the +log+ method to notify about it's
9
+ # state transitions.
10
+ #
11
+ # <tt>run_all</tt>:: Runs all the tests, no matter what. In the Rails &
12
+ # +Test::Unit+ case, this means <tt>Dir["test/**/*_test.rb"]</tt>.
13
+ #
14
+ # <tt>run(tests_files, focused_cases=[])</tt>:: Runs only a subset of the tests, maybe
15
+ # focusing on only a couple of tests / examples.
16
+ module Strategies
17
+ end
18
+ end
@@ -0,0 +1,56 @@
1
+ require "watchr"
2
+ require "pathname"
3
+
4
+ module Nestor
5
+ module Watchers
6
+ # Knows how to map file change events from Rails conventions to the corresponding test case.
7
+ module Rails
8
+ # Launches a Watchr::Controller to and never returns. The Controller will
9
+ # listen for file change events and trigger appropriate events on the Machine.
10
+ #
11
+ # By default, the Rails watcher will use the +Test::Unit+ strategy.
12
+ #
13
+ # @option options :strategy [Nestor::Strategies] The strategy to use. Must be an instance of a class that implements the protocol defined in Nestor::Strategies.
14
+ # @option options :script The path to the Watchr script.
15
+ #
16
+ # @return Never...
17
+ def self.run(options={})
18
+ strategy = options[:strategy] || Nestor::Strategies::Test::Unit.new(Dir.pwd)
19
+ script = instantiate_script(options[:script])
20
+
21
+ strategy.log "Instantiating machine"
22
+ script.nestor_strategy = strategy
23
+ script.nestor_machine = Nestor::Machine.new(strategy)
24
+ Watchr::Controller.new(script, Watchr.handler.new).run
25
+ end
26
+
27
+ def self.path_to_script
28
+ default_script_path
29
+ end
30
+
31
+ private
32
+
33
+ def self.default_script_path
34
+ Pathname.new(File.dirname(__FILE__) + "/rails_script.rb")
35
+ end
36
+
37
+ def self.instantiate_script(path) #:nodoc:
38
+ # Use the default if none provided
39
+ path = default_script_path if path.nil?
40
+
41
+ script = Watchr::Script.new(path)
42
+ class << script
43
+ def nestor_machine=(m)
44
+ @machine = m
45
+ end
46
+
47
+ def nestor_strategy=(s)
48
+ @strategy = s
49
+ end
50
+ end
51
+
52
+ script
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,83 @@
1
+ def log(message) #:nodoc:
2
+ @strategy.log(message)
3
+ end
4
+
5
+ RAILS_ENV = "test" unless defined?(RAILS_ENV)
6
+ log "Entering #{RAILS_ENV.inspect} environment"
7
+
8
+ log "Creating tmp/ if it doesn't exist"
9
+ Dir.mkdir("tmp") unless File.directory?("tmp")
10
+
11
+ log "Preloading test/test_helper.rb"
12
+ start_load_at = Time.now
13
+ $LOAD_PATH.unshift "test" unless $LOAD_PATH.include?("test")
14
+ require "test_helper"
15
+
16
+ end_load_at = Time.now
17
+ log "Waiting for changes (saving #{end_load_at - start_load_at} seconds per run)..."
18
+
19
+ def sendoff(timeout=0.8, path="tmp/nestor-sendoff") #:nodoc:
20
+ Thread.start(timeout, path) do |timeout, path|
21
+ log "Sendoff pending #{timeout}..."
22
+ sleep timeout
23
+ File.open(path, "w") {|io| io.write(rand.to_s)}
24
+ log "Sendoff fired on #{path}"
25
+ end
26
+ end
27
+
28
+ def changed!(filename) #:nodoc:
29
+ @machine.changed! filename
30
+ sendoff
31
+ end
32
+
33
+ watch 'app/models/(.+)\.rb' do |md|
34
+ test_file = "test/unit/#{md[1]}_test.rb"
35
+ log "#{md[0].inspect} => #{test_file.inspect}"
36
+ changed! test_file if File.file?(test_file)
37
+ end
38
+
39
+ watch 'app/controllers/(.+)\.rb' do |md|
40
+ test_file = "test/functional/#{md[1]}_test.rb"
41
+ log "#{md[0].inspect} => #{test_file.inspect}"
42
+ changed! test_file if File.file?(test_file)
43
+ end
44
+
45
+ # It might be possible to run focused tests with the view name
46
+ watch 'app/views/(.+)' do |md|
47
+ segments = md[1].split("/")
48
+ path = segments[0..-2]
49
+ test_file = "test/functional/#{path.join("/")}_controller_test.rb"
50
+ log "#{md[0].inspect} => #{test_file.inspect}"
51
+ changed! test_file if File.file?(test_file)
52
+ end
53
+
54
+ watch 'config/' do |md|
55
+ @machine.reset!
56
+ end
57
+
58
+ watch 'test/test_helper\.rb' do |md|
59
+ @machine.reset!
60
+ end
61
+
62
+ watch 'test/(?:unit|functional|integration|performance)/.*' do |md|
63
+ log "#{md[0].inspect} => #{md[0].inspect}"
64
+ changed! md[0]
65
+ end
66
+
67
+ watch 'tmp/nestor-results.yml' do |md|
68
+ # Since we received the results, we must receive our child process' status, or
69
+ # else we'll have zombie processes lying around
70
+ Thread.start { Process.wait }
71
+
72
+ info = YAML.load_file(md[0])
73
+ log "New results in: #{info.inspect}"
74
+ failures = info["failures"]
75
+ @machine.send("run_#{info["status"]}!", failures.values.uniq, failures.keys)
76
+ end
77
+
78
+ watch 'tmp/nestor-sendoff' do |_|
79
+ log "Sendoff"
80
+ @machine.run!
81
+ end
82
+
83
+ @machine.ready!
@@ -0,0 +1 @@
1
+ require "nestor/watchers/rails"
data/lib/nestor.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "watchr"
2
+ require "nestor/machine"
3
+
4
+ begin
5
+ require "ruby-debug"
6
+ rescue LoadError
7
+ # Ignore: development dependency
8
+ end
9
+
10
+ module Nestor # :nodoc:
11
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Nestor::Machine do
4
+ it "should accept a strategy on instantiation" do
5
+ strategy = mock.as_null_object
6
+ machine = Nestor::Machine.new(strategy)
7
+ machine.strategy.should be_equal(strategy)
8
+ end
9
+ end
10
+
11
+ describe Nestor::Machine do
12
+ before(:each) do
13
+ @strategy = mock
14
+ @strategy.stub(:run_all)
15
+ end
16
+
17
+ it "should start in the :running_all state" do
18
+ @machine = Nestor::Machine.new(@strategy)
19
+ machine.should be_running_all
20
+ end
21
+
22
+ it "should tell the strategy to run all tests" do
23
+ strategy = mock
24
+ strategy.should_receive(:run_all).with().once
25
+ Nestor::Machine.new(strategy)
26
+ end
27
+
28
+ it "should transition to :green when calling #successful" do
29
+ machine.successful
30
+ machine.should be_green
31
+ end
32
+
33
+ it "should transition to :run_focused when calling #failed" do
34
+ machine.failed
35
+ machine.should be_run_focused
36
+ end
37
+
38
+ def machine
39
+ @machine ||= Nestor::Machine.new(@strategy)
40
+ end
41
+ end
42
+
43
+ describe Nestor::Machine, "when in the run_focused state" do
44
+ before(:each) do
45
+ @strategy = mock
46
+ @strategy.stub(:run_all)
47
+ @machine = Nestor::Machine.new(@strategy)
48
+ @machine.failed
49
+ end
50
+
51
+ it "should transition to :running_focused when calling #changed!(filename)" do
52
+ @strategy.should_receive(:run).with(["spec/machine_spec.rb"])
53
+ @machine.changed!("spec/machine_spec.rb")
54
+ @machine.should be_running_focused
55
+ end
56
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'nestor'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -0,0 +1,5 @@
1
+ doc/
2
+ pkg/
3
+ bk/
4
+ .wiki
5
+ .yardoc
@@ -0,0 +1,32 @@
1
+
2
+ === v0.5.7
3
+
4
+ * Added manifest.watchr script
5
+ * Unix handler supports :deleted event type
6
+ * Unix handler supports :accessed (atime), :modified (mtime) and :changed
7
+ (ctime) event types (thanks gzuki[http://github.com/gzuki] for initial work)
8
+
9
+
10
+ === v0.5.6
11
+
12
+ * Rev gem optional in development (thanks TwP[http://github.com/TwP])
13
+ * Allow gems to bundle .watchr scripts (thanks foca[http://github.com/foca])
14
+
15
+ gemname/lib/gemname.watchr
16
+
17
+ is now automatically picked up with
18
+
19
+ $ watchr gemname.watchr
20
+
21
+ * Look for script in path
22
+ * debug msg when rev not found on *nix
23
+ * rake task for cross interpreter testing
24
+
25
+
26
+ === v0.5.5
27
+
28
+ * Rev gem is optional. Fixes issue #1
29
+ Install Rev to automatically get evented handler on *nix
30
+
31
+ gem install rev
32
+
@@ -0,0 +1,19 @@
1
+ Copyright © 2009 Martin Aumont (mynyml)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -0,0 +1,27 @@
1
+ .gitignore
2
+ History.txt
3
+ LICENSE
4
+ Manifest
5
+ README.rdoc
6
+ Rakefile
7
+ TODO.txt
8
+ bin/watchr
9
+ docs.watchr
10
+ gem.watchr
11
+ lib/watchr.rb
12
+ lib/watchr/controller.rb
13
+ lib/watchr/event_handlers/base.rb
14
+ lib/watchr/event_handlers/portable.rb
15
+ lib/watchr/event_handlers/unix.rb
16
+ lib/watchr/script.rb
17
+ manifest.watchr
18
+ specs.watchr
19
+ test/README
20
+ test/event_handlers/test_base.rb
21
+ test/event_handlers/test_portable.rb
22
+ test/event_handlers/test_unix.rb
23
+ test/test_controller.rb
24
+ test/test_helper.rb
25
+ test/test_script.rb
26
+ test/test_watchr.rb
27
+ watchr.gemspec