guard 0.7.0 → 0.8.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 +23 -1
- data/README.md +173 -226
- data/bin/guard +1 -1
- data/lib/guard.rb +243 -45
- data/lib/guard/cli.rb +135 -46
- data/lib/guard/dsl.rb +260 -38
- data/lib/guard/dsl_describer.rb +36 -4
- data/lib/guard/group.rb +22 -0
- data/lib/guard/guard.rb +53 -13
- data/lib/guard/hook.rb +61 -15
- data/lib/guard/interactor.rb +52 -14
- data/lib/guard/listener.rb +181 -26
- data/lib/guard/listeners/darwin.rb +26 -7
- data/lib/guard/listeners/linux.rb +32 -8
- data/lib/guard/listeners/polling.rb +23 -5
- data/lib/guard/listeners/windows.rb +25 -6
- data/lib/guard/notifier.rb +78 -3
- data/lib/guard/ui.rb +125 -47
- data/lib/guard/version.rb +4 -1
- data/lib/guard/watcher.rb +48 -4
- data/man/guard.1 +1 -1
- data/man/guard.1.html +1 -1
- metadata +36 -13
@@ -1,41 +1,60 @@
|
|
1
1
|
module Guard
|
2
|
+
|
3
|
+
# Listener implementation for Mac OS X `FSEvents`.
|
4
|
+
#
|
2
5
|
class Darwin < Listener
|
3
6
|
|
7
|
+
# Initialize the Listener.
|
8
|
+
#
|
4
9
|
def initialize(*)
|
5
10
|
super
|
6
11
|
@fsevent = FSEvent.new
|
7
12
|
end
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
14
|
+
# Start the listener.
|
15
|
+
#
|
13
16
|
def start
|
14
17
|
super
|
15
18
|
worker.run
|
16
19
|
end
|
17
20
|
|
21
|
+
# Stop the listener.
|
22
|
+
#
|
18
23
|
def stop
|
19
24
|
super
|
20
25
|
worker.stop
|
21
26
|
end
|
22
27
|
|
28
|
+
# Check if the listener is usable on the current OS.
|
29
|
+
#
|
30
|
+
# @return [Boolean] whether usable or not
|
31
|
+
#
|
23
32
|
def self.usable?
|
24
33
|
require 'rb-fsevent'
|
25
34
|
if !defined?(FSEvent::VERSION) || (defined?(Gem::Version) &&
|
26
35
|
Gem::Version.new(FSEvent::VERSION) < Gem::Version.new('0.4.0'))
|
27
|
-
UI.info
|
36
|
+
UI.info 'Please update rb-fsevent (>= 0.4.0)'
|
28
37
|
false
|
29
38
|
else
|
30
39
|
true
|
31
40
|
end
|
32
41
|
rescue LoadError
|
33
|
-
UI.info
|
42
|
+
UI.info 'Please install rb-fsevent gem for Mac OSX FSEvents support'
|
34
43
|
false
|
35
44
|
end
|
36
45
|
|
37
|
-
|
46
|
+
private
|
47
|
+
|
48
|
+
# Get the listener worker.
|
49
|
+
#
|
50
|
+
def worker
|
51
|
+
@fsevent
|
52
|
+
end
|
38
53
|
|
54
|
+
# Watch the given directory for file changes.
|
55
|
+
#
|
56
|
+
# @param [String] directory the directory to watch
|
57
|
+
#
|
39
58
|
def watch(directory)
|
40
59
|
worker.watch(directory) do |modified_dirs|
|
41
60
|
files = modified_files(modified_dirs)
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Guard
|
2
|
+
|
3
|
+
# Listener implementation for Linux `inotify`.
|
4
|
+
#
|
2
5
|
class Linux < Listener
|
3
6
|
|
7
|
+
# Initialize the Listener.
|
8
|
+
#
|
4
9
|
def initialize(*)
|
5
10
|
super
|
6
11
|
@inotify = INotify::Notifier.new
|
@@ -8,44 +13,53 @@ module Guard
|
|
8
13
|
@latency = 0.5
|
9
14
|
end
|
10
15
|
|
16
|
+
# Start the listener.
|
17
|
+
#
|
11
18
|
def start
|
12
19
|
@stop = false
|
13
20
|
super
|
14
21
|
watch_change unless watch_change?
|
15
22
|
end
|
16
23
|
|
24
|
+
# Stop the listener.
|
25
|
+
#
|
17
26
|
def stop
|
18
27
|
super
|
19
28
|
@stop = true
|
20
29
|
sleep(@latency)
|
21
30
|
end
|
22
31
|
|
32
|
+
# Check if the listener is usable on the current OS.
|
33
|
+
#
|
34
|
+
# @return [Boolean] whether usable or not
|
35
|
+
#
|
23
36
|
def self.usable?
|
24
37
|
require 'rb-inotify'
|
25
38
|
if !defined?(INotify::VERSION) || (defined?(Gem::Version) &&
|
26
39
|
Gem::Version.new(INotify::VERSION.join('.')) < Gem::Version.new('0.8.5'))
|
27
|
-
UI.info
|
40
|
+
UI.info 'Please update rb-inotify (>= 0.8.5)'
|
28
41
|
false
|
29
42
|
else
|
30
43
|
true
|
31
44
|
end
|
32
45
|
rescue LoadError
|
33
|
-
UI.info
|
46
|
+
UI.info 'Please install rb-inotify gem for Linux inotify support'
|
34
47
|
false
|
35
48
|
end
|
36
49
|
|
37
|
-
|
38
|
-
!!@watch_change
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
50
|
+
private
|
42
51
|
|
52
|
+
# Get the listener worker.
|
53
|
+
#
|
43
54
|
def worker
|
44
55
|
@inotify
|
45
56
|
end
|
46
57
|
|
58
|
+
# Watch the given directory for file changes.
|
59
|
+
#
|
60
|
+
# @param [String] directory the directory to watch
|
61
|
+
#
|
47
62
|
def watch(directory)
|
48
|
-
# The event selection is based on https://github.com/guard/guard/wiki/Analysis-of-inotify-events-for-different-editors
|
49
63
|
worker.watch(directory, :recursive, :attrib, :create, :move_self, :close_write) do |event|
|
50
64
|
unless event.name == "" # Event on root directory
|
51
65
|
@files << event.absolute_name
|
@@ -54,6 +68,16 @@ module Guard
|
|
54
68
|
rescue Interrupt
|
55
69
|
end
|
56
70
|
|
71
|
+
# Test if inotify is watching for changes.
|
72
|
+
#
|
73
|
+
# @return [Boolean] whether inotify is active or not
|
74
|
+
#
|
75
|
+
def watch_change?
|
76
|
+
!!@watch_change
|
77
|
+
end
|
78
|
+
|
79
|
+
# Watch for file system changes.
|
80
|
+
#
|
57
81
|
def watch_change
|
58
82
|
@watch_change = true
|
59
83
|
until @stop
|
@@ -1,24 +1,46 @@
|
|
1
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
|
+
#
|
2
8
|
class Polling < Listener
|
3
9
|
|
10
|
+
# Initialize the Listener.
|
11
|
+
#
|
4
12
|
def initialize(*)
|
5
13
|
super
|
6
14
|
@latency = 1.5
|
7
15
|
end
|
8
16
|
|
17
|
+
# Start the listener.
|
18
|
+
#
|
9
19
|
def start
|
10
20
|
@stop = false
|
11
21
|
super
|
12
22
|
watch_change
|
13
23
|
end
|
14
24
|
|
25
|
+
# Stop the listener.
|
26
|
+
#
|
15
27
|
def stop
|
16
28
|
super
|
17
29
|
@stop = true
|
18
30
|
end
|
19
31
|
|
20
|
-
|
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
|
21
41
|
|
42
|
+
# Watch for file system changes.
|
43
|
+
#
|
22
44
|
def watch_change
|
23
45
|
until @stop
|
24
46
|
start = Time.now.to_f
|
@@ -29,9 +51,5 @@ module Guard
|
|
29
51
|
end
|
30
52
|
end
|
31
53
|
|
32
|
-
def watch(directory)
|
33
|
-
@existing = all_files
|
34
|
-
end
|
35
|
-
|
36
54
|
end
|
37
55
|
end
|
@@ -1,35 +1,48 @@
|
|
1
1
|
module Guard
|
2
|
+
|
3
|
+
# Listener implementation for Windows `fchange`.
|
4
|
+
#
|
2
5
|
class Windows < Listener
|
3
6
|
|
7
|
+
# Initialize the Listener.
|
8
|
+
#
|
4
9
|
def initialize(*)
|
5
10
|
super
|
6
11
|
@fchange = FChange::Notifier.new
|
7
12
|
end
|
8
13
|
|
14
|
+
# Start the listener.
|
15
|
+
#
|
9
16
|
def start
|
10
17
|
super
|
11
18
|
worker.run
|
12
19
|
end
|
13
20
|
|
21
|
+
# Stop the listener.
|
22
|
+
#
|
14
23
|
def stop
|
15
24
|
super
|
16
25
|
worker.stop
|
17
26
|
end
|
18
27
|
|
28
|
+
# Check if the listener is usable on the current OS.
|
29
|
+
#
|
30
|
+
# @return [Boolean] whether usable or not
|
31
|
+
#
|
19
32
|
def self.usable?
|
20
33
|
require 'rb-fchange'
|
21
34
|
true
|
22
35
|
rescue LoadError
|
23
|
-
UI.info
|
36
|
+
UI.info 'Please install rb-fchange gem for Windows file events support'
|
24
37
|
false
|
25
38
|
end
|
26
39
|
|
27
|
-
|
28
|
-
|
29
|
-
def worker
|
30
|
-
@fchange
|
31
|
-
end
|
40
|
+
private
|
32
41
|
|
42
|
+
# Watch the given directory for file changes.
|
43
|
+
#
|
44
|
+
# @param [String] directory the directory to watch
|
45
|
+
#
|
33
46
|
def watch(directory)
|
34
47
|
worker.watch(directory, :all_events, :recursive) do |event|
|
35
48
|
paths = [File.expand_path(event.watcher.path)]
|
@@ -38,5 +51,11 @@ module Guard
|
|
38
51
|
end
|
39
52
|
end
|
40
53
|
|
54
|
+
# Get the listener worker.
|
55
|
+
#
|
56
|
+
def worker
|
57
|
+
@fchange
|
58
|
+
end
|
59
|
+
|
41
60
|
end
|
42
61
|
end
|
data/lib/guard/notifier.rb
CHANGED
@@ -3,13 +3,29 @@ require 'pathname'
|
|
3
3
|
require 'guard/ui'
|
4
4
|
|
5
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
|
+
#
|
6
13
|
module Notifier
|
14
|
+
|
15
|
+
# Application name as shown in the specific notification settings
|
7
16
|
APPLICATION_NAME = "Guard"
|
8
17
|
|
18
|
+
# Turn notifications off.
|
19
|
+
#
|
9
20
|
def self.turn_off
|
10
21
|
ENV["GUARD_NOTIFY"] = 'false'
|
11
22
|
end
|
12
23
|
|
24
|
+
# Turn notifications on. This tries to load the platform
|
25
|
+
# specific notification library.
|
26
|
+
#
|
27
|
+
# @return [Boolean] whether the notification could be enabled.
|
28
|
+
#
|
13
29
|
def self.turn_on
|
14
30
|
ENV["GUARD_NOTIFY"] = 'true'
|
15
31
|
case RbConfig::CONFIG['target_os']
|
@@ -22,6 +38,14 @@ module Guard
|
|
22
38
|
end
|
23
39
|
end
|
24
40
|
|
41
|
+
# Show a message with the system notification.
|
42
|
+
#
|
43
|
+
# @see .image_path
|
44
|
+
#
|
45
|
+
# @param [String] the message to show
|
46
|
+
# @option options [Symbol, String] image the image symbol or path to an image
|
47
|
+
# @option options [String] title the notification title
|
48
|
+
#
|
25
49
|
def self.notify(message, options = {})
|
26
50
|
if enabled?
|
27
51
|
image = options.delete(:image) || :success
|
@@ -38,13 +62,24 @@ module Guard
|
|
38
62
|
end
|
39
63
|
end
|
40
64
|
|
65
|
+
# Test if the notifications are enabled and available.
|
66
|
+
#
|
67
|
+
# @return [Boolean] whether the notifications are available
|
68
|
+
#
|
41
69
|
def self.enabled?
|
42
70
|
ENV["GUARD_NOTIFY"] == 'true'
|
43
71
|
end
|
44
72
|
|
45
73
|
private
|
46
74
|
|
47
|
-
|
75
|
+
# Send a message to Growl either with the `growl` gem or the `growl_notify` gem.
|
76
|
+
#
|
77
|
+
# @param [String] title the notification title
|
78
|
+
# @param [String] message the message to show
|
79
|
+
# @param [Symbol, String] the image to user
|
80
|
+
# @param [Hash] options the growl options
|
81
|
+
#
|
82
|
+
def self.notify_mac(title, message, image, options = {})
|
48
83
|
require_growl # need for guard-rspec formatter that is called out of guard scope
|
49
84
|
|
50
85
|
default_options = { :title => title, :icon => image_path(image), :name => APPLICATION_NAME }
|
@@ -61,18 +96,43 @@ module Guard
|
|
61
96
|
end
|
62
97
|
end
|
63
98
|
|
64
|
-
|
99
|
+
# Send a message to libnotify.
|
100
|
+
#
|
101
|
+
# @param [String] title the notification title
|
102
|
+
# @param [String] message the message to show
|
103
|
+
# @param [Symbol, String] the image to user
|
104
|
+
# @param [Hash] options the libnotify options
|
105
|
+
#
|
106
|
+
def self.notify_linux(title, message, image, options = {})
|
65
107
|
require_libnotify # need for guard-rspec formatter that is called out of guard scope
|
66
108
|
default_options = { :body => message, :summary => title, :icon_path => image_path(image), :transient => true }
|
67
109
|
Libnotify.show default_options.merge(options) if enabled?
|
68
110
|
end
|
69
111
|
|
70
|
-
|
112
|
+
# Send a message to notifu.
|
113
|
+
#
|
114
|
+
# @param [String] title the notification title
|
115
|
+
# @param [String] message the message to show
|
116
|
+
# @param [Symbol, String] the image to user
|
117
|
+
# @param [Hash] options the notifu options
|
118
|
+
#
|
119
|
+
def self.notify_windows(title, message, image, options = {})
|
71
120
|
require_rbnotifu # need for guard-rspec formatter that is called out of guard scope
|
72
121
|
default_options = { :message => message, :title => title, :type => image_level(image), :time => 3 }
|
73
122
|
Notifu.show default_options.merge(options) if enabled?
|
74
123
|
end
|
75
124
|
|
125
|
+
# Get the image path for an image symbol.
|
126
|
+
#
|
127
|
+
# Known symbols are:
|
128
|
+
#
|
129
|
+
# - failed
|
130
|
+
# - pending
|
131
|
+
# - success
|
132
|
+
#
|
133
|
+
# @param [Symbol] image the image name
|
134
|
+
# @return [String] the image path
|
135
|
+
#
|
76
136
|
def self.image_path(image)
|
77
137
|
images_path = Pathname.new(File.dirname(__FILE__)).join('../../images')
|
78
138
|
case image
|
@@ -88,6 +148,11 @@ module Guard
|
|
88
148
|
end
|
89
149
|
end
|
90
150
|
|
151
|
+
# The notification level type for the given image.
|
152
|
+
#
|
153
|
+
# @param [Symbol] image the image
|
154
|
+
# @return [Symbol] the level
|
155
|
+
#
|
91
156
|
def self.image_level(image)
|
92
157
|
case image
|
93
158
|
when :failed
|
@@ -101,6 +166,9 @@ module Guard
|
|
101
166
|
end
|
102
167
|
end
|
103
168
|
|
169
|
+
# Try to safely load growl and turns notifications
|
170
|
+
# off on load failure.
|
171
|
+
#
|
104
172
|
def self.require_growl
|
105
173
|
begin
|
106
174
|
require 'growl_notify'
|
@@ -119,6 +187,9 @@ module Guard
|
|
119
187
|
UI.info "Please install growl_notify or growl gem for Mac OS X notification support and add it to your Gemfile"
|
120
188
|
end
|
121
189
|
|
190
|
+
# Try to safely load libnotify and turns notifications
|
191
|
+
# off on load failure.
|
192
|
+
#
|
122
193
|
def self.require_libnotify
|
123
194
|
require 'libnotify'
|
124
195
|
rescue LoadError
|
@@ -126,11 +197,15 @@ module Guard
|
|
126
197
|
UI.info "Please install libnotify gem for Linux notification support and add it to your Gemfile"
|
127
198
|
end
|
128
199
|
|
200
|
+
# Try to safely load rb-notifu and turns notifications
|
201
|
+
# off on load failure.
|
202
|
+
#
|
129
203
|
def self.require_rbnotifu
|
130
204
|
require 'rb-notifu'
|
131
205
|
rescue LoadError
|
132
206
|
turn_off
|
133
207
|
UI.info "Please install rb-notifu gem for Windows notification support and add it to your Gemfile"
|
134
208
|
end
|
209
|
+
|
135
210
|
end
|
136
211
|
end
|
data/lib/guard/ui.rb
CHANGED
@@ -1,88 +1,88 @@
|
|
1
1
|
module Guard
|
2
|
-
module UI
|
3
|
-
|
4
|
-
ANSI_ESCAPE_BRIGHT = "1"
|
5
|
-
|
6
|
-
ANSI_ESCAPE_BLACK = "30"
|
7
|
-
ANSI_ESCAPE_RED = "31"
|
8
|
-
ANSI_ESCAPE_GREEN = "32"
|
9
|
-
ANSI_ESCAPE_YELLOW = "33"
|
10
|
-
ANSI_ESCAPE_BLUE = "34"
|
11
|
-
ANSI_ESCAPE_MAGENTA = "35"
|
12
|
-
ANSI_ESCAPE_CYAN = "36"
|
13
|
-
ANSI_ESCAPE_WHITE = "37"
|
14
|
-
|
15
|
-
ANSI_ESCAPE_BGBLACK = "40"
|
16
|
-
ANSI_ESCAPE_BGRED = "41"
|
17
|
-
ANSI_ESCAPE_BGGREEN = "42"
|
18
|
-
ANSI_ESCAPE_BGYELLOW = "43"
|
19
|
-
ANSI_ESCAPE_BGBLUE = "44"
|
20
|
-
ANSI_ESCAPE_BGMAGENTA = "45"
|
21
|
-
ANSI_ESCAPE_BGCYAN = "46"
|
22
|
-
ANSI_ESCAPE_BGWHITE = "47"
|
23
2
|
|
3
|
+
# The UI class helps to format messages for the user.
|
4
|
+
#
|
5
|
+
module UI
|
24
6
|
class << self
|
25
7
|
|
26
8
|
color_enabled = nil
|
27
9
|
|
28
|
-
|
29
|
-
|
10
|
+
# Show an info message.
|
11
|
+
#
|
12
|
+
# @param [String] message the message to show
|
13
|
+
# @option options [Boolean] reset whether to clean the output before
|
14
|
+
#
|
15
|
+
def info(message, options = { })
|
16
|
+
unless ENV['GUARD_ENV'] == 'test'
|
30
17
|
reset_line if options[:reset]
|
31
18
|
puts color(message) if message != ''
|
32
19
|
end
|
33
20
|
end
|
34
21
|
|
35
|
-
|
36
|
-
|
22
|
+
# Show a red error message that is prefixed with ERROR.
|
23
|
+
#
|
24
|
+
# @param [String] message the message to show
|
25
|
+
# @option options [Boolean] reset whether to clean the output before
|
26
|
+
#
|
27
|
+
def error(message, options = { })
|
28
|
+
unless ENV['GUARD_ENV'] == 'test'
|
37
29
|
reset_line if options[:reset]
|
38
30
|
puts color('ERROR: ', :red) + message
|
39
31
|
end
|
40
32
|
end
|
41
33
|
|
42
|
-
|
43
|
-
|
34
|
+
# Show a red deprecation message that is prefixed with DEPRECATION.
|
35
|
+
#
|
36
|
+
# @param [String] message the message to show
|
37
|
+
# @option options [Boolean] reset whether to clean the output before
|
38
|
+
#
|
39
|
+
def deprecation(message, options = { })
|
40
|
+
unless ENV['GUARD_ENV'] == 'test'
|
44
41
|
reset_line if options[:reset]
|
45
42
|
puts color('DEPRECATION: ', :red) + message
|
46
43
|
end
|
47
44
|
end
|
48
45
|
|
49
|
-
|
50
|
-
|
46
|
+
# Show a debug message that is prefixed with DEBUG and a timestamp.
|
47
|
+
#
|
48
|
+
# @param [String] message the message to show
|
49
|
+
# @option options [Boolean] reset whether to clean the output before
|
50
|
+
#
|
51
|
+
def debug(message, options = { })
|
52
|
+
unless ENV['GUARD_ENV'] == 'test'
|
51
53
|
reset_line if options[:reset]
|
52
54
|
puts color("DEBUG (#{Time.now.strftime('%T')}): ", :yellow) + message if ::Guard.options && ::Guard.options[:debug]
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
58
|
+
# Reset a line.
|
59
|
+
#
|
56
60
|
def reset_line
|
57
61
|
print(color_enabled? ? "\r\e[0m" : "\r\n")
|
58
62
|
end
|
59
63
|
|
64
|
+
# Clear the output.
|
65
|
+
#
|
60
66
|
def clear
|
61
|
-
system(
|
67
|
+
system('clear;')
|
62
68
|
end
|
63
69
|
|
64
|
-
|
70
|
+
private
|
65
71
|
|
72
|
+
# Reset a color sequence.
|
73
|
+
#
|
66
74
|
# @deprecated
|
75
|
+
# @param [String] text the text
|
76
|
+
#
|
67
77
|
def reset_color(text)
|
68
|
-
deprecation('UI.reset_color(text) is deprecated, please use color(text,
|
69
|
-
color(text,
|
70
|
-
end
|
71
|
-
|
72
|
-
def color(text, *color_options)
|
73
|
-
color_code = ""
|
74
|
-
color_options.each do |color_option|
|
75
|
-
color_option = color_option.to_s
|
76
|
-
if color_option != ""
|
77
|
-
if !(color_option =~ /\d+/)
|
78
|
-
color_option = const_get("ANSI_ESCAPE_#{color_option.upcase}")
|
79
|
-
end
|
80
|
-
color_code += ";" + color_option
|
81
|
-
end
|
82
|
-
end
|
83
|
-
color_enabled? ? "\e[0#{color_code}m#{text}\e[0m" : text
|
78
|
+
deprecation('UI.reset_color(text) is deprecated, please use color(text, ' ') instead.')
|
79
|
+
color(text, '')
|
84
80
|
end
|
85
81
|
|
82
|
+
# Checks if color output can be enabled.
|
83
|
+
#
|
84
|
+
# @return [Boolean] whether color is enabled or not
|
85
|
+
#
|
86
86
|
def color_enabled?
|
87
87
|
if @color_enabled.nil?
|
88
88
|
if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
|
@@ -102,9 +102,87 @@ module Guard
|
|
102
102
|
@color_enabled = true
|
103
103
|
end
|
104
104
|
end
|
105
|
+
|
105
106
|
@color_enabled
|
106
107
|
end
|
107
108
|
|
109
|
+
# Colorizes a text message. See the constant in the UI class for possible
|
110
|
+
# color_options parameters. You can pass optionally :bright, a foreground
|
111
|
+
# color and a background color.
|
112
|
+
#
|
113
|
+
# @example
|
114
|
+
#
|
115
|
+
# color('Hello World', :red, :bright)
|
116
|
+
#
|
117
|
+
# @param [String] the text to colorize
|
118
|
+
# @param [Array] color_options the color options
|
119
|
+
#
|
120
|
+
def color(text, *color_options)
|
121
|
+
color_code = ''
|
122
|
+
color_options.each do |color_option|
|
123
|
+
color_option = color_option.to_s
|
124
|
+
if color_option != ''
|
125
|
+
if !(color_option =~ /\d+/)
|
126
|
+
color_option = const_get("ANSI_ESCAPE_#{ color_option.upcase }")
|
127
|
+
end
|
128
|
+
color_code += ';' + color_option
|
129
|
+
end
|
130
|
+
end
|
131
|
+
color_enabled? ? "\e[0#{ color_code }m#{ text }\e[0m" : text
|
132
|
+
end
|
133
|
+
|
108
134
|
end
|
135
|
+
|
136
|
+
# Brighten the color
|
137
|
+
ANSI_ESCAPE_BRIGHT = '1'
|
138
|
+
|
139
|
+
# Black foreground color
|
140
|
+
ANSI_ESCAPE_BLACK = '30'
|
141
|
+
|
142
|
+
# Red foreground color
|
143
|
+
ANSI_ESCAPE_RED = '31'
|
144
|
+
|
145
|
+
# Green foreground color
|
146
|
+
ANSI_ESCAPE_GREEN = '32'
|
147
|
+
|
148
|
+
# Yellow foreground color
|
149
|
+
ANSI_ESCAPE_YELLOW = '33'
|
150
|
+
|
151
|
+
# Blue foreground color
|
152
|
+
ANSI_ESCAPE_BLUE = '34'
|
153
|
+
|
154
|
+
# Magenta foreground color
|
155
|
+
ANSI_ESCAPE_MAGENTA = '35'
|
156
|
+
|
157
|
+
# Cyan foreground color
|
158
|
+
ANSI_ESCAPE_CYAN = '36'
|
159
|
+
|
160
|
+
# White foreground color
|
161
|
+
ANSI_ESCAPE_WHITE = '37'
|
162
|
+
|
163
|
+
# Black background color
|
164
|
+
ANSI_ESCAPE_BGBLACK = '40'
|
165
|
+
|
166
|
+
# Red background color
|
167
|
+
ANSI_ESCAPE_BGRED = '41'
|
168
|
+
|
169
|
+
# Green background color
|
170
|
+
ANSI_ESCAPE_BGGREEN = '42'
|
171
|
+
|
172
|
+
# Yellow background color
|
173
|
+
ANSI_ESCAPE_BGYELLOW = '43'
|
174
|
+
|
175
|
+
# Blue background color
|
176
|
+
ANSI_ESCAPE_BGBLUE = '44'
|
177
|
+
|
178
|
+
# Magenta background color
|
179
|
+
ANSI_ESCAPE_BGMAGENTA = '45'
|
180
|
+
|
181
|
+
# Cyan background color
|
182
|
+
ANSI_ESCAPE_BGCYAN = '46'
|
183
|
+
|
184
|
+
# White background color
|
185
|
+
ANSI_ESCAPE_BGWHITE = '47'
|
186
|
+
|
109
187
|
end
|
110
188
|
end
|