guard 2.10.1 → 2.10.2
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 +4 -4
- data/lib/guard/compat/test/helper.rb.orig +0 -0
- data/lib/guard/plugin_util.rb +1 -0
- data/lib/guard/plugin_util.rb.orig +182 -0
- data/lib/guard/ui.rb +1 -0
- data/lib/guard/ui.rb.orig +268 -0
- data/lib/guard/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3106af4e3722da1f4bd41e051e5baf1ff8ace4f7
|
4
|
+
data.tar.gz: 0ef587f058e7f02bc5b4195a0b3b3b4d25847ddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5f3825c29f9c01f14b50051055e105a3695288da0ce2ba2d42fdd4e4af92881afb455515da551a1faaf192b28ba8eb2e599f0640002ff9c1d2d8db0796c734a
|
7
|
+
data.tar.gz: c107a499ff6e9814b536a9c1f723c5a7badc97e33f74ae8409f5b72d082fff63c09d3eac630cd9b6b12c9591ed1210b907ea05680f2b615d62bcde31b2eb5784
|
File without changes
|
data/lib/guard/plugin_util.rb
CHANGED
@@ -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
@@ -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
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.
|
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-
|
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
|