backup 4.4.1 → 5.0.0.beta.1

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.
Files changed (80) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +19 -0
  3. data/README.md +1 -1
  4. data/lib/backup.rb +74 -78
  5. data/lib/backup/archive.rb +31 -32
  6. data/lib/backup/binder.rb +2 -6
  7. data/lib/backup/cleaner.rb +14 -18
  8. data/lib/backup/cli.rb +104 -108
  9. data/lib/backup/cloud_io/base.rb +4 -7
  10. data/lib/backup/cloud_io/cloud_files.rb +60 -62
  11. data/lib/backup/cloud_io/s3.rb +69 -76
  12. data/lib/backup/compressor/base.rb +4 -7
  13. data/lib/backup/compressor/bzip2.rb +3 -7
  14. data/lib/backup/compressor/custom.rb +2 -6
  15. data/lib/backup/compressor/gzip.rb +16 -17
  16. data/lib/backup/config.rb +17 -18
  17. data/lib/backup/config/dsl.rb +16 -17
  18. data/lib/backup/config/helpers.rb +10 -16
  19. data/lib/backup/database/base.rb +22 -21
  20. data/lib/backup/database/mongodb.rb +36 -37
  21. data/lib/backup/database/mysql.rb +40 -41
  22. data/lib/backup/database/openldap.rb +8 -10
  23. data/lib/backup/database/postgresql.rb +29 -30
  24. data/lib/backup/database/redis.rb +27 -30
  25. data/lib/backup/database/riak.rb +15 -18
  26. data/lib/backup/database/sqlite.rb +4 -6
  27. data/lib/backup/encryptor/base.rb +2 -4
  28. data/lib/backup/encryptor/gpg.rb +49 -59
  29. data/lib/backup/encryptor/open_ssl.rb +11 -14
  30. data/lib/backup/errors.rb +7 -12
  31. data/lib/backup/logger.rb +16 -18
  32. data/lib/backup/logger/console.rb +5 -8
  33. data/lib/backup/logger/fog_adapter.rb +2 -6
  34. data/lib/backup/logger/logfile.rb +10 -12
  35. data/lib/backup/logger/syslog.rb +2 -4
  36. data/lib/backup/model.rb +75 -40
  37. data/lib/backup/notifier/base.rb +24 -26
  38. data/lib/backup/notifier/campfire.rb +9 -11
  39. data/lib/backup/notifier/command.rb +0 -3
  40. data/lib/backup/notifier/datadog.rb +9 -12
  41. data/lib/backup/notifier/flowdock.rb +13 -17
  42. data/lib/backup/notifier/hipchat.rb +11 -13
  43. data/lib/backup/notifier/http_post.rb +11 -14
  44. data/lib/backup/notifier/mail.rb +44 -47
  45. data/lib/backup/notifier/nagios.rb +5 -9
  46. data/lib/backup/notifier/pagerduty.rb +10 -12
  47. data/lib/backup/notifier/prowl.rb +15 -15
  48. data/lib/backup/notifier/pushover.rb +7 -10
  49. data/lib/backup/notifier/ses.rb +34 -16
  50. data/lib/backup/notifier/slack.rb +39 -40
  51. data/lib/backup/notifier/twitter.rb +2 -5
  52. data/lib/backup/notifier/zabbix.rb +11 -14
  53. data/lib/backup/package.rb +5 -9
  54. data/lib/backup/packager.rb +16 -17
  55. data/lib/backup/pipeline.rb +17 -21
  56. data/lib/backup/splitter.rb +8 -11
  57. data/lib/backup/storage/base.rb +5 -8
  58. data/lib/backup/storage/cloud_files.rb +21 -23
  59. data/lib/backup/storage/cycler.rb +10 -15
  60. data/lib/backup/storage/dropbox.rb +15 -21
  61. data/lib/backup/storage/ftp.rb +8 -10
  62. data/lib/backup/storage/local.rb +5 -8
  63. data/lib/backup/storage/qiniu.rb +8 -8
  64. data/lib/backup/storage/rsync.rb +24 -26
  65. data/lib/backup/storage/s3.rb +27 -28
  66. data/lib/backup/storage/scp.rb +10 -12
  67. data/lib/backup/storage/sftp.rb +10 -12
  68. data/lib/backup/syncer/base.rb +5 -8
  69. data/lib/backup/syncer/cloud/base.rb +27 -30
  70. data/lib/backup/syncer/cloud/cloud_files.rb +16 -18
  71. data/lib/backup/syncer/cloud/local_file.rb +5 -8
  72. data/lib/backup/syncer/cloud/s3.rb +23 -24
  73. data/lib/backup/syncer/rsync/base.rb +6 -10
  74. data/lib/backup/syncer/rsync/local.rb +1 -5
  75. data/lib/backup/syncer/rsync/pull.rb +6 -10
  76. data/lib/backup/syncer/rsync/push.rb +18 -22
  77. data/lib/backup/template.rb +9 -14
  78. data/lib/backup/utilities.rb +82 -69
  79. data/lib/backup/version.rb +1 -3
  80. metadata +100 -660
@@ -1,9 +1,8 @@
1
- # encoding: utf-8
2
- require 'backup/cloud_io/base'
3
- require 'fog'
4
- require 'digest/md5'
5
- require 'base64'
6
- require 'stringio'
1
+ require "backup/cloud_io/base"
2
+ require "fog"
3
+ require "digest/md5"
4
+ require "base64"
5
+ require "stringio"
7
6
 
8
7
  module Backup
9
8
  module CloudIO
@@ -14,8 +13,8 @@ module Backup
14
13
  MAX_MULTIPART_SIZE = 1024**4 * 5 # 5 TiB
15
14
 
16
15
  attr_reader :access_key_id, :secret_access_key, :use_iam_profile,
17
- :region, :bucket, :chunk_size, :encryption, :storage_class,
18
- :fog_options
16
+ :region, :bucket, :chunk_size, :encryption, :storage_class,
17
+ :fog_options
19
18
 
20
19
  def initialize(options = {})
21
20
  super
@@ -39,9 +38,9 @@ module Backup
39
38
  if chunk_bytes > 0 && file_size > chunk_bytes
40
39
  raise FileSizeError, <<-EOS if file_size > MAX_MULTIPART_SIZE
41
40
  File Too Large
42
- File: #{ src }
43
- Size: #{ file_size }
44
- Max Multipart Upload Size is #{ MAX_MULTIPART_SIZE } (5 TiB)
41
+ File: #{src}
42
+ Size: #{file_size}
43
+ Max Multipart Upload Size is #{MAX_MULTIPART_SIZE} (5 TiB)
45
44
  EOS
46
45
 
47
46
  chunk_bytes = adjusted_chunk_bytes(chunk_bytes, file_size)
@@ -51,9 +50,9 @@ module Backup
51
50
  else
52
51
  raise FileSizeError, <<-EOS if file_size > MAX_FILE_SIZE
53
52
  File Too Large
54
- File: #{ src }
55
- Size: #{ file_size }
56
- Max File Size is #{ MAX_FILE_SIZE } (5 GiB)
53
+ File: #{src}
54
+ Size: #{file_size}
55
+ Max File Size is #{MAX_FILE_SIZE} (5 GiB)
57
56
  EOS
58
57
 
59
58
  put_object(src, dest)
@@ -68,15 +67,15 @@ module Backup
68
67
  def objects(prefix)
69
68
  objects = []
70
69
  resp = nil
71
- prefix = prefix.chomp('/')
72
- opts = { 'prefix' => prefix + '/' }
70
+ prefix = prefix.chomp("/")
71
+ opts = { "prefix" => prefix + "/" }
73
72
 
74
- while resp.nil? || resp.body['IsTruncated']
75
- opts.merge!('marker' => objects.last.key) unless objects.empty?
76
- with_retries("GET '#{ bucket }/#{ prefix }/*'") do
73
+ while resp.nil? || resp.body["IsTruncated"]
74
+ opts["marker"] = objects.last.key unless objects.empty?
75
+ with_retries("GET '#{bucket}/#{prefix}/*'") do
77
76
  resp = connection.get_bucket(bucket, opts)
78
77
  end
79
- resp.body['Contents'].each do |obj_data|
78
+ resp.body["Contents"].each do |obj_data|
80
79
  objects << Object.new(self, obj_data)
81
80
  end
82
81
  end
@@ -87,7 +86,7 @@ module Backup
87
86
  # Used by Object to fetch metadata if needed.
88
87
  def head_object(object)
89
88
  resp = nil
90
- with_retries("HEAD '#{ bucket }/#{ object.key }'") do
89
+ with_retries("HEAD '#{bucket}/#{object.key}'") do
91
90
  resp = connection.head_object(bucket, object.key)
92
91
  end
93
92
  resp
@@ -102,18 +101,18 @@ module Backup
102
101
  keys = Array(objects_or_keys).dup
103
102
  keys.map!(&:key) if keys.first.is_a?(Object)
104
103
 
105
- opts = { :quiet => true } # only report Errors in DeleteResult
104
+ opts = { quiet: true } # only report Errors in DeleteResult
106
105
  until keys.empty?
107
- _keys = keys.slice!(0, 1000)
108
- with_retries('DELETE Multiple Objects') do
109
- resp = connection.delete_multiple_objects(bucket, _keys, opts.dup)
110
- unless resp.body['DeleteResult'].empty?
111
- errors = resp.body['DeleteResult'].map do |result|
112
- error = result['Error']
113
- "Failed to delete: #{ error['Key'] }\n" +
114
- "Reason: #{ error['Code'] }: #{ error['Message'] }"
106
+ keys_partial = keys.slice!(0, 1000)
107
+ with_retries("DELETE Multiple Objects") do
108
+ resp = connection.delete_multiple_objects(bucket, keys_partial, opts.dup)
109
+ unless resp.body["DeleteResult"].empty?
110
+ errors = resp.body["DeleteResult"].map do |result|
111
+ error = result["Error"]
112
+ "Failed to delete: #{error["Key"]}\n" \
113
+ "Reason: #{error["Code"]}: #{error["Message"]}"
115
114
  end.join("\n")
116
- raise Error, "The server returned the following:\n#{ errors }"
115
+ raise Error, "The server returned the following:\n#{errors}"
117
116
  end
118
117
  end
119
118
  end
@@ -122,41 +121,40 @@ module Backup
122
121
  private
123
122
 
124
123
  def connection
125
- @connection ||= begin
126
- opts = { :provider => 'AWS', :region => region }
127
- if use_iam_profile
128
- opts.merge!(:use_iam_profile => true)
129
- else
130
- opts.merge!(
131
- :aws_access_key_id => access_key_id,
132
- :aws_secret_access_key => secret_access_key
133
- )
124
+ @connection ||=
125
+ begin
126
+ opts = { provider: "AWS", region: region }
127
+ if use_iam_profile
128
+ opts[:use_iam_profile] = true
129
+ else
130
+ opts[:aws_access_key_id] = access_key_id
131
+ opts[:aws_secret_access_key] = secret_access_key
132
+ end
133
+ opts.merge!(fog_options || {})
134
+ conn = Fog::Storage.new(opts)
135
+ conn.sync_clock
136
+ conn
134
137
  end
135
- opts.merge!(fog_options || {})
136
- conn = Fog::Storage.new(opts)
137
- conn.sync_clock
138
- conn
139
- end
140
138
  end
141
139
 
142
140
  def put_object(src, dest)
143
141
  md5 = Base64.encode64(Digest::MD5.file(src).digest).chomp
144
- options = headers.merge('Content-MD5' => md5)
145
- with_retries("PUT '#{ bucket }/#{ dest }'") do
146
- File.open(src, 'r') do |file|
142
+ options = headers.merge("Content-MD5" => md5)
143
+ with_retries("PUT '#{bucket}/#{dest}'") do
144
+ File.open(src, "r") do |file|
147
145
  connection.put_object(bucket, dest, file, options)
148
146
  end
149
147
  end
150
148
  end
151
149
 
152
150
  def initiate_multipart(dest)
153
- Logger.info "\s\sInitiate Multipart '#{ bucket }/#{ dest }'"
151
+ Logger.info "\s\sInitiate Multipart '#{bucket}/#{dest}'"
154
152
 
155
153
  resp = nil
156
- with_retries("POST '#{ bucket }/#{ dest }' (Initiate)") do
154
+ with_retries("POST '#{bucket}/#{dest}' (Initiate)") do
157
155
  resp = connection.initiate_multipart_upload(bucket, dest, headers)
158
156
  end
159
- resp.body['UploadId']
157
+ resp.body["UploadId"]
160
158
  end
161
159
 
162
160
  # Each part's MD5 is sent to verify the transfer.
@@ -164,26 +162,26 @@ module Backup
164
162
  # once the multipart upload is completed.
165
163
  def upload_parts(src, dest, upload_id, chunk_bytes, file_size)
166
164
  total_parts = (file_size / chunk_bytes.to_f).ceil
167
- progress = (0.1..0.9).step(0.1).map {|n| (total_parts * n).floor }
168
- Logger.info "\s\sUploading #{ total_parts } Parts..."
165
+ progress = (0.1..0.9).step(0.1).map { |n| (total_parts * n).floor }
166
+ Logger.info "\s\sUploading #{total_parts} Parts..."
169
167
 
170
168
  parts = []
171
- File.open(src, 'r') do |file|
169
+ File.open(src, "r") do |file|
172
170
  part_number = 0
173
171
  while data = file.read(chunk_bytes)
174
172
  part_number += 1
175
173
  md5 = Base64.encode64(Digest::MD5.digest(data)).chomp
176
174
 
177
- with_retries("PUT '#{ bucket }/#{ dest }' Part ##{ part_number }") do
175
+ with_retries("PUT '#{bucket}/#{dest}' Part ##{part_number}") do
178
176
  resp = connection.upload_part(
179
177
  bucket, dest, upload_id, part_number, StringIO.new(data),
180
- { 'Content-MD5' => md5 }
178
+ "Content-MD5" => md5
181
179
  )
182
- parts << resp.headers['ETag']
180
+ parts << resp.headers["ETag"]
183
181
  end
184
182
 
185
183
  if i = progress.rindex(part_number)
186
- Logger.info "\s\s...#{ i + 1 }0% Complete..."
184
+ Logger.info "\s\s...#{i + 1}0% Complete..."
187
185
  end
188
186
  end
189
187
  end
@@ -191,13 +189,13 @@ module Backup
191
189
  end
192
190
 
193
191
  def complete_multipart(dest, upload_id, parts)
194
- Logger.info "\s\sComplete Multipart '#{ bucket }/#{ dest }'"
192
+ Logger.info "\s\sComplete Multipart '#{bucket}/#{dest}'"
195
193
 
196
- with_retries("POST '#{ bucket }/#{ dest }' (Complete)") do
194
+ with_retries("POST '#{bucket}/#{dest}' (Complete)") do
197
195
  resp = connection.complete_multipart_upload(bucket, dest, upload_id, parts)
198
- raise Error, <<-EOS if resp.body['Code']
196
+ raise Error, <<-EOS if resp.body["Code"]
199
197
  The server returned the following error:
200
- #{ resp.body['Code'] }: #{ resp.body['Message'] }
198
+ #{resp.body["Code"]}: #{resp.body["Message"]}
201
199
  EOS
202
200
  end
203
201
  end
@@ -206,14 +204,10 @@ module Backup
206
204
  headers = {}
207
205
 
208
206
  enc = encryption.to_s.upcase
209
- headers.merge!(
210
- { 'x-amz-server-side-encryption' => enc}
211
- ) unless enc.empty?
207
+ headers["x-amz-server-side-encryption"] = enc unless enc.empty?
212
208
 
213
209
  sc = storage_class.to_s.upcase
214
- headers.merge!(
215
- { 'x-amz-storage-class' => sc }
216
- ) unless sc.empty? || sc == 'STANDARD'
210
+ headers["x-amz-storage-class"] = sc unless sc.empty? || sc == "STANDARD"
217
211
 
218
212
  headers
219
213
  end
@@ -225,10 +219,10 @@ module Backup
225
219
  mb += 1 until file_size / (1024**2 * mb).to_f <= 10_000
226
220
  Logger.warn Error.new(<<-EOS)
227
221
  Chunk Size Adjusted
228
- Your original #chunk_size of #{ orig_mb } MiB has been adjusted
229
- to #{ mb } MiB in order to satisfy the limit of 10,000 chunks.
222
+ Your original #chunk_size of #{orig_mb} MiB has been adjusted
223
+ to #{mb} MiB in order to satisfy the limit of 10,000 chunks.
230
224
  To enforce your chosen #chunk_size, you should use the Splitter.
231
- e.g. split_into_chunks_of #{ mb * 10_000 } (#chunk_size * 10_000)
225
+ e.g. split_into_chunks_of #{mb * 10_000} (#chunk_size * 10_000)
232
226
  EOS
233
227
  1024**2 * mb
234
228
  end
@@ -238,14 +232,14 @@ module Backup
238
232
 
239
233
  def initialize(cloud_io, data)
240
234
  @cloud_io = cloud_io
241
- @key = data['Key']
242
- @etag = data['ETag']
243
- @storage_class = data['StorageClass']
235
+ @key = data["Key"]
236
+ @etag = data["ETag"]
237
+ @storage_class = data["StorageClass"]
244
238
  end
245
239
 
246
240
  # currently 'AES256' or nil
247
241
  def encryption
248
- metadata['x-amz-server-side-encryption']
242
+ metadata["x-amz-server-side-encryption"]
249
243
  end
250
244
 
251
245
  private
@@ -254,7 +248,6 @@ module Backup
254
248
  @metadata ||= @cloud_io.head_object(self).headers
255
249
  end
256
250
  end
257
-
258
251
  end
259
252
  end
260
253
  end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Backup
4
2
  module Compressor
5
3
  class Base
@@ -18,18 +16,17 @@ module Backup
18
16
  ##
19
17
  # Return the compressor name, with Backup namespace removed
20
18
  def compressor_name
21
- self.class.to_s.sub('Backup::', '')
19
+ self.class.to_s.sub("Backup::", "")
22
20
  end
23
21
 
24
22
  ##
25
23
  # Logs a message to the console and log file to inform
26
24
  # the client that Backup is using the compressor
27
25
  def log!
28
- Logger.info "Using #{ compressor_name } for compression.\n" +
29
- " Command: '#{ @cmd }'\n" +
30
- " Ext: '#{ @ext }'"
26
+ Logger.info "Using #{compressor_name} for compression.\n" \
27
+ " Command: '#{@cmd}'\n" \
28
+ " Ext: '#{@ext}'"
31
29
  end
32
-
33
30
  end
34
31
  end
35
32
  end
@@ -1,9 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  module Backup
4
2
  module Compressor
5
3
  class Bzip2 < Base
6
-
7
4
  ##
8
5
  # Specify the level of compression to use.
9
6
  #
@@ -24,16 +21,15 @@ module Backup
24
21
 
25
22
  instance_eval(&block) if block_given?
26
23
 
27
- @cmd = "#{ utility(:bzip2) }#{ options }"
28
- @ext = '.bz2'
24
+ @cmd = "#{utility(:bzip2)}#{options}"
25
+ @ext = ".bz2"
29
26
  end
30
27
 
31
28
  private
32
29
 
33
30
  def options
34
- " -#{ @level }" if @level
31
+ " -#{@level}" if @level
35
32
  end
36
-
37
33
  end
38
34
  end
39
35
  end
@@ -1,9 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  module Backup
4
2
  module Compressor
5
3
  class Custom < Base
6
-
7
4
  ##
8
5
  # Specify the system command to invoke a compressor,
9
6
  # including any command-line arguments.
@@ -36,9 +33,9 @@ module Backup
36
33
  # Return the command line using the full path.
37
34
  # Ensures the command exists and is executable.
38
35
  def set_cmd
39
- parts = @command.to_s.split(' ')
36
+ parts = @command.to_s.split(" ")
40
37
  parts[0] = utility(parts[0])
41
- parts.join(' ')
38
+ parts.join(" ")
42
39
  end
43
40
 
44
41
  ##
@@ -47,7 +44,6 @@ module Backup
47
44
  def set_ext
48
45
  @extension.to_s.strip
49
46
  end
50
-
51
47
  end
52
48
  end
53
49
  end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Backup
4
2
  module Compressor
5
3
  class Gzip < Base
@@ -35,8 +33,8 @@ module Backup
35
33
  # Determine if +--rsyncable+ is supported and cache the result.
36
34
  def self.has_rsyncable?
37
35
  return @has_rsyncable unless @has_rsyncable.nil?
38
- cmd = "#{ utility(:gzip) } --rsyncable --version >/dev/null 2>&1; echo $?"
39
- @has_rsyncable = %x[#{ cmd }].chomp == '0'
36
+ cmd = "#{utility(:gzip)} --rsyncable --version >/dev/null 2>&1; echo $?"
37
+ @has_rsyncable = `#{cmd}`.chomp == "0"
40
38
  end
41
39
 
42
40
  ##
@@ -49,26 +47,27 @@ module Backup
49
47
 
50
48
  instance_eval(&block) if block_given?
51
49
 
52
- @cmd = "#{ utility(:gzip) }#{ options }"
53
- @ext = '.gz'
50
+ @cmd = "#{utility(:gzip)}#{options}"
51
+ @ext = ".gz"
54
52
  end
55
53
 
56
54
  private
57
55
 
58
56
  def options
59
- opts = ''
60
- opts << " -#{ @level }" if @level
61
- if self.class.has_rsyncable?
62
- opts << ' --rsyncable'
63
- else
64
- Logger.warn Error.new(<<-EOS)
65
- 'rsyncable' option ignored.
66
- Your system's 'gzip' does not support the `--rsyncable` option.
67
- EOS
68
- end if @rsyncable
57
+ opts = ""
58
+ opts << " -#{@level}" if @level
59
+ if @rsyncable
60
+ if self.class.has_rsyncable?
61
+ opts << " --rsyncable"
62
+ else
63
+ Logger.warn Error.new(<<-EOS)
64
+ 'rsyncable' option ignored.
65
+ Your system's 'gzip' does not support the `--rsyncable` option.
66
+ EOS
67
+ end
68
+ end
69
69
  opts
70
70
  end
71
-
72
71
  end
73
72
  end
74
73
  end
@@ -1,15 +1,14 @@
1
- # encoding: utf-8
2
- require 'backup/config/dsl'
3
- require 'backup/config/helpers'
1
+ require "backup/config/dsl"
2
+ require "backup/config/helpers"
4
3
 
5
4
  module Backup
6
5
  module Config
7
6
  class Error < Backup::Error; end
8
7
 
9
8
  DEFAULTS = {
10
- :config_file => 'config.rb',
11
- :data_path => '.data',
12
- :tmp_path => '.tmp'
9
+ config_file: "config.rb",
10
+ data_path: ".data",
11
+ tmp_path: ".tmp"
13
12
  }
14
13
 
15
14
  class << self
@@ -19,20 +18,20 @@ module Backup
19
18
 
20
19
  # Loads the user's +config.rb+ and all model files.
21
20
  def load(options = {})
22
- update(options) # from the command line
21
+ update(options) # from the command line
23
22
 
24
23
  unless File.exist?(config_file)
25
24
  raise Error, "Could not find configuration file: '#{config_file}'."
26
25
  end
27
26
 
28
27
  config = File.read(config_file)
29
- version = Backup::VERSION.split('.').first
28
+ version = Backup::VERSION.split(".").first
30
29
  unless config =~ /^# Backup v#{ version }\.x Configuration$/
31
30
  raise Error, <<-EOS
32
31
  Invalid Configuration File
33
- The configuration file at '#{ config_file }'
34
- does not appear to be a Backup v#{ version }.x configuration file.
35
- If you have upgraded to v#{ version }.x from a previous version,
32
+ The configuration file at '#{config_file}'
33
+ does not appear to be a Backup v#{version}.x configuration file.
34
+ If you have upgraded to v#{version}.x from a previous version,
36
35
  you need to upgrade your configuration file.
37
36
  Please see the instructions for upgrading in the Backup documentation.
38
37
  EOS
@@ -44,7 +43,7 @@ module Backup
44
43
  update(dsl._config_options) # from config.rb
45
44
  update(options) # command line takes precedence
46
45
 
47
- Dir[File.join(File.dirname(config_file), 'models', '*.rb')].each do |model|
46
+ Dir[File.join(File.dirname(config_file), "models", "*.rb")].each do |model|
48
47
  dsl.instance_eval(File.read(model), model)
49
48
  end
50
49
  end
@@ -79,7 +78,7 @@ module Backup
79
78
  raise Error, <<-EOS
80
79
  Root Path Not Found
81
80
  When specifying a --root-path, the path must exist.
82
- Path was: #{ path }
81
+ Path was: #{path}
83
82
  EOS
84
83
  end
85
84
  @root_path = path
@@ -88,7 +87,7 @@ module Backup
88
87
  def set_path_variable(name, path, ending, root_path)
89
88
  # strip any trailing '/' in case the user supplied this as part of
90
89
  # an absolute path, so we can match it against File.expand_path()
91
- path = path.to_s.sub(/\/\s*$/, '').lstrip
90
+ path = path.to_s.sub(/\/\s*$/, "").lstrip
92
91
  new_path = false
93
92
  # If no path is given, the variable will not be set/updated
94
93
  # unless a root_path was given. In which case the value will
@@ -108,12 +107,12 @@ module Backup
108
107
  end
109
108
 
110
109
  def reset!
111
- @user = ENV['USER'] || Etc.getpwuid.name
112
- @root_path = File.join(File.expand_path(ENV['HOME'] || ''), 'Backup')
113
- update(:root_path => @root_path)
110
+ @user = ENV["USER"] || Etc.getpwuid.name
111
+ @root_path = File.join(File.expand_path(ENV["HOME"] || ""), "Backup")
112
+ update(root_path: @root_path)
114
113
  end
115
114
  end
116
115
 
117
- reset! # set defaults on load
116
+ reset! # set defaults on load
118
117
  end
119
118
  end