guard 2.7.1 → 2.7.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.
File without changes
@@ -1,264 +0,0 @@
1
- require "lumberjack"
2
-
3
- require "guard/options"
4
- require "guard/ui/colors"
5
-
6
- module Guard
7
- # The UI class helps to format messages for the user. Everything that is
8
- # logged through this class is considered either as an error message or a
9
- # diagnostic message and is written to standard error ($stderr).
10
- #
11
- # If your Guard plugin does some output that is piped into another process
12
- # for further processing, please just write it to STDOUT with `puts`.
13
- #
14
- module UI
15
- include Colors
16
-
17
- class << self
18
- # Get the Guard::UI logger instance
19
- #
20
- def logger
21
- @logger ||= begin
22
- Lumberjack::Logger.new(
23
- options.fetch(:device) { $stderr },
24
- options)
25
- end
26
- end
27
-
28
- # Since logger is global, for Aruba in-process to properly
29
- # separate output between calls, we need to reset
30
- #
31
- # We don't use logger=() since it's expected to be a Lumberjack instance
32
- def reset_logger
33
- @logger = nil
34
- end
35
-
36
- # Get the logger options
37
- #
38
- # @return [Hash] the logger options
39
- #
40
- def options
41
- @options ||= ::Guard::Options.new(
42
- level: :info,
43
- template: ":time - :severity - :message",
44
- time_format: "%H:%M:%S")
45
- end
46
-
47
- # Set the logger options
48
- #
49
- # @param [Hash] options the logger options
50
- # @option options [Symbol] level the log level
51
- # @option options [String] template the logger template
52
- # @option options [String] time_format the time format
53
- #
54
- def options=(options)
55
- @options = ::Guard::Options.new(options)
56
- end
57
-
58
- # Show an info message.
59
- #
60
- # @param [String] message the message to show
61
- # @option options [Boolean] reset whether to clean the output before
62
- # @option options [String] plugin manually define the calling plugin
63
- #
64
- def info(message, options = {})
65
- _filtered_logger_message(message, :info, nil, options)
66
- end
67
-
68
- # Show a yellow warning message that is prefixed with WARNING.
69
- #
70
- # @param [String] message the message to show
71
- # @option options [Boolean] reset whether to clean the output before
72
- # @option options [String] plugin manually define the calling plugin
73
- #
74
- def warning(message, options = {})
75
- _filtered_logger_message(message, :warn, :yellow, options)
76
- end
77
-
78
- # Show a red error message that is prefixed with ERROR.
79
- #
80
- # @param [String] message the message to show
81
- # @option options [Boolean] reset whether to clean the output before
82
- # @option options [String] plugin manually define the calling plugin
83
- #
84
- def error(message, options = {})
85
- _filtered_logger_message(message, :error, :red, options)
86
- end
87
-
88
- # Show a red deprecation message that is prefixed with DEPRECATION.
89
- # It has a log level of `warn`.
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 deprecation(message, options = {})
96
- msg = "neither ::Guard.setup nor ::Guard.reset_options was called"
97
- fail msg if ::Guard.options.nil?
98
- warning(message, options) if ::Guard.options[:show_deprecations]
99
- end
100
-
101
- # Show a debug message that is prefixed with DEBUG and a timestamp.
102
- #
103
- # @param [String] message the message to show
104
- # @option options [Boolean] reset whether to clean the output before
105
- # @option options [String] plugin manually define the calling plugin
106
- #
107
- def debug(message, options = {})
108
- _filtered_logger_message(message, :debug, :yellow, options)
109
- end
110
-
111
- # Reset a line.
112
- #
113
- def reset_line
114
- $stderr.print(color_enabled? ? "\r\e[0m" : "\r\n")
115
- end
116
-
117
- # Clear the output if clearable.
118
- #
119
- def clear(options = {})
120
- return unless ::Guard.options[:clear] && (@clearable || options[:force])
121
- @clearable = false
122
- ::Guard::Sheller.run("clear;")
123
- end
124
-
125
- # Allow the screen to be cleared again.
126
- #
127
- def clearable
128
- @clearable = true
129
- end
130
-
131
- # Show a scoped action message.
132
- #
133
- # @param [String] action the action to show
134
- # @param [Hash] scope hash with a guard or a group scope
135
- #
136
- def action_with_scopes(action, scope)
137
- first_non_blank_scope = _first_non_blank_scope(scope)
138
- unless first_non_blank_scope.nil?
139
- scope_message = first_non_blank_scope.map(&:title).join(", ")
140
- end
141
-
142
- info "#{ action } #{ scope_message || "all" }"
143
- end
144
-
145
- private
146
-
147
- # Returns the first non-blank scope by searching in the given `scope`
148
- # hash and in Guard.scope. Returns nil if no non-blank scope is found.
149
- #
150
- def _first_non_blank_scope(scope)
151
- [:plugins, :groups].each do |scope_name|
152
- s = scope[scope_name] || ::Guard.scope[scope_name]
153
- return s if !s.nil? && !s.empty?
154
- end
155
-
156
- nil
157
- end
158
-
159
- # Filters log messages depending on either the
160
- # `:only`` or `:except` option.
161
- #
162
- # @param [String] plugin the calling plugin name
163
- # @yield When the message should be logged
164
- # @yieldparam [String] param the calling plugin name
165
- #
166
- def _filter(plugin)
167
- only = options[:only]
168
- except = options[:except]
169
- plugin ||= calling_plugin_name
170
-
171
- match = !(only || except)
172
- match ||= (only && only.match(plugin))
173
- match ||= (except && !except.match(plugin))
174
- return unless match
175
- yield plugin
176
- end
177
-
178
- # Display a message of the type `method` and with the color `color_name`
179
- # (no color by default) conditionnaly given a `plugin_name`.
180
- #
181
- # @param [String] plugin_name the calling plugin name
182
- # @option options [Boolean] reset whether to clean the output before
183
- # @option options [String] plugin manually define the calling plugin
184
- #
185
- def _filtered_logger_message(message, method, color_name, options = {})
186
- message = color(message, color_name) if color_name
187
-
188
- _filter(options[:plugin]) do |plugin|
189
- reset_line if options[:reset]
190
- logger.send(method, message, plugin)
191
- end
192
- end
193
-
194
- # Tries to extract the calling Guard plugin name
195
- # from the call stack.
196
- #
197
- # @param [Integer] depth the stack depth
198
- # @return [String] the Guard plugin name
199
- #
200
- def calling_plugin_name(depth = 2)
201
- name = /(guard\/[a-z_]*)(\/[a-z_]*)?.rb:/i.match(caller[depth])
202
- return "Guard" unless name
203
- name[1].split("/").map do |part|
204
- part.split(/[^a-z0-9]/i).map(&:capitalize).join
205
- end.join("::")
206
- end
207
-
208
- # Checks if color output can be enabled.
209
- #
210
- # @return [Boolean] whether color is enabled or not
211
- #
212
- def color_enabled?
213
- @color_enabled_initialized ||= false
214
- @color_enabled = nil unless @color_enabled_initialized
215
- @color_enabled_initialized = true
216
- if @color_enabled.nil?
217
- if Gem.win_platform?
218
- if ENV["ANSICON"]
219
- @color_enabled = true
220
- else
221
- begin
222
- require "rubygems" unless ENV["NO_RUBYGEMS"]
223
- require "Win32/Console/ANSI"
224
- @color_enabled = true
225
- rescue LoadError
226
- @color_enabled = false
227
- info "Run 'gem install win32console' to use color on Windows"
228
- end
229
- end
230
- else
231
- @color_enabled = true
232
- end
233
- end
234
-
235
- @color_enabled
236
- end
237
-
238
- # Colorizes a text message. See the constant in the UI class for possible
239
- # color_options parameters. You can pass optionally :bright, a foreground
240
- # color and a background color.
241
- #
242
- # @example
243
- #
244
- # color('Hello World', :red, :bright)
245
- #
246
- # @param [String] text the text to colorize
247
- # @param [Array] color_options the color options
248
- #
249
- def color(text, *color_options)
250
- color_code = ""
251
- color_options.each do |color_option|
252
- color_option = color_option.to_s
253
- next if color_option == ""
254
-
255
- unless color_option =~ /\d+/
256
- color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
257
- end
258
- color_code += ";" + color_option
259
- end
260
- color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
261
- end
262
- end
263
- end
264
- end
@@ -1,119 +0,0 @@
1
- require "guard/ui"
2
-
3
- module Guard
4
- # The watcher defines a RegExp that will be matched against file system
5
- # modifications.
6
- # When a watcher matches a change, an optional action block is executed to
7
- # enable processing the file system change result.
8
- #
9
- class Watcher
10
- attr_accessor :pattern, :action
11
-
12
- # Initializes a file watcher.
13
- #
14
- # @param [String, Regexp] pattern the pattern to be watched by the Guard
15
- # plugin
16
- # @param [Block] action the action to execute before passing the result to
17
- # the Guard plugin
18
- #
19
- def initialize(pattern, action = nil)
20
- @pattern, @action = pattern, action
21
- @@warning_printed ||= false
22
-
23
- # deprecation warning
24
- regexp = /(^(\^))|(>?(\\\.)|(\.\*))|(\(.*\))|(\[.*\])|(\$$)/
25
- return unless @pattern.is_a?(String) && @pattern =~ regexp
26
-
27
- unless @@warning_printed
28
- ::Guard::UI.info "*" * 20 + "\nDEPRECATION WARNING!\n" + "*" * 20
29
- ::Guard::UI.info <<-MSG
30
- You have a string in your Guardfile watch patterns that seem to
31
- represent a Regexp.
32
-
33
- Guard matches String with == and Regexp with Regexp#match.
34
-
35
- You should either use plain String (without Regexp special
36
- characters) or real Regexp.
37
- MSG
38
- @@warning_printed = true
39
- end
40
-
41
- new_regexp = Regexp.new(@pattern).inspect
42
- ::Guard::UI.info "\"#{@pattern}\" has been converted to #{ new_regexp }\n"
43
- @pattern = Regexp.new(@pattern)
44
- end
45
-
46
- # Finds the files that matches a Guard plugin.
47
- #
48
- # @param [Guard::Plugin] guard the Guard plugin which watchers are used
49
- # @param [Array<String>] files the changed files
50
- # @return [Array<Object>] the matched watcher response
51
- #
52
- def self.match_files(guard, files)
53
- return [] if files.empty?
54
-
55
- files.inject([]) do |paths, file|
56
- guard.watchers.each do |watcher|
57
- matches = watcher.match(file)
58
- next unless matches
59
-
60
- if watcher.action
61
- result = watcher.call_action(matches)
62
- if guard.options[:any_return]
63
- paths << result
64
- elsif result.respond_to?(:empty?) && !result.empty?
65
- paths << Array(result)
66
- else
67
- next
68
- end
69
- else
70
- paths << matches[0]
71
- end
72
-
73
- break if guard.options[:first_match]
74
- end
75
-
76
- guard.options[:any_return] ? paths : paths.flatten.map(&:to_s)
77
- end
78
- end
79
-
80
- # Tests if any of the files is the Guardfile.
81
- #
82
- # @param [Array<String>] files the files to test
83
- # @return [Boolean] whether one of these files is the Guardfile
84
- #
85
- def self.match_guardfile?(files)
86
- path = ::Guard.evaluator.guardfile_path
87
- files.any? { |file| File.expand_path(file) == path }
88
- end
89
-
90
- # Test the watchers pattern against a file.
91
- #
92
- # @param [String] file the file to test
93
- # @return [Array<String>] an array of matches (or containing a single path
94
- # if the pattern is a string)
95
- #
96
- def match(string_or_pathname)
97
- # TODO: use only match() - and show fnmatch example
98
- file = string_or_pathname.to_s
99
- return (file == @pattern ? [file] : nil) unless @pattern.is_a?(Regexp)
100
- return unless (m = @pattern.match(file))
101
- m = m.to_a
102
- m[0] = file
103
- m
104
- end
105
-
106
- # Executes a watcher action.
107
- #
108
- # @param [String, MatchData] matches the matched path or the match from the
109
- # Regex
110
- # @return [String] the final paths
111
- #
112
- def call_action(matches)
113
- @action.arity > 0 ? @action.call(matches) : @action.call
114
- rescue => ex
115
- ::Guard::UI.error "Problem with watch action!\n#{ ex.message }"
116
- ::Guard::UI.error ex.backtrace.join("\n")
117
- end
118
- end
119
- end