guard 2.6.1 → 2.7.0
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.
- 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
|