guard 1.0.3 → 1.1.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +0 -6
- data/README.md +38 -30
- data/lib/guard.rb +158 -285
- data/lib/guard/cli.rb +16 -2
- data/lib/guard/dsl.rb +41 -20
- data/lib/guard/dsl_describer.rb +1 -1
- data/lib/guard/group.rb +1 -1
- data/lib/guard/guard.rb +39 -5
- data/lib/guard/guardfile.rb +70 -0
- data/lib/guard/runner.rb +179 -0
- data/lib/guard/ui.rb +1 -1
- data/lib/guard/version.rb +2 -4
- data/lib/guard/watcher.rb +1 -0
- metadata +16 -77
- data/bin/fsevent_watch_guard_guard +0 -0
- data/lib/guard/listener.rb +0 -376
- data/lib/guard/listeners/darwin.rb +0 -62
- data/lib/guard/listeners/linux.rb +0 -93
- data/lib/guard/listeners/polling.rb +0 -55
- data/lib/guard/listeners/windows.rb +0 -63
- data/lib/vendor/darwin/Gemfile +0 -6
- data/lib/vendor/darwin/Guardfile +0 -8
- data/lib/vendor/darwin/LICENSE +0 -20
- data/lib/vendor/darwin/README.rdoc +0 -255
- data/lib/vendor/darwin/Rakefile +0 -21
- data/lib/vendor/darwin/bin/fsevent_watch +0 -0
- data/lib/vendor/darwin/ext/fsevent_watch/Info.plist +0 -38
- data/lib/vendor/darwin/ext/fsevent_watch/LICENSE +0 -21
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch.xcodeproj/project.pbxproj +0 -254
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/TSICTString.c +0 -394
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/TSICTString.h +0 -74
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/cli.c +0 -160
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/cli.h +0 -45
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/common.h +0 -34
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/compat.c +0 -20
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/compat.h +0 -40
- data/lib/vendor/darwin/ext/fsevent_watch/fsevent_watch/main.c +0 -509
- data/lib/vendor/darwin/ext/fsevent_watch/xcconfig/Common.xcconfig +0 -82
- data/lib/vendor/darwin/ext/fsevent_watch/xcconfig/Debug.xcconfig +0 -19
- data/lib/vendor/darwin/ext/fsevent_watch/xcconfig/Release.xcconfig +0 -23
- data/lib/vendor/darwin/ext/fsevent_watch/xcconfig/fsevent_watch.xcconfig +0 -17
- data/lib/vendor/darwin/ext/rakefile.rb +0 -47
- data/lib/vendor/darwin/ext/rb-fsevent.xcconfig +0 -33
- data/lib/vendor/darwin/lib/rb-fsevent.rb +0 -2
- data/lib/vendor/darwin/lib/rb-fsevent/fsevent.rb +0 -111
- data/lib/vendor/darwin/lib/rb-fsevent/version.rb +0 -3
- data/lib/vendor/darwin/rb-fsevent.gemspec +0 -25
- data/lib/vendor/darwin/spec/fixtures/folder1/file1.txt +0 -0
- data/lib/vendor/darwin/spec/fixtures/folder1/folder2/file2.txt +0 -0
- data/lib/vendor/darwin/spec/rb-fsevent/fsevent_spec.rb +0 -88
- data/lib/vendor/darwin/spec/spec_helper.rb +0 -23
- data/lib/vendor/linux/MIT-LICENSE +0 -20
- data/lib/vendor/linux/README.md +0 -66
- data/lib/vendor/linux/Rakefile +0 -54
- data/lib/vendor/linux/VERSION +0 -1
- data/lib/vendor/linux/lib/rb-inotify.rb +0 -17
- data/lib/vendor/linux/lib/rb-inotify/event.rb +0 -139
- data/lib/vendor/linux/lib/rb-inotify/native.rb +0 -31
- data/lib/vendor/linux/lib/rb-inotify/native/flags.rb +0 -89
- data/lib/vendor/linux/lib/rb-inotify/notifier.rb +0 -308
- data/lib/vendor/linux/lib/rb-inotify/watcher.rb +0 -83
- data/lib/vendor/linux/rb-inotify.gemspec +0 -53
- data/lib/vendor/windows/Gemfile +0 -4
- data/lib/vendor/windows/README.md +0 -34
- data/lib/vendor/windows/Rakefile +0 -18
- data/lib/vendor/windows/lib/rb-fchange.rb +0 -14
- data/lib/vendor/windows/lib/rb-fchange/event.rb +0 -29
- data/lib/vendor/windows/lib/rb-fchange/native.rb +0 -45
- data/lib/vendor/windows/lib/rb-fchange/native/flags.rb +0 -78
- data/lib/vendor/windows/lib/rb-fchange/notifier.rb +0 -149
- data/lib/vendor/windows/lib/rb-fchange/version.rb +0 -3
- data/lib/vendor/windows/lib/rb-fchange/watcher.rb +0 -99
- data/lib/vendor/windows/rb-fchange.gemspec +0 -34
- data/lib/vendor/windows/spec/fixtures/folder1/file1.txt +0 -0
- data/lib/vendor/windows/spec/fixtures/folder1/folder2/file2.txt +0 -0
- data/lib/vendor/windows/spec/rb-fchange/fchange_spec.rb +0 -119
- data/lib/vendor/windows/spec/spec_helper.rb +0 -21
data/lib/guard/cli.rb
CHANGED
@@ -47,17 +47,19 @@ module Guard
|
|
47
47
|
:aliases => '-G',
|
48
48
|
:banner => 'Specify a Guardfile'
|
49
49
|
|
50
|
+
# DEPRECATED
|
50
51
|
method_option :no_vendor,
|
51
52
|
:type => :boolean,
|
52
53
|
:default => false,
|
53
54
|
:aliases => '-I',
|
54
|
-
:banner => 'Ignore vendored dependencies'
|
55
|
+
:banner => 'DEPRECATED: Ignore vendored dependencies'
|
55
56
|
|
57
|
+
# DEPRECATED
|
56
58
|
method_option :watch_all_modifications,
|
57
59
|
:type => :boolean,
|
58
60
|
:default => false,
|
59
61
|
:aliases => '-A',
|
60
|
-
:banner => 'Watch for all file modifications including moves and deletions'
|
62
|
+
:banner => 'DEPRECATED: Watch for all file modifications including moves and deletions'
|
61
63
|
|
62
64
|
method_option :no_interactions,
|
63
65
|
:type => :boolean,
|
@@ -71,6 +73,18 @@ module Guard
|
|
71
73
|
:aliases => '-B',
|
72
74
|
:banner => 'Turn off warning when Bundler is not present'
|
73
75
|
|
76
|
+
# Listen options
|
77
|
+
method_option :latency,
|
78
|
+
:type => :numeric,
|
79
|
+
:aliases => '-l',
|
80
|
+
:banner => 'Overwrite Listen default latency'
|
81
|
+
|
82
|
+
method_option :force_polling,
|
83
|
+
:type => :boolean,
|
84
|
+
:default => false,
|
85
|
+
:aliases => '-p',
|
86
|
+
:banner => 'Force Listen polling listener usage'
|
87
|
+
|
74
88
|
# Start Guard by initialize the defined Guards and watch the file system.
|
75
89
|
# This is the default task, so calling `guard` is the same as calling `guard start`.
|
76
90
|
#
|
data/lib/guard/dsl.rb
CHANGED
@@ -6,8 +6,8 @@ module Guard
|
|
6
6
|
# The main keywords of the DSL are `guard` and `watch`. These are necessary to define
|
7
7
|
# the used Guards and the file changes they are watching.
|
8
8
|
#
|
9
|
-
# You can optionally group the Guards with the `group` keyword and ignore certain paths
|
10
|
-
# with the `
|
9
|
+
# You can optionally group the Guards with the `group` keyword and ignore and filter certain paths
|
10
|
+
# with the `ignore` and `filter` keywords.
|
11
11
|
#
|
12
12
|
# You can set your preferred system notification library with `notification` and pass
|
13
13
|
# some optional configuration options for the library. If you don't configure a library,
|
@@ -82,6 +82,15 @@ module Guard
|
|
82
82
|
# end
|
83
83
|
#
|
84
84
|
class Dsl
|
85
|
+
|
86
|
+
# Deprecation message for the `ignore_paths` method
|
87
|
+
IGNORE_PATHS_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
88
|
+
Starting with Guard v1.1 the use of the 'ignore_paths' Guardfile dsl method is deprecated.
|
89
|
+
|
90
|
+
Please replace that method with the better 'ignore' or/and 'filter' methods.
|
91
|
+
Documentation on the README: https://github.com/guard/guard#guardfile-dsl-ignore
|
92
|
+
EOS
|
93
|
+
|
85
94
|
class << self
|
86
95
|
|
87
96
|
@@options = nil
|
@@ -105,23 +114,18 @@ module Guard
|
|
105
114
|
# Re-evaluate the `Guardfile` to update the current Guard configuration.
|
106
115
|
#
|
107
116
|
def reevaluate_guardfile
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
after_reevaluate_guardfile
|
112
|
-
end
|
117
|
+
before_reevaluate_guardfile
|
118
|
+
Dsl.evaluate_guardfile(@@options)
|
119
|
+
after_reevaluate_guardfile
|
113
120
|
end
|
114
121
|
|
115
122
|
# Stop Guards and clear internal state
|
116
123
|
# before the Guardfile will be re-evaluated.
|
117
124
|
#
|
118
125
|
def before_reevaluate_guardfile
|
119
|
-
::Guard.
|
120
|
-
::Guard.run_supervised_task(guard, :stop)
|
121
|
-
end
|
122
|
-
|
126
|
+
::Guard.runner.run(:stop)
|
123
127
|
::Guard.guards.clear
|
124
|
-
::Guard.
|
128
|
+
::Guard.setup_groups
|
125
129
|
::Guard::Notifier.clear_notifications
|
126
130
|
|
127
131
|
@@options.delete(:guardfile_contents)
|
@@ -140,9 +144,7 @@ module Guard
|
|
140
144
|
::Guard::UI.info(msg)
|
141
145
|
::Guard::Notifier.notify(msg, :title => 'Guard re-evaluate')
|
142
146
|
|
143
|
-
::Guard.
|
144
|
-
::Guard.run_supervised_task(guard, :start)
|
145
|
-
end
|
147
|
+
::Guard.runner.run(:start)
|
146
148
|
end
|
147
149
|
end
|
148
150
|
|
@@ -421,18 +423,37 @@ module Guard
|
|
421
423
|
@callbacks << { :events => events, :listener => listener }
|
422
424
|
end
|
423
425
|
|
424
|
-
# Ignore certain paths globally.
|
426
|
+
# @deprecated Ignore certain paths globally.
|
425
427
|
#
|
426
428
|
# @example Ignore some paths
|
427
429
|
# ignore_paths ".git", ".svn"
|
428
430
|
#
|
429
431
|
# @param [Array] paths the list of paths to ignore
|
430
432
|
#
|
431
|
-
# @see Guard::Listener
|
432
|
-
#
|
433
433
|
def ignore_paths(*paths)
|
434
|
-
UI.
|
435
|
-
|
434
|
+
UI.deprecation(IGNORE_PATHS_DEPRECATION)
|
435
|
+
end
|
436
|
+
|
437
|
+
# Ignore certain patterns paths globally.
|
438
|
+
#
|
439
|
+
# @example Ignore some paths
|
440
|
+
# ignore %r{^ignored/path/}, /man/
|
441
|
+
#
|
442
|
+
# @param [Regexp] regexp a pattern for ignoring paths
|
443
|
+
#
|
444
|
+
def ignore(*regexps)
|
445
|
+
::Guard.listener = ::Guard.listener.ignore(*regexps)
|
446
|
+
end
|
447
|
+
|
448
|
+
# Filter certain patterns paths globally.
|
449
|
+
#
|
450
|
+
# @example Filter some files
|
451
|
+
# ignore /\.txt$/, /.*\.zip/
|
452
|
+
#
|
453
|
+
# @param [Regexp] regexp a pattern for filtering paths
|
454
|
+
#
|
455
|
+
def filter(*regexps)
|
456
|
+
::Guard.listener = ::Guard.listener.filter(*regexps)
|
436
457
|
end
|
437
458
|
|
438
459
|
end
|
data/lib/guard/dsl_describer.rb
CHANGED
data/lib/guard/group.rb
CHANGED
data/lib/guard/guard.rb
CHANGED
@@ -38,7 +38,7 @@ module Guard
|
|
38
38
|
|
39
39
|
attr_accessor :watchers, :options, :group
|
40
40
|
|
41
|
-
#
|
41
|
+
# Initializes a Guard.
|
42
42
|
#
|
43
43
|
# @param [Array<Guard::Watcher>] watchers the Guard file watchers
|
44
44
|
# @param [Hash] options the custom Guard options
|
@@ -106,24 +106,58 @@ module Guard
|
|
106
106
|
def run_all
|
107
107
|
end
|
108
108
|
|
109
|
+
# Default behavious on file(s) changes that the Guard watches.
|
110
|
+
#
|
111
|
+
# @param [Array<String>] paths the changes files or paths
|
112
|
+
# @raise [:task_has_failed] when run_on_change has failed
|
113
|
+
# @return [Object] the task result
|
114
|
+
#
|
115
|
+
def run_on_changes(paths)
|
116
|
+
raise NotImplementedError
|
117
|
+
end
|
118
|
+
|
119
|
+
# Called on file(s) additions that the Guard watches.
|
120
|
+
#
|
121
|
+
# @param [Array<String>] paths the changes files or paths
|
122
|
+
# @raise [:task_has_failed] when run_on_change has failed
|
123
|
+
# @return [Object] the task result
|
124
|
+
#
|
125
|
+
def run_on_addtions(paths)
|
126
|
+
run_on_changes(paths)
|
127
|
+
end
|
128
|
+
|
109
129
|
# Called on file(s) modifications that the Guard watches.
|
110
130
|
#
|
111
131
|
# @param [Array<String>] paths the changes files or paths
|
112
132
|
# @raise [:task_has_failed] when run_on_change has failed
|
113
133
|
# @return [Object] the task result
|
114
134
|
#
|
115
|
-
def
|
135
|
+
def run_on_modifications(paths)
|
136
|
+
run_on_changes(paths)
|
116
137
|
end
|
117
138
|
|
118
|
-
# Called on file(s)
|
139
|
+
# Called on file(s) removals that the Guard watches.
|
119
140
|
#
|
120
|
-
# @param [Array<String>] paths the
|
141
|
+
# @param [Array<String>] paths the changes files or paths
|
121
142
|
# @raise [:task_has_failed] when run_on_change has failed
|
122
143
|
# @return [Object] the task result
|
123
144
|
#
|
124
|
-
def
|
145
|
+
def run_on_removals(paths)
|
146
|
+
run_on_changes(paths)
|
125
147
|
end
|
126
148
|
|
149
|
+
# @deprecated Use #run_on_modifications or #run_on_addtions instead
|
150
|
+
#
|
151
|
+
# def run_on_change(paths)
|
152
|
+
# raise NotImplementedError
|
153
|
+
# end
|
154
|
+
|
155
|
+
# @deprecated Use #run_on_removals instead
|
156
|
+
#
|
157
|
+
# def run_on_deletion(paths)
|
158
|
+
# raise NotImplementedError
|
159
|
+
# end
|
160
|
+
|
127
161
|
end
|
128
162
|
|
129
163
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# The Guardfile is responsible for generating the Guardfile
|
4
|
+
# and adding guards' template into it.
|
5
|
+
#
|
6
|
+
# @see Guard::CLI
|
7
|
+
#
|
8
|
+
class Guardfile
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# Creates the initial Guardfile template when it does not
|
13
|
+
# already exist.
|
14
|
+
#
|
15
|
+
# @see Guard::CLI.init
|
16
|
+
#
|
17
|
+
# @param [Hash] options The options for creating a Guardfile
|
18
|
+
# @option options [Boolean] :abort_on_existence Whether to abort or not when a Guardfile already exists
|
19
|
+
#
|
20
|
+
def create_guardfile(options = {})
|
21
|
+
if !File.exist?('Guardfile')
|
22
|
+
::Guard::UI.info "Writing new Guardfile to #{ Dir.pwd }/Guardfile"
|
23
|
+
FileUtils.cp(GUARDFILE_TEMPLATE, 'Guardfile')
|
24
|
+
elsif options[:abort_on_existence]
|
25
|
+
::Guard::UI.error "Guardfile already exists at #{ Dir.pwd }/Guardfile"
|
26
|
+
abort
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Adds the Guardfile template of a Guard implementation
|
31
|
+
# to an existing Guardfile.
|
32
|
+
#
|
33
|
+
# @see Guard::CLI.init
|
34
|
+
#
|
35
|
+
# @param [String] guard_name the name of the Guard or template to initialize
|
36
|
+
#
|
37
|
+
def initialize_template(guard_name)
|
38
|
+
guard_class = ::Guard.get_guard_class(guard_name, true)
|
39
|
+
|
40
|
+
if guard_class
|
41
|
+
guard_class.init(guard_name)
|
42
|
+
elsif File.exist?(File.join(HOME_TEMPLATES, guard_name))
|
43
|
+
content = File.read('Guardfile')
|
44
|
+
template = File.read(File.join(HOME_TEMPLATES, guard_name))
|
45
|
+
|
46
|
+
File.open('Guardfile', 'wb') do |f|
|
47
|
+
f.puts(content)
|
48
|
+
f.puts('')
|
49
|
+
f.puts(template)
|
50
|
+
end
|
51
|
+
|
52
|
+
::Guard::UI.info "#{ guard_name } template added to Guardfile, feel free to edit it"
|
53
|
+
else
|
54
|
+
const_name = guard_name.downcase.gsub('-', '')
|
55
|
+
UI.error "Could not load 'guard/#{ guard_name.downcase }' or '~/.guard/templates/#{ guard_name.downcase }' or find class Guard::#{ const_name.capitalize }"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Adds the templates of all installed Guard implementations
|
60
|
+
# to an existing Guardfile.
|
61
|
+
#
|
62
|
+
# @see Guard::CLI.init
|
63
|
+
#
|
64
|
+
def initialize_all_templates
|
65
|
+
::Guard.guard_gem_names.each { |g| initialize_template(g) }
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/guard/runner.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# The runner is responsible for running all methods defined on each guards.
|
4
|
+
#
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
# Deprecation message for the `run_on_change` method
|
8
|
+
RUN_ON_CHANGE_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
9
|
+
Starting with Guard v1.1 the use of the 'run_on_change' method in the '%s' guard is deprecated.
|
10
|
+
|
11
|
+
Please consider replacing that method-call with 'run_on_changes' if the type of change
|
12
|
+
is not important for your usecase or using either 'run_on_modifications' or 'run_on_addtions'
|
13
|
+
based on the type of the changes you want to handle.
|
14
|
+
|
15
|
+
For more information on how to update existing guards, please head over to:
|
16
|
+
https://github.com/guard/guard/wiki/Upgrade-guide-for-existing-guards-to-Guard-v1.1
|
17
|
+
EOS
|
18
|
+
|
19
|
+
# Deprecation message for the `run_on_deletion` method
|
20
|
+
RUN_ON_DELETION_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
21
|
+
Starting with Guard v1.1 the use of the 'run_on_deletion' method in the '%s' guard is deprecated.
|
22
|
+
|
23
|
+
Please consider replacing that method-call with 'run_on_removals' for future proofing your code.
|
24
|
+
|
25
|
+
For more information on how to update existing guards, please head over to:
|
26
|
+
https://github.com/guard/guard/wiki/Upgrade-guide-for-existing-guards-to-Guard-v1.1
|
27
|
+
EOS
|
28
|
+
|
29
|
+
# Displays a warning for each deprecated-method used is any registered guard.
|
30
|
+
#
|
31
|
+
def deprecation_warning
|
32
|
+
::Guard.guards.each do |guard|
|
33
|
+
UI.deprecation(RUN_ON_CHANGE_DEPRECATION % guard.class.name) if guard.respond_to?(:run_on_change)
|
34
|
+
UI.deprecation(RUN_ON_DELETION_DEPRECATION % guard.class.name) if guard.respond_to?(:run_on_deletion)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Runs a Guard-task on all registered guards.
|
39
|
+
#
|
40
|
+
# @param [Symbol] task the task to run
|
41
|
+
# @param [Hash] scope either the guard or the group to run the task on
|
42
|
+
#
|
43
|
+
# @see self.run_supervised_task
|
44
|
+
#
|
45
|
+
def run(task, scopes = {})
|
46
|
+
scoped_guards(scopes) do |guard|
|
47
|
+
run_supervised_task(guard, task)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Runs the appropriate tasks on all registered guards
|
52
|
+
# based on the passed changes.
|
53
|
+
#
|
54
|
+
# @param [Array<String>] modified the modified paths.
|
55
|
+
# @param [Array<String>] added the added paths.
|
56
|
+
# @param [Array<String>] removed the removed paths.
|
57
|
+
#
|
58
|
+
def run_on_changes(modified, added, removed)
|
59
|
+
scoped_guards do |guard|
|
60
|
+
modified_paths = Watcher.match_files(guard, modified)
|
61
|
+
added_paths = Watcher.match_files(guard, added)
|
62
|
+
removed_paths = Watcher.match_files(guard, removed)
|
63
|
+
|
64
|
+
if !modified_paths.empty? || !added_paths.empty? || !removed_paths.empty?
|
65
|
+
UI.clear
|
66
|
+
|
67
|
+
unless modified_paths.empty?
|
68
|
+
run_first_task_found(guard, [:run_on_modifications, :run_on_change], modified_paths)
|
69
|
+
end
|
70
|
+
unless added_paths.empty?
|
71
|
+
run_first_task_found(guard, [:run_on_addtions, :run_on_change], added_paths)
|
72
|
+
end
|
73
|
+
unless removed_paths.empty?
|
74
|
+
run_first_task_found(guard, [:run_on_removals, :run_on_deletion], removed_paths)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Run a Guard task, but remove the Guard when his work leads to a system failure.
|
81
|
+
#
|
82
|
+
# When the Group has `:halt_on_fail` disabled, we've to catch `:task_has_failed`
|
83
|
+
# here in order to avoid an uncaught throw error.
|
84
|
+
#
|
85
|
+
# @param [Guard::Guard] guard the Guard to execute
|
86
|
+
# @param [Symbol] task the task to run
|
87
|
+
# @param [Array] args the arguments for the task
|
88
|
+
# @raise [:task_has_failed] when task has failed
|
89
|
+
#
|
90
|
+
def run_supervised_task(guard, task, *args)
|
91
|
+
::Guard.within_preserved_state do
|
92
|
+
begin
|
93
|
+
catch Runner.stopping_symbol_for(guard) do
|
94
|
+
guard.hook("#{ task }_begin", *args)
|
95
|
+
result = guard.send(task, *args)
|
96
|
+
guard.hook("#{ task }_end", result)
|
97
|
+
result
|
98
|
+
end
|
99
|
+
|
100
|
+
rescue NotImplementedError => ex
|
101
|
+
raise ex
|
102
|
+
rescue Exception => ex
|
103
|
+
UI.error("#{ guard.class.name } failed to achieve its <#{ task.to_s }>, exception was:" +
|
104
|
+
"\n#{ ex.class }: #{ ex.message }\n#{ ex.backtrace.join("\n") }")
|
105
|
+
|
106
|
+
::Guard.guards.delete guard
|
107
|
+
UI.info("\n#{ guard.class.name } has just been fired")
|
108
|
+
|
109
|
+
ex
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the symbol that has to be caught when running a supervised task.
|
115
|
+
#
|
116
|
+
# @note If a Guard group is being run and it has the `:halt_on_fail`
|
117
|
+
# option set, this method returns :no_catch as it will be caught at the
|
118
|
+
# group level.
|
119
|
+
# @see .scoped_guards
|
120
|
+
#
|
121
|
+
# @param [Guard::Guard] guard the Guard to execute
|
122
|
+
#
|
123
|
+
# @return [Symbol] the symbol to catch
|
124
|
+
#
|
125
|
+
def self.stopping_symbol_for(guard)
|
126
|
+
return :task_has_failed if guard.group.class != Symbol
|
127
|
+
|
128
|
+
group = ::Guard.groups(guard.group)
|
129
|
+
group.options[:halt_on_fail] ? :no_catch : :task_has_failed
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
# Tries to run the first implemented task by a given guard
|
135
|
+
# from a collection of tasks.
|
136
|
+
#
|
137
|
+
# @param [Guard::Guard] guard the guard to run the found task on
|
138
|
+
# @param [Array<Symbol>] tasks the tasks to run the first among
|
139
|
+
# @param [Object] task_param the param to pass to each task
|
140
|
+
#
|
141
|
+
def run_first_task_found(guard, tasks, task_param)
|
142
|
+
enum = tasks.to_enum
|
143
|
+
|
144
|
+
begin
|
145
|
+
task = enum.next
|
146
|
+
UI.debug "Trying to run #{ guard.class.name }##{ task.to_s } with #{ task_param.inspect }"
|
147
|
+
run_supervised_task(guard, task, task_param)
|
148
|
+
rescue StopIteration
|
149
|
+
# Do nothing
|
150
|
+
rescue NotImplementedError
|
151
|
+
retry
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Loop through all groups and run the given task for each Guard.
|
156
|
+
#
|
157
|
+
# Stop the task run for the all Guards within a group if one Guard
|
158
|
+
# throws `:task_has_failed`.
|
159
|
+
#
|
160
|
+
# @param [Hash] scope an hash with a guard or a group scope
|
161
|
+
# @yield the task to run
|
162
|
+
#
|
163
|
+
def scoped_guards(scopes = {})
|
164
|
+
if guard = scopes[:guard]
|
165
|
+
yield(guard)
|
166
|
+
else
|
167
|
+
groups = scopes[:group] ? [scopes[:group]] : ::Guard.groups
|
168
|
+
groups.each do |group|
|
169
|
+
catch :task_has_failed do
|
170
|
+
::Guard.guards(:group => group.name).each do |guard|
|
171
|
+
yield(guard)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|