guard 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|