guard 2.9.2 → 2.10.0

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