do_snapshot 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/do_snapshot +2 -2
- data/lib/do_snapshot/adapter/abstract.rb +5 -5
- data/lib/do_snapshot/adapter/digitalocean.rb +8 -9
- data/lib/do_snapshot/adapter/digitalocean_v2.rb +10 -10
- data/lib/do_snapshot/cli.rb +41 -23
- data/lib/do_snapshot/command.rb +15 -16
- data/lib/do_snapshot/configuration.rb +19 -0
- data/lib/do_snapshot/helpers.rb +29 -0
- data/lib/do_snapshot/log.rb +47 -42
- data/lib/do_snapshot/mail.rb +58 -75
- data/lib/do_snapshot/runner.rb +59 -0
- data/lib/do_snapshot/version.rb +1 -1
- data/lib/do_snapshot.rb +37 -4
- data/spec/do_snapshot/adapter/abstract_spec.rb +0 -7
- data/spec/do_snapshot/adapter/digitalocean_spec.rb +7 -13
- data/spec/do_snapshot/adapter/digitalocean_v2_spec.rb +7 -13
- data/spec/do_snapshot/command_spec.rb +8 -8
- data/spec/do_snapshot/configuration_spec.rb +11 -0
- data/spec/do_snapshot/log_spec.rb +88 -0
- data/spec/do_snapshot/mail_spec.rb +18 -4
- data/spec/do_snapshot/runner_spec.rb +334 -0
- data/spec/{do_snapshots_spec.rb → do_snapshot_spec.rb} +4 -12
- data/spec/shared/api_v2_helpers.rb +2 -1
- data/spec/shared/environment.rb +41 -26
- data/spec/spec_helper.rb +3 -2
- data/spec/support/aruba.rb +7 -0
- data/spec/support/matchers.rb +17 -0
- metadata +17 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c4e8fd9920e0fb822c5f84dadf54aa6cf0a90b5
|
4
|
+
data.tar.gz: 26fa16b5c5e5a1ebb5d474e31467488fca1a3c07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8368fd230ea50254df7456a01a7e20199b8ee0d7a6937b7e036c11a8902206b7c0034f79ea7cb2f0b80d4621d48b6715c2f02b62b254e5bc01978fb54ae07b8a
|
7
|
+
data.tar.gz: 8139cdbee917477ecc0dea28a63c5d2fb07485e2f4f47781340959ba97fc94317b401c99f632685b8c37177cbaef35e585de39adad0818a5a4f0b12e996e1757
|
data/bin/do_snapshot
CHANGED
@@ -10,6 +10,6 @@ bin_file = Pathname.new(__FILE__).realpath
|
|
10
10
|
# add self to libpath
|
11
11
|
$LOAD_PATH.unshift File.expand_path('../../lib', bin_file)
|
12
12
|
|
13
|
-
require 'do_snapshot/
|
13
|
+
require 'do_snapshot/runner'
|
14
14
|
|
15
|
-
DoSnapshot::
|
15
|
+
DoSnapshot::Runner.new(ARGV.dup).execute!
|
@@ -6,7 +6,7 @@ module DoSnapshot
|
|
6
6
|
# Operating with Digital Ocean.
|
7
7
|
#
|
8
8
|
class Abstract
|
9
|
-
include DoSnapshot::
|
9
|
+
include DoSnapshot::Helpers
|
10
10
|
|
11
11
|
attr_accessor :delay, :timeout
|
12
12
|
|
@@ -26,18 +26,18 @@ module DoSnapshot
|
|
26
26
|
|
27
27
|
# Waiting for event exit
|
28
28
|
def wait_event(id)
|
29
|
-
|
29
|
+
logger.debug "Event Id: #{id}"
|
30
30
|
time = Time.now
|
31
31
|
sleep(delay) until get_event_status(id, time)
|
32
32
|
end
|
33
33
|
|
34
34
|
def after_cleanup(droplet_id, droplet_name, snapshot, event)
|
35
35
|
if !event
|
36
|
-
|
36
|
+
logger.error "Destroy of snapshot #{snapshot.name} for droplet id: #{droplet_id} name: #{droplet_name} is failed."
|
37
37
|
elsif event && !event.status.include?('OK')
|
38
|
-
|
38
|
+
logger.error event.message
|
39
39
|
else
|
40
|
-
|
40
|
+
logger.debug "Snapshot name: #{snapshot.name} delete requested."
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -36,7 +36,7 @@ module DoSnapshot
|
|
36
36
|
instance = droplet(id)
|
37
37
|
|
38
38
|
if instance.status.include? 'active'
|
39
|
-
|
39
|
+
logger.error 'Droplet is still running.'
|
40
40
|
else
|
41
41
|
power_on id
|
42
42
|
end
|
@@ -85,10 +85,9 @@ module DoSnapshot
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def check_keys
|
88
|
-
|
89
|
-
%w( DIGITAL_OCEAN_CLIENT_ID DIGITAL_OCEAN_API_KEY ).
|
90
|
-
|
91
|
-
end
|
88
|
+
logger.debug 'Checking DigitalOcean Id\'s.'
|
89
|
+
errors = %w( DIGITAL_OCEAN_CLIENT_ID DIGITAL_OCEAN_API_KEY ).map { |key| key if ENV[key].blank? }.compact
|
90
|
+
fail DoSnapshot::NoKeysError, "You must have #{errors.join(', ')} in environment or set it via options." if errors.size > 0
|
92
91
|
end
|
93
92
|
|
94
93
|
protected
|
@@ -96,7 +95,7 @@ module DoSnapshot
|
|
96
95
|
# Set id's of Digital Ocean API.
|
97
96
|
#
|
98
97
|
def set_id
|
99
|
-
|
98
|
+
logger.debug 'Setting DigitalOcean Id\'s.'
|
100
99
|
::DigitaloceanC.client_id = ENV['DIGITAL_OCEAN_CLIENT_ID']
|
101
100
|
::DigitaloceanC.api_key = ENV['DIGITAL_OCEAN_API_KEY']
|
102
101
|
end
|
@@ -115,7 +114,7 @@ module DoSnapshot
|
|
115
114
|
|
116
115
|
def timeout?(id, time)
|
117
116
|
return false unless (Time.now - time) > @timeout
|
118
|
-
|
117
|
+
logger.debug "Event #{id} finished by timeout #{time}"
|
119
118
|
true
|
120
119
|
end
|
121
120
|
|
@@ -126,9 +125,9 @@ module DoSnapshot
|
|
126
125
|
event = ::DigitaloceanC::Droplet.power_on(id)
|
127
126
|
case event && event.status
|
128
127
|
when 'OK'
|
129
|
-
|
128
|
+
logger.info 'Power On has been requested.'
|
130
129
|
else
|
131
|
-
|
130
|
+
logger.error 'Power On failed to request.'
|
132
131
|
end
|
133
132
|
end
|
134
133
|
end
|
@@ -42,7 +42,7 @@ module DoSnapshot
|
|
42
42
|
instance = droplet(id)
|
43
43
|
|
44
44
|
if instance.status && instance.status.include?('active')
|
45
|
-
|
45
|
+
logger.error 'Droplet is still running.'
|
46
46
|
else
|
47
47
|
power_on id
|
48
48
|
end
|
@@ -81,7 +81,7 @@ module DoSnapshot
|
|
81
81
|
event = client.images.delete(id: snapshot)
|
82
82
|
|
83
83
|
unless event.is_a?(TrueClass)
|
84
|
-
|
84
|
+
logger.debug event
|
85
85
|
event = false
|
86
86
|
end
|
87
87
|
|
@@ -90,16 +90,16 @@ module DoSnapshot
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def check_keys
|
93
|
-
|
93
|
+
logger.debug 'Checking DigitalOcean Access Token.'
|
94
94
|
%w( DIGITAL_OCEAN_ACCESS_TOKEN ).each do |key|
|
95
|
-
|
95
|
+
fail DoSnapshot::NoTokenError, "You must have #{key} in environment or set it via options." if ENV[key].blank?
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
# Set id's of Digital Ocean API.
|
100
100
|
#
|
101
101
|
def set_id
|
102
|
-
|
102
|
+
logger.debug 'Setting DigitalOcean Access Token.'
|
103
103
|
@client = ::DropletKit::Client.new(access_token: ENV['DIGITAL_OCEAN_ACCESS_TOKEN'])
|
104
104
|
end
|
105
105
|
|
@@ -107,9 +107,9 @@ module DoSnapshot
|
|
107
107
|
|
108
108
|
def after_cleanup(droplet_id, droplet_name, snapshot, event)
|
109
109
|
if !event
|
110
|
-
|
110
|
+
logger.error "Destroy of snapshot #{snapshot} for droplet id: #{droplet_id} name: #{droplet_name} is failed."
|
111
111
|
else
|
112
|
-
|
112
|
+
logger.debug "Snapshot: #{snapshot} delete requested."
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
@@ -118,7 +118,7 @@ module DoSnapshot
|
|
118
118
|
#
|
119
119
|
def get_event_status(id, time)
|
120
120
|
if (Time.now - time) > @timeout
|
121
|
-
|
121
|
+
logger.debug "Event #{id} finished by timeout #{time}"
|
122
122
|
return true
|
123
123
|
end
|
124
124
|
|
@@ -135,9 +135,9 @@ module DoSnapshot
|
|
135
135
|
# noinspection RubyResolve
|
136
136
|
event = client.droplet_actions.power_on(droplet_id: id)
|
137
137
|
if event.status.include?('in-progress')
|
138
|
-
|
138
|
+
logger.info 'Power On has been requested.'
|
139
139
|
else
|
140
|
-
|
140
|
+
logger.error 'Power On failed to request.'
|
141
141
|
end
|
142
142
|
end
|
143
143
|
end
|
data/lib/do_snapshot/cli.rb
CHANGED
@@ -3,14 +3,14 @@ require 'thor'
|
|
3
3
|
require 'do_snapshot'
|
4
4
|
require_relative 'log'
|
5
5
|
require_relative 'mail'
|
6
|
+
require_relative 'helpers'
|
6
7
|
require_relative 'command'
|
7
8
|
|
8
9
|
module DoSnapshot
|
9
10
|
# CLI is here
|
10
11
|
#
|
11
12
|
class CLI < Thor # rubocop:disable ClassLength
|
12
|
-
include DoSnapshot::
|
13
|
-
include DoSnapshot::Mail
|
13
|
+
include DoSnapshot::Helpers
|
14
14
|
|
15
15
|
default_task :snap
|
16
16
|
|
@@ -22,6 +22,7 @@ module DoSnapshot
|
|
22
22
|
def initialize(*args)
|
23
23
|
super
|
24
24
|
|
25
|
+
setup_config
|
25
26
|
set_logger
|
26
27
|
set_mailer
|
27
28
|
|
@@ -158,11 +159,11 @@ module DoSnapshot
|
|
158
159
|
|
159
160
|
def snap
|
160
161
|
command.snap
|
162
|
+
rescue DoSnapshot::NoTokenError, DoSnapshot::NoKeysError => e
|
163
|
+
error_simple(e)
|
161
164
|
rescue => e
|
162
165
|
command.fail_power_off(e) if [SnapshotCreateError, DropletShutdownError].include?(e.class)
|
163
|
-
|
164
|
-
backtrace(e) if options.include? 'trace'
|
165
|
-
send_error
|
166
|
+
error_with_backtrace(e)
|
166
167
|
end
|
167
168
|
|
168
169
|
desc 'version, -V', 'Shows the version of the currently installed DoSnapshot gem'
|
@@ -171,43 +172,60 @@ module DoSnapshot
|
|
171
172
|
end
|
172
173
|
|
173
174
|
no_commands do
|
175
|
+
def error_simple(e)
|
176
|
+
logger.error e.message
|
177
|
+
send_error
|
178
|
+
fail e
|
179
|
+
end
|
180
|
+
|
181
|
+
def error_with_backtrace(e)
|
182
|
+
logger.error e.message
|
183
|
+
backtrace(e) if options.include? 'trace'
|
184
|
+
send_error
|
185
|
+
fail e
|
186
|
+
end
|
187
|
+
|
174
188
|
def command
|
175
|
-
@command ||= Command.new(options,
|
176
|
-
%w( log smtp mail trace digital_ocean_client_id digital_ocean_api_key digital_ocean_access_token ))
|
189
|
+
@command ||= Command.new(options, command_filter)
|
177
190
|
end
|
178
191
|
|
179
192
|
def update_command
|
180
|
-
command.load_options(options,
|
181
|
-
|
193
|
+
command.load_options(options, command_filter)
|
194
|
+
end
|
195
|
+
|
196
|
+
def command_filter
|
197
|
+
%w( log smtp mail trace digital_ocean_client_id digital_ocean_api_key digital_ocean_access_token )
|
198
|
+
end
|
199
|
+
|
200
|
+
def setup_config # rubocop:disable Metrics/AbcSize
|
201
|
+
DoSnapshot.configure do |config|
|
202
|
+
config.logger = ::Logger.new(options['log']) if options['log']
|
203
|
+
config.logger_level = Logger::DEBUG if config.verbose
|
204
|
+
config.verbose = options['trace']
|
205
|
+
config.quiet = options['quiet']
|
206
|
+
config.mailer = Mail.new(opts: options['mail'], smtp: options['smtp'])
|
207
|
+
end
|
182
208
|
end
|
183
209
|
|
184
210
|
def set_mailer
|
185
|
-
|
211
|
+
DoSnapshot.mailer = DoSnapshot.config.mailer
|
186
212
|
end
|
187
213
|
|
188
214
|
def send_error
|
189
|
-
return unless mailer.opts
|
215
|
+
return unless DoSnapshot.mailer.opts
|
190
216
|
|
191
|
-
|
192
|
-
|
217
|
+
DoSnapshot.mailer.opts[:subject] = 'Digital Ocean: Error.'
|
218
|
+
DoSnapshot.mailer.opts[:body] = 'Please check your droplets.'
|
193
219
|
mailer.notify
|
194
220
|
end
|
195
221
|
|
196
222
|
def set_logger
|
197
|
-
Log.
|
198
|
-
# Use Thor shell
|
199
|
-
Log.shell = shell unless options['quiet']
|
200
|
-
init_logger if options.include?('log')
|
201
|
-
end
|
202
|
-
|
203
|
-
def init_logger
|
204
|
-
Log.logger = Logger.new(options['log'])
|
205
|
-
Log.logger.level = Log.verbose ? Logger::DEBUG : Logger::INFO
|
223
|
+
DoSnapshot.logger = Log.new(shell: shell)
|
206
224
|
end
|
207
225
|
|
208
226
|
def backtrace(e)
|
209
227
|
e.backtrace.each do |t|
|
210
|
-
|
228
|
+
logger.error t
|
211
229
|
end
|
212
230
|
end
|
213
231
|
end
|
data/lib/do_snapshot/command.rb
CHANGED
@@ -5,19 +5,18 @@ module DoSnapshot
|
|
5
5
|
# Our commands live here :)
|
6
6
|
#
|
7
7
|
class Command # rubocop:disable ClassLength
|
8
|
-
include DoSnapshot::
|
9
|
-
include DoSnapshot::Mail
|
8
|
+
include DoSnapshot::Helpers
|
10
9
|
|
11
10
|
def initialize(*args)
|
12
11
|
load_options(*args)
|
13
12
|
end
|
14
13
|
|
15
14
|
def snap
|
16
|
-
|
15
|
+
logger.info 'Start performing operations'
|
17
16
|
work_with_droplets
|
18
|
-
|
17
|
+
logger.info 'All operations has been finished.'
|
19
18
|
|
20
|
-
mailer.notify if notify && !quiet
|
19
|
+
mailer.notify if mailer && notify && !quiet
|
21
20
|
end
|
22
21
|
|
23
22
|
def fail_power_off(e)
|
@@ -41,28 +40,28 @@ module DoSnapshot
|
|
41
40
|
end
|
42
41
|
|
43
42
|
def stop_droplet(droplet)
|
44
|
-
|
43
|
+
logger.debug 'Shutting down droplet.'
|
45
44
|
api.stop_droplet(droplet.id) unless droplet.status.include? 'off'
|
46
45
|
end
|
47
46
|
|
48
47
|
# Trying to create a snapshot.
|
49
48
|
#
|
50
49
|
def create_snapshot(droplet) # rubocop:disable MethodLength,Metrics/AbcSize
|
51
|
-
|
50
|
+
logger.info "Start creating snapshot for droplet id: #{droplet.id} name: #{droplet.name}."
|
52
51
|
|
53
52
|
today = DateTime.now
|
54
53
|
name = "#{droplet.name}_#{today.strftime('%Y_%m_%d')}"
|
55
54
|
# noinspection RubyResolve
|
56
55
|
snapshot_size = api.snapshots(droplet).size
|
57
56
|
|
58
|
-
|
57
|
+
logger.debug 'Wait until snapshot will be created.'
|
59
58
|
|
60
59
|
api.create_snapshot droplet.id, name
|
61
60
|
|
62
61
|
snapshot_size += 1
|
63
62
|
|
64
|
-
|
65
|
-
|
63
|
+
logger.info "Snapshot name: #{name} created successfully."
|
64
|
+
logger.info "Droplet id: #{droplet.id} name: #{droplet.name} snapshots: #{snapshot_size}."
|
66
65
|
|
67
66
|
# Cleanup snapshots.
|
68
67
|
cleanup_snapshots droplet, snapshot_size if clean
|
@@ -99,7 +98,7 @@ module DoSnapshot
|
|
99
98
|
def work_with_droplets
|
100
99
|
load_droplets
|
101
100
|
dispatch_droplets
|
102
|
-
|
101
|
+
logger.debug 'Working with list of DigitalOcean droplets'
|
103
102
|
thread_chain
|
104
103
|
end
|
105
104
|
|
@@ -107,7 +106,7 @@ module DoSnapshot
|
|
107
106
|
# And store into object.
|
108
107
|
#
|
109
108
|
def load_droplets
|
110
|
-
|
109
|
+
logger.debug 'Loading list of DigitalOcean droplets'
|
111
110
|
self.droplets = api.droplets
|
112
111
|
end
|
113
112
|
|
@@ -142,11 +141,11 @@ module DoSnapshot
|
|
142
141
|
# Droplet instance must be powered off first!
|
143
142
|
#
|
144
143
|
def prepare_droplet(id, name)
|
145
|
-
|
144
|
+
logger.debug "Droplet id: #{id} name: #{name} "
|
146
145
|
droplet = api.droplet id
|
147
146
|
|
148
147
|
return unless droplet
|
149
|
-
|
148
|
+
logger.info "Preparing droplet id: #{droplet.id} name: #{droplet.name} to take snapshot."
|
150
149
|
return if too_much_snapshots(droplet)
|
151
150
|
thread_runner(droplet)
|
152
151
|
end
|
@@ -165,7 +164,7 @@ module DoSnapshot
|
|
165
164
|
|
166
165
|
warning_size(droplet.id, droplet.name, size)
|
167
166
|
|
168
|
-
|
167
|
+
logger.debug "Cleaning up snapshots for droplet id: #{droplet.id} name: #{droplet.name}."
|
169
168
|
|
170
169
|
api.cleanup_snapshots(droplet, size - keep - 1)
|
171
170
|
rescue => e
|
@@ -176,7 +175,7 @@ module DoSnapshot
|
|
176
175
|
#
|
177
176
|
def warning_size(id, name, keep)
|
178
177
|
message = "For droplet with id: #{id} and name: #{name} the maximum number #{keep} of snapshots is reached."
|
179
|
-
|
178
|
+
logger.warn message
|
180
179
|
@notify = true
|
181
180
|
end
|
182
181
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DoSnapshot
|
2
|
+
# Configuration class. Used to share config across application.
|
3
|
+
#
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :logger
|
6
|
+
attr_accessor :logger_level
|
7
|
+
attr_accessor :verbose
|
8
|
+
attr_accessor :quiet
|
9
|
+
attr_accessor :mailer
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@logger = nil
|
13
|
+
@logger_level = Logger::INFO
|
14
|
+
@verbose = false
|
15
|
+
@quiet = false
|
16
|
+
@mailer = nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'log'
|
2
|
+
require_relative 'mail'
|
3
|
+
|
4
|
+
module DoSnapshot
|
5
|
+
# Helpers for main class.
|
6
|
+
#
|
7
|
+
module Helpers
|
8
|
+
def logger
|
9
|
+
UniversalLogger
|
10
|
+
end
|
11
|
+
|
12
|
+
# UniversalLogger is a module to deal with singleton methods.
|
13
|
+
# Used to give classes access only for selected methods
|
14
|
+
#
|
15
|
+
module UniversalLogger
|
16
|
+
%w(debug info warn error fatal unknown).each do |name|
|
17
|
+
define_singleton_method(:"#{name}") { |*args, &block| DoSnapshot.logger.send(:"#{name}", *args, &block) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.close
|
21
|
+
DoSnapshot.logger.close
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def mailer
|
26
|
+
DoSnapshot.mailer
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/do_snapshot/log.rb
CHANGED
@@ -4,60 +4,65 @@ require 'logger'
|
|
4
4
|
module DoSnapshot
|
5
5
|
# Shared logger
|
6
6
|
#
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
class Log
|
8
|
+
attr_reader :shell
|
9
|
+
attr_accessor :quiet, :verbose
|
10
|
+
attr_writer :buffer, :instance
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@verbose = DoSnapshot.config.verbose
|
14
|
+
@quiet = DoSnapshot.config.quiet
|
15
|
+
options.each { |key, option| instance_variable_set(:"@#{key}", option) }
|
16
|
+
instance.level = DoSnapshot.config.logger_level if instance
|
10
17
|
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
module UniversalLogger
|
16
|
-
%i(info warn error debug).each do |type|
|
17
|
-
define_singleton_method(type) { |message| Log.log type, message }
|
18
|
-
end
|
19
|
+
def instance
|
20
|
+
@instance ||= DoSnapshot.config.logger
|
19
21
|
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
def buffer
|
24
|
+
@buffer ||= %w()
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def shell=(shell)
|
28
|
+
@shell = shell unless quiet
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def close
|
32
|
+
instance.close if instance
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
%w(debug info warn error fatal unknown).each_with_index do |name, severity|
|
36
|
+
define_method(:"#{name}") { |*args, &block| log severity, *args, &block }
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
+
def log(severity, message = nil, progname = nil, &block)
|
40
|
+
buffer << message
|
41
|
+
instance.add(severity, message, progname, &block) if instance
|
39
42
|
|
40
|
-
|
43
|
+
say message, color(severity) unless print?(severity)
|
44
|
+
end
|
41
45
|
|
42
|
-
|
43
|
-
(type == :debug && !verbose) || quiet
|
44
|
-
end
|
46
|
+
protected
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
def print?(type)
|
49
|
+
(type == :debug && !verbose) || quiet
|
50
|
+
end
|
51
|
+
|
52
|
+
def say(message, color)
|
53
|
+
shell.say message, color if shell
|
54
|
+
end
|
49
55
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
56
|
+
def color(severity)
|
57
|
+
case severity
|
58
|
+
when 0
|
59
|
+
:white
|
60
|
+
when 3
|
61
|
+
:red
|
62
|
+
when 2
|
63
|
+
:yellow
|
64
|
+
else
|
65
|
+
:green
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|