Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Remove all empty methods from guard/guard

Guard methods  need to be now implemented but no more overwritten like
before, logic move to the runner class
  • Loading branch information...
commit 95d9cd1bc7896b1167224e95063923325c243d85 1 parent bf2e0f5
Thibaud Guillaume-Gentil authored
Showing with 69 additions and 167 deletions.
  1. +22 −33 lib/guard/guard.rb
  2. +32 −25 lib/guard/runner.rb
  3. +15 −109 spec/guard/runner_spec.rb
View
55 lib/guard/guard.rb
@@ -2,8 +2,13 @@ module Guard
# Base class that every Guard implementation must inherit from.
#
- # Guard will trigger the `start`, `stop`, `reload`, `run_all`, `run_on_change` and
- # `run_on_deletion` task methods depending on user interaction and file modification.
+ # Guard will trigger the `start`, `stop`, `reload`, `run_all` and `run_on_changes`
+ # (`run_on_additions`, `run_on_modifications` and `run_on_removals`) task methods
+ # depending on user interaction and file modification.
+ #
+ # `run_on_changes` could be implemented to handle all the changes task case (additions,
+ # modifications, removals) in once, or each task can be implemented separatly with a
+ # specific behavior.
#
# In each of these Guard task methods you have to implement some work when you want to
# support this kind of task. The return value of each Guard task method is not evaluated
@@ -81,16 +86,16 @@ def to_s
# @raise [:task_has_failed] when start has failed
# @return [Object] the task result
#
- def start
- end
+ # def start
+ # end
# Called when `stop|quit|exit|s|q|e + enter` is pressed (when Guard quits).
#
# @raise [:task_has_failed] when stop has failed
# @return [Object] the task result
#
- def stop
- end
+ # def stop
+ # end
# Called when `reload|r|z + enter` is pressed.
# This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/...
@@ -98,8 +103,8 @@ def stop
# @raise [:task_has_failed] when reload has failed
# @return [Object] the task result
#
- def reload
- end
+ # def reload
+ # end
# Called when just `enter` is pressed
# This method should be principally used for long action like running all specs/tests/...
@@ -107,8 +112,8 @@ def reload
# @raise [:task_has_failed] when run_all has failed
# @return [Object] the task result
#
- def run_all
- end
+ # def run_all
+ # end
# Default behavious on file(s) changes that the Guard watches.
#
@@ -116,9 +121,8 @@ def run_all
# @raise [:task_has_failed] when run_on_change has failed
# @return [Object] the task result
#
- def run_on_changes(paths)
- raise NotImplementedError
- end
+ # def run_on_changes(paths)
+ # end
# Called on file(s) additions that the Guard watches.
#
@@ -126,9 +130,8 @@ def run_on_changes(paths)
# @raise [:task_has_failed] when run_on_change has failed
# @return [Object] the task result
#
- def run_on_additions(paths)
- run_on_changes(paths)
- end
+ # def run_on_additions(paths)
+ # end
# Called on file(s) modifications that the Guard watches.
#
@@ -136,9 +139,8 @@ def run_on_additions(paths)
# @raise [:task_has_failed] when run_on_change has failed
# @return [Object] the task result
#
- def run_on_modifications(paths)
- run_on_changes(paths)
- end
+ # def run_on_modifications(paths)
+ # end
# Called on file(s) removals that the Guard watches.
#
@@ -146,20 +148,7 @@ def run_on_modifications(paths)
# @raise [:task_has_failed] when run_on_change has failed
# @return [Object] the task result
#
- def run_on_removals(paths)
- run_on_changes(paths)
- end
-
- # @deprecated Use #run_on_modifications or #run_on_additions instead
- #
- # def run_on_change(paths)
- # raise NotImplementedError
- # end
-
- # @deprecated Use #run_on_removals instead
- #
- # def run_on_deletion(paths)
- # raise NotImplementedError
+ # def run_on_removals(paths)
# end
end
View
57 lib/guard/runner.rb
@@ -48,6 +48,10 @@ def run(task, scopes = {})
end
end
+ MODIFICATION_TASKS = [:run_on_modifications, :run_on_changes, :run_on_change]
+ ADDITION_TASKS = [:run_on_additions, :run_on_changes, :run_on_change]
+ REMOVAL_TASKS = [:run_on_removals, :run_on_changes, :run_on_deletion]
+
# Runs the appropriate tasks on all registered guards
# based on the passed changes.
#
@@ -61,19 +65,11 @@ def run_on_changes(modified, added, removed)
added_paths = Watcher.match_files(guard, added)
removed_paths = Watcher.match_files(guard, removed)
- if !modified_paths.empty? || !added_paths.empty? || !removed_paths.empty?
- UI.clear
+ UI.clear if clearable?(guard, modified_paths, added_paths, removed_paths)
- unless modified_paths.empty?
- run_first_task_found(guard, [:run_on_modifications, :run_on_change], modified_paths)
- end
- unless added_paths.empty?
- run_first_task_found(guard, [:run_on_additions, :run_on_change], added_paths)
- end
- unless removed_paths.empty?
- run_first_task_found(guard, [:run_on_removals, :run_on_deletion], removed_paths)
- end
- end
+ run_first_task_found(guard, MODIFICATION_TASKS, modified_paths) unless modified_paths.empty?
+ run_first_task_found(guard, ADDITION_TASKS, added_paths) unless added_paths.empty?
+ run_first_task_found(guard, REMOVAL_TASKS, removed_paths) unless removed_paths.empty?
end
end
@@ -97,8 +93,8 @@ def run_supervised_task(guard, task, *args)
result
end
- rescue NotImplementedError => ex
- raise ex
+ rescue NoMethodError
+ # Do nothing
rescue Exception => ex
UI.error("#{ guard.class.name } failed to achieve its <#{ task.to_s }>, exception was:" +
"\n#{ ex.class }: #{ ex.message }\n#{ ex.backtrace.join("\n") }")
@@ -129,7 +125,7 @@ def self.stopping_symbol_for(guard)
group.options[:halt_on_fail] ? :no_catch : :task_has_failed
end
- private
+ private
# Tries to run the first implemented task by a given guard
# from a collection of tasks.
@@ -139,16 +135,13 @@ def self.stopping_symbol_for(guard)
# @param [Object] task_param the param to pass to each task
#
def run_first_task_found(guard, tasks, task_param)
- enum = tasks.to_enum
-
- begin
- task = enum.next
- UI.debug "Trying to run #{ guard.class.name }##{ task.to_s } with #{ task_param.inspect }"
- run_supervised_task(guard, task, task_param)
- rescue StopIteration
- # Do nothing
- rescue NotImplementedError
- retry
+ tasks.each do |task|
+ if guard.respond_to?(task)
+ run_supervised_task(guard, task, task_param)
+ break
+ else
+ UI.debug "Trying to run #{ guard.class.name }##{ task.to_s } with #{ task_param.inspect }"
+ end
end
end
@@ -175,5 +168,19 @@ def scoped_guards(scopes = {})
end
end
+ # Logic to know if the UI can be cleared or not in the run_on_changes method
+ # based on the guard and the changes.
+ #
+ # @param [Guard::Guard] guard the guard where run_on_changes is called
+ # @param [Array<String>] modified_paths the modified paths.
+ # @param [Array<String>] added_paths the added paths.
+ # @param [Array<String>] removed_paths the removed paths.
+ #
+ def clearable?(guard, modified_paths, added_paths, removed_paths)
+ (MODIFICATION_TASKS.any? { |task| guard.respond_to?(task) } && !modified_paths.empty?) ||
+ (ADDITION_TASKS.any? { |task| guard.respond_to?(task) } && !added_paths.empty?) ||
+ (REMOVAL_TASKS.any? { |task| guard.respond_to?(task) } && !removed_paths.empty?)
+ end
+
end
end
View
124 spec/guard/runner_spec.rb
@@ -121,9 +121,19 @@ class ::Guard::Bar2 < ::Guard::Guard; end
before {
subject.stub(:scoped_guards).and_yield(foo_guard)
+ subject.stub(:clearable?) { false }
watcher_module.stub(:match_files) { [] }
}
+ context 'when clearable' do
+ before { subject.stub(:clearable?) { true } }
+
+ it "clear UI" do
+ Guard::UI.should_receive(:clear)
+ subject.run_on_changes(*changes)
+ end
+ end
+
context 'with no changes' do
it 'does not run any task' do
%w[run_on_modifications run_on_change run_on_additions run_on_removals run_on_deletion].each do |task|
@@ -131,11 +141,6 @@ class ::Guard::Bar2 < ::Guard::Guard; end
end
subject.run_on_changes(*changes)
end
-
- it 'does not clear UI' do
- Guard::UI.should_not_receive(:clear)
- subject.run_on_changes(*changes)
- end
end
context "with modified files but modified paths is empty" do
@@ -150,11 +155,6 @@ class ::Guard::Bar2 < ::Guard::Guard; end
subject.should_not_receive(:run_first_task_found)
subject.run_on_changes(*changes)
end
-
- it 'does not clear UI' do
- Guard::UI.should_not_receive(:clear)
- subject.run_on_changes(*changes)
- end
end
context 'with modified paths' do
@@ -165,38 +165,10 @@ class ::Guard::Bar2 < ::Guard::Guard; end
watcher_module.should_receive(:match_files).with(foo_guard, modified).and_return(modified)
end
- it 'executes the :run_on_modifications task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_modifications, modified)
- subject.run_on_changes(*changes)
- end
-
- it 'clear UI' do
- Guard::UI.should_receive(:clear)
+ it 'executes the :run_first_task_found task' do
+ subject.should_receive(:run_first_task_found).with(foo_guard, [:run_on_modifications, :run_on_changes, :run_on_change], modified)
subject.run_on_changes(*changes)
end
-
- context 'when :run_on_modifications is not implemented' do
- before { subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_modifications, modified).and_raise(NotImplementedError) }
-
- it 'executes the :run_on_change task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_change, modified)
- subject.run_on_changes(*changes)
- end
- end
-
- context 'when neither :run_on_modifications nor :run_on_change is implemented' do
- before do
- %w[run_on_modifications run_on_change].each do |task|
- subject.should_receive(:run_supervised_task).with(foo_guard, task.to_sym, modified).and_raise(NotImplementedError)
- end
- end
-
- it 'ignores the error' do
- expect {
- subject.run_on_changes(*changes)
- }.to_not raise_error(NotImplementedError)
- end
- end
end
context "with added files but added paths is empty" do
@@ -211,11 +183,6 @@ class ::Guard::Bar2 < ::Guard::Guard; end
subject.should_not_receive(:run_first_task_found)
subject.run_on_changes(*changes)
end
-
- it 'does not clear UI' do
- Guard::UI.should_not_receive(:clear)
- subject.run_on_changes(*changes)
- end
end
context 'with added paths' do
@@ -227,40 +194,12 @@ class ::Guard::Bar2 < ::Guard::Guard; end
end
it 'executes the :run_on_additions task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_additions, added)
- subject.run_on_changes(*changes)
- end
-
- it 'clear UI' do
- Guard::UI.should_receive(:clear)
+ subject.should_receive(:run_first_task_found).with(foo_guard, [:run_on_additions, :run_on_changes, :run_on_change], added)
subject.run_on_changes(*changes)
end
-
- context 'when :run_on_additions is not implemented' do
- before { subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_additions, added).and_raise(NotImplementedError) }
-
- it 'executes the :run_on_change task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_change, added)
- subject.run_on_changes(*changes)
- end
- end
-
- context 'when neither :run_on_additions nor :run_on_change is implemented' do
- before do
- %w[run_on_additions run_on_change].each do |task|
- subject.should_receive(:run_supervised_task).with(foo_guard, task.to_sym, added).and_raise(NotImplementedError)
- end
- end
-
- it 'ignores the error' do
- expect {
- subject.run_on_changes(*changes)
- }.to_not raise_error(NotImplementedError)
- end
- end
end
- context "with added files but added paths is empty" do
+ context "with removed files but removed paths is empty" do
let(:removed) { %w[file.txt image.png] }
before do
@@ -272,11 +211,6 @@ class ::Guard::Bar2 < ::Guard::Guard; end
subject.should_not_receive(:run_first_task_found)
subject.run_on_changes(*changes)
end
-
- it 'does not clear UI' do
- Guard::UI.should_not_receive(:clear)
- subject.run_on_changes(*changes)
- end
end
context 'with removed paths' do
@@ -288,37 +222,9 @@ class ::Guard::Bar2 < ::Guard::Guard; end
end
it 'executes the :run_on_removals task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_removals, removed)
- subject.run_on_changes(*changes)
- end
-
- it 'clear UI' do
- Guard::UI.should_receive(:clear)
+ subject.should_receive(:run_first_task_found).with(foo_guard, [:run_on_removals, :run_on_changes, :run_on_deletion], removed)
subject.run_on_changes(*changes)
end
-
- context 'when :run_on_removals is not implemented' do
- before { subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_removals, removed).and_raise(NotImplementedError) }
-
- it 'executes the :run_on_deletion task' do
- subject.should_receive(:run_supervised_task).with(foo_guard, :run_on_deletion, removed)
- subject.run_on_changes(*changes)
- end
- end
-
- context 'when neither :run_on_removals nor :run_on_deletion is implemented' do
- before do
- %w[run_on_removals run_on_deletion].each do |task|
- subject.should_receive(:run_supervised_task).with(foo_guard, task.to_sym, removed).and_raise(NotImplementedError)
- end
- end
-
- it 'ignores the error' do
- expect {
- subject.run_on_changes(*changes)
- }.to_not raise_error(NotImplementedError)
- end
- end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.