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
@@ -0,0 +1,42 @@
|
|
1
|
+
require "guard/plugin/base"
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
# @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
|
5
|
+
# from {Plugin} instead. Please note that the constructor signature has
|
6
|
+
# changed from `Guard::Guard#initialize(watchers = [], options = {})` to
|
7
|
+
# `Guard::Plugin#initialize(options = {})`.
|
8
|
+
#
|
9
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
10
|
+
# upgrade for Guard 2.0
|
11
|
+
#
|
12
|
+
class Guard
|
13
|
+
include ::Guard::Plugin::Base
|
14
|
+
|
15
|
+
# @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit
|
16
|
+
# from {Plugin} instead. Please note that the constructor signature
|
17
|
+
# has changed from `Guard::Guard#initialize(watchers = [], options = {})`
|
18
|
+
# to `Guard::Plugin#initialize(options = {})`.
|
19
|
+
#
|
20
|
+
# Initializes a Guard plugin. Don't do any work here,
|
21
|
+
# especially as Guard plugins get initialized even if they are not in an
|
22
|
+
# active group!
|
23
|
+
#
|
24
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
25
|
+
# upgrade for Guard 2.0
|
26
|
+
#
|
27
|
+
# @param [Array<Guard::Watcher>] watchers the Guard plugin file watchers
|
28
|
+
# @param [Hash] options the custom Guard plugin options
|
29
|
+
# @option options [Symbol] group the group this Guard plugin belongs to
|
30
|
+
# @option options [Boolean] any_return allow any object to be returned from
|
31
|
+
# a watcher
|
32
|
+
# @option options [Boolean] first_match stop after the first watcher that
|
33
|
+
# returns a valid result
|
34
|
+
#
|
35
|
+
def initialize(watchers = [], options = {})
|
36
|
+
UI.deprecation(Deprecator::GUARD_GUARD_DEPRECATION % title)
|
37
|
+
|
38
|
+
_set_instance_variables_from_options(options.merge(watchers: watchers))
|
39
|
+
_register_callbacks
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/guard/guardfile.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "guard/guardfile/evaluator"
|
2
|
+
require "guard/guardfile/generator"
|
3
|
+
require "guard/ui"
|
4
4
|
|
5
5
|
module Guard
|
6
|
-
|
7
6
|
# @deprecated Use instance methods of {Guardfile::Evaluator} and
|
8
7
|
# {Guardfile::Generator} instead.
|
9
8
|
#
|
@@ -11,34 +10,34 @@ module Guard
|
|
11
10
|
# @see Guardfile::Generator
|
12
11
|
#
|
13
12
|
module Guardfile
|
14
|
-
|
15
13
|
# @deprecated Use {Guardfile::Generator#create_guardfile} instead.
|
16
14
|
#
|
17
|
-
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
15
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
16
|
+
# upgrade for Guard 2.0
|
18
17
|
#
|
19
18
|
def self.create_guardfile(options = {})
|
20
|
-
|
19
|
+
UI.deprecation(Deprecator::CREATE_GUARDFILE_DEPRECATION)
|
21
20
|
Generator.new(options).create_guardfile
|
22
21
|
end
|
23
22
|
|
24
23
|
# @deprecated Use {Guardfile::Generator#initialize_template} instead.
|
25
24
|
#
|
26
|
-
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
25
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
26
|
+
# upgrade for Guard 2.0
|
27
27
|
#
|
28
28
|
def self.initialize_template(plugin_name)
|
29
|
-
|
29
|
+
UI.deprecation(Deprecator::INITIALIZE_TEMPLATE_DEPRECATION)
|
30
30
|
Generator.new.initialize_template(plugin_name)
|
31
31
|
end
|
32
32
|
|
33
33
|
# @deprecated Use {Guardfile::Generator#initialize_all_templates} instead.
|
34
34
|
#
|
35
|
-
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
35
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
36
|
+
# upgrade for Guard 2.0
|
36
37
|
#
|
37
38
|
def self.initialize_all_templates
|
38
|
-
|
39
|
+
UI.deprecation(Deprecator::INITIALIZE_ALL_TEMPLATES_DEPRECATION)
|
39
40
|
Generator.new.initialize_all_templates
|
40
41
|
end
|
41
|
-
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
@@ -1,24 +1,35 @@
|
|
1
|
-
require
|
1
|
+
require "guard/options"
|
2
|
+
require "guard/plugin"
|
2
3
|
|
3
4
|
module Guard
|
4
5
|
module Guardfile
|
5
|
-
|
6
|
-
#
|
7
|
-
# to Guard::Dsl for the actual objects generation from the Guardfile content.
|
6
|
+
# This class is responsible for evaluating the Guardfile. It delegates to
|
7
|
+
# Guard::Dsl for the actual objects generation from the Guardfile content.
|
8
8
|
#
|
9
9
|
# @see Guard::Dsl
|
10
10
|
#
|
11
11
|
class Evaluator
|
12
|
+
attr_reader :options, :guardfile_path
|
12
13
|
|
13
|
-
|
14
|
+
def guardfile_source
|
15
|
+
@source
|
16
|
+
end
|
14
17
|
|
15
18
|
# Initializes a new Guard::Guardfile::Evaluator object.
|
16
19
|
#
|
17
20
|
# @option opts [String] guardfile the path to a valid Guardfile
|
18
|
-
# @option opts [String] guardfile_contents a string representing the
|
21
|
+
# @option opts [String] guardfile_contents a string representing the
|
22
|
+
# content of a valid Guardfile
|
19
23
|
#
|
20
24
|
def initialize(opts = {})
|
21
|
-
@
|
25
|
+
@source = nil
|
26
|
+
@guardfile_path = nil
|
27
|
+
|
28
|
+
valid_options = opts.select do |k, _|
|
29
|
+
[:guardfile, :guardfile_contents].include?(k.to_sym)
|
30
|
+
end
|
31
|
+
|
32
|
+
@options = ::Guard::Options.new(valid_options)
|
22
33
|
end
|
23
34
|
|
24
35
|
# Evaluates the DSL methods in the `Guardfile`.
|
@@ -26,14 +37,20 @@ module Guard
|
|
26
37
|
# @example Programmatically evaluate a Guardfile
|
27
38
|
# Guard::Guardfile::Evaluator.new.evaluate_guardfile
|
28
39
|
#
|
29
|
-
# @example Programmatically evaluate a Guardfile with a custom Guardfile
|
30
|
-
#
|
40
|
+
# @example Programmatically evaluate a Guardfile with a custom Guardfile
|
41
|
+
# path
|
42
|
+
#
|
43
|
+
# options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
|
44
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
|
31
45
|
#
|
32
46
|
# @example Programmatically evaluate a Guardfile with an inline Guardfile
|
33
|
-
#
|
47
|
+
#
|
48
|
+
# options = { guardfile_contents: 'guard :rspec' }
|
49
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
|
34
50
|
#
|
35
51
|
def evaluate_guardfile
|
36
52
|
_fetch_guardfile_contents
|
53
|
+
::Guard.add_builtin_plugins(guardfile_path)
|
37
54
|
_instance_eval_guardfile(guardfile_contents)
|
38
55
|
end
|
39
56
|
|
@@ -42,7 +59,7 @@ module Guard
|
|
42
59
|
#
|
43
60
|
def reevaluate_guardfile
|
44
61
|
# Don't re-evaluate inline Guardfile
|
45
|
-
return if @
|
62
|
+
return if @source == :inline
|
46
63
|
|
47
64
|
_before_reevaluate_guardfile
|
48
65
|
evaluate_guardfile
|
@@ -51,7 +68,9 @@ module Guard
|
|
51
68
|
|
52
69
|
# Tests if the current `Guardfile` contains a specific Guard plugin.
|
53
70
|
#
|
54
|
-
# @example Programmatically test if a Guardfile contains a specific Guard
|
71
|
+
# @example Programmatically test if a Guardfile contains a specific Guard
|
72
|
+
# plugin
|
73
|
+
#
|
55
74
|
# File.read('Guardfile')
|
56
75
|
# => "guard :rspec"
|
57
76
|
#
|
@@ -62,7 +81,8 @@ module Guard
|
|
62
81
|
# @return [Boolean] whether the Guard plugin has been declared
|
63
82
|
#
|
64
83
|
def guardfile_include?(plugin_name)
|
65
|
-
|
84
|
+
regexp = /^guard\s*\(?\s*['":]#{ plugin_name }['"]?/
|
85
|
+
_guardfile_contents_without_user_config.match(regexp)
|
66
86
|
end
|
67
87
|
|
68
88
|
# Gets the content of the `Guardfile` concatenated with the global
|
@@ -86,7 +106,7 @@ module Guard
|
|
86
106
|
# @return [String] the Guardfile content
|
87
107
|
#
|
88
108
|
def _guardfile_contents_without_user_config
|
89
|
-
@guardfile_contents ||
|
109
|
+
@guardfile_contents || ""
|
90
110
|
end
|
91
111
|
|
92
112
|
# Evaluates the content of the `Guardfile`.
|
@@ -94,7 +114,7 @@ module Guard
|
|
94
114
|
# @param [String] contents the content to evaluate.
|
95
115
|
#
|
96
116
|
def _instance_eval_guardfile(contents)
|
97
|
-
::Guard::Dsl.new.instance_eval(contents, @guardfile_path ||
|
117
|
+
::Guard::Dsl.new.instance_eval(contents, @guardfile_path || "", 1)
|
98
118
|
rescue => ex
|
99
119
|
::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
|
100
120
|
raise ex
|
@@ -103,62 +123,60 @@ module Guard
|
|
103
123
|
# Gets the content to evaluate and stores it into @guardfile_contents.
|
104
124
|
#
|
105
125
|
def _fetch_guardfile_contents
|
106
|
-
|
126
|
+
_use_inline || _use_provided || _use_default
|
107
127
|
|
108
|
-
|
109
|
-
|
110
|
-
|
128
|
+
return if _guardfile_contents_usable?
|
129
|
+
::Guard::UI.error "No Guard plugins found in Guardfile,"\
|
130
|
+
" please add at least one."
|
111
131
|
end
|
112
132
|
|
113
133
|
# Use the provided inline Guardfile if provided.
|
114
134
|
#
|
115
|
-
def
|
116
|
-
|
135
|
+
def _use_inline
|
136
|
+
source_from_option = @source.nil? && options[:guardfile_contents]
|
137
|
+
inline = @source == :inline
|
117
138
|
|
118
|
-
|
119
|
-
@guardfile_contents = options[:guardfile_contents]
|
139
|
+
return false unless (source_from_option) || inline
|
120
140
|
|
121
|
-
|
141
|
+
@source = :inline
|
142
|
+
@guardfile_contents = options[:guardfile_contents]
|
122
143
|
|
123
|
-
|
124
|
-
|
125
|
-
false
|
126
|
-
end
|
144
|
+
::Guard::UI.info "Using inline Guardfile."
|
145
|
+
true
|
127
146
|
end
|
128
147
|
|
129
148
|
# Try to use the provided Guardfile. Exits Guard if the Guardfile cannot
|
130
149
|
# be found.
|
131
150
|
#
|
132
|
-
def
|
133
|
-
|
151
|
+
def _use_provided
|
152
|
+
source_from_file = @source.nil? && options[:guardfile]
|
153
|
+
return false unless source_from_file || (@source == :custom)
|
134
154
|
|
135
|
-
|
136
|
-
|
137
|
-
options[:guardfile] = File.expand_path(options[:guardfile])
|
138
|
-
if File.exist?(options[:guardfile])
|
139
|
-
_read_guardfile(options[:guardfile])
|
140
|
-
::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
|
141
|
-
true
|
142
|
-
else
|
143
|
-
::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
|
144
|
-
exit 1
|
145
|
-
end
|
155
|
+
@source = :custom
|
146
156
|
|
157
|
+
options[:guardfile] = File.expand_path(options[:guardfile])
|
158
|
+
if File.exist?(options[:guardfile])
|
159
|
+
_read_guardfile(options[:guardfile])
|
160
|
+
::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
|
147
161
|
true
|
148
162
|
else
|
149
|
-
|
163
|
+
::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
|
164
|
+
exit 1
|
150
165
|
end
|
166
|
+
|
167
|
+
true
|
151
168
|
end
|
152
169
|
|
153
170
|
# Try to use one of the default Guardfiles (local or home Guardfile).
|
154
171
|
# Exits Guard if no Guardfile is found.
|
155
172
|
#
|
156
|
-
def
|
173
|
+
def _use_default
|
157
174
|
if guardfile_path = _find_default_guardfile
|
158
|
-
@
|
175
|
+
@source = :default
|
159
176
|
_read_guardfile(guardfile_path)
|
160
177
|
else
|
161
|
-
::Guard::UI.error
|
178
|
+
::Guard::UI.error \
|
179
|
+
"No Guardfile found, please create one with `guard init`."
|
162
180
|
exit 1
|
163
181
|
end
|
164
182
|
end
|
@@ -167,7 +185,9 @@ module Guard
|
|
167
185
|
# or nil otherwise.
|
168
186
|
#
|
169
187
|
def _find_default_guardfile
|
170
|
-
[_local_guardfile_path, _home_guardfile_path].
|
188
|
+
[_local_guardfile_path, _home_guardfile_path].detect do |path|
|
189
|
+
File.exist?(path)
|
190
|
+
end
|
171
191
|
end
|
172
192
|
|
173
193
|
# Reads the current `Guardfile` content.
|
@@ -201,13 +221,17 @@ module Guard
|
|
201
221
|
def _after_reevaluate_guardfile
|
202
222
|
::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
|
203
223
|
|
204
|
-
if
|
205
|
-
::Guard::Notifier.notify(
|
224
|
+
if !::Guard.send(:_non_builtin_plugins?)
|
225
|
+
::Guard::Notifier.notify(
|
226
|
+
"No plugins found in Guardfile, please add at least one.",
|
227
|
+
title: "Guard re-evaluate",
|
228
|
+
image: :failed)
|
206
229
|
else
|
207
|
-
msg =
|
230
|
+
msg = "Guardfile has been re-evaluated."
|
208
231
|
::Guard::UI.info(msg)
|
209
|
-
::Guard::Notifier.notify(msg, title:
|
232
|
+
::Guard::Notifier.notify(msg, title: "Guard re-evaluate")
|
210
233
|
|
234
|
+
::Guard.setup_scope
|
211
235
|
::Guard.runner.run(:start)
|
212
236
|
end
|
213
237
|
end
|
@@ -226,7 +250,7 @@ module Guard
|
|
226
250
|
# @return [String] the path to the local Guardfile
|
227
251
|
#
|
228
252
|
def _local_guardfile_path
|
229
|
-
File.expand_path(File.join(Dir.pwd,
|
253
|
+
File.expand_path(File.join(Dir.pwd, "Guardfile"))
|
230
254
|
end
|
231
255
|
|
232
256
|
# The path to the `.Guardfile` that is located at
|
@@ -235,7 +259,7 @@ module Guard
|
|
235
259
|
# @return [String] the path to `~/.Guardfile`
|
236
260
|
#
|
237
261
|
def _home_guardfile_path
|
238
|
-
File.expand_path(File.join(
|
262
|
+
File.expand_path(File.join("~", ".Guardfile"))
|
239
263
|
end
|
240
264
|
|
241
265
|
# The path to the user configuration `.guard.rb`
|
@@ -244,10 +268,8 @@ module Guard
|
|
244
268
|
# @return [String] the path to `~/.guard.rb`
|
245
269
|
#
|
246
270
|
def _user_config_path
|
247
|
-
File.expand_path(File.join(
|
271
|
+
File.expand_path(File.join("~", ".guard.rb"))
|
248
272
|
end
|
249
|
-
|
250
273
|
end
|
251
|
-
|
252
274
|
end
|
253
275
|
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
require "guard/options"
|
2
|
+
require "guard/plugin"
|
3
|
+
|
4
|
+
module Guard
|
5
|
+
module Guardfile
|
6
|
+
# This class is responsible for evaluating the Guardfile. It delegates to
|
7
|
+
# Guard::Dsl for the actual objects generation from the Guardfile content.
|
8
|
+
#
|
9
|
+
# @see Guard::Dsl
|
10
|
+
#
|
11
|
+
class Evaluator
|
12
|
+
attr_reader :options, :guardfile_path
|
13
|
+
|
14
|
+
def guardfile_source
|
15
|
+
@source
|
16
|
+
end
|
17
|
+
|
18
|
+
# Initializes a new Guard::Guardfile::Evaluator object.
|
19
|
+
#
|
20
|
+
# @option opts [String] guardfile the path to a valid Guardfile
|
21
|
+
# @option opts [String] guardfile_contents a string representing the
|
22
|
+
# content of a valid Guardfile
|
23
|
+
#
|
24
|
+
def initialize(opts = {})
|
25
|
+
@source = nil
|
26
|
+
@guardfile_path = nil
|
27
|
+
|
28
|
+
valid_options = opts.select do |k, _|
|
29
|
+
[:guardfile, :guardfile_contents].include?(k.to_sym)
|
30
|
+
end
|
31
|
+
|
32
|
+
@options = ::Guard::Options.new(valid_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Evaluates the DSL methods in the `Guardfile`.
|
36
|
+
#
|
37
|
+
# @example Programmatically evaluate a Guardfile
|
38
|
+
# Guard::Guardfile::Evaluator.new.evaluate_guardfile
|
39
|
+
#
|
40
|
+
# @example Programmatically evaluate a Guardfile with a custom Guardfile
|
41
|
+
# path
|
42
|
+
#
|
43
|
+
# options = { guardfile: '/Users/guardfile/MyAwesomeGuardfile' }
|
44
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
|
45
|
+
#
|
46
|
+
# @example Programmatically evaluate a Guardfile with an inline Guardfile
|
47
|
+
#
|
48
|
+
# options = { guardfile_contents: 'guard :rspec' }
|
49
|
+
# Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
|
50
|
+
#
|
51
|
+
def evaluate_guardfile
|
52
|
+
_fetch_guardfile_contents
|
53
|
+
::Guard.add_builtin_plugins
|
54
|
+
_instance_eval_guardfile(guardfile_contents)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Re-evaluates the `Guardfile` to update
|
58
|
+
# the current Guard configuration.
|
59
|
+
#
|
60
|
+
def reevaluate_guardfile
|
61
|
+
# Don't re-evaluate inline Guardfile
|
62
|
+
return if @source == :inline
|
63
|
+
|
64
|
+
_before_reevaluate_guardfile
|
65
|
+
evaluate_guardfile
|
66
|
+
_after_reevaluate_guardfile
|
67
|
+
end
|
68
|
+
|
69
|
+
# Tests if the current `Guardfile` contains a specific Guard plugin.
|
70
|
+
#
|
71
|
+
# @example Programmatically test if a Guardfile contains a specific Guard
|
72
|
+
# plugin
|
73
|
+
#
|
74
|
+
# File.read('Guardfile')
|
75
|
+
# => "guard :rspec"
|
76
|
+
#
|
77
|
+
# Guard::Guardfile::Evaluator.new.guardfile_include?('rspec)
|
78
|
+
# => true
|
79
|
+
#
|
80
|
+
# @param [String] plugin_name the name of the Guard
|
81
|
+
# @return [Boolean] whether the Guard plugin has been declared
|
82
|
+
#
|
83
|
+
def guardfile_include?(plugin_name)
|
84
|
+
regexp = /^guard\s*\(?\s*['":]#{ plugin_name }['"]?/
|
85
|
+
_guardfile_contents_without_user_config.match(regexp)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Gets the content of the `Guardfile` concatenated with the global
|
89
|
+
# user configuration file.
|
90
|
+
#
|
91
|
+
# @example Programmatically get the content of the current Guardfile
|
92
|
+
# Guard::Guardfile::Evaluator.new.guardfile_contents
|
93
|
+
# => "guard :rspec"
|
94
|
+
#
|
95
|
+
# @return [String] the Guardfile content
|
96
|
+
#
|
97
|
+
def guardfile_contents
|
98
|
+
config = File.read(_user_config_path) if File.exist?(_user_config_path)
|
99
|
+
[_guardfile_contents_without_user_config, config].compact.join("\n")
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
# Gets the content of the `Guardfile`.
|
105
|
+
#
|
106
|
+
# @return [String] the Guardfile content
|
107
|
+
#
|
108
|
+
def _guardfile_contents_without_user_config
|
109
|
+
@guardfile_contents || ""
|
110
|
+
end
|
111
|
+
|
112
|
+
# Evaluates the content of the `Guardfile`.
|
113
|
+
#
|
114
|
+
# @param [String] contents the content to evaluate.
|
115
|
+
#
|
116
|
+
def _instance_eval_guardfile(contents)
|
117
|
+
::Guard::Dsl.new.instance_eval(contents, @guardfile_path || "", 1)
|
118
|
+
rescue => ex
|
119
|
+
::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
|
120
|
+
raise ex
|
121
|
+
end
|
122
|
+
|
123
|
+
# Gets the content to evaluate and stores it into @guardfile_contents.
|
124
|
+
#
|
125
|
+
def _fetch_guardfile_contents
|
126
|
+
_use_inline || _use_provided || _use_default
|
127
|
+
|
128
|
+
return if _guardfile_contents_usable?
|
129
|
+
::Guard::UI.error "No Guard plugins found in Guardfile,"\
|
130
|
+
" please add at least one."
|
131
|
+
end
|
132
|
+
|
133
|
+
# Use the provided inline Guardfile if provided.
|
134
|
+
#
|
135
|
+
def _use_inline
|
136
|
+
source_from_option = @source.nil? && options[:guardfile_contents]
|
137
|
+
inline = @source == :inline
|
138
|
+
|
139
|
+
return false unless (source_from_option) || inline
|
140
|
+
|
141
|
+
@source = :inline
|
142
|
+
@guardfile_contents = options[:guardfile_contents]
|
143
|
+
|
144
|
+
::Guard::UI.info "Using inline Guardfile."
|
145
|
+
true
|
146
|
+
end
|
147
|
+
|
148
|
+
# Try to use the provided Guardfile. Exits Guard if the Guardfile cannot
|
149
|
+
# be found.
|
150
|
+
#
|
151
|
+
def _use_provided
|
152
|
+
source_from_file = @source.nil? && options[:guardfile]
|
153
|
+
return false unless source_from_file || (@source == :custom)
|
154
|
+
|
155
|
+
@source = :custom
|
156
|
+
|
157
|
+
options[:guardfile] = File.expand_path(options[:guardfile])
|
158
|
+
if File.exist?(options[:guardfile])
|
159
|
+
_read_guardfile(options[:guardfile])
|
160
|
+
::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
|
161
|
+
true
|
162
|
+
else
|
163
|
+
::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
|
164
|
+
exit 1
|
165
|
+
end
|
166
|
+
|
167
|
+
true
|
168
|
+
end
|
169
|
+
|
170
|
+
# Try to use one of the default Guardfiles (local or home Guardfile).
|
171
|
+
# Exits Guard if no Guardfile is found.
|
172
|
+
#
|
173
|
+
def _use_default
|
174
|
+
if guardfile_path = _find_default_guardfile
|
175
|
+
@source = :default
|
176
|
+
_read_guardfile(guardfile_path)
|
177
|
+
else
|
178
|
+
::Guard::UI.error \
|
179
|
+
"No Guardfile found, please create one with `guard init`."
|
180
|
+
exit 1
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns the first default Guardfile (either local or home Guardfile)
|
185
|
+
# or nil otherwise.
|
186
|
+
#
|
187
|
+
def _find_default_guardfile
|
188
|
+
[_local_guardfile_path, _home_guardfile_path].detect do |path|
|
189
|
+
File.exist?(path)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Reads the current `Guardfile` content.
|
194
|
+
#
|
195
|
+
# @param [String] guardfile_path the path to the Guardfile
|
196
|
+
#
|
197
|
+
def _read_guardfile(guardfile_path)
|
198
|
+
@guardfile_path = guardfile_path
|
199
|
+
@guardfile_contents = File.read(guardfile_path)
|
200
|
+
rescue => ex
|
201
|
+
::Guard::UI.error "Error reading file #{ guardfile_path }:"
|
202
|
+
::Guard::UI.error ex.inspect
|
203
|
+
::Guard::UI.error ex.backtrace
|
204
|
+
exit 1
|
205
|
+
end
|
206
|
+
|
207
|
+
# Stops Guard and clear internal state
|
208
|
+
# before the Guardfile will be re-evaluated.
|
209
|
+
#
|
210
|
+
def _before_reevaluate_guardfile
|
211
|
+
::Guard.runner.run(:stop)
|
212
|
+
::Guard.reset_groups
|
213
|
+
::Guard.reset_plugins
|
214
|
+
::Guard.reset_scope
|
215
|
+
::Guard::Notifier.clear_notifiers
|
216
|
+
end
|
217
|
+
|
218
|
+
# Starts Guard and notification and show a message
|
219
|
+
# after the Guardfile has been re-evaluated.
|
220
|
+
#
|
221
|
+
def _after_reevaluate_guardfile
|
222
|
+
::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
|
223
|
+
|
224
|
+
if !::Guard.send(:_non_builtin_plugins?)
|
225
|
+
::Guard::Notifier.notify(
|
226
|
+
"No plugins found in Guardfile, please add at least one.",
|
227
|
+
title: "Guard re-evaluate",
|
228
|
+
image: :failed)
|
229
|
+
else
|
230
|
+
msg = "Guardfile has been re-evaluated."
|
231
|
+
::Guard::UI.info(msg)
|
232
|
+
::Guard::Notifier.notify(msg, title: "Guard re-evaluate")
|
233
|
+
|
234
|
+
::Guard.setup_scope
|
235
|
+
::Guard.runner.run(:start)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Tests if the current `Guardfile` content is usable.
|
240
|
+
#
|
241
|
+
# @return [Boolean] if the Guardfile is usable
|
242
|
+
#
|
243
|
+
def _guardfile_contents_usable?
|
244
|
+
guardfile_contents && guardfile_contents =~ /guard/m
|
245
|
+
end
|
246
|
+
|
247
|
+
# The path to the `Guardfile` that is located at
|
248
|
+
# the directory, where Guard has been started from.
|
249
|
+
#
|
250
|
+
# @return [String] the path to the local Guardfile
|
251
|
+
#
|
252
|
+
def _local_guardfile_path
|
253
|
+
File.expand_path(File.join(Dir.pwd, "Guardfile"))
|
254
|
+
end
|
255
|
+
|
256
|
+
# The path to the `.Guardfile` that is located at
|
257
|
+
# the users home directory.
|
258
|
+
#
|
259
|
+
# @return [String] the path to `~/.Guardfile`
|
260
|
+
#
|
261
|
+
def _home_guardfile_path
|
262
|
+
File.expand_path(File.join("~", ".Guardfile"))
|
263
|
+
end
|
264
|
+
|
265
|
+
# The path to the user configuration `.guard.rb`
|
266
|
+
# that is located at the users home directory.
|
267
|
+
#
|
268
|
+
# @return [String] the path to `~/.guard.rb`
|
269
|
+
#
|
270
|
+
def _user_config_path
|
271
|
+
File.expand_path(File.join("~", ".guard.rb"))
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|