guard 1.8.3 → 2.0.0.pre
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/CHANGELOG.md +68 -10
- data/README.md +54 -33
- data/lib/guard.rb +133 -483
- data/lib/guard/cli.rb +78 -82
- data/lib/guard/commander.rb +121 -0
- data/lib/guard/commands/all.rb +1 -1
- data/lib/guard/commands/reload.rb +1 -1
- data/lib/guard/deprecated_methods.rb +59 -0
- data/lib/guard/deprecator.rb +107 -0
- data/lib/guard/dsl.rb +143 -329
- data/lib/guard/dsl_describer.rb +101 -57
- data/lib/guard/group.rb +27 -8
- data/lib/guard/guard.rb +25 -150
- data/lib/guard/guardfile.rb +35 -85
- data/lib/guard/guardfile/evaluator.rb +245 -0
- data/lib/guard/guardfile/generator.rb +89 -0
- data/lib/guard/interactor.rb +147 -163
- data/lib/guard/notifier.rb +83 -137
- data/lib/guard/notifiers/base.rb +220 -0
- data/lib/guard/notifiers/emacs.rb +39 -37
- data/lib/guard/notifiers/file_notifier.rb +29 -25
- data/lib/guard/notifiers/gntp.rb +68 -75
- data/lib/guard/notifiers/growl.rb +49 -52
- data/lib/guard/notifiers/growl_notify.rb +51 -56
- data/lib/guard/notifiers/libnotify.rb +41 -48
- data/lib/guard/notifiers/notifysend.rb +58 -38
- data/lib/guard/notifiers/rb_notifu.rb +54 -54
- data/lib/guard/notifiers/terminal_notifier.rb +48 -36
- data/lib/guard/notifiers/terminal_title.rb +23 -19
- data/lib/guard/notifiers/tmux.rb +110 -93
- data/lib/guard/options.rb +21 -0
- data/lib/guard/plugin.rb +66 -0
- data/lib/guard/plugin/base.rb +178 -0
- data/lib/guard/plugin/hooker.rb +123 -0
- data/lib/guard/plugin_util.rb +158 -0
- data/lib/guard/rake_task.rb +47 -0
- data/lib/guard/runner.rb +62 -82
- data/lib/guard/setuper.rb +248 -0
- data/lib/guard/ui.rb +24 -80
- data/lib/guard/ui/colors.rb +60 -0
- data/lib/guard/version.rb +1 -2
- data/lib/guard/watcher.rb +30 -30
- data/man/guard.1 +4 -4
- data/man/guard.1.html +6 -4
- metadata +25 -11
- data/lib/guard/hook.rb +0 -120
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'guard/ui'
|
2
|
+
|
3
|
+
module Guard
|
4
|
+
class Deprecator
|
5
|
+
|
6
|
+
MORE_INFO_ON_UPGRADING_TO_GUARD_1_1 = <<-EOS.gsub(/^\s*/, '')
|
7
|
+
For more information on how to update existing Guard plugins, please head over
|
8
|
+
to: https://github.com/guard/guard/wiki/Upgrade-guide-for-existing-guards-to-Guard-v1.1
|
9
|
+
EOS
|
10
|
+
|
11
|
+
MORE_INFO_ON_UPGRADING_TO_GUARD_2 = <<-EOS.gsub(/^\s*/, '')
|
12
|
+
For more information on how to upgrade for Guard 2.0, please head over
|
13
|
+
to: https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0%s
|
14
|
+
EOS
|
15
|
+
|
16
|
+
ADD_GUARD_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
17
|
+
Starting with Guard 2.0 'Guard.add_guard(name, options = {})' is deprecated.
|
18
|
+
|
19
|
+
Please use 'Guard.add_plugin(name, options = {})' instead.
|
20
|
+
|
21
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods'}
|
22
|
+
EOS
|
23
|
+
|
24
|
+
GUARDS_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
25
|
+
Starting with Guard 2.0 'Guard.guards(filter)' is deprecated.
|
26
|
+
|
27
|
+
Please use 'Guard.plugins(filter)' instead.
|
28
|
+
|
29
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods'}
|
30
|
+
EOS
|
31
|
+
|
32
|
+
# Deprecator message for the `Guard.get_guard_class` method
|
33
|
+
GET_GUARD_CLASS_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
34
|
+
Starting with Guard 2.0 'Guard.get_guard_class(name, fail_gracefully =
|
35
|
+
false)' is deprecated and is now always on.
|
36
|
+
|
37
|
+
Please use 'Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
|
38
|
+
fail_gracefully)' instead.
|
39
|
+
|
40
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods'}
|
41
|
+
EOS
|
42
|
+
|
43
|
+
# Deprecator message for the `Guard.locate_guard` method
|
44
|
+
LOCATE_GUARD_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
45
|
+
Starting with Guard 2.0 'Guard.locate_guard(name)' is deprecated.
|
46
|
+
|
47
|
+
Please use 'Guard::PluginUtil.new(name).plugin_location' instead.
|
48
|
+
|
49
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods'}
|
50
|
+
EOS
|
51
|
+
|
52
|
+
# Deprecator message for the `Guard.guard_gem_names` method
|
53
|
+
GUARD_GEM_NAMES_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
54
|
+
Starting with Guard 2.0 'Guard.guard_gem_names' is deprecated.
|
55
|
+
|
56
|
+
Please use 'Guard::PluginUtil.plugin_names' instead.
|
57
|
+
|
58
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods'}
|
59
|
+
EOS
|
60
|
+
|
61
|
+
# Deprecator message for the `Guard::Dsl.evaluate_guardfile` method
|
62
|
+
EVALUATE_GUARDFILE_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
63
|
+
Starting with Guard 2.0 'Guard::Dsl.evaluate_guardfile(options)' is deprecated.
|
64
|
+
|
65
|
+
Please use 'Guard::Guardfile::Evaluator.new(options).evaluate_guardfile' instead.
|
66
|
+
|
67
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods-1'}
|
68
|
+
EOS
|
69
|
+
|
70
|
+
# Deprecator message for the `Guardfile.create_guardfile` method
|
71
|
+
CREATE_GUARDFILE_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
72
|
+
Starting with Guard 2.0 'Guard::Guardfile.create_guardfile(options)' is deprecated.
|
73
|
+
|
74
|
+
Please use 'Guard::Guardfile::Generator.new(options).create_guardfile' instead.
|
75
|
+
|
76
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods-2'}
|
77
|
+
EOS
|
78
|
+
|
79
|
+
# Deprecator message for the `Guardfile.initialize_template` method
|
80
|
+
INITIALIZE_TEMPLATE_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
81
|
+
Starting with Guard 2.0 'Guard::Guardfile.initialize_template(plugin_name)' is deprecated.
|
82
|
+
|
83
|
+
Please use 'Guard::Guardfile::Generator.new.initialize_template(plugin_name)' instead.
|
84
|
+
|
85
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods-2'}
|
86
|
+
EOS
|
87
|
+
|
88
|
+
# Deprecator message for the `Guardfile.initialize_all_templates` method
|
89
|
+
INITIALIZE_ALL_TEMPLATES_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
90
|
+
Starting with Guard 2.0 'Guard::Guardfile.initialize_all_templates' is deprecated.
|
91
|
+
|
92
|
+
Please use 'Guard::Guardfile::Generator.new.initialize_all_templates' instead.
|
93
|
+
|
94
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#deprecated-methods-2'}
|
95
|
+
EOS
|
96
|
+
|
97
|
+
# Deprecator message for when a Guard plugin inherits from Guard::Guard
|
98
|
+
GUARD_GUARD_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
99
|
+
Starting with Guard 2.0, Guard::%s should inherit from Guard::Plugin instead of Guard::Guard.
|
100
|
+
|
101
|
+
Please note that the constructor signature has changed from Guard::Guard#initialize(watchers = [], options = {}) to Guard::Plugin#initialize(options = {}).
|
102
|
+
|
103
|
+
#{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % '#changes-in-guardguard'}
|
104
|
+
EOS
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/lib/guard/dsl.rb
CHANGED
@@ -1,347 +1,159 @@
|
|
1
|
+
require 'guard/guardfile'
|
2
|
+
require 'guard/interactor'
|
3
|
+
require 'guard/notifier'
|
4
|
+
require 'guard/ui'
|
5
|
+
require 'guard/watcher'
|
6
|
+
|
1
7
|
module Guard
|
2
8
|
|
3
|
-
# The
|
4
|
-
# the behaviour of Guard.
|
9
|
+
# The Dsl class provides the methods that are used in each `Guardfile` to
|
10
|
+
# describe the behaviour of Guard.
|
5
11
|
#
|
6
|
-
# The main keywords of the DSL are
|
7
|
-
# the used Guard plugins and the file changes they are watching.
|
12
|
+
# The main keywords of the DSL are {#guard} and {#watch}. These are necessary
|
13
|
+
# to define the used Guard plugins and the file changes they are watching.
|
8
14
|
#
|
9
|
-
# You can optionally group the Guard plugins with the
|
10
|
-
# with the
|
15
|
+
# You can optionally group the Guard plugins with the {#group} keyword and
|
16
|
+
# ignore and filter certain paths with the {#ignore} and {#filter} keywords.
|
11
17
|
#
|
12
|
-
# You can set your preferred system notification library with
|
13
|
-
# some optional configuration options for the library. If you don't
|
14
|
-
# Guard will automatically pick one with default options
|
15
|
-
# specify `:off` as library).
|
18
|
+
# You can set your preferred system notification library with {#notification}
|
19
|
+
# and pass some optional configuration options for the library. If you don't
|
20
|
+
# configure a library, Guard will automatically pick one with default options
|
21
|
+
# (if you don't want notifications, specify `:off` as library). Please see
|
22
|
+
# {Notifier} for more information about the supported libraries.
|
16
23
|
#
|
17
|
-
# A more advanced DSL use is the
|
18
|
-
# code before or after any of the
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
24
|
+
# A more advanced DSL use is the {#callback} keyword that allows you to
|
25
|
+
# execute arbitrary code before or after any of the {Plugin::Base#start},
|
26
|
+
# {Plugin::Base#stop}, {Plugin::Base#reload}, {Plugin::Base#run_all},
|
27
|
+
# {Plugin::Base#run_on_changes}, {Plugin::Base#run_on_additions},
|
28
|
+
# {Plugin::Base#run_on_modifications} and {Plugin::Base#run_on_removals}
|
29
|
+
# Guard plugins method.
|
30
|
+
# You can even insert more hooks inside these methods. Please [checkout the
|
31
|
+
# Wiki page](https://github.com/guard/guard/wiki/Hooks-and-callbacks) for
|
32
|
+
# more details.
|
22
33
|
#
|
23
34
|
# The DSL will also evaluate normal Ruby code.
|
24
35
|
#
|
25
36
|
# There are two possible locations for the `Guardfile`:
|
26
|
-
# - The `Guardfile` in the current directory where Guard has been started
|
27
|
-
# - The `.Guardfile` in your home directory.
|
28
37
|
#
|
29
|
-
#
|
30
|
-
#
|
38
|
+
# * The `Guardfile` in the current directory where Guard has been started
|
39
|
+
# * The `.Guardfile` in your home directory.
|
40
|
+
#
|
41
|
+
# In addition, if a user configuration `.guard.rb` in your home directory is
|
42
|
+
# found, it will be appended to the current project `Guardfile`.
|
31
43
|
#
|
32
44
|
# @see https://github.com/guard/guard/wiki/Guardfile-examples
|
33
45
|
#
|
34
46
|
class Dsl
|
35
47
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
Starting with Guard v1.1 the use of the 'ignore_paths' Guardfile DSL method is deprecated.
|
46
|
-
|
47
|
-
Please replace that method with the better 'ignore' or/and 'filter' methods.
|
48
|
-
Documentation on the README: https://github.com/guard/guard#ignore
|
49
|
-
EOS
|
50
|
-
|
51
|
-
# Deprecation message for the `interactor` method
|
52
|
-
INTERACTOR_DEPRECATION = <<-EOS.gsub(/^\s*/, '')
|
53
|
-
Starting with Guard v1.4 the use of the 'interactor' Guardfile DSL method is only used to
|
54
|
-
disable or pass options to the Pry interactor. All other usages are deprecated.
|
55
|
-
EOS
|
56
|
-
|
57
|
-
class << self
|
58
|
-
|
59
|
-
attr_accessor :options
|
60
|
-
|
61
|
-
# Evaluate the DSL methods in the `Guardfile`.
|
62
|
-
#
|
63
|
-
# @option options [Array<Symbol,String>] groups the groups to evaluate
|
64
|
-
# @option options [String] guardfile the path to a valid Guardfile
|
65
|
-
# @option options [String] guardfile_contents a string representing the content of a valid Guardfile
|
66
|
-
# @raise [ArgumentError] when options are not a Hash
|
67
|
-
#
|
68
|
-
def evaluate_guardfile(options = {})
|
69
|
-
raise ArgumentError.new('No option hash passed to evaluate_guardfile!') unless options.is_a?(Hash)
|
70
|
-
|
71
|
-
self.options = options.dup
|
72
|
-
|
73
|
-
fetch_guardfile_contents
|
74
|
-
instance_eval_guardfile(guardfile_contents_with_user_config)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Re-evaluate the `Guardfile` to update the current Guard configuration.
|
78
|
-
#
|
79
|
-
def reevaluate_guardfile
|
80
|
-
before_reevaluate_guardfile
|
81
|
-
::Guard::Dsl.evaluate_guardfile(options)
|
82
|
-
after_reevaluate_guardfile
|
83
|
-
end
|
84
|
-
|
85
|
-
# Stop Guard and clear internal state
|
86
|
-
# before the Guardfile will be re-evaluated.
|
87
|
-
#
|
88
|
-
def before_reevaluate_guardfile
|
89
|
-
::Guard.runner.run(:stop)
|
90
|
-
::Guard.guards.clear
|
91
|
-
::Guard.setup_groups
|
92
|
-
::Guard::Notifier.clear_notifications
|
93
|
-
|
94
|
-
options.delete(:guardfile_contents)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Start Guard and notification and show a message
|
98
|
-
# after the Guardfile has been re-evaluated.
|
99
|
-
#
|
100
|
-
def after_reevaluate_guardfile
|
101
|
-
::Guard::Notifier.turn_on if ::Guard::Notifier.enabled?
|
102
|
-
|
103
|
-
if ::Guard.guards.empty?
|
104
|
-
::Guard::Notifier.notify('No guards found in Guardfile, please add at least one.', :title => 'Guard re-evaluate', :image => :failed)
|
105
|
-
else
|
106
|
-
msg = 'Guardfile has been re-evaluated.'
|
107
|
-
::Guard::UI.info(msg)
|
108
|
-
::Guard::Notifier.notify(msg, :title => 'Guard re-evaluate')
|
109
|
-
|
110
|
-
::Guard.runner.run(:start)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Evaluate the content of the `Guardfile`.
|
115
|
-
#
|
116
|
-
# @param [String] contents the content to evaluate.
|
117
|
-
#
|
118
|
-
def instance_eval_guardfile(contents)
|
119
|
-
new.instance_eval(contents, options[:guardfile_path], 1)
|
120
|
-
rescue
|
121
|
-
::Guard::UI.error "Invalid Guardfile, original error is:\n#{ $! }"
|
122
|
-
end
|
123
|
-
|
124
|
-
# Test if the current `Guardfile` contains a specific Guard plugin.
|
125
|
-
#
|
126
|
-
# @param [String] guard_name the name of the Guard
|
127
|
-
# @return [Boolean] whether the Guard has been declared
|
128
|
-
#
|
129
|
-
def guardfile_include?(guard_name)
|
130
|
-
guardfile_contents.match(/^guard\s*\(?\s*['":]#{ guard_name }['"]?/)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Read the current `Guardfile` content.
|
134
|
-
#
|
135
|
-
# @param [String] guardfile_path the path to the Guardfile
|
136
|
-
#
|
137
|
-
def read_guardfile(guardfile_path)
|
138
|
-
options[:guardfile_path] = guardfile_path
|
139
|
-
options[:guardfile_contents] = File.read(guardfile_path)
|
140
|
-
rescue
|
141
|
-
::Guard::UI.error("Error reading file #{ guardfile_path }")
|
142
|
-
exit 1
|
143
|
-
end
|
144
|
-
|
145
|
-
# Get the content to evaluate and stores it into
|
146
|
-
# the options as `:guardfile_contents`.
|
147
|
-
#
|
148
|
-
def fetch_guardfile_contents
|
149
|
-
if options[:guardfile_contents]
|
150
|
-
::Guard::UI.info 'Using inline Guardfile.'
|
151
|
-
options[:guardfile_path] = 'Inline Guardfile'
|
152
|
-
|
153
|
-
elsif options[:guardfile]
|
154
|
-
if File.exist?(options[:guardfile])
|
155
|
-
read_guardfile(options[:guardfile])
|
156
|
-
::Guard::UI.info "Using Guardfile at #{ options[:guardfile] }."
|
157
|
-
else
|
158
|
-
::Guard::UI.error "No Guardfile exists at #{ options[:guardfile] }."
|
159
|
-
exit 1
|
160
|
-
end
|
161
|
-
|
162
|
-
else
|
163
|
-
if File.exist?(guardfile_default_path)
|
164
|
-
read_guardfile(guardfile_default_path)
|
165
|
-
else
|
166
|
-
::Guard::UI.error 'No Guardfile found, please create one with `guard init`.'
|
167
|
-
exit 1
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
unless guardfile_contents_usable?
|
172
|
-
::Guard::UI.error 'No Guard plugins found in Guardfile, please add at least one.'
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
# Get the content of the `Guardfile`.
|
177
|
-
#
|
178
|
-
# @return [String] the Guardfile content
|
179
|
-
#
|
180
|
-
def guardfile_contents
|
181
|
-
options ? options[:guardfile_contents] : ''
|
182
|
-
end
|
183
|
-
|
184
|
-
# Get the content of the `Guardfile` and the global
|
185
|
-
# user configuration file.
|
186
|
-
#
|
187
|
-
# @see #user_config_path
|
188
|
-
#
|
189
|
-
# @return [String] the Guardfile content
|
190
|
-
#
|
191
|
-
def guardfile_contents_with_user_config
|
192
|
-
config = File.read(user_config_path) if File.exist?(user_config_path)
|
193
|
-
[guardfile_contents, config].join("\n")
|
194
|
-
end
|
195
|
-
|
196
|
-
# Get the file path to the project `Guardfile`.
|
197
|
-
#
|
198
|
-
# @return [String] the path to the Guardfile
|
199
|
-
#
|
200
|
-
def guardfile_path
|
201
|
-
options ? options[:guardfile_path] : ''
|
202
|
-
end
|
203
|
-
|
204
|
-
# Tests if the current `Guardfile` content is usable.
|
205
|
-
#
|
206
|
-
# @return [Boolean] if the Guardfile is usable
|
207
|
-
#
|
208
|
-
def guardfile_contents_usable?
|
209
|
-
guardfile_contents && guardfile_contents.size >= 'guard :a'.size # Smallest Guard definition
|
210
|
-
end
|
211
|
-
|
212
|
-
# Gets the default path of the `Guardfile`. This returns the `Guardfile`
|
213
|
-
# from the current directory when existing, or the global `.Guardfile`
|
214
|
-
# at the home directory.
|
215
|
-
#
|
216
|
-
# @return [String] the path to the Guardfile
|
217
|
-
#
|
218
|
-
def guardfile_default_path
|
219
|
-
File.exist?(local_guardfile_path) ? local_guardfile_path : home_guardfile_path
|
220
|
-
end
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
# The path to the `Guardfile` that is located at
|
225
|
-
# the directory, where Guard has been started from.
|
226
|
-
#
|
227
|
-
# @return [String] the path to the local Guardfile
|
228
|
-
#
|
229
|
-
def local_guardfile_path
|
230
|
-
File.join(Dir.pwd, 'Guardfile')
|
231
|
-
end
|
232
|
-
|
233
|
-
# The path to the `.Guardfile` that is located at
|
234
|
-
# the users home directory.
|
235
|
-
#
|
236
|
-
# @return [String] the path to ~/.Guardfile
|
237
|
-
#
|
238
|
-
def home_guardfile_path
|
239
|
-
File.expand_path(File.join('~', '.Guardfile'))
|
240
|
-
end
|
241
|
-
|
242
|
-
# The path to the user configuration `.guard.rb`
|
243
|
-
# that is located at the users home directory.
|
244
|
-
#
|
245
|
-
# @return [String] the path to ~/.guard.rb
|
246
|
-
#
|
247
|
-
def user_config_path
|
248
|
-
File.expand_path(File.join('~', '.guard.rb'))
|
249
|
-
end
|
250
|
-
|
48
|
+
# @deprecated Use
|
49
|
+
# `Guard::Guardfile::Evaluator.new(options).evaluate_guardfile` instead.
|
50
|
+
#
|
51
|
+
# @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
|
52
|
+
# upgrade for Guard 2.0
|
53
|
+
#
|
54
|
+
def self.evaluate_guardfile(options = {})
|
55
|
+
::Guard::UI.deprecation(::Guard::Deprecator::EVALUATE_GUARDFILE_DEPRECATION)
|
56
|
+
::Guard::Guardfile::Evaluator.new(options).evaluate_guardfile
|
251
57
|
end
|
252
58
|
|
253
59
|
# Set notification options for the system notifications.
|
254
|
-
# You can set multiple
|
60
|
+
# You can set multiple notifications, which allows you to show local
|
255
61
|
# system notifications and remote notifications with separate libraries.
|
256
62
|
# You can also pass `:off` as library to turn off notifications.
|
257
63
|
#
|
258
64
|
# @example Define multiple notifications
|
259
65
|
# notification :growl_notify
|
260
|
-
# notification :ruby_gntp, :
|
261
|
-
#
|
262
|
-
# @see Guard::Notifier for available notifier and its options.
|
66
|
+
# notification :ruby_gntp, host: '192.168.1.5'
|
263
67
|
#
|
264
68
|
# @param [Symbol, String] notifier the name of the notifier to use
|
265
69
|
# @param [Hash] options the notification library options
|
266
70
|
#
|
71
|
+
# @see Guard::Notifier for available notifier and its options.
|
72
|
+
#
|
267
73
|
def notification(notifier, options = {})
|
268
|
-
::Guard::Notifier.
|
74
|
+
::Guard::Notifier.add_notifier(notifier.to_sym, options.merge(silent: false))
|
269
75
|
end
|
270
76
|
|
271
|
-
# Sets the interactor
|
77
|
+
# Sets the interactor options or disable the interactor.
|
78
|
+
#
|
79
|
+
# @example Pass options to the interactor
|
80
|
+
# interactor option1: 'value1', option2: 'value2'
|
272
81
|
#
|
273
82
|
# @example Turn off interactions
|
274
83
|
# interactor :off
|
275
84
|
#
|
276
|
-
# @param [Symbol,Hash] options either `:off` or a Hash with interactor
|
85
|
+
# @param [Symbol, Hash] options either `:off` or a Hash with interactor
|
86
|
+
# options
|
277
87
|
#
|
278
88
|
def interactor(options)
|
279
|
-
|
89
|
+
case options
|
90
|
+
when :off
|
280
91
|
::Guard::Interactor.enabled = false
|
281
|
-
|
282
|
-
elsif options.is_a?(Hash)
|
92
|
+
when Hash
|
283
93
|
::Guard::Interactor.options = options
|
284
|
-
|
285
|
-
else
|
286
|
-
::Guard::UI.deprecation(INTERACTOR_DEPRECATION)
|
287
94
|
end
|
288
95
|
end
|
289
96
|
|
290
|
-
# Declares a group of Guard plugins to be run with `guard start --group
|
97
|
+
# Declares a group of Guard plugins to be run with `guard start --group
|
98
|
+
# group_name`.
|
291
99
|
#
|
292
100
|
# @example Declare two groups of Guard plugins
|
293
|
-
#
|
294
|
-
#
|
295
|
-
# guard
|
296
|
-
# guard 'rspec'
|
101
|
+
# group :backend do
|
102
|
+
# guard :spork
|
103
|
+
# guard :rspec
|
297
104
|
# end
|
298
105
|
#
|
299
|
-
# group
|
300
|
-
# guard
|
301
|
-
# guard
|
106
|
+
# group :frontend do
|
107
|
+
# guard :passenger
|
108
|
+
# guard :livereload
|
302
109
|
# end
|
303
110
|
#
|
304
111
|
# @param [Symbol, String] name the group name called from the CLI
|
305
112
|
# @param [Hash] options the options accepted by the group
|
306
|
-
# @yield a block where you can declare several
|
113
|
+
# @yield a block where you can declare several Guard plugins
|
307
114
|
#
|
115
|
+
# @see Group
|
308
116
|
# @see Guard.add_group
|
309
|
-
# @see
|
310
|
-
# @see Guard::DslDescriber
|
117
|
+
# @see #guard
|
311
118
|
#
|
312
119
|
def group(name, options = {})
|
313
|
-
name
|
120
|
+
raise ArgumentError, "'all' is not an allowed group name!" if name.to_sym == :all
|
314
121
|
|
315
122
|
if block_given?
|
316
|
-
::Guard.add_group(name
|
123
|
+
::Guard.add_group(name, options)
|
317
124
|
@current_group = name
|
318
125
|
|
319
|
-
yield
|
126
|
+
yield
|
320
127
|
|
321
128
|
@current_group = nil
|
129
|
+
else
|
130
|
+
::Guard::UI.error "No Guard plugins found in the group '#{ name }', please add at least one."
|
322
131
|
end
|
323
132
|
end
|
324
133
|
|
325
|
-
#
|
134
|
+
# Declares a Guard plugin to be used when running `guard start`.
|
326
135
|
#
|
327
136
|
# The name parameter is usually the name of the gem without
|
328
137
|
# the 'guard-' prefix.
|
329
138
|
#
|
330
139
|
# The available options are different for each Guard implementation.
|
331
140
|
#
|
332
|
-
# @example Declare a Guard
|
141
|
+
# @example Declare a Guard without `watch` patterns
|
142
|
+
# guard :rspec
|
333
143
|
#
|
334
|
-
#
|
144
|
+
# @example Declare a Guard with a `watch` pattern
|
145
|
+
# guard :rspec do
|
146
|
+
# watch %r{.*_spec.rb}
|
335
147
|
# end
|
336
148
|
#
|
337
|
-
# @param [String] name the Guard name
|
338
|
-
# @param [Hash] options the options accepted by the Guard
|
149
|
+
# @param [String] name the Guard plugin name
|
150
|
+
# @param [Hash] options the options accepted by the Guard plugin
|
339
151
|
# @yield a block where you can declare several watch patterns and actions
|
340
152
|
#
|
341
|
-
# @see
|
342
|
-
# @see
|
343
|
-
# @see
|
344
|
-
# @see
|
153
|
+
# @see Plugin
|
154
|
+
# @see Guard.add_plugin
|
155
|
+
# @see #watch
|
156
|
+
# @see #group
|
345
157
|
#
|
346
158
|
def guard(name, options = {})
|
347
159
|
@watchers = []
|
@@ -350,129 +162,137 @@ module Guard
|
|
350
162
|
|
351
163
|
yield if block_given?
|
352
164
|
|
353
|
-
options.
|
354
|
-
::Guard.
|
165
|
+
options.merge!(group: @current_group, watchers: @watchers, callbacks: @callbacks)
|
166
|
+
::Guard.add_plugin(name, options)
|
355
167
|
end
|
356
168
|
|
357
|
-
#
|
169
|
+
# Defines a pattern to be watched in order to run actions on file modification.
|
358
170
|
#
|
359
171
|
# @example Declare watchers for a Guard
|
360
|
-
#
|
361
|
-
# guard 'rspec' do
|
172
|
+
# guard :rspec do
|
362
173
|
# watch('spec/spec_helper.rb')
|
363
174
|
# watch(%r{^.+_spec.rb})
|
364
175
|
# watch(%r{^app/controllers/(.+).rb}) { |m| 'spec/acceptance/#{m[1]}s_spec.rb' }
|
365
176
|
# end
|
366
177
|
#
|
367
|
-
# @param [String, Regexp] pattern the pattern
|
178
|
+
# @param [String, Regexp] pattern the pattern that Guard must watch for modification
|
368
179
|
# @yield a block to be run when the pattern is matched
|
369
180
|
# @yieldparam [MatchData] m matches of the pattern
|
370
181
|
# @yieldreturn a directory, a filename, an array of directories / filenames, or nothing (can be an arbitrary command)
|
371
182
|
#
|
372
183
|
# @see Guard::Watcher
|
373
|
-
# @see
|
184
|
+
# @see #guard
|
374
185
|
#
|
375
186
|
def watch(pattern, &action)
|
376
187
|
@watchers << ::Guard::Watcher.new(pattern, action)
|
377
188
|
end
|
378
189
|
|
379
|
-
#
|
380
|
-
# the `start`, `stop`, `reload`, `run_all`, `run_on_changes
|
381
|
-
# and `run_on_removals` plugin
|
190
|
+
# Defines a callback to execute arbitrary code before or after any of
|
191
|
+
# the `start`, `stop`, `reload`, `run_all`, `run_on_changes`,
|
192
|
+
# `run_on_additions`, `run_on_modifications` and `run_on_removals` plugin
|
193
|
+
# method.
|
382
194
|
#
|
383
|
-
# @
|
384
|
-
#
|
195
|
+
# @example Define a callback that'll be called before the `reload` action.
|
196
|
+
# callback(:reload_begin) { puts "Let's reload!" }
|
385
197
|
#
|
386
|
-
# @
|
198
|
+
# @example Define a callback that'll be called before the `start` and `stop` actions.
|
199
|
+
# my_lambda = lambda { |plugin, event, *args| puts "Let's #{event} #{plugin} with #{args}!" }
|
200
|
+
# callback(my_lambda, [:start_begin, :start_end])
|
387
201
|
#
|
388
|
-
|
389
|
-
|
390
|
-
@callbacks << { :events => events, :listener => listener }
|
391
|
-
end
|
392
|
-
|
393
|
-
# @deprecated Ignore certain paths globally.
|
394
|
-
#
|
395
|
-
# @example Ignore some paths
|
396
|
-
# ignore_paths ".git", ".svn"
|
202
|
+
# @param [Array] args the callback arguments
|
203
|
+
# @yield a callback block
|
397
204
|
#
|
398
|
-
# @
|
205
|
+
# @see Guard::Hooker
|
399
206
|
#
|
400
|
-
def
|
401
|
-
|
207
|
+
def callback(*args, &block)
|
208
|
+
block, events = if args.size > 1
|
209
|
+
# block must be the first argument in that case, the yielded block is
|
210
|
+
# ignored
|
211
|
+
args
|
212
|
+
else
|
213
|
+
[block, args[0]]
|
214
|
+
end
|
215
|
+
@callbacks << { events: events, listener: block }
|
402
216
|
end
|
403
217
|
|
404
|
-
#
|
218
|
+
# Ignores certain paths globally.
|
405
219
|
#
|
406
220
|
# @example Ignore some paths
|
407
221
|
# ignore %r{^ignored/path/}, /man/
|
408
222
|
#
|
409
|
-
# @param [Regexp] regexps a pattern for ignoring paths
|
223
|
+
# @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
|
410
224
|
#
|
411
225
|
def ignore(*regexps)
|
412
226
|
::Guard.listener = ::Guard.listener.ignore(*regexps) if ::Guard.listener
|
413
227
|
end
|
414
228
|
|
415
|
-
#
|
229
|
+
# Replaces ignored paths globally
|
416
230
|
#
|
417
231
|
# @example Ignore only these paths
|
418
232
|
# ignore! %r{^ignored/path/}, /man/
|
419
233
|
#
|
420
|
-
# @param [Regexp] regexps a pattern for ignoring paths
|
234
|
+
# @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
|
421
235
|
#
|
422
236
|
def ignore!(*regexps)
|
423
237
|
::Guard.listener = ::Guard.listener.ignore!(*regexps) if ::Guard.listener
|
424
238
|
end
|
425
239
|
|
426
|
-
#
|
240
|
+
# Filters certain paths globally.
|
427
241
|
#
|
428
242
|
# @example Filter some files
|
429
243
|
# filter /\.txt$/, /.*\.zip/
|
430
244
|
#
|
431
|
-
# @param [Regexp] regexps a pattern for filtering
|
245
|
+
# @param [Regexp] regexps a pattern (or list of patterns) for filtering
|
246
|
+
# paths
|
432
247
|
#
|
433
248
|
def filter(*regexps)
|
434
249
|
::Guard.listener = ::Guard.listener.filter(*regexps) if ::Guard.listener
|
435
250
|
end
|
436
251
|
|
437
|
-
#
|
252
|
+
# Replaces filtered paths globally.
|
438
253
|
#
|
439
254
|
# @example Filter only these files
|
440
255
|
# filter! /\.txt$/, /.*\.zip/
|
441
256
|
#
|
442
|
-
# @param [Regexp] regexps a pattern for filtering
|
257
|
+
# @param [Regexp] regexps a pattern (or list of patterns) for filtering
|
258
|
+
# paths
|
443
259
|
#
|
444
260
|
def filter!(*regexps)
|
445
261
|
::Guard.listener = ::Guard.listener.filter!(*regexps) if ::Guard.listener
|
446
262
|
end
|
447
263
|
|
448
|
-
#
|
264
|
+
# Configures the Guard logger.
|
449
265
|
#
|
450
266
|
# * Log level must be either `:debug`, `:info`, `:warn` or `:error`.
|
451
|
-
# * Template supports the following placeholders: `:time`, `:severity`,
|
452
|
-
#
|
453
|
-
# *
|
267
|
+
# * Template supports the following placeholders: `:time`, `:severity`,
|
268
|
+
# `:progname`, `:pid`, `:unit_of_work_id` and `:message`.
|
269
|
+
# * Time format directives are the same as `Time#strftime` or
|
270
|
+
# `:milliseconds`.
|
271
|
+
# * The `:only` and `:except` options must be a `RegExp`.
|
454
272
|
#
|
455
273
|
# @example Set the log level
|
456
|
-
# logger :
|
274
|
+
# logger level: :warn
|
457
275
|
#
|
458
276
|
# @example Set a custom log template
|
459
|
-
# logger :
|
277
|
+
# logger template: '[Guard - :severity - :progname - :time] :message'
|
460
278
|
#
|
461
279
|
# @example Set a custom time format
|
462
|
-
# logger :
|
280
|
+
# logger time_format: '%h'
|
463
281
|
#
|
464
282
|
# @example Limit logging to a Guard plugin
|
465
|
-
# logger :
|
283
|
+
# logger only: :jasmine
|
466
284
|
#
|
467
285
|
# @example Log all but not the messages from a specific Guard plugin
|
468
|
-
# logger :
|
286
|
+
# logger except: :jasmine
|
469
287
|
#
|
470
288
|
# @param [Hash] options the log options
|
471
289
|
# @option options [String, Symbol] level the log level
|
472
290
|
# @option options [String] template the logger template
|
473
291
|
# @option options [String, Symbol] time_format the time format
|
474
|
-
# @option options [
|
475
|
-
#
|
292
|
+
# @option options [Regexp] only show only messages from the matching Guard
|
293
|
+
# plugin
|
294
|
+
# @option options [Regexp] except does not show messages from the matching
|
295
|
+
# Guard plugin
|
476
296
|
#
|
477
297
|
def logger(options)
|
478
298
|
if options[:level]
|
@@ -499,35 +319,29 @@ module Guard
|
|
499
319
|
end
|
500
320
|
end
|
501
321
|
|
502
|
-
::Guard::UI.options = ::Guard::UI.options.merge options
|
322
|
+
::Guard::UI.options = ::Guard::UI.options.marshal_dump.merge options
|
503
323
|
end
|
504
324
|
|
505
325
|
# Sets the default scope on startup
|
506
326
|
#
|
507
327
|
# @example Scope Guard to a single group
|
508
|
-
# scope :
|
328
|
+
# scope group: :frontend
|
509
329
|
#
|
510
330
|
# @example Scope Guard to multiple groups
|
511
|
-
# scope :
|
331
|
+
# scope groups: [:specs, :docs]
|
512
332
|
#
|
513
333
|
# @example Scope Guard to a single plugin
|
514
|
-
# scope :
|
334
|
+
# scope plugin: :test
|
515
335
|
#
|
516
336
|
# @example Scope Guard to multiple plugins
|
517
|
-
# scope :
|
337
|
+
# scope plugins: [:jasmine, :rspec]
|
518
338
|
#
|
519
339
|
# @param [Hash] scopes the scope for the groups and plugins
|
520
340
|
#
|
521
|
-
def scope(
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
end
|
526
|
-
|
527
|
-
if ::Guard.options[:group].empty?
|
528
|
-
::Guard.options[:group] = [scopes[:group]] if scopes[:group]
|
529
|
-
::Guard.options[:group] = scopes[:groups] if scopes[:groups]
|
530
|
-
end
|
341
|
+
def scope(scope = {})
|
342
|
+
scope[:plugins] = Array(scope[:plugins] || scope[:plugin] || [])
|
343
|
+
scope[:groups] = Array(scope[:groups] || scope[:group] || [])
|
344
|
+
::Guard.setup_scope(scope)
|
531
345
|
end
|
532
346
|
|
533
347
|
end
|