Permalink
Browse files

Merge branch 'master' of github.com:guard/guard

Conflicts:
	lib/guard.rb
	lib/guard/interactor.rb
	spec/guard_spec.rb
  • Loading branch information...
2 parents 53a7969 + ae55268 commit 2fc67458371c75dd2aeb6471dcf785e96b98dfee Thibaud Guillaume-Gentil committed Nov 30, 2010
Showing with 277 additions and 125 deletions.
  1. +12 −0 CHANGELOG.rdoc
  2. +8 −9 README.rdoc
  3. +7 −5 lib/guard.rb
  4. +1 −1 lib/guard/dsl.rb
  5. +3 −3 lib/guard/guard.rb
  6. +3 −3 lib/guard/interactor.rb
  7. +7 −3 lib/guard/ui.rb
  8. +24 −12 lib/guard/watcher.rb
  9. +135 −0 spec/guard/watcher_spec.rb
  10. +72 −84 spec/guard_spec.rb
  11. +5 −5 spec/spec_helper.rb
View
@@ -1,3 +1,15 @@
+== Nov 26, 2010 [by rymai]
+
+Features:
+- It's now possible to return an enumerable in the 'watch' optional blocks in the Guardfile.
+- Listener now continue to watch changed files even when guards plugin are running.
+
+Specs:
+- Guard::Watcher
+
+Bugs fixes:
+- Avoid launching run_on_change guards method when no files matched. --clear guard argument is now usable.
+
== 0.2.2 (Oct 25, 2010)
Bugs fixes:
View
@@ -83,20 +83,18 @@ Signal handlers are used to interact with Guard:
- {guard-coffeescript}[http://github.com/guard/guard-coffeescript] by {Michael Kessler}[http://github.com/netzpirat]
- {guard-compass}[http://github.com/guard/guard-compass] by {Olivier Amblet}[http://github.com/oliamb]
- {guard-cucumber}[http://github.com/guard/guard-cucumber] by {Michael Kessler}[http://github.com/netzpirat]
+- {guard-ego}[http://github.com/guard/guard-ego] by {Fabio Kuhn}[http://github.com/mordaroso]
+- {guard-jammit}[http://github.com/guard/guard-jammit] by {Pelle Braendgaard}[http://github.com/pelle]
- {guard-livereload}[http://github.com/guard/guard-livereload] by {Thibaud Guillaume-Gentil}[http://github.com/thibaudgg]
- {guard-minitest}[http://github.com/guard/guard-minitest] by {Yann Lugrin}[http://github.com/yannlugrin]
- {guard-nanoc}[http://github.com/guard/guard-nanoc] by {Yann Lugrin}[http://github.com/yannlugrin]
- {guard-passenger}[http://github.com/guard/guard-passenger] by {Fabio Kuhn}[http://github.com/mordaroso]
- {guard-rspec}[http://github.com/guard/guard-rspec] by {Thibaud Guillaume-Gentil}[http://github.com/thibaudgg]
- {guard-sass}[http://github.com/guard/guard-sass] by {Joshua Hawxwell}[http://github.com/hawx]
- {guard-shell}[http://github.com/guard/guard-shell] by {Joshua Hawxwell}[http://github.com/hawx]
+- {guard-spork}[http://github.com/guard/guard-spork] by {Thibaud Guillaume-Gentil}[http://github.com/thibaudgg]
- {guard-test}[http://github.com/guard/guard-test] by {Rémy Coutable}[http://github.com/rymai]
-guard ideas:
-
-- guard-spork
-- others ideas?
-
=== Add a guard to your Guardfile
Add it to your Gemfile (inside test group):
@@ -178,10 +176,11 @@ Looks at available guards code for more concrete example.
Guardfile DSL consists of just two simple methods: guard & watch. Example:
guard 'rspec', :version => 2 do
- watch('^spec/(.*)_spec.rb')
- watch('^lib/(.*)\.rb') { |m| "spec/lib/#{m[1]}_spec.rb" }
- watch('^spec/spec_helper.rb') { "spec" }
- watch('^spec/spec_helper.rb') { `say hello` }
+ watch(%|^spec/(.*)_spec\.rb|)
+ watch(%|^lib/(.*)\.rb|) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch(%|^spec/spec_helper\.rb|) { "spec" }
+ watch(%|^spec/models/.*\.rb|) { ["spec/models", "spec/acceptance"] }
+ watch(%|^spec/spec_helper\.rb|) { `say hello` }
end
- "guard" method allow to add a guard with an optional options hash
View
@@ -17,7 +17,7 @@ def setup(options = {})
@options = options
@listener = Listener.select_and_init
@guards = []
- return self
+ self
end
def start(options = {})
@@ -40,10 +40,12 @@ def wait_for_changes_and_launch_guards
loop do
if !running? && !listener.changed_files.empty?
changed_files = listener.get_and_clear_changed_files
- run do
- guards.each do |guard|
- paths = Watcher.match_files(guard, changed_files)
- supervised_task(guard, :run_on_change, paths) unless paths.empty?
+ if Watcher.match_files?(guards, files)
+ run do
+ guards.each do |guard|
+ paths = Watcher.match_files(guard, changed_files)
+ supervised_task(guard, :run_on_change, paths) unless paths.empty?
+ end
end
end
end
View
@@ -3,7 +3,7 @@ class Dsl
def self.evaluate_guardfile
guardfile = "#{Dir.pwd}/Guardfile"
- if File.exists? guardfile
+ if File.exists?(guardfile)
begin
dsl = new
dsl.instance_eval(File.read(guardfile.to_s), guardfile.to_s, 1)
View
@@ -14,9 +14,9 @@ def self.init(name)
content = File.read('Guardfile')
guard = File.read("#{::Guard.locate_guard(name)}/lib/guard/#{name}/templates/Guardfile")
File.open('Guardfile', 'wb') do |f|
- f.puts content
- f.puts ""
- f.puts guard
+ f.puts(content)
+ f.puts("")
+ f.puts(guard)
end
::Guard::UI.info "#{name} guard added to Guardfile, feel free to edit it"
end
@@ -5,22 +5,22 @@ def self.init_signal_traps
# Run all (Ctrl-\)
Signal.trap('QUIT') do
::Guard.run do
- ::Guard.guards.each { |g| ::Guard.supervised_task g, :run_all }
+ ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) }
end
end
# Stop (Ctrl-C)
Signal.trap('INT') do
UI.info "Bye bye...", :reset => true
::Guard.listener.stop
- ::Guard.guards.each { |g| ::Guard.supervised_task g, :stop }
+ ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) }
abort("\n")
end
# Reload (Ctrl-Z)
Signal.trap('TSTP') do
::Guard.run do
- ::Guard.guards.each { |g| ::Guard.supervised_task g, :reload }
+ ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :reload) }
end
end
end
View
@@ -9,12 +9,16 @@ def info(message, options = {})
end
end
- def error(message)
- puts "ERROR: #{message}"
+ def error(message, options = {})
+ unless ENV["GUARD_ENV"] == "test"
+ reset_line if options[:reset]
+ puts "ERROR: #{message}"
+ end
end
- def debug(message)
+ def debug(message, options = {})
unless ENV["GUARD_ENV"] == "test"
+ reset_line if options[:reset]
puts "DEBUG: #{message}" if ::Guard.options && ::Guard.options[:debug]
end
end
View
@@ -9,24 +9,36 @@ def initialize(pattern, action = nil)
def self.match_files(guard, files)
guard.watchers.inject([]) do |paths, watcher|
files.each do |file|
- if matches = file.match(watcher.pattern)
+ if matches = watcher.match_file?(file)
if watcher.action
- begin
- if watcher.action.arity == 1
- result = watcher.action.call(matches)
- else
- result = watcher.action.call
- end
- rescue
- UI.info "Problem with watch action"
- end
- paths << result if result.is_a?(String) && result != ''
+ result = watcher.call_action(matches)
+ paths << Array(result) if result.respond_to?(:empty?) && !result.empty?
else
paths << matches[0]
end
end
end
- paths
+ paths.flatten.map { |p| p.to_s }
+ end
+ end
+
+ def self.match_files?(guards, files)
+ guards.any? do |guard|
+ guard.watchers.any? do |watcher|
+ files.any? { |file| watcher.match_file?(file) }
+ end
+ end
+ end
+
+ def match_file?(file)
+ file.match(@pattern)
+ end
+
+ def call_action(matches)
+ begin
+ @action.arity > 0 ? @action.call(matches) : @action.call
+ rescue
+ UI.error "Problem with watch action!"
end
end
@@ -0,0 +1,135 @@
+require 'spec_helper'
+require 'guard/guard'
+
+describe Guard::Watcher do
+
+ describe "pattern" do
+ it "should be required" do
+ expect { Guard::Watcher.new }.to raise_error(ArgumentError)
+ end
+
+ it "should be set" do
+ Guard::Watcher.new(%|spec_helper\.rb|).pattern.should == %|spec_helper\.rb|
+ end
+ end
+
+ describe "action" do
+ it "should set action to nil by default" do
+ Guard::Watcher.new(%|spec_helper\.rb|).action.should be_nil
+ end
+
+ it "should set action with a block" do
+ action = lambda { |m| "spec/#{m[1]}_spec.rb" }
+ Guard::Watcher.new(%|^lib/(.*).rb|, action).action.should == action
+ end
+ end
+
+ describe ".match_files" do
+ before(:all) { @guard = Guard::Guard.new }
+
+ describe "a watcher's with no action" do
+ before(:all) { @guard.watchers = [Guard::Watcher.new(%|.*_spec\.rb|)] }
+
+ it "should return paths as they came" do
+ Guard::Watcher.match_files(@guard, ['guard_rocks_spec.rb']).should == ['guard_rocks_spec.rb']
+ end
+ end
+
+ describe "a watcher's action with an arity equal to 0" do
+ before(:all) do
+ @guard.watchers = [
+ Guard::Watcher.new(%|spec_helper\.rb|, lambda { 'spec' }),
+ Guard::Watcher.new(%|addition\.rb|, lambda { 1 + 1 }),
+ Guard::Watcher.new(%|hash\.rb|, lambda { Hash[:foo, 'bar'] }),
+ Guard::Watcher.new(%|array\.rb|, lambda { ['foo', 'bar'] }),
+ Guard::Watcher.new(%|blank\.rb|, lambda { '' }),
+ Guard::Watcher.new(%|uptime\.rb|, lambda { `uptime > /dev/null` })
+ ]
+ end
+
+ it "should return paths specified in the watcher's action" do
+ Guard::Watcher.match_files(@guard, ['spec_helper.rb']).should == ['spec']
+ end
+ it "should return nothing if action.call doesn't respond_to :empty?" do
+ Guard::Watcher.match_files(@guard, ['addition.rb']).should == []
+ end
+ it "should return action.call.to_a if result respond_to :empty?" do
+ Guard::Watcher.match_files(@guard, ['hash.rb']).should == ['foo', 'bar']
+ end
+ it "should return files including files from array if paths are an array" do
+ Guard::Watcher.match_files(@guard, ['spec_helper.rb', 'array.rb']).should == ['spec', 'foo', 'bar']
+ end
+ it "should return nothing if action.call return ''" do
+ Guard::Watcher.match_files(@guard, ['blank.rb']).should == []
+ end
+ it "should return nothing if action.call return nil" do
+ Guard::Watcher.match_files(@guard, ['uptime.rb']).should == []
+ end
+ end
+
+ describe "a watcher's action with an arity equal to 1" do
+ before(:all) do
+ @guard.watchers = [
+ Guard::Watcher.new(%|lib/(.*)\.rb|, lambda { |m| "spec/#{m[1]}_spec.rb" }),
+ Guard::Watcher.new(%|addition(.*)\.rb|, lambda { |m| 1 + 1 }),
+ Guard::Watcher.new(%|hash\.rb|, lambda { Hash[:foo, 'bar'] }),
+ Guard::Watcher.new(%|array(.*)\.rb|, lambda { |m| ['foo', 'bar'] }),
+ Guard::Watcher.new(%|blank(.*)\.rb|, lambda { |m| '' }),
+ Guard::Watcher.new(%|uptime(.*)\.rb|, lambda { |m| `uptime > /dev/null` })
+ ]
+ end
+
+ it "should return paths after watcher's action has been called against them" do
+ Guard::Watcher.match_files(@guard, ['lib/my_wonderful_lib.rb']).should == ['spec/my_wonderful_lib_spec.rb']
+ end
+ it "should return nothing if action.call doesn't respond_to :empty?" do
+ Guard::Watcher.match_files(@guard, ['addition.rb']).should == []
+ end
+ it "should return action.call.to_a if result respond_to :empty?" do
+ Guard::Watcher.match_files(@guard, ['hash.rb']).should == ['foo', 'bar']
+ end
+ it "should return files including files from array if paths are an array" do
+ Guard::Watcher.match_files(@guard, ['lib/my_wonderful_lib.rb', 'array.rb']).should == ['spec/my_wonderful_lib_spec.rb', 'foo', 'bar']
+ end
+ it "should return nothing if action.call return ''" do
+ Guard::Watcher.match_files(@guard, ['blank.rb']).should == []
+ end
+ it "should return nothing if action.call return nil" do
+ Guard::Watcher.match_files(@guard, ['uptime.rb']).should == []
+ end
+ end
+
+ describe "an exception is raised" do
+ before(:all) { @guard.watchers = [Guard::Watcher.new('evil.rb', lambda { raise "EVIL" })] }
+
+ it "should display an error" do
+ Guard::UI.should_receive(:error).with("Problem with watch action!")
+ Guard::Watcher.match_files(@guard, ['evil.rb'])
+ end
+ end
+ end
+
+ describe ".match_files?" do
+ before(:all) do
+ @guard1 = Guard::Guard.new([Guard::Watcher.new(%|.*_spec\.rb|)])
+ @guard2 = Guard::Guard.new([Guard::Watcher.new(%|spec_helper\.rb|, 'spec')])
+ @guards = [@guard1, @guard2]
+ end
+
+ describe "with at least on watcher that match a file given" do
+ specify { Guard::Watcher.match_files?(@guards, ['lib/my_wonderful_lib.rb', 'guard_rocks_spec.rb']).should be_true }
+ end
+
+ describe "with no watcher matching a file given" do
+ specify { Guard::Watcher.match_files?(@guards, ['lib/my_wonderful_lib.rb']).should be_false }
+ end
+ end
+
+ describe "#match_file?" do
+ subject { Guard::Watcher.new(%|.*_spec\.rb|) }
+
+ specify { subject.match_file?('lib/my_wonderful_lib.rb').should be_false }
+ specify { subject.match_file?('guard_rocks_spec.rb').should be_true }
+ end
+
+end
Oops, something went wrong.

0 comments on commit 2fc6745

Please sign in to comment.