Skip to content

Commit

Permalink
change Watcher.new to take an options hash; improve functional tests;…
Browse files Browse the repository at this point in the history
… glob understands ** and **/
  • Loading branch information
alexch committed Jul 2, 2012
1 parent e3725ed commit 3a222c1
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 45 deletions.
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format=documentation
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ desc "Run all specs"
RSpec::Core::RakeTask.new('spec') do |t|
ENV['ENV'] = "test"
t.pattern = 'spec/**/*_spec.rb'
t.ruby_opts = ['-rubygems'] if defined? Gem
t.rspec_opts = ['--color']
end

$rubyforge_project = 'pivotalrb'
Expand Down
20 changes: 20 additions & 0 deletions lib/rerun/glob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ def initialize glob_string

def to_regexp_string
chars = @glob_string.split('')

chars = smoosh(chars)

curlies = 0;
escaping = false;
chars.map do |char|
Expand All @@ -20,6 +23,8 @@ def to_regexp_string
char
else
case char
when '**'
"([^/]+/)*"
when '*'
".*"
when "?"
Expand Down Expand Up @@ -58,5 +63,20 @@ def to_regexp_string
def to_regexp
Regexp.new(to_regexp_string)
end

def smoosh chars
out = []
until chars.empty?
char = chars.shift
if char == "*" and chars.first == "*"
chars.shift
chars.shift if chars.first == "/"
out.push("**")
else
out.push(char)
end
end
out
end
end
end
4 changes: 1 addition & 3 deletions lib/rerun/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,10 @@ def start

unless @watcher

watcher = Watcher.new do
watcher = Watcher.new(:directory => dir, :pattern => pattern) do
restart unless @restarting
end
say "Watching #{dir}/#{pattern}"
watcher.add_directory(dir, pattern)
watcher.sleep_time = 1
watcher.start
@watcher = watcher
end
Expand Down
50 changes: 27 additions & 23 deletions lib/rerun/watcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,40 @@ class Watcher
MODIFIED = 1
DELETED = 2

attr_accessor :sleep_time, :priority
attr_reader :directory

def initialize(&client_callback)
attr_reader :directory, :pattern, :priority

# Create a file system watcher. Start it by calling #start.
#
# @param options[:directory] the directory to watch (default ".")
# @param options[:pattern] the glob pattern to search under the watched directory (default "**/*")
# @param options[:priority] the priority of the watcher thread (default 0)
#
def initialize(options = {}, &client_callback)
@client_callback = client_callback

@sleep_time = 1
@priority = 0
options = {
:directory => ".",
:pattern => "**/*",
:priority => 0,
}.merge(options)

@directory = nil
@files = []
@pattern = options[:pattern]
@directory = options[:directory]
if FileTest.exists?(directory) && FileTest.readable?(directory) then
@directory = Directory.new(directory, @pattern)
else
raise InvalidDirectoryError, "Dir '#{directory}' either doesnt exist or isnt readable"
end
@priority = options[:priority]

@found = nil
@first_time = true
@thread = nil

end

# add a directory to be watched
# @param dir the directory to watch
# @param expression the glob pattern to search under the watched directory
def add_directory(dir, expression="**/*")
if FileTest.exists?(dir) && FileTest.readable?(dir) then
@directory = Directory.new(dir, expression)
else
raise InvalidDirectoryError, "Dir '#{dir}' either doesnt exist or isnt readable"
end
end

def prime
@first_time = true
@found = Hash.new()
@found = {}
examine
@first_time = false
end
Expand All @@ -58,13 +60,15 @@ def start

@thread = Thread.new do
# todo: multiple dirs

# todo: convert each dir's pattern to a regex and get Listen to do the file scan for us
@listener = Listen::Listener.new(@directory.dir) do |modified, added, removed|
regexp = Glob.new(@pattern).to_regexp
puts "regexp is #{regexp.inspect}"
@listener = Listen::Listener.new(@directory.dir, :filter => regexp) do |modified, added, removed|
#d { modified }
#d { added }
#d { removed }
examine
sleep(@sleep_time)
end
@listener.start
end
Expand Down
24 changes: 15 additions & 9 deletions spec/functional_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require "#{here}/spec_helper.rb"
require 'tmpdir'

describe "Rerun functionally" do
describe "the rerun command" do
before do
@dir = Dir.tmpdir + "/#{Time.now.to_i}"
FileUtils.mkdir_p(@dir)
Expand All @@ -15,15 +15,16 @@

after do
# puts "Killing #{@pid}"
Process.kill("KILL", @pid) && Process.wait(@pid)
Process.kill("KILL", @pid) && Process.wait(@pid) rescue Errno::ESRCH
end

def launch_inc
@pid = fork do
root = File.dirname(__FILE__) + "/.."
exec("#{root}/bin/rerun -d '#{@dir}' ruby #{root}/inc.rb #{@file}")
end
sleep 4
sleep 0.5 until File.exist?(@file)
sleep 2 # let inc get going
end

def read
Expand Down Expand Up @@ -51,14 +52,14 @@ def type char
# todo: send a character to stdin of the rerun process
end

it "counts up" do
it "increments a test file once per second" do
x = current_count
sleep 1
y = current_count
y.should be > x
end

it "restarts when an app file is modified" do
it "restarts its target when an app file is modified" do
first_launched_at, count = read
touch @app_file
sleep 4
Expand All @@ -67,7 +68,7 @@ def type char
second_launched_at.should be > first_launched_at
end

it "restarts when an app file is created" do
it "restarts its target when an app file is created" do
first_launched_at, count = read
touch @app_file2
sleep 4
Expand All @@ -76,9 +77,14 @@ def type char
second_launched_at.should be > first_launched_at
end

it "sends its child process a SIGINT when restarting"
#it "sends its child process a SIGINT to restart"

it "dies when sent a control-C (SIGINT)"
it "dies when sent a control-C (SIGINT)" do
Process.kill("INT", @pid)
timeout(6) {
Process.wait(@pid) rescue Errno::ESRCH
}
end

it "accepts a key press"
#it "accepts a key press"
end
32 changes: 31 additions & 1 deletion spec/glob_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module Rerun
"\\*" => "\\*",
"\\\\" => "\\\\",

#"**/*.txt" => "([^/]*/)*.*\\.txt"
"**/*.txt" => "([^/]+/)*.*\\.txt",

}.each_pair do |glob_string, regexp_string|
specify glob_string do
Expand All @@ -42,6 +42,36 @@ module Rerun
end
end

describe "#smoosh" do

def check_smoosh string, array
glob = Glob.new("")
glob.smoosh(string.split('')).should == array
end

it "ignores non-stars" do
check_smoosh "", []
check_smoosh "abc", ["a", "b", "c"]
end

it "passes solitary stars" do
check_smoosh "*", ["*"]
check_smoosh "a*b", ["a", "*", "b"]
end

it "smooshes two stars in a row into a single '**' string" do
check_smoosh "**", ["**"]
check_smoosh "a**b", ["a", "**", "b"]
check_smoosh "**b", ["**", "b"]
check_smoosh "a**", ["a", "**"]
end

it "treats **/ like **" do
check_smoosh "**/", ["**"]
check_smoosh "a**/b", ["a", "**", "b"]
end
end

end
end

2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
require "rspec"
#require "rspec/autorun"

require "wrong"
require "wrong/adapters/rspec"
include Wrong::D

here = File.expand_path(File.dirname(__FILE__))
Expand Down
8 changes: 1 addition & 7 deletions spec/watcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,14 @@
module Rerun
describe Watcher do

def create_watcher(&block)
Watcher.new(&block)
end

before do
@dir = Dir.tmpdir + "/#{Time.now.to_i}"
FileUtils.mkdir_p(@dir)

@log = []
@watcher = create_watcher do |status, file|
@watcher = Watcher.new(:directory => @dir, :pattern => "*.txt") do |status, file|
@log << [status, file]
end
@watcher.add_directory(@dir, "*.txt")
@watcher.sleep_time = 0.1
@watcher.start

@test_file = "#{@dir}/test.txt"
Expand Down

0 comments on commit 3a222c1

Please sign in to comment.