guard 2.7.0 → 2.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,200 +0,0 @@
1
- require "lumberjack"
2
-
3
- require "guard/ui"
4
- require "guard/watcher"
5
-
6
- module Guard
7
- # The runner is responsible for running all methods defined on each plugin.
8
- #
9
- class Runner
10
- # Runs a Guard-task on all registered plugins.
11
- #
12
- # @param [Symbol] task the task to run
13
- #
14
- # @param [Hash] scopes either the Guard plugin or the group to run the task
15
- # on
16
- #
17
- # @see self.run_supervised_task
18
- #
19
- def run(task, scope = {})
20
- Lumberjack.unit_of_work do
21
- _scoped_plugins(scope) do |guard|
22
- run_supervised_task(guard, task) if guard.respond_to?(task)
23
- end
24
- end
25
- end
26
-
27
- MODIFICATION_TASKS = [
28
- :run_on_modifications, :run_on_changes, :run_on_change
29
- ]
30
-
31
- ADDITION_TASKS = [:run_on_additions, :run_on_changes, :run_on_change]
32
- REMOVAL_TASKS = [:run_on_removals, :run_on_changes, :run_on_deletion]
33
-
34
- # Runs the appropriate tasks on all registered plugins
35
- # based on the passed changes.
36
- #
37
- # @param [Array<String>] modified the modified paths.
38
- # @param [Array<String>] added the added paths.
39
- # @param [Array<String>] removed the removed paths.
40
- #
41
- def run_on_changes(modified, added, removed)
42
- types = {
43
- MODIFICATION_TASKS => modified,
44
- ADDITION_TASKS => added,
45
- REMOVAL_TASKS => removed
46
- }
47
-
48
- ::Guard::UI.clearable
49
-
50
- _scoped_plugins do |guard|
51
- ::Guard::UI.clear
52
-
53
- types.each do |tasks, unmatched_paths|
54
- paths = ::Guard::Watcher.match_files(guard, unmatched_paths)
55
- next if paths.empty?
56
-
57
- next unless (task = tasks.detect { |meth| guard.respond_to?(meth) })
58
- run_supervised_task(guard, task, paths)
59
- end
60
- end
61
- end
62
-
63
- # Run a Guard plugin task, but remove the Guard plugin when his work leads
64
- # to a system failure.
65
- #
66
- # When the Group has `:halt_on_fail` disabled, we've to catch
67
- # `:task_has_failed` here in order to avoid an uncaught throw error.
68
- #
69
- # @param [Guard::Plugin] guard the Guard to execute
70
- # @param [Symbol] task the task to run
71
- # @param [Array] args the arguments for the task
72
- # @raise [:task_has_failed] when task has failed
73
- #
74
- def run_supervised_task(guard, task, *args)
75
- catch self.class.stopping_symbol_for(guard) do
76
- guard.hook("#{ task }_begin", *args)
77
- begin
78
- result = guard.send(task, *args)
79
- rescue Interrupt
80
- throw(:task_has_failed)
81
- end
82
- guard.hook("#{ task }_end", result)
83
- result
84
- end
85
- rescue ScriptError, StandardError, RuntimeError
86
- ::Guard::UI.error("#{ guard.class.name } failed to achieve its"\
87
- " <#{ task }>, exception was:" \
88
- "\n#{ $!.class }: #{ $!.message }" \
89
- "\n#{ $!.backtrace.join("\n") }")
90
- ::Guard.plugins.delete guard
91
- ::Guard::UI.info("\n#{ guard.class.name } has just been fired")
92
- $!
93
- end
94
-
95
- # Returns the symbol that has to be caught when running a supervised task.
96
- #
97
- # @note If a Guard group is being run and it has the `:halt_on_fail`
98
- # option set, this method returns :no_catch as it will be caught at the
99
- # group level.
100
- # @see ._scoped_plugins
101
- #
102
- # @param [Guard::Plugin] guard the Guard plugin to execute
103
- # @return [Symbol] the symbol to catch
104
- #
105
- def self.stopping_symbol_for(guard)
106
- guard.group.options[:halt_on_fail] ? :no_catch : :task_has_failed
107
- end
108
-
109
- private
110
-
111
- # Loop through all groups and run the given task for each Guard plugin.
112
- #
113
- # If no scope is supplied, the global Guard scope is taken into account.
114
- # If both a plugin and a group scope is given, then only the plugin scope
115
- # is used.
116
- #
117
- # Stop the task run for the all Guard plugins within a group if one Guard
118
- # throws `:task_has_failed`.
119
- #
120
- # @param [Hash] scopes hash with plugins or a groups scope
121
- # @yield the task to run
122
- #
123
- def _scoped_plugins(scopes = {})
124
- if plugins = _current_plugins_scope(scopes)
125
- plugins.each do |guard|
126
- yield(guard)
127
- end
128
- else
129
- _current_groups_scope(scopes).each do |group|
130
- current_plugin = nil
131
- block_return = catch :task_has_failed do
132
- ::Guard.plugins(group: group.name).each do |guard|
133
- current_plugin = guard
134
- yield(guard)
135
- end
136
- end
137
-
138
- next unless block_return.nil?
139
-
140
- ::Guard::UI.info "#{ current_plugin.class.name } has failed,"\
141
- " other group's plugins execution has been halted."
142
- end
143
- end
144
- end
145
-
146
- # Returns the current plugins scope.
147
- # Local plugins scope wins over global plugins scope.
148
- # If no plugins scope is found, then NO plugins are returned.
149
- #
150
- # @param [Hash] scopes hash with a local plugins or a groups scope
151
- # @return [Array<Guard::Plugin>] the plugins to scope to
152
- #
153
- def _current_plugins_scope(scope)
154
- if plugins = _find_non_empty_plugins_scope(scope)
155
- Array(plugins).map do |plugin|
156
- plugin.is_a?(Symbol) ? ::Guard.plugin(plugin) : plugin
157
- end
158
- else
159
- nil
160
- end
161
- end
162
-
163
- # Returns the current groups scope.
164
- # Local groups scope wins over global groups scope.
165
- # If no groups scope is found, then ALL groups are returned.
166
- #
167
- # @param [Hash] scopes hash with a local plugins or a groups scope
168
- # @return [Array<Guard::Group>] the groups to scope to
169
- #
170
- def _current_groups_scope(scope)
171
- Array(_find_non_empty_groups_scope(scope)).map do |group|
172
- group.is_a?(Symbol) ? ::Guard.group(group) : group
173
- end
174
- end
175
-
176
- # Find the first non empty element in the given possibilities
177
- #
178
- def _find_non_empty_scope(type, local_scope, *additional_possibilities)
179
- found = [
180
- local_scope[:"#{type}s"],
181
- local_scope[type.to_sym],
182
- ::Guard.scope[:"#{type}s"],
183
- additional_possibilities.flatten
184
- ].compact.detect { |a| !Array(a).empty? }
185
- found ? [::Guard.group(:common)] + Array(found) : found
186
- end
187
-
188
- # Find the first non empty plugins scope
189
- #
190
- def _find_non_empty_plugins_scope(scope)
191
- _find_non_empty_scope(:plugin, scope)
192
- end
193
-
194
- # Find the first non empty groups scope
195
- #
196
- def _find_non_empty_groups_scope(scope)
197
- _find_non_empty_scope(:group, scope, ::Guard.groups)
198
- end
199
- end
200
- end