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
@@ -1,395 +0,0 @@
1
- require "thread"
2
- require "listen"
3
- require "guard/options"
4
-
5
- module Guard
6
- # Sets up initial variables and options
7
- module Setuper
8
- DEFAULT_OPTIONS = {
9
- clear: false,
10
- notify: true,
11
- debug: false,
12
- group: [],
13
- plugin: [],
14
- watchdir: nil,
15
- guardfile: nil,
16
- no_interactions: false,
17
- no_bundler_warning: false,
18
- show_deprecations: false,
19
- latency: nil,
20
- force_polling: false,
21
- wait_for_delay: nil,
22
- listen_on: nil
23
- }
24
- DEFAULT_GROUPS = [:common, :default]
25
-
26
- # Initializes the Guard singleton:
27
- #
28
- # * Initialize the internal Guard state;
29
- # * Create the interactor
30
- # * Select and initialize the file change listener.
31
- #
32
- # @option options [Boolean] clear if auto clear the UI should be done
33
- # @option options [Boolean] notify if system notifications should be shown
34
- # @option options [Boolean] debug if debug output should be shown
35
- # @option options [Array<String>] group the list of groups to start
36
- # @option options [Array<String>] watchdir the directories to watch
37
- # @option options [String] guardfile the path to the Guardfile
38
- # @option options [Boolean] watch_all_modifications **[deprecated]** watches all file modifications if true
39
- # @option options [Boolean] no_vendor **[deprecated]** ignore vendored dependencies
40
- #
41
- # @return [Guard] the Guard singleton
42
- #
43
-
44
- # TODO: this method has too many instance variables
45
- # and some are mock and leak between tests,
46
- # so ideally there should be a guard "instance"
47
- # object that can be created anew between tests
48
- def setup(opts = {})
49
- reset_options(opts)
50
- reset_evaluator(opts)
51
-
52
- @queue = Queue.new
53
- @runner = ::Guard::Runner.new
54
- @watchdirs = _setup_watchdirs
55
-
56
- ::Guard::UI.setup(options)
57
-
58
- <<<<<<< HEAD
59
- _setup_debug if options[:debug]
60
- @listener = _setup_listener
61
- _setup_signal_traps
62
- =======
63
- ::Guard::Deprecator.deprecated_options_warning(options)
64
- ::Guard::Deprecator.deprecated_plugin_methods_warning
65
-
66
- _setup_notifier
67
- _setup_interactor
68
- >>>>>>> parent of a5162d2... Remove deprecated methods and options. Fixes #425.
69
-
70
- _load_guardfile
71
- @interactor = _setup_interactor
72
- self
73
- end
74
-
75
- attr_reader :options, :interactor
76
-
77
- # Used only by tests (for all I know...)
78
- def clear_options
79
- @options = nil
80
- end
81
-
82
- # Initializes the groups array with the default group(s).
83
- #
84
- # @see DEFAULT_GROUPS
85
- #
86
- def reset_groups
87
- @groups = DEFAULT_GROUPS.map { |name| Group.new(name) }
88
- end
89
-
90
- # Initializes the plugins array to an empty array.
91
- #
92
- # @see Guard.plugins
93
- #
94
- def reset_plugins
95
- @plugins = []
96
- end
97
-
98
- # Initializes the scope hash to `{ groups: [], plugins: [] }`.
99
- #
100
- # @see Guard.setup_scope
101
- #
102
- def reset_scope
103
- # calls Guard.scope=() to set the instance variable directly, as opposed
104
- # to Guard.scope()
105
- ::Guard.scope = { groups: [], plugins: [] }
106
- end
107
-
108
- # Used to merge CLI options with Setuper defaults
109
- def reset_options(new_options)
110
- @options = ::Guard::Options.new(new_options, DEFAULT_OPTIONS)
111
- end
112
-
113
- # TODO: code smell - too many reset_* methods
114
- def reset_evaluator(new_options)
115
- @evaluator = ::Guard::Guardfile::Evaluator.new(new_options)
116
- end
117
-
118
- def save_scope
119
- # This actually replaces scope from command line,
120
- # so scope set by 'scope' Pry command will be reset
121
- @saved_scope = _prepare_scope(::Guard.scope)
122
- end
123
-
124
- def restore_scope
125
- ::Guard.setup_scope(@saved_scope)
126
- end
127
-
128
- attr_reader :watchdirs
129
-
130
- # Stores the scopes defined by the user via the `--group` / `-g` option (to
131
- # run only a specific group) or the `--plugin` / `-P` option (to run only a
132
- # specific plugin).
133
- #
134
- # @see CLI#start
135
- # @see Dsl#scope
136
- #
137
- def setup_scope(scope = {})
138
- # TODO: there should be a special Scope class instead
139
- scope = _prepare_scope(scope)
140
-
141
- ::Guard.scope = {
142
- groups: scope[:groups].map { |item| ::Guard.add_group(item) },
143
- plugins: scope[:plugins].map { |item| ::Guard.plugin(item) },
144
- }
145
- end
146
-
147
- # Evaluates the Guardfile content. It displays an error message if no
148
- # Guard plugins are instantiated after the Guardfile evaluation.
149
- #
150
- # @see Guard::Guardfile::Evaluator#evaluate_guardfile
151
- #
152
- def evaluate_guardfile
153
- evaluator.evaluate_guardfile
154
- msg = "No plugins found in Guardfile, please add at least one."
155
- ::Guard::UI.error msg unless _pluginless_guardfile?
156
- end
157
-
158
- # Asynchronously trigger changes
159
- #
160
- # Currently supported args:
161
- #
162
- # old style hash: {modified: ['foo'], added: ['bar'], removed: []}
163
- #
164
- # new style signals with args: [:guard_pause, :unpaused ]
165
- #
166
- def async_queue_add(changes)
167
- @queue << changes
168
-
169
- # Putting interactor in background puts guard into foreground
170
- # so it can handle change notifications
171
- Thread.new { interactor.background }
172
- end
173
-
174
- def pending_changes?
175
- ! @queue.empty?
176
- end
177
-
178
- def add_builtin_plugins(guardfile)
179
- return unless guardfile
180
-
181
- pattern = _relative_pathname(guardfile).to_s
182
- watcher = ::Guard::Watcher.new(pattern)
183
- ::Guard.add_plugin(:reevaluator, watchers: [watcher], group: :common)
184
- end
185
-
186
- private
187
-
188
- # Sets up various debug behaviors:
189
- #
190
- # * Abort threads on exception;
191
- # * Set the logging level to `:debug`;
192
- # * Modify the system and ` methods to log themselves before being executed
193
- #
194
- # @see #_debug_command_execution
195
- #
196
- def _setup_debug
197
- Thread.abort_on_exception = true
198
- ::Guard::UI.options[:level] = :debug
199
- _debug_command_execution
200
- end
201
-
202
- # Initializes the listener and registers a callback for changes.
203
- #
204
- def _setup_listener
205
- if options[:listen_on]
206
- Listen.on(options[:listen_on], &_listener_callback)
207
- else
208
- listener_options = {}
209
- [:latency, :force_polling, :wait_for_delay].each do |option|
210
- listener_options[option] = options[option] if options[option]
211
- end
212
- listen_args = watchdirs + [listener_options]
213
- Listen.to(*listen_args, &_listener_callback)
214
- end
215
- end
216
-
217
- # Process the change queue, running tasks within the main Guard thread
218
- def _process_queue
219
- actions, changes = [], { modified: [], added: [], removed: [] }
220
-
221
- while pending_changes?
222
- if (item = @queue.pop).first.is_a?(Symbol)
223
- actions << item
224
- else
225
- item.each { |key, value| changes[key] += value }
226
- end
227
- end
228
-
229
- _run_actions(actions)
230
- return if changes.values.all?(&:empty?)
231
- runner.run_on_changes(*changes.values)
232
- end
233
-
234
- # Sets up traps to catch signals used to control Guard.
235
- #
236
- # Currently two signals are caught:
237
- # - `USR1` which pauses listening to changes.
238
- # - `USR2` which resumes listening to changes.
239
- # - 'INT' which is delegated to Pry if active, otherwise stops Guard.
240
- #
241
- def _setup_signal_traps
242
- return if defined?(JRUBY_VERSION)
243
-
244
- if Signal.list.keys.include?("USR1")
245
- Signal.trap("USR1") { async_queue_add([:guard_pause, :paused]) }
246
- end
247
-
248
- if Signal.list.keys.include?("USR2")
249
- Signal.trap("USR2") { async_queue_add([:guard_pause, :unpaused]) }
250
- end
251
-
252
- return unless Signal.list.keys.include?("INT")
253
- Signal.trap("INT") { interactor.handle_interrupt }
254
- end
255
-
256
- # Enables or disables the notifier based on user's configurations.
257
- #
258
- def _setup_notifier
259
- if options[:notify] && ENV["GUARD_NOTIFY"] != "false"
260
- ::Guard::Notifier.turn_on
261
- else
262
- ::Guard::Notifier.turn_off
263
- end
264
- end
265
-
266
- # Adds a command logger in debug mode. This wraps common command
267
- # execution functions and logs the executed command before execution.
268
- #
269
- def _debug_command_execution
270
- Kernel.send(:alias_method, :original_system, :system)
271
- Kernel.send(:define_method, :system) do |command, *args|
272
- ::Guard::UI.debug "Command execution: #{ command } #{ args.join(" ") }"
273
- Kernel.send :original_system, command, *args
274
- end
275
-
276
- Kernel.send(:alias_method, :original_backtick, :'`')
277
- Kernel.send(:define_method, :'`') do |command|
278
- ::Guard::UI.debug "Command execution: #{ command }"
279
- Kernel.send :original_backtick, command
280
- end
281
- end
282
-
283
- # TODO: Guard::Watch or Guard::Scope should provide this
284
- def _scoped_watchers
285
- watchers = []
286
- runner.send(:_scoped_plugins) { |guard| watchers += guard.watchers }
287
- watchers
288
- end
289
-
290
- # Check if any of the changes are actually watched for
291
- def _relevant_changes?(changes)
292
- files = changes.values.flatten(1)
293
- watchers = _scoped_watchers
294
- watchers.any? { |watcher| files.any? { |file| watcher.match(file) } }
295
- end
296
-
297
- def _relative_pathname(path)
298
- full_path = Pathname(path)
299
- full_path.relative_path_from(Pathname.pwd)
300
- rescue ArgumentError
301
- full_path
302
- end
303
-
304
- def _relative_pathnames(paths)
305
- paths.map { |path| _relative_pathname(path) }
306
- end
307
-
308
- def _run_actions(actions)
309
- actions.each do |action_args|
310
- args = action_args.dup
311
- namespaced_action = args.shift
312
- action = namespaced_action.to_s.sub(/^guard_/, "")
313
- if ::Guard.respond_to?(action)
314
- ::Guard.send(action, *args)
315
- else
316
- fail "Unknown action: #{action.inspect}"
317
- end
318
- end
319
- end
320
-
321
- def _setup_watchdirs
322
- dirs = Array(options[:watchdir])
323
- dirs.empty? ? [Dir.pwd] : dirs.map { |dir| File.expand_path dir }
324
- end
325
-
326
- def _listener_callback
327
- lambda do |modified, added, removed|
328
- relative_paths = {
329
- modified: _relative_pathnames(modified),
330
- added: _relative_pathnames(added),
331
- removed: _relative_pathnames(removed)
332
- }
333
-
334
- async_queue_add(relative_paths) if _relevant_changes?(relative_paths)
335
- end
336
- end
337
-
338
- def _reset_all
339
- reset_groups
340
- reset_plugins
341
- reset_scope
342
- end
343
-
344
- def _setup_interactor
345
- ::Guard::Interactor.new(options[:no_interactions])
346
- end
347
-
348
- def _load_guardfile
349
- _reset_all
350
- evaluate_guardfile
351
- setup_scope
352
- _setup_notifier
353
- end
354
-
355
- def _prepare_scope(scope)
356
- fail "Guard::setup() not called!" if options.nil?
357
- plugins = Array(options[:plugin])
358
- plugins = Array(scope[:plugins] || scope[:plugin]) if plugins.empty?
359
-
360
- # Convert objects to names
361
- plugins.map! { |p| p.respond_to?(:name) ? p.name : p }
362
-
363
- groups = Array(options[:group])
364
- groups = Array(scope[:groups] || scope[:group]) if groups.empty?
365
-
366
- # Convert objects to names
367
- groups.map! { |g| g.respond_to?(:name) ? g.name : g }
368
-
369
- { plugins: plugins, groups: groups }
370
- end
371
-
372
- def _pluginless_guardfile?
373
- # no Reevaluator means there was no Guardfile configured that could be
374
- # reevaluated, so we don't have a pluginless guardfile, because we don't
375
- # have a Guardfile to begin with...
376
- #
377
- # But, if we have a Guardfile, we'll at least have the built-in
378
- # Reevaluator, so the following will work:
379
-
380
- plugins.map(&:name) != ["reevaluator"]
381
- end
382
-
383
- def _reset_for_tests
384
- @options = nil
385
- @queue = nil
386
- @runner = nil
387
- @evaluator = nil
388
- @watchdirs = nil
389
- @watchdirs = nil
390
- @listener = nil
391
- @interactor = nil
392
- @scope = nil
393
- end
394
- end
395
- end
data/lib/guard/ui.rb.orig DELETED
@@ -1,278 +0,0 @@
1
- require "lumberjack"
2
-
3
- require "guard/options"
4
- require "guard/ui/colors"
5
-
6
- require "guard/terminal"
7
-
8
- module Guard
9
- # The UI class helps to format messages for the user. Everything that is
10
- # logged through this class is considered either as an error message or a
11
- # diagnostic message and is written to standard error ($stderr).
12
- #
13
- # If your Guard plugin does some output that is piped into another process
14
- # for further processing, please just write it to STDOUT with `puts`.
15
- #
16
- module UI
17
- include Colors
18
-
19
- class << self
20
- # Get the Guard::UI logger instance
21
- #
22
- def logger
23
- @logger ||= begin
24
- Lumberjack::Logger.new(
25
- options.fetch(:device) { $stderr },
26
- options)
27
- end
28
- end
29
-
30
- # Since logger is global, for Aruba in-process to properly
31
- # separate output between calls, we need to reset
32
- #
33
- # We don't use logger=() since it's expected to be a Lumberjack instance
34
- def reset_logger
35
- @logger = nil
36
- end
37
-
38
- # Get the logger options
39
- #
40
- # @return [Hash] the logger options
41
- #
42
- def options
43
- @options ||= ::Guard::Options.new(
44
- level: :info,
45
- template: ":time - :severity - :message",
46
- time_format: "%H:%M:%S")
47
- end
48
-
49
- # Set the logger options
50
- #
51
- # @param [Hash] options the logger options
52
- # @option options [Symbol] level the log level
53
- # @option options [String] template the logger template
54
- # @option options [String] time_format the time format
55
- #
56
- def options=(options)
57
- @options = ::Guard::Options.new(options)
58
- end
59
-
60
- # Show an info message.
61
- #
62
- # @param [String] message the message to show
63
- # @option options [Boolean] reset whether to clean the output before
64
- # @option options [String] plugin manually define the calling plugin
65
- #
66
- def info(message, options = {})
67
- _filtered_logger_message(message, :info, nil, options)
68
- end
69
-
70
- # Show a yellow warning message that is prefixed with WARNING.
71
- #
72
- # @param [String] message the message to show
73
- # @option options [Boolean] reset whether to clean the output before
74
- # @option options [String] plugin manually define the calling plugin
75
- #
76
- def warning(message, options = {})
77
- _filtered_logger_message(message, :warn, :yellow, options)
78
- end
79
-
80
- # Show a red error message that is prefixed with ERROR.
81
- #
82
- # @param [String] message the message to show
83
- # @option options [Boolean] reset whether to clean the output before
84
- # @option options [String] plugin manually define the calling plugin
85
- #
86
- def error(message, options = {})
87
- _filtered_logger_message(message, :error, :red, options)
88
- end
89
-
90
- # Show a red deprecation message that is prefixed with DEPRECATION.
91
- # It has a log level of `warn`.
92
- #
93
- # @param [String] message the message to show
94
- # @option options [Boolean] reset whether to clean the output before
95
- # @option options [String] plugin manually define the calling plugin
96
- #
97
- def deprecation(message, options = {})
98
- msg = "neither ::Guard.setup nor ::Guard.reset_options was called"
99
- fail msg if ::Guard.options.nil?
100
- warning(message, options) if ::Guard.options[:show_deprecations]
101
- end
102
-
103
- # Show a debug message that is prefixed with DEBUG and a timestamp.
104
- #
105
- # @param [String] message the message to show
106
- # @option options [Boolean] reset whether to clean the output before
107
- # @option options [String] plugin manually define the calling plugin
108
- #
109
- def debug(message, options = {})
110
- _filtered_logger_message(message, :debug, :yellow, options)
111
- end
112
-
113
- # Reset a line.
114
- #
115
- def reset_line
116
- $stderr.print(color_enabled? ? "\r\e[0m" : "\r\n")
117
- end
118
-
119
- # Clear the output if clearable.
120
- #
121
- def clear(opts = {})
122
- return unless ::Guard.options[:clear]
123
-
124
- fail "UI not set up!" if @clearable.nil?
125
- return unless @clearable || opts[:force]
126
-
127
- @clearable = false
128
- ::Guard::Terminal.clear
129
- rescue Errno::ENOENT => e
130
- warning("Failed to clear the screen: #{e.inspect}")
131
- end
132
-
133
- # TODO: arguments: UI uses Guard::options anyway
134
- def setup(_options)
135
- @clearable = false
136
- clear(force: true)
137
- end
138
-
139
- # Allow the screen to be cleared again.
140
- #
141
- def clearable
142
- @clearable = true
143
- end
144
-
145
- # Show a scoped action message.
146
- #
147
- # @param [String] action the action to show
148
- # @param [Hash] scope hash with a guard or a group scope
149
- #
150
- def action_with_scopes(action, scope)
151
- first_non_blank_scope = _first_non_blank_scope(scope)
152
- unless first_non_blank_scope.nil?
153
- scope_message = first_non_blank_scope.map(&:title).join(", ")
154
- end
155
-
156
- info "#{ action } #{ scope_message || "all" }"
157
- end
158
-
159
- private
160
-
161
- # Returns the first non-blank scope by searching in the given `scope`
162
- # hash and in Guard.scope. Returns nil if no non-blank scope is found.
163
- #
164
- def _first_non_blank_scope(scope)
165
- [:plugins, :groups].each do |scope_name|
166
- s = scope[scope_name] || ::Guard.scope[scope_name]
167
- return s if !s.nil? && !s.empty?
168
- end
169
-
170
- nil
171
- end
172
-
173
- # Filters log messages depending on either the
174
- # `:only`` or `:except` option.
175
- #
176
- # @param [String] plugin the calling plugin name
177
- # @yield When the message should be logged
178
- # @yieldparam [String] param the calling plugin name
179
- #
180
- def _filter(plugin)
181
- only = options[:only]
182
- except = options[:except]
183
- plugin ||= calling_plugin_name
184
-
185
- match = !(only || except)
186
- match ||= (only && only.match(plugin))
187
- match ||= (except && !except.match(plugin))
188
- return unless match
189
- yield plugin
190
- end
191
-
192
- # Display a message of the type `method` and with the color `color_name`
193
- # (no color by default) conditionnaly given a `plugin_name`.
194
- #
195
- # @param [String] plugin_name the calling plugin name
196
- # @option options [Boolean] reset whether to clean the output before
197
- # @option options [String] plugin manually define the calling plugin
198
- #
199
- def _filtered_logger_message(message, method, color_name, options = {})
200
- message = color(message, color_name) if color_name
201
-
202
- _filter(options[:plugin]) do |plugin|
203
- reset_line if options[:reset]
204
- logger.send(method, message, plugin)
205
- end
206
- end
207
-
208
- # Tries to extract the calling Guard plugin name
209
- # from the call stack.
210
- #
211
- # @param [Integer] depth the stack depth
212
- # @return [String] the Guard plugin name
213
- #
214
- def calling_plugin_name(depth = 2)
215
- name = /(guard\/[a-z_]*)(\/[a-z_]*)?.rb:/i.match(caller[depth])
216
- return "Guard" unless name
217
- name[1].split("/").map do |part|
218
- part.split(/[^a-z0-9]/i).map(&:capitalize).join
219
- end.join("::")
220
- end
221
-
222
- # Checks if color output can be enabled.
223
- #
224
- # @return [Boolean] whether color is enabled or not
225
- #
226
- def color_enabled?
227
- @color_enabled_initialized ||= false
228
- @color_enabled = nil unless @color_enabled_initialized
229
- @color_enabled_initialized = true
230
- if @color_enabled.nil?
231
- if Gem.win_platform?
232
- if ENV["ANSICON"]
233
- @color_enabled = true
234
- else
235
- begin
236
- require "rubygems" unless ENV["NO_RUBYGEMS"]
237
- require "Win32/Console/ANSI"
238
- @color_enabled = true
239
- rescue LoadError
240
- @color_enabled = false
241
- info "Run 'gem install win32console' to use color on Windows"
242
- end
243
- end
244
- else
245
- @color_enabled = true
246
- end
247
- end
248
-
249
- @color_enabled
250
- end
251
-
252
- # Colorizes a text message. See the constant in the UI class for possible
253
- # color_options parameters. You can pass optionally :bright, a foreground
254
- # color and a background color.
255
- #
256
- # @example
257
- #
258
- # color('Hello World', :red, :bright)
259
- #
260
- # @param [String] text the text to colorize
261
- # @param [Array] color_options the color options
262
- #
263
- def color(text, *color_options)
264
- color_code = ""
265
- color_options.each do |color_option|
266
- color_option = color_option.to_s
267
- next if color_option == ""
268
-
269
- unless color_option =~ /\d+/
270
- color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
271
- end
272
- color_code += ";" + color_option
273
- end
274
- color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
275
- end
276
- end
277
- end
278
- end