guard 2.9.2 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2893a48637334eddc679ffc6afeed7867611c0e
4
- data.tar.gz: ddc0123c5b7bc8d0a63271ddb996c612b9f4d848
3
+ metadata.gz: 6996dd69034de1636618026e8606df7f10b2b22b
4
+ data.tar.gz: c374f6846a61be304447f9518ad72d219ba0b12f
5
5
  SHA512:
6
- metadata.gz: acf4ff94539a63b66805573b16560b49fc8050b9561efce3a3cd358f14bb6e85f64c35eadc33d98f1cf4de0597cad56da9a0dbf5a6079ef46b341087dcac2b71
7
- data.tar.gz: 1c6829ecc0fc789ea4fa6423cb96ed8251b223d0ed9d21421652683672ab72e37f47108c4354f100784b81a115e0b5e900a0b1e1ab57d84fc9462bb46e16e2a0
6
+ metadata.gz: 2d4cf024a8ce54ad66c2bd9ba03b46a457924da685ec6987e6ae0c4823e2ebc30fd15627b9dae5b01f7c844158cc420f1396d532c525e4b6d4175feb0167aef2
7
+ data.tar.gz: fc31605dee865f1371c2e6fca5d71c35ef7f4d1ca5255acf364972f9312785ebb897776e985632d966edc88b58b0d9e2d913b6987a9cc9576943041b0e74f304
data/README.md CHANGED
@@ -198,10 +198,11 @@ $ bundle exec guard --clear
198
198
  $ bundle exec guard -c # shortcut
199
199
  ```
200
200
 
201
- You can add the following snippet to your `~/.guardrc` to have the clear option always be enabled:
201
+ You may prefer to enable clearing in all projects by addin the `clearing`
202
+ statement (described below) in you `~/.guardrc` instead:
202
203
 
203
- ```
204
- Guard.options[:clear] = true
204
+ ```ruby
205
+ clearing :on
205
206
  ```
206
207
 
207
208
  #### `-n`/`--notify` option
@@ -262,6 +263,9 @@ directory - by selecting which ones to actually track.*
262
263
  If your watched directories are outside the current one, or if `--watchdirs` isn't working
263
264
  as you expect, be sure to read: [Correctly using watchdirs](https://github.com/guard/guard/wiki/Correctly-using-the---watchdir-option)
264
265
 
266
+ You may find it more convenient to use the `directories` statement (described
267
+ below) in your Guardfile
268
+
265
269
 
266
270
  #### `-G`/`--guardfile` option
267
271
 
@@ -641,6 +645,40 @@ plural and the singular option, the plural has precedence.
641
645
 
642
646
  **Please be sure to call the `scope` method after you've declared your Guard plugins!**
643
647
 
648
+ ### directories
649
+
650
+ This option limits the directories watch to those given, which can improve
651
+ responsiveness, performance and help reduce resource usage (CPU, memory) on
652
+ larger projects.
653
+
654
+ ```ruby
655
+ directories %w(app config lib spec features)
656
+ ```
657
+
658
+ Note: The `--watchdir` option overrides this. (see `--watchdir` above for extra
659
+ info).
660
+
661
+ Note: Since recursion cannot be diabled on OSX, all other backends were made
662
+ recursive - so if you want to watch selected directories AND files in the root
663
+ directory of your project, move them to another directory and create symlinks
664
+ back, e.g.
665
+
666
+ ```
667
+ mkdir config
668
+ mv Gemfile config
669
+ ln -s config/Gemfile Gemfile
670
+ ```
671
+
672
+ ### clearing
673
+
674
+ Guard can clear the screen before every action (which some people prefer).
675
+
676
+ The this clearing behavior can be set to `:on` or `:off`:
677
+
678
+ ```ruby
679
+ clearing :on
680
+ ```
681
+
644
682
  ### notification
645
683
 
646
684
  If you don't specify any notification configuration in your `Guardfile`, Guard goes through the list of available
data/lib/guard.rb CHANGED
@@ -57,8 +57,6 @@ module Guard
57
57
 
58
58
  @queue = Internals::Queue.new(Guard)
59
59
 
60
- UI.reset_and_clear
61
-
62
60
  _evaluate(state.session.evaluator_options)
63
61
 
64
62
  # NOTE: this should be *after* evaluate so :directories can work
@@ -146,6 +144,12 @@ module Guard
146
144
  def _evaluate(options)
147
145
  evaluator = Guardfile::Evaluator.new(options)
148
146
  evaluator.evaluate
147
+
148
+ # TODO: remove this workaround when options are removed
149
+ state.session.clearing(state.session.options[:clear])
150
+
151
+ UI.reset_and_clear
152
+
149
153
  msg = "No plugins found in Guardfile, please add at least one."
150
154
  UI.error msg if _pluginless_guardfile?
151
155
 
@@ -172,6 +172,18 @@ module Guard
172
172
  msg = "No plugins found in Guardfile, please add at least one."
173
173
  ::Guard::UI.error msg if _pluginless_guardfile?
174
174
  end
175
+
176
+ OPTIONS = <<-EOS.gsub(/^\s*/, "")
177
+ Starting with Guard 2.9.0 Guard.options is deprecated and ideally you
178
+ should be able to set specific options through an API or a DSL
179
+ method. Feel free to add feature requests if there's something
180
+ missing.
181
+ EOS
182
+
183
+ def options
184
+ UI.deprecation(OPTIONS)
185
+ ::Guard.state.session.options
186
+ end
175
187
  end
176
188
  end
177
189
  end
@@ -0,0 +1,178 @@
1
+ require "guard/config"
2
+ fail "Deprecations disabled (strict mode)" if Guard::Config.new.strict?
3
+
4
+ require "guard/ui"
5
+ require "guard/plugin_util"
6
+ require "guard/guardfile/evaluator"
7
+
8
+ module Guard
9
+ # @deprecated Every method in this module is deprecated
10
+ module Deprecated
11
+ module Guard
12
+ def self.add_deprecated(klass)
13
+ klass.send(:extend, ClassMethods)
14
+ end
15
+
16
+ module ClassMethods
17
+ MORE_INFO_ON_UPGRADING_TO_GUARD_2 = <<-EOS.gsub(/^\s*/, "")
18
+ For more information on how to upgrade for Guard 2.0, please head
19
+ over to: https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0%s
20
+ EOS
21
+
22
+ # @deprecated Use `Guard.plugins(filter)` instead.
23
+ #
24
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
25
+ # upgrade for Guard 2.0
26
+ #
27
+ GUARDS = <<-EOS.gsub(/^\s*/, "")
28
+ Starting with Guard 2.0 'Guard.guards(filter)' is deprecated.
29
+
30
+ Please use 'Guard.plugins(filter)' instead.
31
+
32
+ #{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
33
+ EOS
34
+
35
+ def guards(filter = nil)
36
+ ::Guard::UI.deprecation(GUARDS)
37
+ plugins(filter)
38
+ end
39
+
40
+ # @deprecated Use `Guard.add_plugin(name, options = {})` instead.
41
+ #
42
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
43
+ # upgrade for Guard 2.0
44
+ #
45
+ ADD_GUARD = <<-EOS.gsub(/^\s*/, "")
46
+ Starting with Guard 2.0 'Guard.add_guard(name, options = {})' is
47
+ deprecated.
48
+
49
+ Please use 'Guard.add_plugin(name, options = {})' instead.
50
+
51
+ #{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
52
+ EOS
53
+
54
+ def add_guard(*args)
55
+ ::Guard::UI.deprecation(ADD_GUARD)
56
+ add_plugin(*args)
57
+ end
58
+
59
+ # @deprecated Use
60
+ # `Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
61
+ # fail_gracefully)` instead.
62
+ #
63
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
64
+ # upgrade for Guard 2.0
65
+ #
66
+ GET_GUARD_CLASS = <<-EOS.gsub(/^\s*/, "")
67
+ Starting with Guard 2.0 'Guard.get_guard_class(name, fail_gracefully
68
+ = false)' is deprecated and is now always on.
69
+
70
+ Please use 'Guard::PluginUtil.new(name).plugin_class(fail_gracefully:
71
+ fail_gracefully)' instead.
72
+
73
+ #{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
74
+ EOS
75
+
76
+ def get_guard_class(name, fail_gracefully = false)
77
+ UI.deprecation(GET_GUARD_CLASS)
78
+ PluginUtil.new(name).plugin_class(fail_gracefully: fail_gracefully)
79
+ end
80
+
81
+ # @deprecated Use `Guard::PluginUtil.new(name).plugin_location` instead.
82
+ #
83
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
84
+ # upgrade for Guard 2.0
85
+ #
86
+ LOCATE_GUARD = <<-EOS.gsub(/^\s*/, "")
87
+ Starting with Guard 2.0 'Guard.locate_guard(name)' is deprecated.
88
+
89
+ Please use 'Guard::PluginUtil.new(name).plugin_location' instead.
90
+
91
+ #{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
92
+ EOS
93
+
94
+ def locate_guard(name)
95
+ UI.deprecation(LOCATE_GUARD)
96
+ PluginUtil.new(name).plugin_location
97
+ end
98
+
99
+ # @deprecated Use `Guard::PluginUtil.plugin_names` instead.
100
+ #
101
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
102
+ # upgrade for Guard 2.0
103
+ #
104
+ # Deprecator message for the `Guard.guard_gem_names` method
105
+ GUARD_GEM_NAMES = <<-EOS.gsub(/^\s*/, "")
106
+ Starting with Guard 2.0 'Guard.guard_gem_names' is deprecated.
107
+
108
+ Please use 'Guard::PluginUtil.plugin_names' instead.
109
+
110
+ #{MORE_INFO_ON_UPGRADING_TO_GUARD_2 % "#deprecated-methods"}
111
+ EOS
112
+
113
+ def guard_gem_names
114
+ UI.deprecation(GUARD_GEM_NAMES)
115
+ PluginUtil.plugin_names
116
+ end
117
+
118
+ RUNNING = <<-EOS.gsub(/^\s*/, "")
119
+ Starting with Guard 2.7.1 it was discovered that Guard.running was
120
+ never initialized or used internally.
121
+ EOS
122
+
123
+ def running
124
+ UI.deprecation(RUNNING)
125
+ nil
126
+ end
127
+
128
+ LOCK = <<-EOS.gsub(/^\s*/, "")
129
+ Starting with Guard 2.7.1 it was discovered that this accessor was
130
+ never initialized or used internally.
131
+ EOS
132
+ def lock
133
+ UI.deprecation(LOCK)
134
+ end
135
+
136
+ EVALUATOR = <<-EOS.gsub(/^\s*/, "")
137
+ Starting with Guard 2.8.2 this method shouldn't be used
138
+ EOS
139
+
140
+ def evaluator
141
+ UI.deprecation(EVALUATOR)
142
+ options = ::Guard.state.session.evaluator_options
143
+ ::Guard::Guardfile::Evaluator.new(options)
144
+ end
145
+
146
+ RESET_EVALUATOR = <<-EOS.gsub(/^\s*/, "")
147
+ Starting with Guard 2.8.2 this method shouldn't be used
148
+ EOS
149
+
150
+ def reset_evaluator(_options)
151
+ UI.deprecation(RESET_EVALUATOR)
152
+ end
153
+
154
+ RUNNER = <<-EOS.gsub(/^\s*/, "")
155
+ Starting with Guard 2.8.2 this method shouldn't be used
156
+ EOS
157
+
158
+ def runner
159
+ UI.deprecation(RUNNER)
160
+ ::Guard::Runner.new
161
+ end
162
+
163
+ EVALUATE_GUARDFILE = <<-EOS.gsub(/^\s*/, "")
164
+ Starting with Guard 2.8.2 this method shouldn't be used
165
+ EOS
166
+
167
+ def evaluate_guardfile
168
+ UI.deprecation(EVALUATE_GUARDFILE)
169
+ options = ::Guard.state.session.evaluator_options
170
+ evaluator = ::Guard::Guardfile::Evaluator.new(options)
171
+ evaluator.evaluate
172
+ msg = "No plugins found in Guardfile, please add at least one."
173
+ ::Guard::UI.error msg if _pluginless_guardfile?
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
data/lib/guard/dsl.rb CHANGED
@@ -379,6 +379,31 @@ module Guard
379
379
  raise Error, format(msg, e, backtrace)
380
380
  end
381
381
 
382
+ # Sets the directories to pass to Listen
383
+ #
384
+ # @example watch only given directories
385
+ # directories %w(lib specs)
386
+ #
387
+ # @param [Array] directories directories for Listen to watch
388
+ #
389
+ def directories(directories)
390
+ directories.each do |dir|
391
+ fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
392
+ end
393
+ Guard.state.session.watchdirs = directories
394
+ end
395
+
396
+ # Sets Guard to clear the screen before every task is run
397
+ #
398
+ # @example switching clearing the screen on
399
+ # clearing(:on)
400
+ #
401
+ # @param [Symbol] on ':on' to turn on, ':off' (default) to turn off
402
+ #
403
+ def clearing(on)
404
+ Guard.state.session.clearing(on == :on)
405
+ end
406
+
382
407
  private
383
408
 
384
409
  def _cleanup_backtrace(backtrace)
@@ -404,19 +429,5 @@ module Guard
404
429
  end
405
430
  end
406
431
  end
407
-
408
- # Sets the directories to pass to Listen
409
- #
410
- # @example watch only given directories
411
- # directories %w(lib specs)
412
- #
413
- # @param [Array] directories directories for Listen to watch
414
- #
415
- def directories(directories)
416
- directories.each do |dir|
417
- fail "Directory #{dir.inspect} does not exist!" unless Dir.exist?(dir)
418
- end
419
- Guard.state.session.watchdirs = directories
420
- end
421
432
  end
422
433
  end
@@ -81,11 +81,16 @@ module Guard
81
81
  attr_reader :guardfile_group_scope
82
82
  attr_reader :guardfile_plugin_scope
83
83
 
84
- # TODO: not tested
85
- def clear?
84
+ def clearing(on)
85
+ @clear = on
86
+ end
87
+
88
+ def clearing?
86
89
  @clear
87
90
  end
88
91
 
92
+ alias :clear? :clearing?
93
+
89
94
  def debug?
90
95
  @debug
91
96
  end
@@ -0,0 +1,135 @@
1
+ require "guard/internals/plugins"
2
+ require "guard/internals/groups"
3
+
4
+ require "guard/options"
5
+
6
+ module Guard
7
+ # @private api
8
+ module Internals
9
+ # TODO: split into a commandline class and session (plugins, groups)
10
+ # TODO: swap session and metadata
11
+ # This class contains variables set during
12
+ # evaluation of the guardfile (and are reset
13
+ # before reevaluation)
14
+ class Session
15
+ attr_reader :options
16
+ attr_reader :plugins
17
+ attr_reader :groups
18
+
19
+ DEFAULT_OPTIONS = {
20
+ clear: false,
21
+ debug: false,
22
+ no_bundler_warning: false,
23
+
24
+ # User defined scopes
25
+ group: [],
26
+ plugin: [],
27
+
28
+ # Notifier
29
+ notify: true,
30
+
31
+ # Interactor
32
+ no_interactions: false,
33
+
34
+ # Guardfile options:
35
+ # guardfile_contents
36
+ guardfile: nil,
37
+
38
+ # Listener options
39
+ # TODO: rename to watchdirs?
40
+ watchdir: Dir.pwd,
41
+ latency: nil,
42
+ force_polling: false,
43
+ wait_for_delay: nil,
44
+ listen_on: nil
45
+ }
46
+
47
+ def cmdline_groups
48
+ @cmdline_groups.dup.freeze
49
+ end
50
+
51
+ def cmdline_plugins
52
+ @cmdline_plugins.dup.freeze
53
+ end
54
+
55
+ def initialize(new_options)
56
+ @options = Options.new(new_options, DEFAULT_OPTIONS)
57
+
58
+ @plugins = Internals::Plugins.new
59
+ @groups = Internals::Groups.new
60
+
61
+ @cmdline_groups = @options[:group]
62
+ @cmdline_plugins = @options[:plugin]
63
+
64
+ @clear = @options[:clear]
65
+ @debug = @options[:debug]
66
+ @watchdirs = Array(@options[:watchdir])
67
+ @notify = @options[:notify]
68
+ @interactor_name = @options[:no_interactions] ? :sleep : :pry_wrapper
69
+
70
+ @guardfile_plugin_scope = []
71
+ @guardfile_group_scope = []
72
+ end
73
+
74
+ def guardfile_scope(scope)
75
+ opts = scope.dup
76
+ @guardfile_plugin_scope = Array(opts.delete(:plugins))
77
+ @guardfile_group_scope = Array(opts.delete(:groups))
78
+ fail "Unknown options: #{opts.inspect}" unless opts.empty?
79
+ end
80
+
81
+ attr_reader :guardfile_group_scope
82
+ attr_reader :guardfile_plugin_scope
83
+
84
+ # TODO: not tested
85
+ def clear?
86
+ @clear
87
+ end
88
+
89
+ def debug?
90
+ @debug
91
+ end
92
+
93
+ def watchdirs
94
+ @watchdirs_from_guardfile ||= nil
95
+ @watchdirs_from_guardfile || @watchdirs
96
+ end
97
+
98
+ # set by Dsl with :directories() command
99
+ def watchdirs=(dirs)
100
+ dirs = [Dir.pwd] if dirs.empty?
101
+ @watchdirs_from_guardfile = dirs.map { |dir| File.expand_path dir }
102
+ end
103
+
104
+ def listener_args
105
+ if options[:listen_on]
106
+ [:on, options[:listen_on]]
107
+ else
108
+ listener_options = {}
109
+ [:latency, :force_polling, :wait_for_delay].each do |option|
110
+ listener_options[option] = options[option] if options[option]
111
+ end
112
+ expanded_watchdirs = watchdirs.map { |dir| File.expand_path dir }
113
+ [:to, *expanded_watchdirs, listener_options]
114
+ end
115
+ end
116
+
117
+ def evaluator_options
118
+ opts = { guardfile: options[:guardfile] }
119
+ # TODO: deprecate :guardfile_contents
120
+ if options[:guardfile_contents]
121
+ opts[:contents] = options[:guardfile_contents]
122
+ end
123
+ opts
124
+ end
125
+
126
+ def notify_options
127
+ { notify: @options[:notify] }
128
+ end
129
+
130
+ def interactor_name
131
+ @interactor_name
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,6 +1,8 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- # Uncomment and set this to only include directories you want to watch
5
- #
4
+ ## Uncomment and set this to only include directories you want to watch
6
5
  # directories %(app lib config test spec feature)
6
+
7
+ ## Uncomment to clear the screen before every task
8
+ # clearing :on
@@ -0,0 +1,274 @@
1
+ require "lumberjack"
2
+
3
+ require "guard/internals/state"
4
+
5
+ require "guard/options"
6
+
7
+ require "guard/ui/colors"
8
+
9
+ require "guard/terminal"
10
+
11
+ module Guard
12
+ # The UI class helps to format messages for the user. Everything that is
13
+ # logged through this class is considered either as an error message or a
14
+ # diagnostic message and is written to standard error ($stderr).
15
+ #
16
+ # If your Guard plugin does some output that is piped into another process
17
+ # for further processing, please just write it to STDOUT with `puts`.
18
+ #
19
+ module UI
20
+ include Colors
21
+
22
+ class << self
23
+ # Get the Guard::UI logger instance
24
+ #
25
+ def logger
26
+ @logger ||= begin
27
+ Lumberjack::Logger.new(
28
+ options.fetch(:device) { $stderr },
29
+ options)
30
+ end
31
+ end
32
+
33
+ # Since logger is global, for Aruba in-process to properly
34
+ # separate output between calls, we need to reset
35
+ #
36
+ # We don't use logger=() since it's expected to be a Lumberjack instance
37
+ def reset_logger
38
+ @logger = nil
39
+ end
40
+
41
+ # Get the logger options
42
+ #
43
+ # @return [Hash] the logger options
44
+ #
45
+ def options
46
+ @options ||= ::Guard::Options.new(
47
+ level: :info,
48
+ template: ":time - :severity - :message",
49
+ time_format: "%H:%M:%S")
50
+ end
51
+
52
+ # Set the logger options
53
+ #
54
+ # @param [Hash] options the logger options
55
+ # @option options [Symbol] level the log level
56
+ # @option options [String] template the logger template
57
+ # @option options [String] time_format the time format
58
+ #
59
+ # TODO: deprecate?
60
+ def options=(options)
61
+ @options = ::Guard::Options.new(options)
62
+ end
63
+
64
+ # Assigns a log level
65
+ def level=(new_level)
66
+ logger.level = new_level
67
+ end
68
+
69
+ # Show an info message.
70
+ #
71
+ # @param [String] message the message to show
72
+ # @option options [Boolean] reset whether to clean the output before
73
+ # @option options [String] plugin manually define the calling plugin
74
+ #
75
+ def info(message, options = {})
76
+ _filtered_logger_message(message, :info, nil, options)
77
+ end
78
+
79
+ # Show a yellow warning message that is prefixed with WARNING.
80
+ #
81
+ # @param [String] message the message to show
82
+ # @option options [Boolean] reset whether to clean the output before
83
+ # @option options [String] plugin manually define the calling plugin
84
+ #
85
+ def warning(message, options = {})
86
+ _filtered_logger_message(message, :warn, :yellow, options)
87
+ end
88
+
89
+ # Show a red error message that is prefixed with ERROR.
90
+ #
91
+ # @param [String] message the message to show
92
+ # @option options [Boolean] reset whether to clean the output before
93
+ # @option options [String] plugin manually define the calling plugin
94
+ #
95
+ def error(message, options = {})
96
+ _filtered_logger_message(message, :error, :red, options)
97
+ end
98
+
99
+ # Show a red deprecation message that is prefixed with DEPRECATION.
100
+ # It has a log level of `warn`.
101
+ #
102
+ # @param [String] message the message to show
103
+ # @option options [Boolean] reset whether to clean the output before
104
+ # @option options [String] plugin manually define the calling plugin
105
+ #
106
+ def deprecation(message, options = {})
107
+ unless ENV["GUARD_GEM_SILENCE_DEPRECATIONS"] == "1"
108
+ backtrace = Thread.current.backtrace[1..5].join("\n\t >")
109
+ msg = format("%s\nDeprecation backtrace: %s", message, backtrace)
110
+ warning(msg, options)
111
+ end
112
+ end
113
+
114
+ # Show a debug message that is prefixed with DEBUG and a timestamp.
115
+ #
116
+ # @param [String] message the message to show
117
+ # @option options [Boolean] reset whether to clean the output before
118
+ # @option options [String] plugin manually define the calling plugin
119
+ #
120
+ def debug(message, options = {})
121
+ _filtered_logger_message(message, :debug, :yellow, options)
122
+ end
123
+
124
+ # Reset a line.
125
+ #
126
+ def reset_line
127
+ $stderr.print(color_enabled? ? "\r\e[0m" : "\r\n")
128
+ end
129
+
130
+ # Clear the output if clearable.
131
+ #
132
+ def clear(opts = {})
133
+ return unless Guard.state.session.clear?
134
+
135
+ fail "UI not set up!" if @clearable.nil?
136
+ return unless @clearable || opts[:force]
137
+
138
+ @clearable = false
139
+ Terminal.clear
140
+ rescue Errno::ENOENT => e
141
+ warning("Failed to clear the screen: #{e.inspect}")
142
+ end
143
+
144
+ # TODO: arguments: UI uses Guard::options anyway
145
+ # @private api
146
+ def reset_and_clear
147
+ @clearable = false
148
+ clear(force: true)
149
+ end
150
+
151
+ # Allow the screen to be cleared again.
152
+ #
153
+ def clearable
154
+ @clearable = true
155
+ end
156
+
157
+ # Show a scoped action message.
158
+ #
159
+ # @param [String] action the action to show
160
+ # @param [Hash] scope hash with a guard or a group scope
161
+ #
162
+ def action_with_scopes(action, scope)
163
+ titles = Guard.state.scope.titles(scope)
164
+ info "#{action} #{titles.join(", ")}"
165
+ end
166
+
167
+ private
168
+
169
+ # Filters log messages depending on either the
170
+ # `:only`` or `:except` option.
171
+ #
172
+ # @param [String] plugin the calling plugin name
173
+ # @yield When the message should be logged
174
+ # @yieldparam [String] param the calling plugin name
175
+ #
176
+ def _filter(plugin)
177
+ only = options[:only]
178
+ except = options[:except]
179
+ plugin ||= calling_plugin_name
180
+
181
+ match = !(only || except)
182
+ match ||= (only && only.match(plugin))
183
+ match ||= (except && !except.match(plugin))
184
+ return unless match
185
+ yield plugin
186
+ end
187
+
188
+ # Display a message of the type `method` and with the color `color_name`
189
+ # (no color by default) conditionnaly given a `plugin_name`.
190
+ #
191
+ # @param [String] plugin_name the calling plugin name
192
+ # @option options [Boolean] reset whether to clean the output before
193
+ # @option options [String] plugin manually define the calling plugin
194
+ #
195
+ def _filtered_logger_message(message, method, color_name, options = {})
196
+ message = color(message, color_name) if color_name
197
+
198
+ _filter(options[:plugin]) do |plugin|
199
+ reset_line if options[:reset]
200
+ logger.send(method, message, plugin)
201
+ end
202
+ end
203
+
204
+ # Tries to extract the calling Guard plugin name
205
+ # from the call stack.
206
+ #
207
+ # @param [Integer] depth the stack depth
208
+ # @return [String] the Guard plugin name
209
+ #
210
+ def calling_plugin_name(depth = 2)
211
+ name = /(guard\/[a-z_]*)(\/[a-z_]*)?.rb:/i.match(caller[depth])
212
+ return "Guard" unless name
213
+ name[1].split("/").map do |part|
214
+ part.split(/[^a-z0-9]/i).map(&:capitalize).join
215
+ end.join("::")
216
+ end
217
+
218
+ # Checks if color output can be enabled.
219
+ #
220
+ # @return [Boolean] whether color is enabled or not
221
+ #
222
+ def color_enabled?
223
+ @color_enabled_initialized ||= false
224
+ @color_enabled = nil unless @color_enabled_initialized
225
+ @color_enabled_initialized = true
226
+ if @color_enabled.nil?
227
+ if Gem.win_platform?
228
+ if ENV["ANSICON"]
229
+ @color_enabled = true
230
+ else
231
+ begin
232
+ require "rubygems" unless ENV["NO_RUBYGEMS"]
233
+ require "Win32/Console/ANSI"
234
+ @color_enabled = true
235
+ rescue LoadError
236
+ @color_enabled = false
237
+ info "Run 'gem install win32console' to use color on Windows"
238
+ end
239
+ end
240
+ else
241
+ @color_enabled = true
242
+ end
243
+ end
244
+
245
+ @color_enabled
246
+ end
247
+
248
+ # Colorizes a text message. See the constant in the UI class for possible
249
+ # color_options parameters. You can pass optionally :bright, a foreground
250
+ # color and a background color.
251
+ #
252
+ # @example
253
+ #
254
+ # color('Hello World', :red, :bright)
255
+ #
256
+ # @param [String] text the text to colorize
257
+ # @param [Array] color_options the color options
258
+ #
259
+ def color(text, *color_options)
260
+ color_code = ""
261
+ color_options.each do |color_option|
262
+ color_option = color_option.to_s
263
+ next if color_option == ""
264
+
265
+ unless color_option =~ /\d+/
266
+ color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
267
+ end
268
+ color_code += ";" + color_option
269
+ end
270
+ color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
271
+ end
272
+ end
273
+ end
274
+ end
data/lib/guard/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Guard
2
- VERSION = "2.9.2"
2
+ VERSION = "2.10.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.2
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibaud Guillaume-Gentil
@@ -113,6 +113,7 @@ files:
113
113
  - lib/guard/deprecated/dsl.rb
114
114
  - lib/guard/deprecated/evaluator.rb
115
115
  - lib/guard/deprecated/guard.rb
116
+ - lib/guard/deprecated/guard.rb.orig
116
117
  - lib/guard/deprecated/guardfile.rb
117
118
  - lib/guard/deprecated/watcher.rb
118
119
  - lib/guard/dsl.rb
@@ -132,6 +133,7 @@ files:
132
133
  - lib/guard/internals/queue.rb
133
134
  - lib/guard/internals/scope.rb
134
135
  - lib/guard/internals/session.rb
136
+ - lib/guard/internals/session.rb.orig
135
137
  - lib/guard/internals/state.rb
136
138
  - lib/guard/internals/tracing.rb
137
139
  - lib/guard/internals/traps.rb
@@ -166,6 +168,7 @@ files:
166
168
  - lib/guard/templates/Guardfile.orig
167
169
  - lib/guard/terminal.rb
168
170
  - lib/guard/ui.rb
171
+ - lib/guard/ui.rb.orig
169
172
  - lib/guard/ui/colors.rb
170
173
  - lib/guard/version.rb
171
174
  - lib/guard/version.rb.orig