guard 2.8.2 → 2.9.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -7
  3. data/lib/guard.rb +220 -152
  4. data/lib/guard.rb.orig +213 -155
  5. data/lib/guard/aruba_adapter.rb +2 -2
  6. data/lib/guard/cli.rb +8 -13
  7. data/lib/guard/cli.rb.orig +12 -10
  8. data/lib/guard/commander.rb +15 -7
  9. data/lib/guard/commands/all.rb +3 -0
  10. data/lib/guard/commands/change.rb +3 -0
  11. data/lib/guard/commands/pause.rb +2 -0
  12. data/lib/guard/commands/reload.rb +4 -0
  13. data/lib/guard/commands/scope.rb +3 -0
  14. data/lib/guard/config.rb +24 -0
  15. data/lib/guard/deprecated/dsl.rb +45 -0
  16. data/lib/guard/deprecated/guard.rb +166 -0
  17. data/lib/guard/deprecated/guardfile.rb +84 -0
  18. data/lib/guard/dsl.rb +24 -13
  19. data/lib/guard/dsl.rb.orig +378 -0
  20. data/lib/guard/dsl_describer.rb +8 -2
  21. data/lib/guard/dsl_describer.rb.orig +11 -3
  22. data/lib/guard/guardfile.rb +32 -44
  23. data/lib/guard/guardfile/evaluator.rb +13 -6
  24. data/lib/guard/guardfile/generator.rb +4 -3
  25. data/lib/guard/interactor.rb +7 -3
  26. data/lib/guard/internals/debugging.rb +1 -0
  27. data/lib/guard/internals/environment.rb +93 -0
  28. data/lib/guard/internals/helpers.rb +13 -0
  29. data/lib/guard/internals/traps.rb +10 -0
  30. data/lib/guard/jobs/pry_wrapper.rb +4 -3
  31. data/lib/guard/jobs/sleep.rb +2 -0
  32. data/lib/guard/metadata.rb +190 -0
  33. data/lib/guard/notifier.rb +124 -99
  34. data/lib/guard/notifier.rb.orig +124 -99
  35. data/lib/guard/notifier/detected.rb +83 -0
  36. data/lib/guard/notifiers/emacs.rb +2 -1
  37. data/lib/guard/notifiers/tmux.rb +173 -177
  38. data/lib/guard/plugin/base.rb +2 -0
  39. data/lib/guard/plugin_util.rb +26 -32
  40. data/lib/guard/reevaluator.rb +3 -3
  41. data/lib/guard/reevaluator.rb.orig +22 -0
  42. data/lib/guard/runner.rb +1 -0
  43. data/lib/guard/session.rb +5 -0
  44. data/lib/guard/sheller.rb +2 -2
  45. data/lib/guard/templates/Guardfile +4 -0
  46. data/lib/guard/templates/Guardfile.orig +2 -0
  47. data/lib/guard/terminal.rb +1 -0
  48. data/lib/guard/ui.rb +4 -1
  49. data/lib/guard/version.rb +1 -1
  50. data/lib/guard/version.rb.orig +1 -1
  51. data/lib/guard/watcher.rb +3 -1
  52. data/lib/guard/watcher.rb.orig +122 -0
  53. data/man/guard.1 +1 -4
  54. data/man/guard.1.html +1 -4
  55. metadata +17 -25
  56. data/lib/guard/commander.rb.orig +0 -103
  57. data/lib/guard/commands/all.rb.orig +0 -36
  58. data/lib/guard/commands/reload.rb.orig +0 -34
  59. data/lib/guard/commands/scope.rb.orig +0 -36
  60. data/lib/guard/deprecated_methods.rb +0 -72
  61. data/lib/guard/deprecated_methods.rb.orig +0 -71
  62. data/lib/guard/deprecator.rb +0 -133
  63. data/lib/guard/deprecator.rb.orig +0 -206
  64. data/lib/guard/guard.rb +0 -100
  65. data/lib/guard/guard.rb.orig +0 -42
  66. data/lib/guard/guardfile.rb.orig +0 -43
  67. data/lib/guard/guardfile/evaluator.rb.orig +0 -275
  68. data/lib/guard/internals/debugging.rb.orig +0 -0
  69. data/lib/guard/internals/environment.rb.orig +0 -0
  70. data/lib/guard/internals/tracing.rb.orig +0 -0
  71. data/lib/guard/notifiers/base.rb.orig +0 -221
  72. data/lib/guard/notifiers/tmux.rb.orig +0 -339
  73. data/lib/guard/plugin_util.rb.orig +0 -186
  74. data/lib/guard/runner.rb.orig +0 -210
  75. data/lib/guard/setuper.rb +0 -359
  76. data/lib/guard/setuper.rb.orig +0 -395
  77. data/lib/guard/ui.rb.orig +0 -278
data/lib/guard/dsl.rb CHANGED
@@ -1,9 +1,14 @@
1
- require "guard/guardfile"
1
+ require "guard/guardfile/evaluator"
2
2
  require "guard/interactor"
3
3
  require "guard/notifier"
4
4
  require "guard/ui"
5
5
  require "guard/watcher"
6
6
 
7
+ require "guard/deprecated/dsl" unless Guard::Config.new.strict?
8
+
9
+ # TODO: only for listener
10
+ require "guard"
11
+
7
12
  module Guard
8
13
  # The Dsl class provides the methods that are used in each `Guardfile` to
9
14
  # describe the behaviour of Guard.
@@ -43,23 +48,14 @@ module Guard
43
48
  # @see https://github.com/guard/guard/wiki/Guardfile-examples
44
49
  #
45
50
  class Dsl
51
+ Deprecated::Dsl.add_deprecated(self) unless Config.new.strict?
52
+
46
53
  WARN_INVALID_LOG_LEVEL = "Invalid log level `%s` ignored. "\
47
54
  "Please use either :debug, :info, :warn or :error."
48
55
 
49
56
  WARN_INVALID_LOG_OPTIONS = "You cannot specify the logger options"\
50
57
  " :only and :except at the same time."
51
58
 
52
- # @deprecated Use
53
- # `Guard::Guardfile::Evaluator.new(options).evaluate_guardfile` instead.
54
- #
55
- # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
56
- # upgrade for Guard 2.0
57
- #
58
- def self.evaluate_guardfile(options = {})
59
- UI.deprecation(Deprecator::EVALUATE_GUARDFILE_DEPRECATION)
60
- Guardfile::Evaluator.new(options).evaluate_guardfile
61
- end
62
-
63
59
  # Set notification options for the system notifications.
64
60
  # You can set multiple notifications, which allows you to show local
65
61
  # system notifications and remote notifications with separate libraries.
@@ -75,7 +71,7 @@ module Guard
75
71
  # @see Guard::Notifier for available notifier and its options.
76
72
  #
77
73
  def notification(notifier, options = {})
78
- Notifier.add_notifier(notifier.to_sym, options.merge(silent: false))
74
+ Notifier.add(notifier.to_sym, options.merge(silent: false))
79
75
  end
80
76
 
81
77
  # Sets the interactor options or disable the interactor.
@@ -265,6 +261,7 @@ module Guard
265
261
  # @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
266
262
  #
267
263
  def ignore(*regexps)
264
+ # TODO: instead, use Guard.reconfigure(ignore: regexps) or something
268
265
  ::Guard.listener.ignore(regexps) if ::Guard.listener
269
266
  end
270
267
  alias filter ignore
@@ -366,5 +363,19 @@ module Guard
366
363
  def scope(scope = {})
367
364
  ::Guard.setup_scope(scope)
368
365
  end
366
+
367
+ # Sets the directories to pass to Listen
368
+ #
369
+ # @example watch only given directories
370
+ # directories %w(lib specs)
371
+ #
372
+ # @param [Array] directories directories for Listen to watch
373
+ #
374
+ def directories(directories)
375
+ directories.each do |dir|
376
+ fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
377
+ end
378
+ ::Guard.watchdirs = directories
379
+ end
369
380
  end
370
381
  end
@@ -0,0 +1,378 @@
1
+ require "guard/guardfile/evaluator"
2
+ require "guard/interactor"
3
+ require "guard/notifier"
4
+ require "guard/ui"
5
+ require "guard/watcher"
6
+
7
+ require "guard/deprecated/dsl" unless Guard::Config.new.strict?
8
+
9
+ # TODO: only for listener
10
+ require "guard"
11
+
12
+ module Guard
13
+ # The Dsl class provides the methods that are used in each `Guardfile` to
14
+ # describe the behaviour of Guard.
15
+ #
16
+ # The main keywords of the DSL are {#guard} and {#watch}. These are necessary
17
+ # to define the used Guard plugins and the file changes they are watching.
18
+ #
19
+ # You can optionally group the Guard plugins with the {#group} keyword and
20
+ # ignore and filter certain paths with the {#ignore} and {#filter} keywords.
21
+ #
22
+ # You can set your preferred system notification library with {#notification}
23
+ # and pass some optional configuration options for the library. If you don't
24
+ # configure a library, Guard will automatically pick one with default options
25
+ # (if you don't want notifications, specify `:off` as library). Please see
26
+ # {Notifier} for more information about the supported libraries.
27
+ #
28
+ # A more advanced DSL use is the {#callback} keyword that allows you to
29
+ # execute arbitrary code before or after any of the {Plugin::Base#start},
30
+ # {Plugin::Base#stop}, {Plugin::Base#reload}, {Plugin::Base#run_all},
31
+ # {Plugin::Base#run_on_changes}, {Plugin::Base#run_on_additions},
32
+ # {Plugin::Base#run_on_modifications} and {Plugin::Base#run_on_removals}
33
+ # Guard plugins method.
34
+ # You can even insert more hooks inside these methods. Please [checkout the
35
+ # Wiki page](https://github.com/guard/guard/wiki/Hooks-and-callbacks) for
36
+ # more details.
37
+ #
38
+ # The DSL will also evaluate normal Ruby code.
39
+ #
40
+ # There are two possible locations for the `Guardfile`:
41
+ #
42
+ # * The `Guardfile` in the current directory where Guard has been started
43
+ # * The `.Guardfile` in your home directory.
44
+ #
45
+ # In addition, if a user configuration `.guard.rb` in your home directory is
46
+ # found, it will be appended to the current project `Guardfile`.
47
+ #
48
+ # @see https://github.com/guard/guard/wiki/Guardfile-examples
49
+ #
50
+ class Dsl
51
+ Deprecated::Dsl.add_deprecated(self) unless Config.new.strict?
52
+
53
+ WARN_INVALID_LOG_LEVEL = "Invalid log level `%s` ignored. "\
54
+ "Please use either :debug, :info, :warn or :error."
55
+
56
+ WARN_INVALID_LOG_OPTIONS = "You cannot specify the logger options"\
57
+ " :only and :except at the same time."
58
+
59
+ # Set notification options for the system notifications.
60
+ # You can set multiple notifications, which allows you to show local
61
+ # system notifications and remote notifications with separate libraries.
62
+ # You can also pass `:off` as library to turn off notifications.
63
+ #
64
+ # @example Define multiple notifications
65
+ # notification :ruby_gntp
66
+ # notification :ruby_gntp, host: '192.168.1.5'
67
+ #
68
+ # @param [Symbol, String] notifier the name of the notifier to use
69
+ # @param [Hash] options the notification library options
70
+ #
71
+ # @see Guard::Notifier for available notifier and its options.
72
+ #
73
+ def notification(notifier, options = {})
74
+ Notifier.add(notifier.to_sym, options.merge(silent: false))
75
+ end
76
+
77
+ # Sets the interactor options or disable the interactor.
78
+ #
79
+ # @example Pass options to the interactor
80
+ # interactor option1: 'value1', option2: 'value2'
81
+ #
82
+ # @example Turn off interactions
83
+ # interactor :off
84
+ #
85
+ # @param [Symbol, Hash] options either `:off` or a Hash with interactor
86
+ # options
87
+ #
88
+ def interactor(options)
89
+ case options
90
+ when :off
91
+ ::Guard::Interactor.enabled = false
92
+ when Hash
93
+ ::Guard::Interactor.options = options
94
+ end
95
+ end
96
+
97
+ # Declares a group of Guard plugins to be run with `guard start --group
98
+ # group_name`.
99
+ #
100
+ # @example Declare two groups of Guard plugins
101
+ # group :backend do
102
+ # guard :spork
103
+ # guard :rspec
104
+ # end
105
+ #
106
+ # group :frontend do
107
+ # guard :passenger
108
+ # guard :livereload
109
+ # end
110
+ #
111
+ # @param [Symbol, String, Array<Symbol, String>] name the group name called
112
+ # from the CLI
113
+ # @param [Hash] options the options accepted by the group
114
+ # @yield a block where you can declare several Guard plugins
115
+ #
116
+ # @see Group
117
+ # @see Guard.add_group
118
+ # @see #guard
119
+ #
120
+ def group(*args)
121
+ options = args.last.is_a?(Hash) ? args.pop : {}
122
+ groups = args
123
+
124
+ groups.each do |group|
125
+ next unless group.to_sym == :all
126
+ fail ArgumentError, "'all' is not an allowed group name!"
127
+ end
128
+
129
+ if block_given?
130
+ groups.each do |group|
131
+ ::Guard.add_group(group, options)
132
+ end
133
+
134
+ @current_groups ||= []
135
+ @current_groups.push(groups)
136
+
137
+ yield
138
+
139
+ @current_groups.pop
140
+ else
141
+ ::Guard::UI.error \
142
+ "No Guard plugins found in the group '#{ groups.join(", ") }',"\
143
+ " please add at least one."
144
+ end
145
+ end
146
+
147
+ # Declares a Guard plugin to be used when running `guard start`.
148
+ #
149
+ # The name parameter is usually the name of the gem without
150
+ # the 'guard-' prefix.
151
+ #
152
+ # The available options are different for each Guard implementation.
153
+ #
154
+ # @example Declare a Guard without `watch` patterns
155
+ # guard :rspec
156
+ #
157
+ # @example Declare a Guard with a `watch` pattern
158
+ # guard :rspec do
159
+ # watch %r{.*_spec.rb}
160
+ # end
161
+ #
162
+ # @param [String] name the Guard plugin name
163
+ # @param [Hash] options the options accepted by the Guard plugin
164
+ # @yield a block where you can declare several watch patterns and actions
165
+ #
166
+ # @see Plugin
167
+ # @see Guard.add_plugin
168
+ # @see #watch
169
+ # @see #group
170
+ #
171
+ def guard(name, options = {})
172
+ @plugin_options = options.merge(watchers: [], callbacks: [])
173
+
174
+ yield if block_given?
175
+
176
+ @current_groups ||= []
177
+ groups = @current_groups && @current_groups.last || [:default]
178
+ groups.each do |group|
179
+ ::Guard.add_plugin(name, @plugin_options.merge(group: group))
180
+ end
181
+
182
+ @plugin_options = nil
183
+ end
184
+
185
+ # Defines a pattern to be watched in order to run actions on file
186
+ # modification.
187
+ #
188
+ # @example Declare watchers for a Guard
189
+ # guard :rspec do
190
+ # watch('spec/spec_helper.rb')
191
+ # watch(%r{^.+_spec.rb})
192
+ # watch(%r{^app/controllers/(.+).rb}) do |m|
193
+ # 'spec/acceptance/#{m[1]}s_spec.rb'
194
+ # end
195
+ # end
196
+ #
197
+ # @example Declare global watchers outside of a Guard
198
+ # watch(%r{^(.+)$}) { |m| puts "#{m[1]} changed." }
199
+ #
200
+ # @param [String, Regexp] pattern the pattern that Guard must watch for
201
+ # modification
202
+ #
203
+ # @yield a block to be run when the pattern is matched
204
+ # @yieldparam [MatchData] m matches of the pattern
205
+ # @yieldreturn a directory, a filename, an array of
206
+ # directories / filenames, or nothing (can be an arbitrary command)
207
+ #
208
+ # @see Guard::Watcher
209
+ # @see #guard
210
+ #
211
+ def watch(pattern, &action)
212
+ # Allow watches in the global scope (to execute arbitrary commands) by
213
+ # building a generic Guard::Plugin.
214
+ @plugin_options ||= nil
215
+ return guard(:plugin) { watch(pattern, &action) } unless @plugin_options
216
+
217
+ @plugin_options[:watchers] << ::Guard::Watcher.new(pattern, action)
218
+ end
219
+
220
+ # Defines a callback to execute arbitrary code before or after any of
221
+ # the `start`, `stop`, `reload`, `run_all`, `run_on_changes`,
222
+ # `run_on_additions`, `run_on_modifications` and `run_on_removals` plugin
223
+ # method.
224
+ #
225
+ # @example Define a callback that'll be called before the `reload` action.
226
+ # callback(:reload_begin) { puts "Let's reload!" }
227
+ #
228
+ # @example Define a callback that'll be called before the `start` and
229
+ # `stop` actions.
230
+ #
231
+ # my_lambda = lambda do |plugin, event, *args|
232
+ # puts "Let's #{event} #{plugin} with #{args}!"
233
+ # end
234
+ #
235
+ # callback(my_lambda, [:start_begin, :start_end])
236
+ #
237
+ # @param [Array] args the callback arguments
238
+ # @yield a callback block
239
+ #
240
+ # @see Guard::Hooker
241
+ #
242
+ def callback(*args, &block)
243
+ @plugin_options ||= nil
244
+ fail "callback must be called within a guard block" unless @plugin_options
245
+
246
+ block, events = if args.size > 1
247
+ # block must be the first argument in that case, the
248
+ # yielded block is ignored
249
+ args
250
+ else
251
+ [block, args[0]]
252
+ end
253
+ @plugin_options[:callbacks] << { events: events, listener: block }
254
+ end
255
+
256
+ # Ignores certain paths globally.
257
+ #
258
+ # @example Ignore some paths
259
+ # ignore %r{^ignored/path/}, /man/
260
+ #
261
+ # @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
262
+ #
263
+ def ignore(*regexps)
264
+ # TODO: instead, use Guard.reconfigure(ignore: regexps) or something
265
+ ::Guard.listener.ignore(regexps) if ::Guard.listener
266
+ end
267
+ alias filter ignore
268
+
269
+ # Replaces ignored paths globally
270
+ #
271
+ # @example Ignore only these paths
272
+ # ignore! %r{^ignored/path/}, /man/
273
+ #
274
+ # @param [Regexp] regexps a pattern (or list of patterns) for ignoring paths
275
+ #
276
+ def ignore!(*regexps)
277
+ @ignore_regexps ||= []
278
+ @ignore_regexps << regexps
279
+ ::Guard.listener.ignore!(@ignore_regexps) if ::Guard.listener
280
+ end
281
+ alias filter! ignore!
282
+
283
+ # Configures the Guard logger.
284
+ #
285
+ # * Log level must be either `:debug`, `:info`, `:warn` or `:error`.
286
+ # * Template supports the following placeholders: `:time`, `:severity`,
287
+ # `:progname`, `:pid`, `:unit_of_work_id` and `:message`.
288
+ # * Time format directives are the same as `Time#strftime` or
289
+ # `:milliseconds`.
290
+ # * The `:only` and `:except` options must be a `RegExp`.
291
+ #
292
+ # @example Set the log level
293
+ # logger level: :warn
294
+ #
295
+ # @example Set a custom log template
296
+ # logger template: '[Guard - :severity - :progname - :time] :message'
297
+ #
298
+ # @example Set a custom time format
299
+ # logger time_format: '%h'
300
+ #
301
+ # @example Limit logging to a Guard plugin
302
+ # logger only: :jasmine
303
+ #
304
+ # @example Log all but not the messages from a specific Guard plugin
305
+ # logger except: :jasmine
306
+ #
307
+ # @param [Hash] options the log options
308
+ # @option options [String, Symbol] level the log level
309
+ # @option options [String] template the logger template
310
+ # @option options [String, Symbol] time_format the time format
311
+ # @option options [Regexp] only show only messages from the matching Guard
312
+ # plugin
313
+ # @option options [Regexp] except does not show messages from the matching
314
+ # Guard plugin
315
+ #
316
+ def logger(options)
317
+ if options[:level]
318
+ options[:level] = options[:level].to_sym
319
+
320
+ unless [:debug, :info, :warn, :error].include? options[:level]
321
+ UI.warning WARN_INVALID_LOG_LEVEL % [options[:level]]
322
+ options.delete :level
323
+ end
324
+ end
325
+
326
+ if options[:only] && options[:except]
327
+ UI.warning WARN_INVALID_LOG_OPTIONS
328
+
329
+ options.delete :only
330
+ options.delete :except
331
+ end
332
+
333
+ # Convert the :only and :except options to a regular expression
334
+ [:only, :except].each do |name|
335
+ next unless options[name]
336
+
337
+ list = [].push(options[name]).flatten.map do |plugin|
338
+ Regexp.escape(plugin.to_s)
339
+ end
340
+
341
+ options[name] = Regexp.new(list.join("|"), Regexp::IGNORECASE)
342
+ end
343
+
344
+ ::Guard::UI.options.merge!(options)
345
+ end
346
+
347
+ # Sets the default scope on startup
348
+ #
349
+ # @example Scope Guard to a single group
350
+ # scope group: :frontend
351
+ #
352
+ # @example Scope Guard to multiple groups
353
+ # scope groups: [:specs, :docs]
354
+ #
355
+ # @example Scope Guard to a single plugin
356
+ # scope plugin: :test
357
+ #
358
+ # @example Scope Guard to multiple plugins
359
+ # scope plugins: [:jasmine, :rspec]
360
+ #
361
+ # @param [Hash] scopes the scope for the groups and plugins
362
+ #
363
+ def scope(scope = {})
364
+ ::Guard.setup_scope(scope)
365
+ end
366
+
367
+ # Sets the directories to pass to Listen (watchdirs)
368
+ #
369
+ # @example watch only given directories
370
+ # directories %w(lib specs)
371
+ #
372
+ # @param [Array] directories to watch
373
+ #
374
+ def directories(dirs)
375
+ ::Guard.watchdirs = dirs
376
+ end
377
+ end
378
+ end