joshbuddy-guard 0.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.
- data/CHANGELOG.md +370 -0
- data/LICENSE +20 -0
- data/README.md +470 -0
- data/bin/fsevent_watch_guard +0 -0
- data/bin/guard +6 -0
- data/images/failed.png +0 -0
- data/images/pending.png +0 -0
- data/images/success.png +0 -0
- data/lib/guard.rb +463 -0
- data/lib/guard/cli.rb +125 -0
- data/lib/guard/dsl.rb +370 -0
- data/lib/guard/dsl_describer.rb +150 -0
- data/lib/guard/group.rb +37 -0
- data/lib/guard/guard.rb +129 -0
- data/lib/guard/hook.rb +118 -0
- data/lib/guard/interactor.rb +116 -0
- data/lib/guard/listener.rb +351 -0
- data/lib/guard/listeners/darwin.rb +60 -0
- data/lib/guard/listeners/linux.rb +91 -0
- data/lib/guard/listeners/polling.rb +55 -0
- data/lib/guard/listeners/windows.rb +61 -0
- data/lib/guard/notifier.rb +290 -0
- data/lib/guard/templates/Guardfile +2 -0
- data/lib/guard/ui.rb +193 -0
- data/lib/guard/version.rb +6 -0
- data/lib/guard/watcher.rb +114 -0
- data/lib/vendor/darwin/Gemfile +6 -0
- data/lib/vendor/darwin/Guardfile +8 -0
- data/lib/vendor/darwin/LICENSE +20 -0
- data/lib/vendor/darwin/README.rdoc +254 -0
- data/lib/vendor/darwin/Rakefile +21 -0
- data/lib/vendor/darwin/ext/extconf.rb +61 -0
- data/lib/vendor/darwin/ext/fsevent/fsevent_watch.c +226 -0
- data/lib/vendor/darwin/lib/rb-fsevent.rb +2 -0
- data/lib/vendor/darwin/lib/rb-fsevent/fsevent.rb +105 -0
- data/lib/vendor/darwin/lib/rb-fsevent/version.rb +3 -0
- data/lib/vendor/darwin/rb-fsevent.gemspec +24 -0
- data/lib/vendor/darwin/spec/fixtures/folder1/file1.txt +0 -0
- data/lib/vendor/darwin/spec/fixtures/folder1/folder2/file2.txt +0 -0
- data/lib/vendor/darwin/spec/rb-fsevent/fsevent_spec.rb +75 -0
- data/lib/vendor/darwin/spec/spec_helper.rb +24 -0
- data/lib/vendor/linux/MIT-LICENSE +20 -0
- data/lib/vendor/linux/README.md +66 -0
- data/lib/vendor/linux/Rakefile +54 -0
- data/lib/vendor/linux/VERSION +1 -0
- data/lib/vendor/linux/lib/rb-inotify.rb +17 -0
- data/lib/vendor/linux/lib/rb-inotify/event.rb +139 -0
- data/lib/vendor/linux/lib/rb-inotify/native.rb +31 -0
- data/lib/vendor/linux/lib/rb-inotify/native/flags.rb +89 -0
- data/lib/vendor/linux/lib/rb-inotify/notifier.rb +308 -0
- data/lib/vendor/linux/lib/rb-inotify/watcher.rb +83 -0
- data/lib/vendor/linux/rb-inotify.gemspec +53 -0
- data/lib/vendor/windows/Gemfile +4 -0
- data/lib/vendor/windows/README.md +34 -0
- data/lib/vendor/windows/Rakefile +18 -0
- data/lib/vendor/windows/lib/rb-fchange.rb +14 -0
- data/lib/vendor/windows/lib/rb-fchange/event.rb +29 -0
- data/lib/vendor/windows/lib/rb-fchange/native.rb +45 -0
- data/lib/vendor/windows/lib/rb-fchange/native/flags.rb +78 -0
- data/lib/vendor/windows/lib/rb-fchange/notifier.rb +149 -0
- data/lib/vendor/windows/lib/rb-fchange/version.rb +3 -0
- data/lib/vendor/windows/lib/rb-fchange/watcher.rb +99 -0
- data/lib/vendor/windows/rb-fchange.gemspec +34 -0
- data/lib/vendor/windows/spec/fixtures/folder1/file1.txt +0 -0
- data/lib/vendor/windows/spec/fixtures/folder1/folder2/file2.txt +0 -0
- data/lib/vendor/windows/spec/rb-fchange/fchange_spec.rb +119 -0
- data/lib/vendor/windows/spec/spec_helper.rb +21 -0
- data/man/guard.1 +96 -0
- data/man/guard.1.html +181 -0
- metadata +193 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# Polling listener that works cross-platform and
|
4
|
+
# has no dependencies. This is the listener that
|
5
|
+
# uses the most CPU processing power and has higher
|
6
|
+
# file IO that the other implementations.
|
7
|
+
#
|
8
|
+
class Polling < Listener
|
9
|
+
|
10
|
+
# Initialize the Listener.
|
11
|
+
#
|
12
|
+
def initialize(*)
|
13
|
+
super
|
14
|
+
@latency = 1.5
|
15
|
+
end
|
16
|
+
|
17
|
+
# Start the listener.
|
18
|
+
#
|
19
|
+
def start
|
20
|
+
@stop = false
|
21
|
+
super
|
22
|
+
watch_change
|
23
|
+
end
|
24
|
+
|
25
|
+
# Stop the listener.
|
26
|
+
#
|
27
|
+
def stop
|
28
|
+
super
|
29
|
+
@stop = true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Watch the given directory for file changes.
|
33
|
+
#
|
34
|
+
# @param [String] directory the directory to watch
|
35
|
+
#
|
36
|
+
def watch(directory)
|
37
|
+
@existing = all_files
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Watch for file system changes.
|
43
|
+
#
|
44
|
+
def watch_change
|
45
|
+
until @stop
|
46
|
+
start = Time.now.to_f
|
47
|
+
files = modified_files([@directory], :all => true)
|
48
|
+
@callback.call(files) unless files.empty?
|
49
|
+
nap_time = @latency - (Time.now.to_f - start)
|
50
|
+
sleep(nap_time) if nap_time > 0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# Listener implementation for Windows `fchange`.
|
4
|
+
#
|
5
|
+
class Windows < Listener
|
6
|
+
|
7
|
+
# Initialize the Listener.
|
8
|
+
#
|
9
|
+
def initialize(*)
|
10
|
+
super
|
11
|
+
@fchange = FChange::Notifier.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Start the listener.
|
15
|
+
#
|
16
|
+
def start
|
17
|
+
super
|
18
|
+
worker.run
|
19
|
+
end
|
20
|
+
|
21
|
+
# Stop the listener.
|
22
|
+
#
|
23
|
+
def stop
|
24
|
+
super
|
25
|
+
worker.stop
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check if the listener is usable on the current OS.
|
29
|
+
#
|
30
|
+
# @return [Boolean] whether usable or not
|
31
|
+
#
|
32
|
+
def self.usable?(no_vendor = false)
|
33
|
+
$LOAD_PATH << File.expand_path('../../../vendor/windows/lib', __FILE__) unless no_vendor
|
34
|
+
require 'rb-fchange'
|
35
|
+
true
|
36
|
+
rescue LoadError
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Watch the given directory for file changes.
|
43
|
+
#
|
44
|
+
# @param [String] directory the directory to watch
|
45
|
+
#
|
46
|
+
def watch(directory)
|
47
|
+
worker.watch(directory, :all_events, :recursive) do |event|
|
48
|
+
paths = [File.expand_path(event.watcher.path)]
|
49
|
+
files = modified_files(paths, :all => true)
|
50
|
+
@callback.call(files) unless files.empty?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the listener worker.
|
55
|
+
#
|
56
|
+
def worker
|
57
|
+
@fchange
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
require 'pathname'
|
3
|
+
require 'guard/ui'
|
4
|
+
|
5
|
+
module Guard
|
6
|
+
|
7
|
+
# The notifier class handles cross-platform system notifications that supports:
|
8
|
+
#
|
9
|
+
# - Growl on Mac OS X
|
10
|
+
# - Libnotify on Linux
|
11
|
+
# - Notifu on Windows
|
12
|
+
#
|
13
|
+
module Notifier
|
14
|
+
|
15
|
+
# Application name as shown in the specific notification settings
|
16
|
+
APPLICATION_NAME = "Guard"
|
17
|
+
|
18
|
+
class << self
|
19
|
+
|
20
|
+
attr_accessor :growl_library, :gntp
|
21
|
+
|
22
|
+
# Turn notifications off.
|
23
|
+
#
|
24
|
+
def turn_off
|
25
|
+
ENV["GUARD_NOTIFY"] = 'false'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Turn notifications on. This tries to load the platform
|
29
|
+
# specific notification library.
|
30
|
+
#
|
31
|
+
# @return [Boolean] whether the notification could be enabled.
|
32
|
+
#
|
33
|
+
def turn_on
|
34
|
+
ENV["GUARD_NOTIFY"] = 'true'
|
35
|
+
case RbConfig::CONFIG['target_os']
|
36
|
+
when /darwin/i
|
37
|
+
require_growl
|
38
|
+
when /linux/i
|
39
|
+
require_libnotify
|
40
|
+
when /mswin|mingw/i
|
41
|
+
require_rbnotifu
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Show a message with the system notification.
|
46
|
+
#
|
47
|
+
# @see .image_path
|
48
|
+
#
|
49
|
+
# @param [String] the message to show
|
50
|
+
# @option options [Symbol, String] image the image symbol or path to an image
|
51
|
+
# @option options [String] title the notification title
|
52
|
+
#
|
53
|
+
def notify(message, options = { })
|
54
|
+
if enabled?
|
55
|
+
image = options.delete(:image) || :success
|
56
|
+
title = options.delete(:title) || "Guard"
|
57
|
+
|
58
|
+
case RbConfig::CONFIG['target_os']
|
59
|
+
when /darwin/i
|
60
|
+
notify_mac(title, message, image, options)
|
61
|
+
when /linux/i
|
62
|
+
notify_linux(title, message, image, options)
|
63
|
+
when /mswin|mingw/i
|
64
|
+
notify_windows(title, message, image, options)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Test if the notifications are enabled and available.
|
70
|
+
#
|
71
|
+
# @return [Boolean] whether the notifications are available
|
72
|
+
#
|
73
|
+
def enabled?
|
74
|
+
ENV["GUARD_NOTIFY"] == 'true'
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# Send a message to Growl either with the `growl` gem or the `growl_notify` gem.
|
80
|
+
#
|
81
|
+
# @param [String] title the notification title
|
82
|
+
# @param [String] message the message to show
|
83
|
+
# @param [Symbol, String] the image to user
|
84
|
+
# @param [Hash] options the growl options
|
85
|
+
#
|
86
|
+
def notify_mac(title, message, image, options = { })
|
87
|
+
require_growl # need for guard-rspec formatter that is called out of guard scope
|
88
|
+
|
89
|
+
notification = { :title => title, :icon => image_path(image) }.merge(options)
|
90
|
+
|
91
|
+
case self.growl_library
|
92
|
+
when :growl_notify
|
93
|
+
notification.delete(:name)
|
94
|
+
|
95
|
+
GrowlNotify.send_notification({
|
96
|
+
:description => message,
|
97
|
+
:application_name => APPLICATION_NAME
|
98
|
+
}.merge(notification))
|
99
|
+
|
100
|
+
when :ruby_gntp
|
101
|
+
icon = "file://#{ notification.delete(:icon) }"
|
102
|
+
|
103
|
+
self.gntp.notify({
|
104
|
+
:name => [:pending, :success, :failed].include?(image) ? image.to_s : 'notify',
|
105
|
+
:text => message,
|
106
|
+
:icon => icon
|
107
|
+
}.merge(notification))
|
108
|
+
|
109
|
+
when :growl
|
110
|
+
Growl.notify(message, {
|
111
|
+
:name => APPLICATION_NAME
|
112
|
+
}.merge(notification))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Send a message to libnotify.
|
117
|
+
#
|
118
|
+
# @param [String] title the notification title
|
119
|
+
# @param [String] message the message to show
|
120
|
+
# @param [Symbol, String] the image to user
|
121
|
+
# @param [Hash] options the libnotify options
|
122
|
+
#
|
123
|
+
def notify_linux(title, message, image, options = { })
|
124
|
+
require_libnotify # need for guard-rspec formatter that is called out of guard scope
|
125
|
+
|
126
|
+
notification = { :body => message, :summary => title, :icon_path => image_path(image), :transient => true }
|
127
|
+
Libnotify.show notification.merge(options)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Send a message to notifu.
|
131
|
+
#
|
132
|
+
# @param [String] title the notification title
|
133
|
+
# @param [String] message the message to show
|
134
|
+
# @param [Symbol, String] the image to user
|
135
|
+
# @param [Hash] options the notifu options
|
136
|
+
#
|
137
|
+
def notify_windows(title, message, image, options = { })
|
138
|
+
require_rbnotifu # need for guard-rspec formatter that is called out of guard scope
|
139
|
+
|
140
|
+
notification = { :message => message, :title => title, :type => image_level(image), :time => 3 }
|
141
|
+
Notifu.show notification.merge(options)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Get the image path for an image symbol.
|
145
|
+
#
|
146
|
+
# Known symbols are:
|
147
|
+
#
|
148
|
+
# - failed
|
149
|
+
# - pending
|
150
|
+
# - success
|
151
|
+
#
|
152
|
+
# @param [Symbol] image the image name
|
153
|
+
# @return [String] the image path
|
154
|
+
#
|
155
|
+
def image_path(image)
|
156
|
+
images_path = Pathname.new(File.dirname(__FILE__)).join('../../images')
|
157
|
+
case image
|
158
|
+
when :failed
|
159
|
+
images_path.join("failed.png").to_s
|
160
|
+
when :pending
|
161
|
+
images_path.join("pending.png").to_s
|
162
|
+
when :success
|
163
|
+
images_path.join("success.png").to_s
|
164
|
+
else
|
165
|
+
# path given
|
166
|
+
image
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# The notification level type for the given image.
|
171
|
+
#
|
172
|
+
# @param [Symbol] image the image
|
173
|
+
# @return [Symbol] the level
|
174
|
+
#
|
175
|
+
def image_level(image)
|
176
|
+
case image
|
177
|
+
when :failed
|
178
|
+
:error
|
179
|
+
when :pending
|
180
|
+
:warn
|
181
|
+
when :success
|
182
|
+
:info
|
183
|
+
else
|
184
|
+
:info
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Try to safely load growl and turns notifications off on load failure.
|
189
|
+
# The Guard notifier knows three different library to handle sending
|
190
|
+
# Growl messages and tries to loading them in the given order:
|
191
|
+
#
|
192
|
+
# - [Growl Notify](https://github.com/scottdavis/growl_notify)
|
193
|
+
# - [Ruby GNTP](https://github.com/snaka/ruby_gntp)
|
194
|
+
# - [Growl](https://github.com/visionmedia/growl)
|
195
|
+
#
|
196
|
+
# On successful loading of any of the libraries, the active library name is
|
197
|
+
# accessible through `.growl_library`.
|
198
|
+
#
|
199
|
+
def require_growl
|
200
|
+
self.growl_library = try_growl_notify || try_ruby_gntp || try_growl
|
201
|
+
|
202
|
+
unless self.growl_library
|
203
|
+
turn_off
|
204
|
+
UI.info "Please install growl_notify or growl gem for Mac OS X notification support and add it to your Gemfile"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Try to load the `growl_notify` gem.
|
209
|
+
#
|
210
|
+
# @return [Symbol, nil] A symbol with the name of the loaded library
|
211
|
+
#
|
212
|
+
def try_growl_notify
|
213
|
+
require 'growl_notify'
|
214
|
+
|
215
|
+
begin
|
216
|
+
if GrowlNotify.application_name != APPLICATION_NAME
|
217
|
+
GrowlNotify.config do |c|
|
218
|
+
c.notifications = c.default_notifications = [APPLICATION_NAME]
|
219
|
+
c.application_name = c.notifications.first
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
rescue ::GrowlNotify::GrowlNotFound
|
224
|
+
turn_off
|
225
|
+
UI.info "Please install Growl from http://growl.info"
|
226
|
+
end
|
227
|
+
|
228
|
+
:growl_notify
|
229
|
+
|
230
|
+
rescue LoadError
|
231
|
+
end
|
232
|
+
|
233
|
+
# Try to load the `ruby_gntp` gem and register the available
|
234
|
+
# notification channels.
|
235
|
+
#
|
236
|
+
# @return [Symbol, nil] A symbol with the name of the loaded library
|
237
|
+
#
|
238
|
+
def try_ruby_gntp
|
239
|
+
require 'ruby_gntp'
|
240
|
+
|
241
|
+
self.gntp = GNTP.new(APPLICATION_NAME)
|
242
|
+
self.gntp.register(:notifications => [
|
243
|
+
{ :name => 'notify', :enabled => true },
|
244
|
+
{ :name => 'failed', :enabled => true },
|
245
|
+
{ :name => 'pending', :enabled => true },
|
246
|
+
{ :name => 'success', :enabled => true }
|
247
|
+
])
|
248
|
+
|
249
|
+
:ruby_gntp
|
250
|
+
|
251
|
+
rescue LoadError
|
252
|
+
end
|
253
|
+
|
254
|
+
# Try to load the `growl_notify` gem.
|
255
|
+
#
|
256
|
+
# @return [Symbol, nil] A symbol with the name of the loaded library
|
257
|
+
#
|
258
|
+
def try_growl
|
259
|
+
require 'growl'
|
260
|
+
|
261
|
+
:growl
|
262
|
+
|
263
|
+
rescue LoadError
|
264
|
+
end
|
265
|
+
|
266
|
+
# Try to safely load libnotify and turns notifications
|
267
|
+
# off on load failure.
|
268
|
+
#
|
269
|
+
def require_libnotify
|
270
|
+
require 'libnotify'
|
271
|
+
|
272
|
+
rescue LoadError
|
273
|
+
turn_off
|
274
|
+
UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile"
|
275
|
+
end
|
276
|
+
|
277
|
+
# Try to safely load rb-notifu and turns notifications
|
278
|
+
# off on load failure.
|
279
|
+
#
|
280
|
+
def require_rbnotifu
|
281
|
+
require 'rb-notifu'
|
282
|
+
|
283
|
+
rescue LoadError
|
284
|
+
turn_off
|
285
|
+
UI.info "Please install rb-notifu gem for Windows notification support and add it to your Gemfile"
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
data/lib/guard/ui.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
module Guard
|
2
|
+
|
3
|
+
# The UI class helps to format messages for the user. Everything that is logged
|
4
|
+
# through this class is considered either as an error message or a diagnostic
|
5
|
+
# message and is written to standard error (STDERR).
|
6
|
+
#
|
7
|
+
# If your Guard does some output that is piped into another process for further
|
8
|
+
# processing, please just write it to STDOUT with `puts`.
|
9
|
+
#
|
10
|
+
module UI
|
11
|
+
class << self
|
12
|
+
|
13
|
+
color_enabled = nil
|
14
|
+
|
15
|
+
# Show an info message.
|
16
|
+
#
|
17
|
+
# @param [String] message the message to show
|
18
|
+
# @option options [Boolean] reset whether to clean the output before
|
19
|
+
#
|
20
|
+
def info(message, options = { })
|
21
|
+
unless ENV['GUARD_ENV'] == 'test'
|
22
|
+
reset_line if options[:reset]
|
23
|
+
STDERR.puts color(message) if message != ''
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Show a red error message that is prefixed with ERROR.
|
28
|
+
#
|
29
|
+
# @param [String] message the message to show
|
30
|
+
# @option options [Boolean] reset whether to clean the output before
|
31
|
+
#
|
32
|
+
def error(message, options = { })
|
33
|
+
unless ENV['GUARD_ENV'] == 'test'
|
34
|
+
reset_line if options[:reset]
|
35
|
+
STDERR.puts color('ERROR: ', :red) + message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Show a red deprecation message that is prefixed with DEPRECATION.
|
40
|
+
#
|
41
|
+
# @param [String] message the message to show
|
42
|
+
# @option options [Boolean] reset whether to clean the output before
|
43
|
+
#
|
44
|
+
def deprecation(message, options = { })
|
45
|
+
unless ENV['GUARD_ENV'] == 'test'
|
46
|
+
reset_line if options[:reset]
|
47
|
+
STDERR.puts color('DEPRECATION: ', :red) + message
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Show a debug message that is prefixed with DEBUG and a timestamp.
|
52
|
+
#
|
53
|
+
# @param [String] message the message to show
|
54
|
+
# @option options [Boolean] reset whether to clean the output before
|
55
|
+
#
|
56
|
+
def debug(message, options = { })
|
57
|
+
unless ENV['GUARD_ENV'] == 'test'
|
58
|
+
reset_line if options[:reset]
|
59
|
+
STDERR.puts color("DEBUG (#{Time.now.strftime('%T')}): ", :yellow) + message if ::Guard.options && ::Guard.options[:debug]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Reset a line.
|
64
|
+
#
|
65
|
+
def reset_line
|
66
|
+
STDERR.print(color_enabled? ? "\r\e[0m" : "\r\n")
|
67
|
+
end
|
68
|
+
|
69
|
+
# Clear the output.
|
70
|
+
#
|
71
|
+
def clear
|
72
|
+
system('clear;')
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Reset a color sequence.
|
78
|
+
#
|
79
|
+
# @deprecated
|
80
|
+
# @param [String] text the text
|
81
|
+
#
|
82
|
+
def reset_color(text)
|
83
|
+
deprecation('UI.reset_color(text) is deprecated, please use color(text, ' ') instead.')
|
84
|
+
color(text, '')
|
85
|
+
end
|
86
|
+
|
87
|
+
# Checks if color output can be enabled.
|
88
|
+
#
|
89
|
+
# @return [Boolean] whether color is enabled or not
|
90
|
+
#
|
91
|
+
def color_enabled?
|
92
|
+
if @color_enabled.nil?
|
93
|
+
if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
|
94
|
+
if ENV['ANSICON']
|
95
|
+
@color_enabled = true
|
96
|
+
else
|
97
|
+
begin
|
98
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
99
|
+
require 'Win32/Console/ANSI'
|
100
|
+
@color_enabled = true
|
101
|
+
rescue LoadError
|
102
|
+
@color_enabled = false
|
103
|
+
info "You must 'gem install win32console' to use color on Windows"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
else
|
107
|
+
@color_enabled = true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
@color_enabled
|
112
|
+
end
|
113
|
+
|
114
|
+
# Colorizes a text message. See the constant in the UI class for possible
|
115
|
+
# color_options parameters. You can pass optionally :bright, a foreground
|
116
|
+
# color and a background color.
|
117
|
+
#
|
118
|
+
# @example
|
119
|
+
#
|
120
|
+
# color('Hello World', :red, :bright)
|
121
|
+
#
|
122
|
+
# @param [String] the text to colorize
|
123
|
+
# @param [Array] color_options the color options
|
124
|
+
#
|
125
|
+
def color(text, *color_options)
|
126
|
+
color_code = ''
|
127
|
+
color_options.each do |color_option|
|
128
|
+
color_option = color_option.to_s
|
129
|
+
if color_option != ''
|
130
|
+
if !(color_option =~ /\d+/)
|
131
|
+
color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
|
132
|
+
end
|
133
|
+
color_code += ';' + color_option
|
134
|
+
end
|
135
|
+
end
|
136
|
+
color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# Brighten the color
|
142
|
+
ANSI_ESCAPE_BRIGHT = '1'
|
143
|
+
|
144
|
+
# Black foreground color
|
145
|
+
ANSI_ESCAPE_BLACK = '30'
|
146
|
+
|
147
|
+
# Red foreground color
|
148
|
+
ANSI_ESCAPE_RED = '31'
|
149
|
+
|
150
|
+
# Green foreground color
|
151
|
+
ANSI_ESCAPE_GREEN = '32'
|
152
|
+
|
153
|
+
# Yellow foreground color
|
154
|
+
ANSI_ESCAPE_YELLOW = '33'
|
155
|
+
|
156
|
+
# Blue foreground color
|
157
|
+
ANSI_ESCAPE_BLUE = '34'
|
158
|
+
|
159
|
+
# Magenta foreground color
|
160
|
+
ANSI_ESCAPE_MAGENTA = '35'
|
161
|
+
|
162
|
+
# Cyan foreground color
|
163
|
+
ANSI_ESCAPE_CYAN = '36'
|
164
|
+
|
165
|
+
# White foreground color
|
166
|
+
ANSI_ESCAPE_WHITE = '37'
|
167
|
+
|
168
|
+
# Black background color
|
169
|
+
ANSI_ESCAPE_BGBLACK = '40'
|
170
|
+
|
171
|
+
# Red background color
|
172
|
+
ANSI_ESCAPE_BGRED = '41'
|
173
|
+
|
174
|
+
# Green background color
|
175
|
+
ANSI_ESCAPE_BGGREEN = '42'
|
176
|
+
|
177
|
+
# Yellow background color
|
178
|
+
ANSI_ESCAPE_BGYELLOW = '43'
|
179
|
+
|
180
|
+
# Blue background color
|
181
|
+
ANSI_ESCAPE_BGBLUE = '44'
|
182
|
+
|
183
|
+
# Magenta background color
|
184
|
+
ANSI_ESCAPE_BGMAGENTA = '45'
|
185
|
+
|
186
|
+
# Cyan background color
|
187
|
+
ANSI_ESCAPE_BGCYAN = '46'
|
188
|
+
|
189
|
+
# White background color
|
190
|
+
ANSI_ESCAPE_BGWHITE = '47'
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|