Skip to content
Browse files

--dir option; improve documentation and test; add geminstaller file; …

…confirm that it doesn't work on Windows
  • Loading branch information...
1 parent 75b1bab commit dfb3dc209301f4279c6298e38c2aa72911d0c82d @alexch committed
Showing with 157 additions and 44 deletions.
  1. +34 −7 README.md
  2. +4 −0 bin/rerun
  3. +4 −0 geminstaller.yml
  4. +12 −0 inc.rb
  5. +0 −10 lib/osxwatcher.rb
  6. +11 −5 lib/rerun.rb
  7. +26 −16 lib/system.rb
  8. +58 −0 spec/functional_spec.rb
  9. +7 −5 spec/osxwatcher_spec.rb
  10. +1 −1 spec/watcher_spec.rb
View
41 README.md
@@ -5,14 +5,22 @@
Launches your app, then watches the filesystem. If a relevant file
changes, then it restarts your app.
-Currently only *.rb files are watched, anywhere under the current
-directory (.). This is pretty lame so it will change soon.
+Currently only *.rb files are watched. This is pretty lame so it will
+change soon.
If you're on Mac OS X, it uses the built-in facilities for monitoring
-the filesystem, so CPU use is very light.
+the filesystem, so CPU use is very light. And if you have "growlnotify"
+available on the PATH, it sends notifications to growl in addition to
+the console. Here's how to install
+[growlnotify](http://growl.info/documentation/growlnotify.php):
-If you have "growlcmd" available on the PATH, it sends notifications
-to growl in addition to the console.
+> In your shell, cd to the directory on the Growl disk image
+> containing growlnotify, and type ./install.sh. That script
+> will install growlnotify to /usr/local/bin and the manpage
+> to /usr/local/man.
+
+Rerun does not work on Windows. Sorry, but you can't do much relaunching
+without "fork".
# Installation:
@@ -42,14 +50,18 @@ but you want it on port 4000 and in debug mode:
# Options:
-Only --version and --help so far.
+--dir directory to watch (default = ".")
+
+Also --version and --help.
# To Do:
* If the cmd is, or starts with, a ".rb" file, then run it with ruby
+* Watch arbitrary file types via globbing
* Allow arbitrary sets of directories and file types, possibly with "include" and "exclude" sets
* ".rerun" file to specify options per project or in $HOME.
-* Test on Windows and Linux.
+* Test on Linux.
+* Test on Mac without Growlnotify.
# Other projects that do similar things
@@ -83,6 +95,20 @@ server so this doesn't affect them too much.
YMMV!
+# Why would I use this instead of Rack::Reloader?
+
+Rack::Reloader is certifiably beautiful code, and is a very elegant use
+of Rack's middleware architecture. But because it relies on the
+LOADED_FEATURES variable, it only reloads .rb files that were 'require'd,
+not 'load'ed. That leaves out (non-Erector) template files, and also,
+the way I was doing it, sub-actions (see
+[this thread](http://groups.google.com/group/sinatrarb/browse_thread/thread/7329727a9296e96a#
+)).
+
+Rack::Reloader also doesn't reload configuration changes or redo other
+things that happen during app startup. Rerun takes the attitude that if
+you want to restart an app, you should just restart the whole app. You know?
+
# Why did you write this?
I've been using [Sinatra](http://sinatrarb.com) and loving it. In order
@@ -103,6 +129,7 @@ Based upon and/or inspired by:
Shotgun: <http://github.com/rtomayko/shotgun>
Rspactor: <http://github.com/mislav/rspactor>
+(In turn based on http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/ )
FileSystemWatcher: <http://paulhorman.com/filesystemwatcher/>
View
4 bin/rerun
@@ -20,6 +20,10 @@ opts = OptionParser.new("", 24, ' ') { |opts|
opts.separator ""
opts.separator "Options:"
+ opts.on("-d dir", "--dir dir", "directory to watch") do |dir|
+ options[:dir] = dir
+ end
+
opts.on_tail("-h", "--help", "--usage", "show this message") do
puts opts
exit
View
4 geminstaller.yml
@@ -0,0 +1,4 @@
+---
+gems:
+- name: rspec
+ version: '>= 1.2.6'
View
12 inc.rb
@@ -0,0 +1,12 @@
+launched = Time.now.to_i
+file = ARGV[0] || "./inc.txt"
+i = 0
+while i < 10
+ puts "Writing #{launched}/#{i}"
+ File.open(file, "w") do |f|
+ f.puts(launched)
+ f.puts(i)
+ end
+ sleep 0.5
+ i+=1
+end
View
10 lib/osxwatcher.rb
@@ -1,16 +1,6 @@
require "system"
require "watcher"
-begin
- require 'osx/foundation'
- OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
-rescue MissingSourceFile
- # this is to not fail when running on a non-Mac
-end
-
-# stolen from RSpactor, http://github.com/mislav/rspactor
-# based on http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/
-
#TODO: make it notice deleted files
require "watcher"
module Rerun
View
16 lib/rerun.rb
@@ -3,7 +3,7 @@
require "osxwatcher"
require "fswatcher"
-# todo: make this work in non-Mac and non-Unix environments (also Macs without growlnotify)
+# todo: make sure this works in non-Mac environments (also Macs without growlnotify)
module Rerun
class Runner
@@ -20,6 +20,10 @@ def restart
@restarting = false
end
+ def dir
+ @options[:dir] || "."
+ end
+
def start
if (!@already_running)
taglines = [
@@ -66,16 +70,18 @@ def start
end
unless @watcher
- watcher_class = osx? ? OSXWatcher : FSWatcher
+ watcher_class = mac? ? OSXWatcher : FSWatcher
# watcher_class = FSWatcher
watcher = watcher_class.new do
restart unless @restarting
end
- watcher.add_directory(".", "**/*.rb")
+ puts "Watching #{dir}"
+ watcher.add_directory(dir, "**/*.rb")
watcher.sleep_time = 1
watcher.start
-
+
+
@watcher = watcher
end
@@ -117,7 +123,7 @@ def read_git_head
end
def notify(title, body)
- growl title, body if has_growl?
+ growl title, body
puts
puts "#{Time.now.strftime("%T")} - #{app_name} #{title}"
end
View
42 lib/system.rb
@@ -1,22 +1,30 @@
+def mac?
+ RUBY_PLATFORM =~ /darwin/i && !$osx_foundation_failed_to_load
+end
+
+def windows?
+ RUBY_PLATFORM =~ /mswin/i
+end
-# are we on OSX or not?
-begin
- require 'osx/foundation'
- OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
- $osx = true
-rescue MissingSourceFile
- # this is to not fail when running on a non-Mac
+def linux?
+ RUBY_PLATFORM =~ /linux/i
+end
+
+if mac?
+ begin
+ require 'osx/foundation'
+ OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
+ rescue
+ $osx_foundation_failed_to_load = true
+ end
end
module Rerun
module System
- def osx?
- $osx
- end
-
+
# do we have growl or not?
- def has_growl?
- growlcmd != ""
+ def growl?
+ mac? && (growlcmd != "")
end
def growlcmd
@@ -29,9 +37,11 @@ def app_name
end
def growl(title, body, background = true)
- s = "#{growlcmd} -n \"#{app_name}\" -m \"#{body}\" \"#{app_name} #{title}\""
- s += " &" if background
- `#{s}`
+ if growl?
+ s = "#{growlcmd} -n \"#{app_name}\" -m \"#{body}\" \"#{app_name} #{title}\""
+ s += " &" if background
+ `#{s}`
+ end
end
end
View
58 spec/functional_spec.rb
@@ -0,0 +1,58 @@
+require "#{File.dirname(__FILE__)}/spec_helper.rb"
+require 'tmpdir'
+
+describe "Rerun functionally" do
+ before do
+ @dir = Dir.tmpdir + "/#{Time.now.to_i}"
+ FileUtils.mkdir_p(@dir)
+ @file = "#{@dir}/inc.txt"
+ @app_file = "#{@dir}/foo.rb"
+ touch_app_file
+ launch_inc
+ end
+
+ def launch_inc
+ fork do
+ root = File.dirname(__FILE__) + "/.."
+ exec("#{root}/bin/rerun -d #{@dir} ruby #{root}/inc.rb #{@file}")
+ end
+ end
+
+ def read
+ File.open(@file, "r") do |f|
+ launched_at = f.gets.to_i
+ count = f.gets.to_i
+ [launched_at, count]
+ end
+ end
+
+ def current_count
+ launched_at, count = read
+ count
+ end
+
+ def touch_app_file
+ File.open(@app_file, "w") do |f|
+ f.puts Time.now
+ end
+ end
+
+ it "counts up" do
+ sleep 1
+ x = current_count
+ sleep 0.5
+ y = current_count
+ y.should be > x
+ end
+
+ it "restarts when an app file is created" do
+ sleep 2
+ first_launched_at, count = read
+ touch_app_file
+ sleep 4
+ second_launched_at, count = read
+
+ second_launched_at.should be > first_launched_at
+ end
+
+end
View
12 spec/osxwatcher_spec.rb
@@ -5,11 +5,13 @@
require 'watcher_spec'
-module Rerun
- describe OSXWatcher do
- it_should_behave_like "all watchers"
- def create_watcher(&block)
- OSXWatcher.new(&block)
+if mac?
+ module Rerun
+ describe OSXWatcher do
+ it_should_behave_like "all watchers"
+ def create_watcher(&block)
+ OSXWatcher.new(&block)
+ end
end
end
end
View
2 spec/watcher_spec.rb
@@ -30,7 +30,7 @@ module Rerun
end
it "watches file changes" do
- rest = 1.0
+ rest = 0.5
@log.clear
File.open(@test_file, "w") do |f|
f.puts("test")

0 comments on commit dfb3dc2

Please sign in to comment.
Something went wrong with that request. Please try again.