guard 2.6.1 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +73 -58
- data/bin/guard +2 -2
- data/lib/guard.rb +64 -59
- data/lib/guard/cli.rb +66 -60
- data/lib/guard/cli.rb.orig +215 -0
- data/lib/guard/commander.rb +45 -69
- data/lib/guard/commands/all.rb +21 -19
- data/lib/guard/commands/change.rb +17 -22
- data/lib/guard/commands/notification.rb +15 -16
- data/lib/guard/commands/pause.rb +14 -15
- data/lib/guard/commands/reload.rb +19 -20
- data/lib/guard/commands/scope.rb +23 -19
- data/lib/guard/commands/show.rb +13 -16
- data/lib/guard/deprecated_methods.rb +6 -10
- data/lib/guard/deprecator.rb +52 -37
- data/lib/guard/dsl.rb +55 -33
- data/lib/guard/dsl_describer.rb +83 -31
- data/lib/guard/dsl_describer.rb.orig +184 -0
- data/lib/guard/group.rb +7 -6
- data/lib/guard/guard.rb +4 -4
- data/lib/guard/guard.rb.orig +42 -0
- data/lib/guard/guardfile.rb +12 -13
- data/lib/guard/guardfile/evaluator.rb +77 -55
- data/lib/guard/guardfile/evaluator.rb.orig +275 -0
- data/lib/guard/guardfile/generator.rb +25 -20
- data/lib/guard/interactor.rb +52 -293
- data/lib/guard/interactor.rb.orig +85 -0
- data/lib/guard/jobs/base.rb +21 -0
- data/lib/guard/jobs/pry_wrapper.rb +290 -0
- data/lib/guard/jobs/pry_wrapper.rb.orig +293 -0
- data/lib/guard/jobs/sleep.rb +25 -0
- data/lib/guard/notifier.rb +42 -39
- data/lib/guard/notifiers/base.rb +25 -24
- data/lib/guard/notifiers/emacs.rb +30 -24
- data/lib/guard/notifiers/file_notifier.rb +3 -7
- data/lib/guard/notifiers/gntp.rb +22 -22
- data/lib/guard/notifiers/growl.rb +16 -15
- data/lib/guard/notifiers/libnotify.rb +7 -10
- data/lib/guard/notifiers/notifysend.rb +15 -14
- data/lib/guard/notifiers/rb_notifu.rb +8 -10
- data/lib/guard/notifiers/terminal_notifier.rb +15 -11
- data/lib/guard/notifiers/terminal_title.rb +4 -8
- data/lib/guard/notifiers/tmux.rb +104 -71
- data/lib/guard/options.rb +1 -5
- data/lib/guard/plugin.rb +1 -3
- data/lib/guard/plugin/base.rb +12 -9
- data/lib/guard/plugin/hooker.rb +1 -5
- data/lib/guard/plugin_util.rb +46 -25
- data/lib/guard/plugin_util.rb.orig +178 -0
- data/lib/guard/rake_task.rb +4 -7
- data/lib/guard/reevaluator.rb +13 -0
- data/lib/guard/runner.rb +50 -78
- data/lib/guard/runner.rb.orig +200 -0
- data/lib/guard/setuper.rb +199 -130
- data/lib/guard/setuper.rb.orig +348 -0
- data/lib/guard/sheller.rb +107 -0
- data/lib/guard/tags +367 -0
- data/lib/guard/ui.rb +50 -38
- data/lib/guard/ui.rb.orig +254 -0
- data/lib/guard/ui/colors.rb +17 -21
- data/lib/guard/version.rb +1 -1
- data/lib/guard/version.rb.orig +3 -0
- data/lib/guard/watcher.rb +49 -62
- metadata +21 -4
- data/lib/guard/notifiers/growl_notify.rb +0 -93
data/lib/guard/plugin_util.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "guard/ui"
|
2
2
|
|
3
3
|
module Guard
|
4
|
-
|
5
4
|
# This class contains useful methods to:
|
6
5
|
#
|
7
6
|
# * Fetch all the Guard plugins names;
|
@@ -10,6 +9,11 @@ module Guard
|
|
10
9
|
# * Add its template to the Guardfile.
|
11
10
|
#
|
12
11
|
class PluginUtil
|
12
|
+
ERROR_NO_GUARD_OR_CLASS = "Could not load 'guard/%s' or'\
|
13
|
+
' find class Guard::%s"
|
14
|
+
|
15
|
+
INFO_ADDED_GUARD_TO_GUARDFILE = "%s guard added to Guardfile,"\
|
16
|
+
" feel free to edit it"
|
13
17
|
|
14
18
|
attr_accessor :name
|
15
19
|
|
@@ -18,18 +22,27 @@ module Guard
|
|
18
22
|
# @return [Array<String>] a list of Guard plugin gem names
|
19
23
|
#
|
20
24
|
def self.plugin_names
|
21
|
-
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create(
|
25
|
+
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
|
22
26
|
Gem::Specification.find_all.select do |x|
|
23
27
|
if x.name =~ /^guard-/
|
24
28
|
true
|
25
|
-
elsif x.name !=
|
26
|
-
|
27
|
-
File.
|
29
|
+
elsif x.name != "guard"
|
30
|
+
|
31
|
+
guard_plugin_path = File.join(
|
32
|
+
x.full_gem_path,
|
33
|
+
"lib/guard/#{ x.name }.rb"
|
34
|
+
)
|
35
|
+
|
36
|
+
File.exist?(guard_plugin_path)
|
28
37
|
end
|
29
38
|
end
|
30
39
|
else
|
40
|
+
::Guard::UI.deprecation \
|
41
|
+
"Rubygems version prior to 1.8.0 are no longer supported"\
|
42
|
+
" and may not work"
|
43
|
+
|
31
44
|
Gem.source_index.find_name(/^guard-/)
|
32
|
-
end.map { |x| x.name.sub(/^guard-/,
|
45
|
+
end.map { |x| x.name.sub(/^guard-/, "") }.uniq
|
33
46
|
end
|
34
47
|
|
35
48
|
# Initializes a new `Guard::PluginUtil` object.
|
@@ -37,7 +50,7 @@ module Guard
|
|
37
50
|
# @param [String] name the name of the Guard plugin
|
38
51
|
#
|
39
52
|
def initialize(name)
|
40
|
-
@name = name.to_s.sub(/^guard-/,
|
53
|
+
@name = name.to_s.sub(/^guard-/, "")
|
41
54
|
end
|
42
55
|
|
43
56
|
# Initializes a new `Guard::Plugin` with the given `options` hash. This
|
@@ -45,16 +58,18 @@ module Guard
|
|
45
58
|
# class as well as plugins that inherit from `Guard::Plugin`.
|
46
59
|
#
|
47
60
|
# @see Guard::Plugin
|
48
|
-
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
61
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
62
|
+
# upgrade for Guard 2.0
|
49
63
|
#
|
50
64
|
# @return [Guard::Plugin] the initialized plugin
|
51
65
|
# @return [Guard::Guard] the initialized plugin. This return type is
|
52
66
|
# deprecated and the plugin's maintainer should update it to be
|
53
67
|
# compatible with Guard 2.0. For more information on how to upgrade for
|
54
|
-
# Guard 2.0, please head over to:
|
68
|
+
# Guard 2.0, please head over to:
|
69
|
+
# https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0
|
55
70
|
#
|
56
71
|
def initialize_plugin(options)
|
57
|
-
if plugin_class.superclass.to_s ==
|
72
|
+
if plugin_class.superclass.to_s == "Guard::Guard"
|
58
73
|
plugin_class.new(options.delete(:watchers), options)
|
59
74
|
else
|
60
75
|
plugin_class.new(options)
|
@@ -67,7 +82,7 @@ module Guard
|
|
67
82
|
#
|
68
83
|
def plugin_location
|
69
84
|
@plugin_location ||= begin
|
70
|
-
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create(
|
85
|
+
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
|
71
86
|
Gem::Specification.find_by_name("guard-#{ name }").full_gem_path
|
72
87
|
else
|
73
88
|
Gem.source_index.find_name("guard-#{ name }").last.full_gem_path
|
@@ -89,7 +104,9 @@ module Guard
|
|
89
104
|
#
|
90
105
|
# * `rspec` will find a class `Guard::RSpec`
|
91
106
|
#
|
92
|
-
# @option options [Boolean] fail_gracefully whether error messages should
|
107
|
+
# @option options [Boolean] fail_gracefully whether error messages should
|
108
|
+
# not be printed
|
109
|
+
#
|
93
110
|
# @return [Class, nil] the loaded class
|
94
111
|
#
|
95
112
|
def plugin_class(options = {})
|
@@ -100,18 +117,18 @@ module Guard
|
|
100
117
|
require "guard/#{ name.downcase }" if try_require
|
101
118
|
|
102
119
|
@plugin_class ||= ::Guard.const_get(_plugin_constant)
|
103
|
-
rescue TypeError =>
|
120
|
+
rescue TypeError => error
|
104
121
|
if try_require
|
105
122
|
::Guard::UI.error "Could not find class Guard::#{ _constant_name }"
|
106
|
-
::Guard::UI.error
|
123
|
+
::Guard::UI.error error.backtrace.join("\n")
|
107
124
|
else
|
108
125
|
try_require = true
|
109
126
|
retry
|
110
127
|
end
|
111
|
-
rescue LoadError =>
|
128
|
+
rescue LoadError => error
|
112
129
|
unless options[:fail_gracefully]
|
113
|
-
|
114
|
-
|
130
|
+
UI.error ERROR_NO_GUARD_OR_CLASS % [name.downcase, _constant_name]
|
131
|
+
UI.error error.backtrace.join("\n")
|
115
132
|
end
|
116
133
|
end
|
117
134
|
end
|
@@ -119,17 +136,19 @@ module Guard
|
|
119
136
|
# Adds a plugin's template to the Guardfile.
|
120
137
|
#
|
121
138
|
def add_to_guardfile
|
139
|
+
msg = "Guard.evaluator not initialized"
|
140
|
+
fail msg if ::Guard.evaluator.nil?
|
122
141
|
if ::Guard.evaluator.guardfile_include?(name)
|
123
142
|
::Guard::UI.info "Guardfile already includes #{ name } guard"
|
124
143
|
else
|
125
|
-
content = File.read(
|
126
|
-
File.open(
|
144
|
+
content = File.read("Guardfile")
|
145
|
+
File.open("Guardfile", "wb") do |f|
|
127
146
|
f.puts(content)
|
128
|
-
f.puts(
|
147
|
+
f.puts("")
|
129
148
|
f.puts(plugin_class.template(plugin_location))
|
130
149
|
end
|
131
150
|
|
132
|
-
|
151
|
+
UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
|
133
152
|
end
|
134
153
|
end
|
135
154
|
|
@@ -142,7 +161,9 @@ module Guard
|
|
142
161
|
# => Guard::RSpec
|
143
162
|
#
|
144
163
|
def _plugin_constant
|
145
|
-
@_plugin_constant ||= ::Guard.constants.
|
164
|
+
@_plugin_constant ||= ::Guard.constants.detect do |c|
|
165
|
+
c.to_s.downcase == _constant_name.downcase
|
166
|
+
end
|
146
167
|
end
|
147
168
|
|
148
169
|
# Guesses the most probable name for the current plugin based on its name.
|
@@ -152,8 +173,8 @@ module Guard
|
|
152
173
|
# => "Rspec"
|
153
174
|
#
|
154
175
|
def _constant_name
|
155
|
-
@_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
|
176
|
+
@_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
|
177
|
+
gsub(/(?:^|[_-])(.)/) { $1.upcase }
|
156
178
|
end
|
157
|
-
|
158
179
|
end
|
159
180
|
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require "guard/ui"
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
# This class contains useful methods to:
|
5
|
+
#
|
6
|
+
# * Fetch all the Guard plugins names;
|
7
|
+
# * Initialize a plugin, get its location;
|
8
|
+
# * Return its class name;
|
9
|
+
# * Add its template to the Guardfile.
|
10
|
+
#
|
11
|
+
class PluginUtil
|
12
|
+
ERROR_NO_GUARD_OR_CLASS = "Could not load 'guard/%s' or'\
|
13
|
+
' find class Guard::%s"
|
14
|
+
|
15
|
+
INFO_ADDED_GUARD_TO_GUARDFILE = "%s guard added to Guardfile,"\
|
16
|
+
" feel free to edit it"
|
17
|
+
|
18
|
+
attr_accessor :name
|
19
|
+
|
20
|
+
# Returns a list of Guard plugin Gem names installed locally.
|
21
|
+
#
|
22
|
+
# @return [Array<String>] a list of Guard plugin gem names
|
23
|
+
#
|
24
|
+
def self.plugin_names
|
25
|
+
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
|
26
|
+
Gem::Specification.find_all.select do |x|
|
27
|
+
if x.name =~ /^guard-/
|
28
|
+
true
|
29
|
+
elsif x.name != "guard"
|
30
|
+
|
31
|
+
guard_plugin_path = File.join(
|
32
|
+
x.full_gem_path,
|
33
|
+
"lib/guard/#{ x.name }.rb"
|
34
|
+
)
|
35
|
+
|
36
|
+
File.exist?(guard_plugin_path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
else
|
40
|
+
::Guard::UI.deprecation \
|
41
|
+
"Rubygems version prior to 1.8.0 are no longer supported"\
|
42
|
+
" and may not work"
|
43
|
+
|
44
|
+
Gem.source_index.find_name(/^guard-/)
|
45
|
+
end.map { |x| x.name.sub(/^guard-/, "") }.uniq
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initializes a new `Guard::PluginUtil` object.
|
49
|
+
#
|
50
|
+
# @param [String] name the name of the Guard plugin
|
51
|
+
#
|
52
|
+
def initialize(name)
|
53
|
+
@name = name.to_s.sub(/^guard-/, "")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Initializes a new `Guard::Plugin` with the given `options` hash. This
|
57
|
+
# methods handles plugins that inherit from the deprecated `Guard::Guard`
|
58
|
+
# class as well as plugins that inherit from `Guard::Plugin`.
|
59
|
+
#
|
60
|
+
# @see Guard::Plugin
|
61
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
62
|
+
# upgrade for Guard 2.0
|
63
|
+
#
|
64
|
+
# @return [Guard::Plugin] the initialized plugin
|
65
|
+
# @return [Guard::Guard] the initialized plugin. This return type is
|
66
|
+
# deprecated and the plugin's maintainer should update it to be
|
67
|
+
# compatible with Guard 2.0. For more information on how to upgrade for
|
68
|
+
# Guard 2.0, please head over to:
|
69
|
+
# https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0
|
70
|
+
#
|
71
|
+
def initialize_plugin(options)
|
72
|
+
if plugin_class.superclass.to_s == "Guard::Guard"
|
73
|
+
plugin_class.new(options.delete(:watchers), options)
|
74
|
+
else
|
75
|
+
plugin_class.new(options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Locates a path to a Guard plugin gem.
|
80
|
+
#
|
81
|
+
# @return [String] the full path to the plugin gem
|
82
|
+
#
|
83
|
+
def plugin_location
|
84
|
+
@plugin_location ||= begin
|
85
|
+
if Gem::Version.create(Gem::VERSION) >= Gem::Version.create("1.8.0")
|
86
|
+
Gem::Specification.find_by_name("guard-#{ name }").full_gem_path
|
87
|
+
else
|
88
|
+
Gem.source_index.find_name("guard-#{ name }").last.full_gem_path
|
89
|
+
end
|
90
|
+
end
|
91
|
+
rescue
|
92
|
+
::Guard::UI.error "Could not find 'guard-#{ name }' gem path."
|
93
|
+
end
|
94
|
+
|
95
|
+
# Tries to load the Guard plugin main class. This transforms the supplied
|
96
|
+
# plugin name into a class name:
|
97
|
+
#
|
98
|
+
# * `guardname` will become `Guard::Guardname`
|
99
|
+
# * `dashed-guard-name` will become `Guard::DashedGuardName`
|
100
|
+
# * `underscore_guard_name` will become `Guard::UnderscoreGuardName`
|
101
|
+
#
|
102
|
+
# When no class is found with the strict case sensitive rules, another
|
103
|
+
# try is made to locate the class without matching case:
|
104
|
+
#
|
105
|
+
# * `rspec` will find a class `Guard::RSpec`
|
106
|
+
#
|
107
|
+
# @option options [Boolean] fail_gracefully whether error messages should
|
108
|
+
# not be printed
|
109
|
+
#
|
110
|
+
# @return [Class, nil] the loaded class
|
111
|
+
#
|
112
|
+
def plugin_class(options = {})
|
113
|
+
options = { fail_gracefully: false }.merge(options)
|
114
|
+
|
115
|
+
try_require = false
|
116
|
+
begin
|
117
|
+
require "guard/#{ name.downcase }" if try_require
|
118
|
+
|
119
|
+
@plugin_class ||= ::Guard.const_get(_plugin_constant)
|
120
|
+
rescue TypeError => error
|
121
|
+
if try_require
|
122
|
+
::Guard::UI.error "Could not find class Guard::#{ _constant_name }"
|
123
|
+
::Guard::UI.error error.backtrace.join("\n")
|
124
|
+
else
|
125
|
+
try_require = true
|
126
|
+
retry
|
127
|
+
end
|
128
|
+
rescue LoadError => error
|
129
|
+
unless options[:fail_gracefully]
|
130
|
+
UI.error ERROR_NO_GUARD_OR_CLASS % [name.downcase, _constant_name]
|
131
|
+
UI.error error.backtrace.join("\n")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Adds a plugin's template to the Guardfile.
|
137
|
+
#
|
138
|
+
def add_to_guardfile
|
139
|
+
if ::Guard.evaluator.guardfile_include?(name)
|
140
|
+
::Guard::UI.info "Guardfile already includes #{ name } guard"
|
141
|
+
else
|
142
|
+
content = File.read("Guardfile")
|
143
|
+
File.open("Guardfile", "wb") do |f|
|
144
|
+
f.puts(content)
|
145
|
+
f.puts("")
|
146
|
+
f.puts(plugin_class.template(plugin_location))
|
147
|
+
end
|
148
|
+
|
149
|
+
UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
# Returns the constant for the current plugin.
|
156
|
+
#
|
157
|
+
# @example Returns the constant for a plugin
|
158
|
+
# > Guard::PluginUtil.new('rspec').send(:_plugin_constant)
|
159
|
+
# => Guard::RSpec
|
160
|
+
#
|
161
|
+
def _plugin_constant
|
162
|
+
@_plugin_constant ||= ::Guard.constants.detect do |c|
|
163
|
+
c.to_s.downcase == _constant_name.downcase
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Guesses the most probable name for the current plugin based on its name.
|
168
|
+
#
|
169
|
+
# @example Returns the most probable name for a plugin
|
170
|
+
# > Guard::PluginUtil.new('rspec').send(:_constant_name)
|
171
|
+
# => "Rspec"
|
172
|
+
#
|
173
|
+
def _constant_name
|
174
|
+
@_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
|
175
|
+
gsub(/(?:^|[_-])(.)/) { $1.upcase }
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
data/lib/guard/rake_task.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "rake"
|
4
|
+
require "rake/tasklib"
|
5
5
|
|
6
|
-
require
|
6
|
+
require "guard/cli"
|
7
7
|
|
8
8
|
module Guard
|
9
|
-
|
10
9
|
# Provides a method to define a Rake task that
|
11
10
|
# runs the Guard plugins.
|
12
11
|
#
|
13
12
|
class RakeTask < ::Rake::TaskLib
|
14
|
-
|
15
13
|
# Name of the main, top level task
|
16
14
|
attr_accessor :name
|
17
15
|
|
@@ -24,7 +22,7 @@ module Guard
|
|
24
22
|
# @param [String] options the CLI options
|
25
23
|
# @yield [Guard::RakeTask] the task
|
26
24
|
#
|
27
|
-
def initialize(name = :guard, options =
|
25
|
+
def initialize(name = :guard, options = "")
|
28
26
|
@name = name
|
29
27
|
@options = options
|
30
28
|
|
@@ -42,6 +40,5 @@ module Guard
|
|
42
40
|
|
43
41
|
end
|
44
42
|
end
|
45
|
-
|
46
43
|
end
|
47
44
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "guard"
|
2
|
+
require "guard/plugin"
|
3
|
+
|
4
|
+
module Guard
|
5
|
+
class Reevaluator < Guard::Plugin
|
6
|
+
def run_on_modifications(files)
|
7
|
+
return unless ::Guard::Watcher.match_guardfile?(files)
|
8
|
+
::Guard.save_scope
|
9
|
+
::Guard.evaluator.reevaluate_guardfile
|
10
|
+
::Guard.restore_scope
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/guard/runner.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
1
|
+
require "lumberjack"
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "guard/ui"
|
4
|
+
require "guard/watcher"
|
5
5
|
|
6
6
|
module Guard
|
7
|
-
|
8
7
|
# The runner is responsible for running all methods defined on each plugin.
|
9
8
|
#
|
10
9
|
class Runner
|
11
|
-
|
12
10
|
# Runs a Guard-task on all registered plugins.
|
13
11
|
#
|
14
12
|
# @param [Symbol] task the task to run
|
15
|
-
#
|
13
|
+
#
|
14
|
+
# @param [Hash] scopes either the Guard plugin or the group to run the task
|
15
|
+
# on
|
16
16
|
#
|
17
17
|
# @see self.run_supervised_task
|
18
18
|
#
|
@@ -24,7 +24,10 @@ module Guard
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
MODIFICATION_TASKS = [
|
27
|
+
MODIFICATION_TASKS = [
|
28
|
+
:run_on_modifications, :run_on_changes, :run_on_change
|
29
|
+
]
|
30
|
+
|
28
31
|
ADDITION_TASKS = [:run_on_additions, :run_on_changes, :run_on_change]
|
29
32
|
REMOVAL_TASKS = [:run_on_removals, :run_on_changes, :run_on_deletion]
|
30
33
|
|
@@ -36,30 +39,32 @@ module Guard
|
|
36
39
|
# @param [Array<String>] removed the removed paths.
|
37
40
|
#
|
38
41
|
def run_on_changes(modified, added, removed)
|
39
|
-
|
42
|
+
types = {
|
43
|
+
MODIFICATION_TASKS => modified,
|
44
|
+
ADDITION_TASKS => added,
|
45
|
+
REMOVAL_TASKS => removed
|
46
|
+
}
|
40
47
|
|
41
|
-
|
42
|
-
if ::Guard::Watcher.match_guardfile?(modified)
|
43
|
-
::Guard.evaluator.reevaluate_guardfile
|
44
|
-
end
|
48
|
+
::Guard::UI.clearable
|
45
49
|
|
46
50
|
_scoped_plugins do |guard|
|
47
|
-
|
48
|
-
added_paths = ::Guard::Watcher.match_files(guard, added)
|
49
|
-
removed_paths = ::Guard::Watcher.match_files(guard, removed)
|
51
|
+
::Guard::UI.clear
|
50
52
|
|
51
|
-
|
53
|
+
types.each do |tasks, unmatched_paths|
|
54
|
+
paths = ::Guard::Watcher.match_files(guard, unmatched_paths)
|
55
|
+
next if paths.empty?
|
52
56
|
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
next unless (task = tasks.detect { |meth| guard.respond_to?(meth) })
|
58
|
+
run_supervised_task(guard, task, paths)
|
59
|
+
end
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
59
|
-
# Run a Guard plugin task, but remove the Guard plugin when his work leads
|
63
|
+
# Run a Guard plugin task, but remove the Guard plugin when his work leads
|
64
|
+
# to a system failure.
|
60
65
|
#
|
61
|
-
# When the Group has `:halt_on_fail` disabled, we've to catch
|
62
|
-
# here in order to avoid an uncaught throw error.
|
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.
|
63
68
|
#
|
64
69
|
# @param [Guard::Plugin] guard the Guard to execute
|
65
70
|
# @param [Symbol] task the task to run
|
@@ -67,27 +72,24 @@ module Guard
|
|
67
72
|
# @raise [:task_has_failed] when task has failed
|
68
73
|
#
|
69
74
|
def run_supervised_task(guard, task, *args)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
throw(:task_has_failed)
|
77
|
-
end
|
78
|
-
guard.hook("#{ task }_end", result)
|
79
|
-
result
|
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)
|
80
81
|
end
|
81
|
-
|
82
|
-
|
83
|
-
::Guard::UI.error("#{ guard.class.name } failed to achieve its <#{ task.to_s }>, exception was:" +
|
84
|
-
"\n#{ ex.class }: #{ ex.message }\n#{ ex.backtrace.join("\n") }")
|
85
|
-
|
86
|
-
::Guard.plugins.delete guard
|
87
|
-
::Guard::UI.info("\n#{ guard.class.name } has just been fired")
|
88
|
-
|
89
|
-
ex
|
82
|
+
guard.hook("#{ task }_end", result)
|
83
|
+
result
|
90
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
|
+
$!
|
91
93
|
end
|
92
94
|
|
93
95
|
# Returns the symbol that has to be caught when running a supervised task.
|
@@ -106,24 +108,6 @@ module Guard
|
|
106
108
|
|
107
109
|
private
|
108
110
|
|
109
|
-
# Tries to run the first implemented task by a given guard
|
110
|
-
# from a collection of tasks.
|
111
|
-
#
|
112
|
-
# @param [Guard::Plugin] guard the Guard plugin to run the first found task on
|
113
|
-
# @param [Array<Symbol>] tasks the tasks to run the first among
|
114
|
-
# @param [Object] task_param the param to pass to each task
|
115
|
-
#
|
116
|
-
def _run_first_task_found(guard, tasks, task_param)
|
117
|
-
tasks.each do |task|
|
118
|
-
if guard.respond_to?(task)
|
119
|
-
run_supervised_task(guard, task, task_param)
|
120
|
-
break
|
121
|
-
else
|
122
|
-
::Guard::UI.debug "Trying to run #{ guard.class.name }##{ task.to_s } with #{ task_param.inspect }"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
111
|
# Loop through all groups and run the given task for each Guard plugin.
|
128
112
|
#
|
129
113
|
# If no scope is supplied, the global Guard scope is taken into account.
|
@@ -151,27 +135,14 @@ module Guard
|
|
151
135
|
end
|
152
136
|
end
|
153
137
|
|
154
|
-
|
155
|
-
|
156
|
-
|
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."
|
157
142
|
end
|
158
143
|
end
|
159
144
|
end
|
160
145
|
|
161
|
-
# Logic to know if the UI can be cleared or not in the run_on_changes method
|
162
|
-
# based on the guard and the changes.
|
163
|
-
#
|
164
|
-
# @param [Guard::Plugin] guard the Guard plugin where run_on_changes is called
|
165
|
-
# @param [Array<String>] modified_paths the modified paths.
|
166
|
-
# @param [Array<String>] added_paths the added paths.
|
167
|
-
# @param [Array<String>] removed_paths the removed paths.
|
168
|
-
#
|
169
|
-
def _clearable?(guard, modified_paths, added_paths, removed_paths)
|
170
|
-
(MODIFICATION_TASKS.any? { |task| guard.respond_to?(task) } && !modified_paths.empty?) ||
|
171
|
-
(ADDITION_TASKS.any? { |task| guard.respond_to?(task) } && !added_paths.empty?) ||
|
172
|
-
(REMOVAL_TASKS.any? { |task| guard.respond_to?(task) } && !removed_paths.empty?)
|
173
|
-
end
|
174
|
-
|
175
146
|
# Returns the current plugins scope.
|
176
147
|
# Local plugins scope wins over global plugins scope.
|
177
148
|
# If no plugins scope is found, then NO plugins are returned.
|
@@ -205,12 +176,13 @@ module Guard
|
|
205
176
|
# Find the first non empty element in the given possibilities
|
206
177
|
#
|
207
178
|
def _find_non_empty_scope(type, local_scope, *additional_possibilities)
|
208
|
-
[
|
179
|
+
found = [
|
209
180
|
local_scope[:"#{type}s"],
|
210
181
|
local_scope[type.to_sym],
|
211
182
|
::Guard.scope[:"#{type}s"],
|
212
183
|
additional_possibilities.flatten
|
213
|
-
].compact.
|
184
|
+
].compact.detect { |a| !Array(a).empty? }
|
185
|
+
found ? [::Guard.group(:common)] + Array(found) : found
|
214
186
|
end
|
215
187
|
|
216
188
|
# Find the first non empty plugins scope
|