backup 3.2.0 → 3.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/README.md +3 -5
- data/lib/backup/archive.rb +11 -1
- data/lib/backup/cli.rb +252 -141
- data/lib/backup/database/base.rb +50 -24
- data/lib/backup/database/mongodb.rb +101 -127
- data/lib/backup/database/mysql.rb +50 -76
- data/lib/backup/database/postgresql.rb +44 -70
- data/lib/backup/database/redis.rb +61 -66
- data/lib/backup/database/riak.rb +64 -43
- data/lib/backup/dependency.rb +1 -1
- data/lib/backup/model.rb +10 -7
- data/lib/backup/storage/cloudfiles.rb +2 -0
- data/lib/backup/storage/cycler.rb +2 -1
- data/lib/backup/storage/dropbox.rb +66 -5
- data/lib/backup/utilities.rb +29 -14
- data/lib/backup/version.rb +1 -1
- data/templates/cli/archive +2 -0
- data/templates/cli/database/mongodb +1 -4
- data/templates/cli/database/mysql +0 -3
- data/templates/cli/database/postgresql +0 -3
- data/templates/cli/database/redis +11 -9
- data/templates/cli/database/riak +11 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8030ea8ce771bafd23266be65ddac30e62d9954b
|
4
|
+
data.tar.gz: bc53925b9956147157e9200d4cfb9d8c7886d343
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9631215669b56c92b1694d5a1005d5292ae9d3e25dd2da717cfbe40e30af80d6163b38e6662b7c309c2b480d4d69fe953458171c7dcd5fa908a51314d1ab584
|
7
|
+
data.tar.gz: 799f65d322c49d396d9301163412db25369ced068c6260a66fb54444cbd234da73fa07d92c3f6b8e8a58f6bfc241d763c1261d475dc2d3580f6acee02e295cce
|
data/README.md
CHANGED
@@ -68,10 +68,8 @@ $ tar -tvf my_backup.tar
|
|
68
68
|
my_backup/archives/user_avatars.tar.gz
|
69
69
|
my_backup/archives/log_files.tar.gz
|
70
70
|
my_backup/databases/
|
71
|
-
my_backup/databases/PostgreSQL
|
72
|
-
my_backup/databases/
|
73
|
-
my_backup/databases/Redis/
|
74
|
-
my_backup/databases/Redis/redis_db_name.rdb.gz
|
71
|
+
my_backup/databases/PostgreSQL.sql.gz
|
72
|
+
my_backup/databases/Redis.rdb.gz
|
75
73
|
```
|
76
74
|
|
77
75
|
### Storages
|
@@ -200,7 +198,7 @@ Backup::Model.new(:my_backup, 'Description for my_backup') do
|
|
200
198
|
mail.user_name = "sender@email.com"
|
201
199
|
mail.password = "my_password"
|
202
200
|
mail.authentication = "plain"
|
203
|
-
mail.
|
201
|
+
mail.encryption = :starttls
|
204
202
|
end
|
205
203
|
|
206
204
|
notify_by Twitter do |tweet|
|
data/lib/backup/archive.rb
CHANGED
@@ -53,6 +53,7 @@ module Backup
|
|
53
53
|
@model = model
|
54
54
|
@name = name.to_s
|
55
55
|
@options = {
|
56
|
+
:sudo => false,
|
56
57
|
:root => false,
|
57
58
|
:paths => [],
|
58
59
|
:excludes => [],
|
@@ -69,7 +70,7 @@ module Backup
|
|
69
70
|
|
70
71
|
pipeline = Pipeline.new
|
71
72
|
pipeline.add(
|
72
|
-
"#{
|
73
|
+
"#{ tar_command } #{ tar_options } -cPf -#{ tar_root } " +
|
73
74
|
"#{ paths_to_exclude } #{ paths_to_package }",
|
74
75
|
tar_success_codes
|
75
76
|
)
|
@@ -95,6 +96,11 @@ module Backup
|
|
95
96
|
|
96
97
|
private
|
97
98
|
|
99
|
+
def tar_command
|
100
|
+
tar = utility(:tar)
|
101
|
+
options[:sudo] ? "#{ utility(:sudo) } -n #{ tar }" : tar
|
102
|
+
end
|
103
|
+
|
98
104
|
def tar_root
|
99
105
|
options[:root] ? " -C '#{ File.expand_path(options[:root]) }'" : ''
|
100
106
|
end
|
@@ -129,6 +135,10 @@ module Backup
|
|
129
135
|
@options = options
|
130
136
|
end
|
131
137
|
|
138
|
+
def use_sudo(val = true)
|
139
|
+
@options[:sudo] = val
|
140
|
+
end
|
141
|
+
|
132
142
|
def root(path)
|
133
143
|
@options[:root] = path
|
134
144
|
end
|
data/lib/backup/cli.rb
CHANGED
@@ -4,25 +4,17 @@
|
|
4
4
|
# Build the Backup Command Line Interface using Thor
|
5
5
|
module Backup
|
6
6
|
class CLI < Thor
|
7
|
-
include Thor::Actions
|
8
7
|
|
9
8
|
##
|
10
9
|
# [Perform]
|
11
|
-
# Performs the backup process. The only required option is the --trigger [-t].
|
12
|
-
# If the other options (--config-file, --data-path, --cache-path, --tmp-path)
|
13
|
-
# aren't specified they will fallback to the (good) defaults.
|
14
10
|
#
|
11
|
+
# The only required option is the --trigger [-t].
|
12
|
+
# If --config-file, --data-path, --cache-path, --tmp-path aren't specified
|
13
|
+
# they will fallback to defaults defined in Backup::Config.
|
15
14
|
# If --root-path is given, it will be used as the base path for our defaults,
|
16
15
|
# as well as the base path for any option specified as a relative path.
|
17
16
|
# Any option given as an absolute path will be used "as-is".
|
18
17
|
#
|
19
|
-
# If the --check option is given, the config.rb and all model files will be
|
20
|
-
# loaded, but no triggers will be run. If the check fails, errors will be
|
21
|
-
# reported to the console. If the check passes, a success message will be
|
22
|
-
# reported to the console unless --quiet is set. Use --no-quiet to ensure
|
23
|
-
# these messages are output. The command will exit with status 0 if
|
24
|
-
# successful, or status 1 if there were problems.
|
25
|
-
#
|
26
18
|
# This command will exit with one of the following status codes:
|
27
19
|
#
|
28
20
|
# 0: All triggers were successful and no warnings were issued.
|
@@ -30,128 +22,201 @@ module Backup
|
|
30
22
|
# 2: All triggers were processed, but some failed.
|
31
23
|
# 3: A fatal error caused Backup to exit.
|
32
24
|
# Some triggers may not have been processed.
|
25
|
+
#
|
26
|
+
# If the --check option is given, `backup check` will be run
|
27
|
+
# and no triggers will be performed.
|
33
28
|
desc 'perform', "Performs the backup for the specified trigger(s)."
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
method_option :
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
29
|
+
|
30
|
+
long_desc <<-EOS.gsub(/^ +/, '')
|
31
|
+
Performs the backup for the specified trigger(s).
|
32
|
+
|
33
|
+
You may perform multiple backups by providing multiple triggers,
|
34
|
+
separated by commas. Each will run in the order specified.
|
35
|
+
|
36
|
+
$ backup perform --triggers backup1,backup2,backup3,backup4
|
37
|
+
|
38
|
+
--root-path may be an absolute path or relative to the current directory.
|
39
|
+
|
40
|
+
To use the current directory, use: `--root-path .`
|
41
|
+
|
42
|
+
Relative paths given for --config-file, --data-path, --log-path,
|
43
|
+
--cache-path and --tmp-path will be relative to --root-path.
|
44
|
+
|
45
|
+
Console log output may be forced using --no-quiet.
|
46
|
+
|
47
|
+
Logging to file or syslog may be disabled using --no-logfile or --no-syslog
|
48
|
+
respectively. This will override logging options set in `config.rb`.
|
49
|
+
EOS
|
50
|
+
|
51
|
+
method_option :trigger,
|
52
|
+
:aliases => ['-t', '--triggers'],
|
53
|
+
:required => true,
|
54
|
+
:type => :string,
|
55
|
+
:desc => "Triggers to perform. e.g. 'trigger_a,trigger_b'"
|
56
|
+
|
57
|
+
method_option :config_file,
|
58
|
+
:aliases => '-c',
|
59
|
+
:type => :string,
|
60
|
+
:default => '',
|
61
|
+
:desc => 'Path to your config.rb file.'
|
62
|
+
|
63
|
+
method_option :root_path,
|
64
|
+
:aliases => '-r',
|
65
|
+
:type => :string,
|
66
|
+
:default => '',
|
67
|
+
:desc => 'Root path to base all relative path on.'
|
68
|
+
|
69
|
+
method_option :data_path,
|
70
|
+
:aliases => '-d',
|
71
|
+
:type => :string,
|
72
|
+
:default => '',
|
73
|
+
:desc => 'Path to store storage cycling data.'
|
74
|
+
|
75
|
+
method_option :log_path,
|
76
|
+
:aliases => '-l',
|
77
|
+
:type => :string,
|
78
|
+
:default => '',
|
79
|
+
:desc => "Path to store Backup's log file."
|
80
|
+
|
81
|
+
method_option :cache_path,
|
82
|
+
:type => :string,
|
83
|
+
:default => '',
|
84
|
+
:desc => "Path to store Dropbox's cached authorization."
|
85
|
+
|
86
|
+
method_option :tmp_path,
|
87
|
+
:type => :string,
|
88
|
+
:default => '',
|
89
|
+
:desc => 'Path to store temporary data during the backup.'
|
90
|
+
|
62
91
|
# Note that :quiet, :syslog and :logfile are specified as :string types,
|
63
92
|
# so the --no-<option> usage will set the value to nil instead of false.
|
64
|
-
method_option :quiet,
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
93
|
+
method_option :quiet,
|
94
|
+
:aliases => '-q',
|
95
|
+
:type => :string,
|
96
|
+
:default => false,
|
97
|
+
:banner => '',
|
98
|
+
:desc => 'Disable console log output.'
|
99
|
+
|
100
|
+
method_option :syslog,
|
101
|
+
:type => :string,
|
102
|
+
:default => false,
|
103
|
+
:banner => '',
|
104
|
+
:desc => 'Enable logging to syslog.'
|
105
|
+
|
106
|
+
method_option :logfile,
|
107
|
+
:type => :string,
|
108
|
+
:default => true,
|
109
|
+
:banner => '',
|
110
|
+
:desc => "Enable Backup's log file."
|
111
|
+
|
112
|
+
method_option :check,
|
113
|
+
:type => :boolean,
|
114
|
+
:default => false,
|
115
|
+
:desc => 'Check configuration for errors or warnings.'
|
75
116
|
|
76
117
|
def perform
|
77
|
-
|
78
|
-
|
118
|
+
check if options[:check] # this will exit()
|
119
|
+
|
79
120
|
models = nil
|
80
121
|
begin
|
81
|
-
##
|
82
122
|
# Set logger options
|
83
123
|
opts = options
|
84
124
|
Logger.configure do
|
85
|
-
console.quiet
|
86
|
-
logfile.enabled
|
87
|
-
logfile.log_path
|
88
|
-
syslog.enabled
|
125
|
+
console.quiet = opts[:quiet]
|
126
|
+
logfile.enabled = opts[:logfile]
|
127
|
+
logfile.log_path = opts[:log_path]
|
128
|
+
syslog.enabled = opts[:syslog]
|
89
129
|
end
|
90
130
|
|
91
|
-
##
|
92
131
|
# Update Config variables
|
93
132
|
# (config_file, root_path, data_path, cache_path, tmp_path)
|
94
133
|
Config.update(options)
|
95
134
|
|
96
|
-
##
|
97
|
-
# Ensure the :cache_path and :tmp_path are created
|
98
|
-
# if they do not yet exist
|
99
|
-
[Config.cache_path, Config.tmp_path].each do |path|
|
100
|
-
FileUtils.mkdir_p(path)
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
135
|
# Load the user's +config.rb+ file (and all their Models).
|
105
|
-
# May update Logger options.
|
136
|
+
# May update Logger (and Config) options.
|
106
137
|
Config.load_config!
|
107
138
|
|
108
|
-
##
|
109
139
|
# Identify all Models to be run for the given +triggers+.
|
110
140
|
triggers = options[:trigger].split(',').map(&:strip)
|
111
141
|
models = triggers.map {|trigger|
|
112
142
|
Model.find_by_trigger(trigger)
|
113
143
|
}.flatten.uniq
|
114
144
|
|
115
|
-
|
116
|
-
|
117
|
-
"No Models found for trigger(s) '#{triggers.join(',')}'."
|
118
|
-
end
|
145
|
+
raise Errors::CLIError, "No Models found for trigger(s) " +
|
146
|
+
"'#{ triggers.join(',') }'." if models.empty?
|
119
147
|
|
120
|
-
|
121
|
-
raise Errors::CLIError, 'Configuration Check has warnings.'
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# Finalize Logger configuration and begin real-time logging.
|
148
|
+
# Finalize Logger and begin real-time logging.
|
126
149
|
Logger.start!
|
127
150
|
|
128
151
|
rescue Exception => err
|
129
152
|
Logger.error Errors::CLIError.wrap(err)
|
130
|
-
Logger.error 'Configuration Check Failed.' if options[:check]
|
131
153
|
# Logger configuration will be ignored
|
132
154
|
# and messages will be output to the console only.
|
133
155
|
Logger.abort!
|
134
|
-
exit(
|
156
|
+
exit(3)
|
135
157
|
end
|
136
158
|
|
137
|
-
|
138
|
-
|
159
|
+
# Model#perform! handles all exceptions from this point,
|
160
|
+
# as each model may fail and return here to allow others to run.
|
161
|
+
warnings = errors = false
|
162
|
+
models.each do |model|
|
163
|
+
model.perform!
|
164
|
+
warnings ||= Logger.has_warnings?
|
165
|
+
errors ||= Logger.has_errors?
|
166
|
+
Logger.clear!
|
167
|
+
end
|
168
|
+
exit(errors ? 2 : 1) if errors || warnings
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# [Check]
|
173
|
+
#
|
174
|
+
# Loads the user's `config.rb` (and all Model files) and reports any Errors
|
175
|
+
# or Warnings. This is primarily for checking for syntax errors, missing
|
176
|
+
# dependencies and deprecation warnings.
|
177
|
+
#
|
178
|
+
# This may also be invoked using the `--check` option to `backup perform`.
|
179
|
+
#
|
180
|
+
# This command only requires `Config.config_file` to be correct.
|
181
|
+
# All other Config paths are irrelevant.
|
182
|
+
#
|
183
|
+
# All output will be sent to the console only.
|
184
|
+
# Logger options will be ignored.
|
185
|
+
#
|
186
|
+
# If successful, this method with exit(0).
|
187
|
+
# If there are Errors or Warnings, it will exit(1).
|
188
|
+
desc 'check', 'Check for configuration errors or warnings'
|
189
|
+
|
190
|
+
long_desc <<-EOS.gsub(/^ +/, '')
|
191
|
+
Loads your 'config.rb' file and all models and reports any
|
192
|
+
errors or warnings with your configuration, including missing
|
193
|
+
dependencies and the use of any deprecated settings.
|
194
|
+
EOS
|
195
|
+
|
196
|
+
method_option :config_file,
|
197
|
+
:aliases => '-c',
|
198
|
+
:type => :string,
|
199
|
+
:default => '',
|
200
|
+
:desc => "Path to your config.rb file."
|
201
|
+
|
202
|
+
def check
|
203
|
+
begin
|
204
|
+
Config.update(options)
|
205
|
+
Config.load_config!
|
206
|
+
rescue Exception => err
|
207
|
+
Logger.error Errors::CLIError.wrap(err)
|
208
|
+
end
|
209
|
+
|
210
|
+
if Logger.has_warnings? || Logger.has_errors?
|
211
|
+
Logger.error 'Configuration Check Failed.'
|
212
|
+
exit_code = 1
|
139
213
|
else
|
140
|
-
|
141
|
-
|
142
|
-
# clearing the Logger after each job.
|
143
|
-
#
|
144
|
-
# Model#perform! handles all exceptions from this point,
|
145
|
-
# as each model may fail and return here to allow others to run.
|
146
|
-
warnings = errors = false
|
147
|
-
models.each do |model|
|
148
|
-
model.perform!
|
149
|
-
warnings ||= Logger.has_warnings?
|
150
|
-
errors ||= Logger.has_errors?
|
151
|
-
Logger.clear!
|
152
|
-
end
|
153
|
-
exit(errors ? 2 : 1) if errors || warnings
|
214
|
+
Logger.info 'Configuration Check Succeeded.'
|
215
|
+
exit_code = 0
|
154
216
|
end
|
217
|
+
|
218
|
+
Logger.abort!
|
219
|
+
exit(exit_code)
|
155
220
|
end
|
156
221
|
|
157
222
|
##
|
@@ -161,14 +226,28 @@ module Backup
|
|
161
226
|
# $ backup generate:model --trigger my_backup --databases='mongodb'
|
162
227
|
# will generate a pre-populated model with a base MongoDB setup
|
163
228
|
desc 'generate:model', "Generates a Backup model file."
|
164
|
-
long_desc "Generates a Backup model file.\n\n" +
|
165
|
-
"\s\sNote: '--config-path' is the path to the directory where 'config.rb' is located.\n\n" +
|
166
|
-
"\s\sThe model file will be created as '<config_path>/models/<trigger>.rb'\n\n" +
|
167
|
-
"\s\sDefault: #{Config.root_path}\n\n"
|
168
229
|
|
169
|
-
|
170
|
-
|
171
|
-
|
230
|
+
long_desc <<-EOS.gsub(/^ +/, '')
|
231
|
+
Generates a Backup model file.
|
232
|
+
|
233
|
+
'--config-path' is the path to the *directory* where 'config.rb' is located.
|
234
|
+
|
235
|
+
The model file will be created as '<config_path>/models/<trigger>.rb'
|
236
|
+
|
237
|
+
The default location would be:
|
238
|
+
|
239
|
+
#{ Config.root_path }/models/
|
240
|
+
EOS
|
241
|
+
|
242
|
+
method_option :trigger,
|
243
|
+
:aliases => '-t',
|
244
|
+
:required => true,
|
245
|
+
:type => :string,
|
246
|
+
:desc => 'Trigger name for the Backup model'
|
247
|
+
|
248
|
+
method_option :config_path,
|
249
|
+
:type => :string,
|
250
|
+
:desc => 'Path to your Backup configuration directory'
|
172
251
|
|
173
252
|
# options with their available values
|
174
253
|
%w{ databases storages syncers
|
@@ -178,9 +257,13 @@ module Backup
|
|
178
257
|
"(#{Dir[path + '/*'].sort.map {|p| File.basename(p) }.join(', ')})"
|
179
258
|
end
|
180
259
|
|
181
|
-
method_option :archives,
|
182
|
-
|
183
|
-
|
260
|
+
method_option :archives,
|
261
|
+
:type => :boolean,
|
262
|
+
:desc => 'Model will include tar archives.'
|
263
|
+
method_option :splitter,
|
264
|
+
:type => :boolean,
|
265
|
+
:default => true,
|
266
|
+
:desc => "Use `--no-splitter` to disable"
|
184
267
|
|
185
268
|
define_method "generate:model" do
|
186
269
|
opts = options.merge(
|
@@ -193,8 +276,12 @@ module Backup
|
|
193
276
|
config = File.join(config_path, "config.rb")
|
194
277
|
model = File.join(models_path, "#{opts[:trigger]}.rb")
|
195
278
|
|
279
|
+
if File.file?(config_path)
|
280
|
+
abort('--config-path should be a directory, not a file.')
|
281
|
+
end
|
282
|
+
|
196
283
|
FileUtils.mkdir_p(models_path)
|
197
|
-
if overwrite?(model)
|
284
|
+
if Helpers.overwrite?(model)
|
198
285
|
File.open(model, 'w') do |file|
|
199
286
|
file.write(
|
200
287
|
Backup::Template.new({:options => opts}).result("cli/model.erb")
|
@@ -203,7 +290,7 @@ module Backup
|
|
203
290
|
puts "Generated model file: '#{ model }'."
|
204
291
|
end
|
205
292
|
|
206
|
-
|
293
|
+
unless File.exist?(config)
|
207
294
|
File.open(config, "w") do |file|
|
208
295
|
file.write(Backup::Template.new.result("cli/config"))
|
209
296
|
end
|
@@ -215,8 +302,18 @@ module Backup
|
|
215
302
|
# [Generate:Config]
|
216
303
|
# Generates the main configuration file
|
217
304
|
desc 'generate:config', 'Generates the main Backup bootstrap/configuration file'
|
218
|
-
|
219
|
-
|
305
|
+
|
306
|
+
long_desc <<-EOS.gsub(/^ +/, '')
|
307
|
+
Path to your Backup configuration directory.
|
308
|
+
|
309
|
+
Default path would be:
|
310
|
+
|
311
|
+
#{ Config.root_path }
|
312
|
+
EOS
|
313
|
+
|
314
|
+
method_option :config_path,
|
315
|
+
:type => :string,
|
316
|
+
:desc => 'Path to your Backup configuration directory.'
|
220
317
|
|
221
318
|
define_method 'generate:config' do
|
222
319
|
config_path = options[:config_path] ?
|
@@ -224,7 +321,7 @@ module Backup
|
|
224
321
|
config = File.join(config_path, "config.rb")
|
225
322
|
|
226
323
|
FileUtils.mkdir_p(config_path)
|
227
|
-
if overwrite?(config)
|
324
|
+
if Helpers.overwrite?(config)
|
228
325
|
File.open(config, "w") do |file|
|
229
326
|
file.write(Backup::Template.new.result("cli/config"))
|
230
327
|
end
|
@@ -247,13 +344,20 @@ module Backup
|
|
247
344
|
case options[:encryptor].downcase
|
248
345
|
when 'openssl'
|
249
346
|
base64 = options[:base64] ? '-base64' : ''
|
250
|
-
password = options[:password_file].empty? ? '' :
|
347
|
+
password = options[:password_file].empty? ? '' :
|
348
|
+
"-pass file:#{ options[:password_file] }"
|
251
349
|
salt = options[:salt] ? '-salt' : ''
|
252
|
-
|
350
|
+
|
351
|
+
Helpers.exec!(
|
352
|
+
"openssl aes-256-cbc -d #{ base64 } #{ password } #{ salt } " +
|
353
|
+
"-in '#{ options[:in] }' -out '#{ options[:out] }'"
|
354
|
+
)
|
253
355
|
when 'gpg'
|
254
|
-
|
356
|
+
Helpers.exec!(
|
357
|
+
"gpg -o '#{ options[:out] }' -d '#{ options[:in] }'"
|
358
|
+
)
|
255
359
|
else
|
256
|
-
puts "Unknown encryptor: #{options[:encryptor]}"
|
360
|
+
puts "Unknown encryptor: #{ options[:encryptor] }"
|
257
361
|
puts "Use either 'openssl' or 'gpg'."
|
258
362
|
end
|
259
363
|
end
|
@@ -262,24 +366,27 @@ module Backup
|
|
262
366
|
# [Dependencies]
|
263
367
|
# Returns a list of Backup's dependencies
|
264
368
|
desc 'dependencies', 'Display, Check or Install Dependencies for Backup.'
|
265
|
-
|
266
|
-
|
369
|
+
|
370
|
+
long_desc <<-EOS.gsub(/^ +/, '')
|
371
|
+
To display a list of available dependencies, run:
|
372
|
+
|
373
|
+
$ backup dependencies --list
|
374
|
+
|
375
|
+
To install one of these dependencies, run:
|
376
|
+
|
377
|
+
$ backup dependencies --install <name>
|
378
|
+
|
379
|
+
To check if a dependency is already installed, run:
|
380
|
+
|
381
|
+
$ backup dependencies --installed <name>
|
382
|
+
EOS
|
383
|
+
|
384
|
+
method_option :install, :type => :string, :banner => 'NAME'
|
267
385
|
method_option :list, :type => :boolean
|
268
|
-
method_option :installed, :type => :string
|
386
|
+
method_option :installed, :type => :string, :banner => 'NAME'
|
269
387
|
|
270
388
|
def dependencies
|
271
|
-
unless options.any?
|
272
|
-
puts
|
273
|
-
puts "To display a list of available dependencies, run:\n\n"
|
274
|
-
puts " backup dependencies --list"
|
275
|
-
puts
|
276
|
-
puts "To install one of these dependencies (with the correct version), run:\n\n"
|
277
|
-
puts " backup dependencies --install <name>"
|
278
|
-
puts
|
279
|
-
puts "To check if a dependency is already installed, run:\n\n"
|
280
|
-
puts " backup dependencies --installed <name>"
|
281
|
-
exit
|
282
|
-
end
|
389
|
+
Helpers.exec!("#{ $0 } help dependencies") unless options.any?
|
283
390
|
|
284
391
|
if options[:list]
|
285
392
|
deps = Dependency.all
|
@@ -361,23 +468,27 @@ module Backup
|
|
361
468
|
puts "Backup #{Backup::Version.current}"
|
362
469
|
end
|
363
470
|
|
364
|
-
private
|
365
|
-
|
366
|
-
##
|
367
|
-
# Helper method for asking the user if he/she wants to overwrite the file
|
368
|
-
def overwrite?(path)
|
369
|
-
if File.exist?(path)
|
370
|
-
return yes? "A file already exists at '#{ path }'. Do you want to overwrite? [y/n]"
|
371
|
-
end
|
372
|
-
true
|
373
|
-
end
|
374
|
-
|
375
471
|
# This is to avoid Thor's warnings when stubbing methods on the Thor class.
|
376
472
|
module Helpers
|
377
473
|
class << self
|
474
|
+
|
475
|
+
def overwrite?(path)
|
476
|
+
return true unless File.exist?(path)
|
477
|
+
|
478
|
+
$stderr.print "A file already exists at '#{ path }'.\n" +
|
479
|
+
"Do you want to overwrite? [y/n] "
|
480
|
+
/^[Yy]/ =~ $stdin.gets
|
481
|
+
end
|
482
|
+
|
483
|
+
def exec!(cmd)
|
484
|
+
puts "Lauching: #{ cmd }"
|
485
|
+
exec(cmd)
|
486
|
+
end
|
487
|
+
|
378
488
|
def bundler_loaded?
|
379
489
|
!ENV['BUNDLE_GEMFILE'].to_s.empty?
|
380
490
|
end
|
491
|
+
|
381
492
|
end
|
382
493
|
end
|
383
494
|
|