guard 2.7.0 → 2.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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