From ba0b84838d1b9204edc5e800ded4678a97900a94 Mon Sep 17 00:00:00 2001 From: Thibaud Guillaume-Gentil Date: Sat, 2 Jul 2011 10:01:45 +0200 Subject: [PATCH] Integrated Guard::Ego inside Guard, oh yeah! --- CHANGELOG.md | 1 + Guardfile | 26 ++++++++++---------- lib/guard.rb | 24 ++++++++++--------- lib/guard/dsl.rb | 16 ++++++++++++- lib/guard/ui.rb | 9 ++++++- lib/guard/watcher.rb | 18 ++++++++------ spec/guard/dsl_describer_spec.rb | 2 ++ spec/guard/dsl_spec.rb | 41 +++++++++++++++++++------------- spec/guard/watcher_spec.rb | 12 ++++++++++ 9 files changed, 99 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64e236e..dcc715a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## New features +- Guard::Ego is now part of Guard, so Guardfile is automagically re-evaluated when modified. ([@thibaudgg][]) - Pull request [#91](https://github.com/guard/guard/pull/91): Show Guards in Guardfile with the `guard -T`. ([@johnbintz][]) ## Improvements diff --git a/Guardfile b/Guardfile index d241983..2804e8f 100644 --- a/Guardfile +++ b/Guardfile @@ -4,16 +4,16 @@ guard :rspec, :version => 2 do watch('spec/spec_helper.rb') { "spec" } end -require 'guard/guard' - -module ::Guard - class Breaking < ::Guard::Guard - def run_all - raise "Fool !" - end - end -end - -group "exceptional" do - guard :breaking -end \ No newline at end of file +# require 'guard/guard' +# +# module ::Guard +# class Breaking < ::Guard::Guard +# def run_all +# raise "Fool !" +# end +# end +# end +# +# group "exceptional" do +# guard :breaking +# end \ No newline at end of file diff --git a/lib/guard.rb b/lib/guard.rb index 12b8d47..723beb6 100644 --- a/lib/guard.rb +++ b/lib/guard.rb @@ -29,17 +29,15 @@ module Guard Interactor.init_signal_traps Dsl.evaluate_guardfile(options) - if guards.empty? - UI.error "No guards found in Guardfile, please add at least one." - else - listener.on_change do |files| - run { run_on_change_for_all_guards(files) } if Watcher.match_files?(guards, files) - end + listener.on_change do |files| + Dsl.revaluate_guardfile if Watcher.match_guardfile?(files) - UI.info "Guard is now watching at '#{Dir.pwd}'" - guards.each { |guard| supervised_task(guard, :start) } - listener.start + run { run_on_change_for_all_guards(files) } if Watcher.match_files?(guards, files) end + + UI.info "Guard is now watching at '#{Dir.pwd}'" + guards.each { |guard| supervised_task(guard, :start) } + listener.start end def run_on_change_for_all_guards(files) @@ -79,8 +77,12 @@ module Guard end def add_guard(name, watchers = [], options = {}) - guard_class = get_guard_class(name) - @guards << guard_class.new(watchers, options) + if name.downcase == 'ego' + UI.deprecation("Guard::Ego is now part of Guard you can removed it from your Guardfile.") + else + guard_class = get_guard_class(name) + @guards << guard_class.new(watchers, options) + end end def get_guard_class(name) diff --git a/lib/guard/dsl.rb b/lib/guard/dsl.rb index c814803..ebff95d 100644 --- a/lib/guard/dsl.rb +++ b/lib/guard/dsl.rb @@ -2,12 +2,22 @@ module Guard class Dsl class << self @@options = nil - + def evaluate_guardfile(options = {}) options.is_a?(Hash) or raise ArgumentError.new("evaluate_guardfile not passed a Hash!") @@options = options.dup instance_eval_guardfile(fetch_guardfile_contents) + + UI.error "No guards found in Guardfile, please add at least one." if ::Guard.guards.empty? + end + + def revaluate_guardfile + ::Guard.guards.clear + Dsl.evaluate_guardfile(@@options) + msg = "Guardfile has been re-evaluated." + UI.info(msg) + Notifier.notify(msg) end def instance_eval_guardfile(contents) @@ -69,6 +79,10 @@ module Guard @@options ? @@options[:guardfile_contents] : "" end + def guardfile_path + @@options ? @@options[:guardfile_path] : "" + end + def guardfile_contents_usable? guardfile_contents && guardfile_contents.size >= 'guard :a'.size # smallest guard-definition end diff --git a/lib/guard/ui.rb b/lib/guard/ui.rb index 2be472e..71ee8e7 100644 --- a/lib/guard/ui.rb +++ b/lib/guard/ui.rb @@ -16,6 +16,13 @@ module Guard end end + def deprecation(message, options = {}) + unless ENV["GUARD_ENV"] == "test" + reset_line if options[:reset] + puts "#{color('DEPRECATION:', ';31')} #{message}" + end + end + def debug(message, options = {}) unless ENV["GUARD_ENV"] == "test" reset_line if options[:reset] @@ -48,7 +55,7 @@ module Guard require 'rubygems' unless ENV['NO_RUBYGEMS'] require 'Win32/Console/ANSI' rescue LoadError - @color_enabled = false + @color_enabled = false info "You must 'gem install win32console' to use color on Windows" false end diff --git a/lib/guard/watcher.rb b/lib/guard/watcher.rb index a09f3da..7955c5d 100644 --- a/lib/guard/watcher.rb +++ b/lib/guard/watcher.rb @@ -1,11 +1,11 @@ module Guard class Watcher attr_accessor :pattern, :action - + def initialize(pattern, action = nil) @pattern, @action = pattern, action @@warning_printed ||= false - + # deprecation warning if @pattern.is_a?(String) && @pattern =~ /(^(\^))|(>?(\\\.)|(\.\*))|(\(.*\))|(\[.*\])|(\$$)/ unless @@warning_printed @@ -17,7 +17,7 @@ module Guard @pattern = Regexp.new(@pattern) end end - + def self.match_files(guard, files) guard.watchers.inject([]) do |paths, watcher| files.each do |file| @@ -33,7 +33,7 @@ module Guard paths.flatten.map { |p| p.to_s } end end - + def self.match_files?(guards, files) guards.any? do |guard| guard.watchers.any? do |watcher| @@ -41,7 +41,7 @@ module Guard end end end - + def match_file?(file) if @pattern.is_a?(Regexp) file.match(@pattern) @@ -49,7 +49,11 @@ module Guard file == @pattern ? [file] : nil end end - + + def self.match_guardfile?(files) + files.any? { |file| "#{Dir.pwd}/#{file}" == Dsl.guardfile_path } + end + def call_action(matches) begin @action.arity > 0 ? @action.call(matches) : @action.call @@ -57,6 +61,6 @@ module Guard UI.error "Problem with watch action!\n#{e.message}\n\n#{e.backtrace.join("\n")}" end end - + end end diff --git a/spec/guard/dsl_describer_spec.rb b/spec/guard/dsl_describer_spec.rb index 3850186..c66367d 100644 --- a/spec/guard/dsl_describer_spec.rb +++ b/spec/guard/dsl_describer_spec.rb @@ -1,8 +1,10 @@ require 'spec_helper' describe Guard::DslDescriber do + before(:each) { ::Guard.stub!(:guards).and_return([mock('Guard')]) } subject { described_class } + it 'should evaluate a Guardfile and create the right structure' do mixed_guardfile_string = <<-GUARD guard 'test', :a => :b do diff --git a/spec/guard/dsl_spec.rb b/spec/guard/dsl_spec.rb index 1c98278..d6323f0 100644 --- a/spec/guard/dsl_spec.rb +++ b/spec/guard/dsl_spec.rb @@ -6,13 +6,11 @@ describe Guard::Dsl do @local_guardfile_path = File.join(Dir.pwd, 'Guardfile') @home_guardfile_path = File.expand_path(File.join("~", ".Guardfile")) ::Guard.stub!(:options).and_return(:debug => true) + ::Guard.stub!(:guards).and_return([mock('Guard')]) end describe "it should select the correct data source for Guardfile" do - - before(:each) do - ::Guard::Dsl.stub!(:instance_eval_guardfile) - end + before(:each) { ::Guard::Dsl.stub!(:instance_eval_guardfile) } it "should use a string for initializing" do Guard::UI.should_not_receive(:error) @@ -60,10 +58,15 @@ describe Guard::Dsl do lambda { subject.evaluate_guardfile }.should raise_error end + it "displays an error message when no guard are defined in Guardfile" do + ::Guard::Dsl.stub!(:instance_eval_guardfile) + ::Guard.stub!(:guards).and_return([]) + Guard::UI.should_receive(:error) + subject.evaluate_guardfile(:guardfile_contents => valid_guardfile_string) + end + describe "it should correctly read data from its valid data source" do - before(:each) do - ::Guard::Dsl.stub!(:instance_eval_guardfile) - end + before(:each) { ::Guard::Dsl.stub!(:instance_eval_guardfile) } it "should read correctly from a string" do lambda { subject.evaluate_guardfile(:guardfile_contents => valid_guardfile_string) }.should_not raise_error @@ -86,9 +89,7 @@ describe Guard::Dsl do end describe "It should correctly throw errors when initializing with invalid data" do - before(:each) do - ::Guard::Dsl.stub!(:instance_eval_guardfile) - end + before(:each) { ::Guard::Dsl.stub!(:instance_eval_guardfile) } it "should raise error when there's a problem reading a file" do File.stub!(:exist?).with('/def/Guardfile') { true } @@ -118,7 +119,6 @@ describe Guard::Dsl do lambda { subject.evaluate_guardfile(:guardfile_contents => "") }.should raise_error lambda { subject.evaluate_guardfile(:guardfile_contents => nil) }.should raise_error end - end it "displays an error message when Guardfile is not valid" do @@ -127,13 +127,22 @@ describe Guard::Dsl do lambda { subject.evaluate_guardfile(:guardfile_contents => invalid_guardfile_string ) }.should raise_error end + describe ".revaluate_guardfile" do + before(:each) { ::Guard::Dsl.stub!(:instance_eval_guardfile) } + + it "resets already definded guards before calling evaluate_guardfile" do + subject.evaluate_guardfile(:guardfile_contents => invalid_guardfile_string) + ::Guard.guards.should_not be_empty + ::Guard::Dsl.should_receive(:evaluate_guardfile) + subject.revaluate_guardfile + ::Guard.guards.should be_empty + end + end + describe ".guardfile_default_path" do let(:local_path) { File.join(Dir.pwd, 'Guardfile') } let(:user_path) { File.expand_path(File.join("~", '.Guardfile')) } - - before do - File.stub(:exist? => false) - end + before(:each) { File.stub(:exist? => false) } context "when there is a local Guardfile" do it "returns the path to the local Guardfile" do @@ -156,7 +165,6 @@ describe Guard::Dsl do subject.guardfile_default_path.should == local_path end end - end describe ".guardfile_include?" do @@ -226,7 +234,6 @@ describe Guard::Dsl do subject.evaluate_guardfile(:guardfile_contents => "guard 'test', :opt_a => 1, :opt_b => 'fancy'") end - end describe "#watch" do diff --git a/spec/guard/watcher_spec.rb b/spec/guard/watcher_spec.rb index c9f82dc..bf09df5 100644 --- a/spec/guard/watcher_spec.rb +++ b/spec/guard/watcher_spec.rb @@ -210,4 +210,16 @@ describe Guard::Watcher do end end + describe ".match_guardfile?" do + before(:all) { Guard::Dsl.stub(:guardfile_path) { Dir.pwd + '/Guardfile' } } + + context "with files that match the Guardfile" do + specify { Guard::Watcher.match_guardfile?(['Guardfile', 'guard_rocks_spec.rb']).should be_true } + end + + context "with no files that match the Guardfile" do + specify { Guard::Watcher.match_guardfile?(['guard_rocks.rb', 'guard_rocks_spec.rb']).should be_false } + end + end + end