guard 2.10.1 → 2.10.2

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: 100b160735c5c331821d9fa8119bb168ed5f907e
4
- data.tar.gz: d677f7e1a7491ff72654d415d7c571f028fbef52
3
+ metadata.gz: 3106af4e3722da1f4bd41e051e5baf1ff8ace4f7
4
+ data.tar.gz: 0ef587f058e7f02bc5b4195a0b3b3b4d25847ddd
5
5
  SHA512:
6
- metadata.gz: 0dcad099ca8bd1dca2486e078233215366c4236b8a1b0b465336d020667e041bd16e75df106efeef75a6013fcdb9601fdd35bd28eac8130c4eb3a910694004a3
7
- data.tar.gz: 835a20ae288b6c660d9cb058eeba5b2c25f999bc3790c0dfb0ccf48a7816eff2405fe82e26cc9884b2397f02a610ba73f848c63bf89eb478fd94aae632ff31f7
6
+ metadata.gz: b5f3825c29f9c01f14b50051055e105a3695288da0ce2ba2d42fdd4e4af92881afb455515da551a1faaf192b28ba8eb2e599f0640002ff9c1d2d8db0796c734a
7
+ data.tar.gz: c107a499ff6e9814b536a9c1f723c5a7badc97e33f74ae8409f5b72d082fff63c09d3eac630cd9b6b12c9591ed1210b907ea05680f2b615d62bcde31b2eb5784
File without changes
@@ -168,6 +168,7 @@ module Guard
168
168
  end
169
169
 
170
170
  def self._gem_valid?(gem)
171
+ return false if gem.name == "guard-compat"
171
172
  return true if gem.name =~ /^guard-/
172
173
  full_path = gem.full_gem_path
173
174
  file = File.join(full_path, "lib", "guard", "#{gem.name}.rb")
@@ -0,0 +1,182 @@
1
+ require "guard/ui"
2
+
3
+ module Guard
4
+ # This class contains useful methods to:
5
+ #
6
+ # * Fetch all the Guard plugins names;
7
+ # * Initialize a plugin, get its location;
8
+ # * Return its class name;
9
+ # * Add its template to the Guardfile.
10
+ #
11
+ class PluginUtil
12
+ ERROR_NO_GUARD_OR_CLASS = "Could not load 'guard/%s' or'\
13
+ ' find class Guard::%s"
14
+
15
+ INFO_ADDED_GUARD_TO_GUARDFILE = "%s guard added to Guardfile,"\
16
+ " feel free to edit it"
17
+
18
+ attr_accessor :name
19
+
20
+ # Returns a list of Guard plugin Gem names installed locally.
21
+ #
22
+ # @return [Array<String>] a list of Guard plugin gem names
23
+ #
24
+ def self.plugin_names
25
+ valid = Gem::Specification.find_all.select do |gem|
26
+ _gem_valid?(gem)
27
+ end
28
+
29
+ valid.map { |x| x.name.sub(/^guard-/, "") }.uniq
30
+ end
31
+
32
+ # Initializes a new `Guard::PluginUtil` object.
33
+ #
34
+ # @param [String] name the name of the Guard plugin
35
+ #
36
+ def initialize(name)
37
+ @name = name.to_s.sub(/^guard-/, "")
38
+ end
39
+
40
+ # Initializes a new `Guard::Plugin` with the given `options` hash. This
41
+ # methods handles plugins that inherit from the deprecated `Guard::Guard`
42
+ # class as well as plugins that inherit from `Guard::Plugin`.
43
+ #
44
+ # @see Guard::Plugin
45
+ # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to
46
+ # upgrade for Guard 2.0
47
+ #
48
+ # @return [Guard::Plugin] the initialized plugin
49
+ # @return [Guard::Guard] the initialized plugin. This return type is
50
+ # deprecated and the plugin's maintainer should update it to be
51
+ # compatible with Guard 2.0. For more information on how to upgrade for
52
+ # Guard 2.0, please head over to:
53
+ # https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0
54
+ #
55
+ def initialize_plugin(options)
56
+ klass = plugin_class
57
+ fail "Could not load class: #{_constant_name.inspect}" unless klass
58
+ if klass.superclass.to_s == "Guard::Guard"
59
+ klass.new(options.delete(:watchers), options)
60
+ else
61
+ begin
62
+ klass.new(options)
63
+ rescue ArgumentError => e
64
+ fail "Failed to call #{klass}.new(options): #{e}"
65
+ end
66
+ end
67
+ end
68
+
69
+ # Locates a path to a Guard plugin gem.
70
+ #
71
+ # @return [String] the full path to the plugin gem
72
+ #
73
+ def plugin_location
74
+ @plugin_location ||= _full_gem_path("guard-#{name}")
75
+ rescue Gem::LoadError
76
+ ::Guard::UI.error "Could not find 'guard-#{ name }' gem path."
77
+ end
78
+
79
+ # Tries to load the Guard plugin main class. This transforms the supplied
80
+ # plugin name into a class name:
81
+ #
82
+ # * `guardname` will become `Guard::Guardname`
83
+ # * `dashed-guard-name` will become `Guard::DashedGuardName`
84
+ # * `underscore_guard_name` will become `Guard::UnderscoreGuardName`
85
+ #
86
+ # When no class is found with the strict case sensitive rules, another
87
+ # try is made to locate the class without matching case:
88
+ #
89
+ # * `rspec` will find a class `Guard::RSpec`
90
+ #
91
+ # @option options [Boolean] fail_gracefully whether error messages should
92
+ # not be printed
93
+ #
94
+ # @return [Class, nil] the loaded class
95
+ #
96
+ def plugin_class(options = {})
97
+ options = { fail_gracefully: false }.merge(options)
98
+
99
+ const = _plugin_constant
100
+ fail TypeError, "no constant: #{_constant_name}" unless const
101
+ @plugin_class ||= Guard.const_get(const)
102
+
103
+ rescue TypeError
104
+ begin
105
+ require "guard/#{ name.downcase }"
106
+ const = _plugin_constant
107
+ @plugin_class ||= Guard.const_get(const)
108
+
109
+ rescue TypeError => error
110
+ UI.error "Could not find class Guard::#{ _constant_name }"
111
+ UI.error error.backtrace.join("\n")
112
+ rescue LoadError => error
113
+ unless options[:fail_gracefully]
114
+ UI.error ERROR_NO_GUARD_OR_CLASS % [name.downcase, _constant_name]
115
+ UI.error "Error is: #{error}"
116
+ UI.error error.backtrace.join("\n")
117
+ end
118
+ end
119
+ end
120
+
121
+ # Adds a plugin's template to the Guardfile.
122
+ #
123
+ def add_to_guardfile
124
+ klass = plugin_class # call here to avoid failing later
125
+
126
+ require "guard/guardfile/evaluator"
127
+ # TODO: move this to Generator?
128
+ options = Guard.state.session.evaluator_options
129
+ evaluator = Guardfile::Evaluator.new(options)
130
+ evaluator.evaluate
131
+ if evaluator.guardfile_include?(name)
132
+ UI.info "Guardfile already includes #{ name } guard"
133
+ else
134
+ content = File.read("Guardfile")
135
+ File.open("Guardfile", "wb") do |f|
136
+ f.puts(content)
137
+ f.puts("")
138
+ f.puts(klass.template(plugin_location))
139
+ end
140
+
141
+ UI.info INFO_ADDED_GUARD_TO_GUARDFILE % name
142
+ end
143
+ end
144
+
145
+ private
146
+
147
+ # Returns the constant for the current plugin.
148
+ #
149
+ # @example Returns the constant for a plugin
150
+ # > Guard::PluginUtil.new('rspec').send(:_plugin_constant)
151
+ # => Guard::RSpec
152
+ #
153
+ def _plugin_constant
154
+ @_plugin_constant ||= Guard.constants.detect do |c|
155
+ c.to_s.downcase == _constant_name.downcase
156
+ end
157
+ end
158
+
159
+ # Guesses the most probable name for the current plugin based on its name.
160
+ #
161
+ # @example Returns the most probable name for a plugin
162
+ # > Guard::PluginUtil.new('rspec').send(:_constant_name)
163
+ # => "Rspec"
164
+ #
165
+ def _constant_name
166
+ @_constant_name ||= name.gsub(/\/(.?)/) { "::#{ $1.upcase }" }.
167
+ gsub(/(?:^|[_-])(.)/) { $1.upcase }
168
+ end
169
+
170
+ def self._gem_valid?(gem)
171
+ return false if gem.name == 'guard-compat'
172
+ return true if gem.name =~ /^guard-/
173
+ full_path = gem.full_gem_path
174
+ file = File.join(full_path, "lib", "guard", "#{gem.name}.rb")
175
+ File.exist?(file)
176
+ end
177
+
178
+ def _full_gem_path(name)
179
+ Gem::Specification.find_by_name(name).full_gem_path
180
+ end
181
+ end
182
+ end
data/lib/guard/ui.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "lumberjack"
2
2
 
3
+ # TODO: remove this dep!
3
4
  require "guard/internals/state"
4
5
 
5
6
  require "guard/options"
@@ -0,0 +1,268 @@
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
+ # @private
189
+ def _filtered_logger_message(message, method, color_name, options = {})
190
+ message = color(message, color_name) if color_name
191
+
192
+ _filter(options[:plugin]) do |plugin|
193
+ reset_line if options[:reset]
194
+ logger.send(method, message, plugin)
195
+ end
196
+ end
197
+
198
+ # Tries to extract the calling Guard plugin name
199
+ # from the call stack.
200
+ #
201
+ # @param [Integer] depth the stack depth
202
+ # @return [String] the Guard plugin name
203
+ #
204
+ def calling_plugin_name(depth = 2)
205
+ name = /(guard\/[a-z_]*)(\/[a-z_]*)?.rb:/i.match(caller[depth])
206
+ return "Guard" unless name
207
+ name[1].split("/").map do |part|
208
+ part.split(/[^a-z0-9]/i).map(&:capitalize).join
209
+ end.join("::")
210
+ end
211
+
212
+ # Checks if color output can be enabled.
213
+ #
214
+ # @return [Boolean] whether color is enabled or not
215
+ #
216
+ def color_enabled?
217
+ @color_enabled_initialized ||= false
218
+ @color_enabled = nil unless @color_enabled_initialized
219
+ @color_enabled_initialized = true
220
+ if @color_enabled.nil?
221
+ if Gem.win_platform?
222
+ if ENV["ANSICON"]
223
+ @color_enabled = true
224
+ else
225
+ begin
226
+ require "rubygems" unless ENV["NO_RUBYGEMS"]
227
+ require "Win32/Console/ANSI"
228
+ @color_enabled = true
229
+ rescue LoadError
230
+ @color_enabled = false
231
+ info "Run 'gem install win32console' to use color on Windows"
232
+ end
233
+ end
234
+ else
235
+ @color_enabled = true
236
+ end
237
+ end
238
+
239
+ @color_enabled
240
+ end
241
+
242
+ # Colorizes a text message. See the constant in the UI class for possible
243
+ # color_options parameters. You can pass optionally :bright, a foreground
244
+ # color and a background color.
245
+ #
246
+ # @example
247
+ #
248
+ # color('Hello World', :red, :bright)
249
+ #
250
+ # @param [String] text the text to colorize
251
+ # @param [Array] color_options the color options
252
+ #
253
+ def color(text, *color_options)
254
+ color_code = ""
255
+ color_options.each do |color_option|
256
+ color_option = color_option.to_s
257
+ next if color_option == ""
258
+
259
+ unless color_option =~ /\d+/
260
+ color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
261
+ end
262
+ color_code += ";" + color_option
263
+ end
264
+ color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
265
+ end
266
+ end
267
+ end
268
+ end
data/lib/guard/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Guard
2
- VERSION = "2.10.1"
2
+ VERSION = "2.10.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: guard
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.10.1
4
+ version: 2.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibaud Guillaume-Gentil
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-01 00:00:00.000000000 Z
11
+ date: 2014-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -108,6 +108,7 @@ files:
108
108
  - lib/guard/commands/reload.rb
109
109
  - lib/guard/commands/scope.rb
110
110
  - lib/guard/commands/show.rb
111
+ - lib/guard/compat/test/helper.rb.orig
111
112
  - lib/guard/config.rb
112
113
  - lib/guard/deprecated/dsl.rb
113
114
  - lib/guard/deprecated/evaluator.rb
@@ -153,6 +154,7 @@ files:
153
154
  - lib/guard/options.rb
154
155
  - lib/guard/plugin.rb
155
156
  - lib/guard/plugin_util.rb
157
+ - lib/guard/plugin_util.rb.orig
156
158
  - lib/guard/rake_task.rb
157
159
  - lib/guard/reevaluator.rb
158
160
  - lib/guard/runner.rb
@@ -160,6 +162,7 @@ files:
160
162
  - lib/guard/templates/Guardfile
161
163
  - lib/guard/terminal.rb
162
164
  - lib/guard/ui.rb
165
+ - lib/guard/ui.rb.orig
163
166
  - lib/guard/ui/colors.rb
164
167
  - lib/guard/version.rb
165
168
  - lib/guard/version.rb.orig