do_snapshot 0.2.2 → 0.3.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.
- 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
|