guard 2.8.2 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
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