backupper 0.3.0 → 0.4.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 +5 -5
- data/.gitignore +1 -0
- data/Gemfile +2 -2
- data/Gemfile.lock +34 -0
- data/README.md +9 -3
- data/Rakefile +2 -2
- data/backupper.gemspec +11 -11
- data/bin/backupper +27 -4
- data/lib/backupper.rb +2 -2
- data/lib/backupper/backupper.rb +55 -54
- data/lib/backupper/dump_command.rb +1 -3
- data/lib/backupper/mailer.rb +37 -38
- data/lib/backupper/version.rb +1 -1
- metadata +30 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e342e000d1463ab2e5acda75380d51b4234e15c10bc9926de642657ffadbbe02
|
4
|
+
data.tar.gz: c5b08c11facbf564daaf375ccff26e0e8ba4aa59b5d03a0981dc8f69ea5d5463
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2c543a27f6f781700acded008b3629a19507da9b10b3851cf513edceac10bcaf8e8efdb771dfee04ae2ee208ba966c5134b03e71002df6d65d3851cbc658a26
|
7
|
+
data.tar.gz: caccc5dd3ec837854f29efa9e94f11a02543d67c4f6e659f9a5d037760ffe3e5eed577d39eed86151d9e9fb69e5d7ca93d5aaf416adc58386b82dcc49e280269
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in backupper.gemspec
|
6
6
|
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
backupper (0.4.0)
|
5
|
+
mail (~> 2.7)
|
6
|
+
sshkit (~> 1.15)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
byebug (11.0.1)
|
12
|
+
mail (2.7.1)
|
13
|
+
mini_mime (>= 0.1.1)
|
14
|
+
mini_mime (1.0.2)
|
15
|
+
net-scp (2.0.0)
|
16
|
+
net-ssh (>= 2.6.5, < 6.0.0)
|
17
|
+
net-ssh (5.2.0)
|
18
|
+
rake (10.5.0)
|
19
|
+
sshkit (1.20.0)
|
20
|
+
net-scp (>= 1.1.2)
|
21
|
+
net-ssh (>= 2.8.0)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
x86_64-darwin-18
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
backupper!
|
29
|
+
bundler
|
30
|
+
byebug
|
31
|
+
rake (~> 10.0)
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
2.0.2
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Backupper
|
2
2
|
|
3
|
-
Backupper is a tool to backup all your databases spread
|
3
|
+
Backupper is a tool to backup all your databases spread all over the world!
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -8,7 +8,7 @@ Backupper is a tool to backup all your databases spread in the world!
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
-
$ backupper path/to/config.yml
|
11
|
+
$ backupper path/to/config.yml [options]
|
12
12
|
|
13
13
|
## Configuration file
|
14
14
|
|
@@ -52,6 +52,12 @@ After done all backups a report email is sent to you using gmail smtp service (r
|
|
52
52
|
|
53
53
|
⚠️ __WARNING__: the backupper configuration file contains many important passwords, so be careful to lock it and protect it with care!
|
54
54
|
|
55
|
+
To backup only specific databases you can pass the option `-o db1,db3`. In this way only databases under the key `db1` and `db3` will be backupped,
|
56
|
+
ignoring the others configuration keys.
|
57
|
+
|
58
|
+
## Resources
|
59
|
+
* [Blog post about Backupper](https://tech.uqido.com/2018/07/16/backupper-tool-backup-database/) (italian only).
|
60
|
+
|
55
61
|
## Contributing
|
56
62
|
|
57
63
|
Bug reports and pull requests are welcome on GitHub at https://github.com/uqido/backupper.
|
@@ -67,4 +73,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
67
73
|
Backupper is maintained and funded by [Uqido](https://uqido.com).
|
68
74
|
The names and logos for Uqido are trademarks of Uqido s.r.l.
|
69
75
|
|
70
|
-
The [Uqido team](https://www.uqido.com/en/about-us/).
|
76
|
+
The [Uqido team](https://www.uqido.com/en/about-us/).
|
data/Rakefile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require
|
2
|
-
task :
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
task default: :spec
|
data/backupper.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'backupper/version'
|
5
4
|
|
@@ -9,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
9
8
|
spec.authors = ['pioz']
|
10
9
|
spec.email = ['enrico.pilotto@uqido.com']
|
11
10
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
11
|
+
spec.summary = 'Tool to backup databases'
|
12
|
+
spec.description = 'Backupper is a tool to backup all your databases spread all over the world'
|
14
13
|
spec.homepage = 'https://github.com/uqido/backupper'
|
15
14
|
spec.license = 'MIT'
|
16
15
|
|
@@ -22,16 +21,17 @@ Gem::Specification.new do |spec|
|
|
22
21
|
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
23
22
|
end
|
24
23
|
|
25
|
-
spec.files
|
26
|
-
f.match(
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
f.match(/^(test|spec|features)\//)
|
27
26
|
end
|
28
|
-
spec.bindir =
|
29
|
-
spec.executables = spec.files.grep(
|
30
|
-
spec.require_paths = [
|
27
|
+
spec.bindir = 'bin'
|
28
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ['lib']
|
31
30
|
|
32
|
-
spec.add_runtime_dependency 'sshkit', '~> 1.15'
|
33
31
|
spec.add_runtime_dependency 'mail', '~> 2.7'
|
32
|
+
spec.add_runtime_dependency 'sshkit', '~> 1.15'
|
34
33
|
|
35
|
-
spec.add_development_dependency 'bundler'
|
34
|
+
spec.add_development_dependency 'bundler'
|
35
|
+
spec.add_development_dependency 'byebug'
|
36
36
|
spec.add_development_dependency 'rake', '~> 10.0'
|
37
37
|
end
|
data/bin/backupper
CHANGED
@@ -1,11 +1,34 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'optparse'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
require_relative '../lib/backupper'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
parser = OptionParser.new do |opts|
|
9
|
+
opts.banner = "usage: #{$PROGRAM_NAME} path/to/config.yml [options]"
|
10
|
+
|
11
|
+
opts.on('-v', 'Print version') do |v|
|
12
|
+
options[:version] = v
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on('-o', '--only=conf-key1,conf-key2', Array, 'Backup only specific database configurations') do |keys|
|
16
|
+
options[:only] = keys
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
parser.parse!
|
22
|
+
raise OptionParser::InvalidOption if ARGV.size != 1
|
23
|
+
rescue OptionParser::InvalidOption
|
24
|
+
puts parser.banner
|
7
25
|
exit 1
|
8
26
|
end
|
9
27
|
|
28
|
+
if options[:version]
|
29
|
+
puts Backupper::VERSION
|
30
|
+
exit 0
|
31
|
+
end
|
32
|
+
|
10
33
|
b = Backupper.new(ARGV.first)
|
11
|
-
b.backup!
|
34
|
+
b.backup!(options[:only])
|
data/lib/backupper.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'backupper/backupper'
|
2
|
+
require_relative 'backupper/version'
|
data/lib/backupper/backupper.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
-
require 'yaml'
|
2
1
|
require 'fileutils'
|
3
2
|
require 'sshkit'
|
4
3
|
require 'sshkit/dsl'
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
require_relative 'dump_command'
|
7
|
+
require_relative 'mailer'
|
8
8
|
|
9
9
|
class Backupper
|
10
|
+
include SSHKit::DSL
|
10
11
|
|
11
12
|
SSHKit::Backend::Netssh.configure do |ssh|
|
12
13
|
ssh.connection_timeout = 30
|
13
14
|
ssh.ssh_options = {
|
14
|
-
auth_methods: %w
|
15
|
+
auth_methods: %w[publickey password]
|
15
16
|
}
|
16
17
|
end
|
17
18
|
|
@@ -19,17 +20,20 @@ class Backupper
|
|
19
20
|
conf = YAML.load_file(conf_file_path)
|
20
21
|
@default = conf['default'] || {}
|
21
22
|
@mailer = conf['mailer'] || {}
|
22
|
-
@conf = conf.select{|k, v| !%w
|
23
|
+
@conf = conf.select { |k, v| !%w[default mailer].include?(k) && (v['disabled'].nil? || v['disabled'] == false) }
|
23
24
|
@report = {}
|
25
|
+
@logger = SSHKit::Formatter::Pretty.new($stdout)
|
24
26
|
end
|
25
27
|
|
26
|
-
def backup!
|
27
|
-
@conf
|
28
|
-
|
28
|
+
def backup!(only_these_keys = nil)
|
29
|
+
filtered_conf = @conf
|
30
|
+
filtered_conf = @conf.slice(*only_these_keys) if only_these_keys
|
31
|
+
filtered_conf.each do |k, options|
|
32
|
+
@logger.info "[#{Time.now}] ⬇️ backing up #{k}..."
|
29
33
|
o, err = setup_options(options)
|
30
34
|
if err
|
31
35
|
error(k, err)
|
32
|
-
|
36
|
+
@logger.error err
|
33
37
|
next
|
34
38
|
end
|
35
39
|
begin
|
@@ -47,7 +51,7 @@ class Backupper
|
|
47
51
|
)
|
48
52
|
rescue SSHKit::Runner::ExecuteError => e
|
49
53
|
error(k, e.to_s)
|
50
|
-
|
54
|
+
@logger.error e
|
51
55
|
end
|
52
56
|
end
|
53
57
|
send_report_email!
|
@@ -73,58 +77,55 @@ class Backupper
|
|
73
77
|
size: (File.size(path).to_f / 2**20).round(2),
|
74
78
|
time: (Process.clock_gettime(Process::CLOCK_MONOTONIC) - t).round(2)
|
75
79
|
}
|
76
|
-
@report[key].merge!({extra_copy: File.absolute_path(File.join(extra_copy, dumpname))}) if extra_copy
|
80
|
+
@report[key].merge!({ extra_copy: File.absolute_path(File.join(extra_copy, dumpname)) }) if extra_copy
|
77
81
|
end
|
78
82
|
|
79
83
|
private
|
80
84
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
return nil, '
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
unless DumpCommand.respond_to?(o['adapter'])
|
98
|
-
return nil, "Cannot handle adapter '#{o['adapter']}'"
|
85
|
+
def setup_options(options)
|
86
|
+
o = @default.merge(options)
|
87
|
+
o['outdir'] = check_dir(o['dump'].to_s)
|
88
|
+
return nil, 'Invalid directory where to save database dump' unless o['outdir']
|
89
|
+
return nil, 'Please specify the database name!' unless o['database']
|
90
|
+
return nil, 'Please specify the host!' unless o['host']
|
91
|
+
|
92
|
+
o['url'] = o['host']
|
93
|
+
o['url'] = "#{o['username']}@#{o['url']}" if o['username']
|
94
|
+
o['url'] = "#{o['url']}:#{o['port']}" if o['port']
|
95
|
+
o['adapter'] ||= 'mysql'
|
96
|
+
unless DumpCommand.respond_to?(o['adapter'])
|
97
|
+
return nil, "Cannot handle adapter '#{o['adapter']}'"
|
98
|
+
end
|
99
|
+
|
100
|
+
return o, nil
|
99
101
|
end
|
100
|
-
return o, nil
|
101
|
-
end
|
102
102
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
103
|
+
def send_report_email!
|
104
|
+
if @report.any? && @mailer['from'] && @mailer['to'] && @mailer['password']
|
105
|
+
begin
|
106
|
+
Mailer.send(from: @mailer['from'], to: @mailer['to'], password: @mailer['password'], report: @report)
|
107
|
+
rescue Net::SMTPAuthenticationError => e
|
108
|
+
@logger.error e
|
109
|
+
end
|
109
110
|
end
|
110
111
|
end
|
111
|
-
end
|
112
112
|
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
def error(key, error)
|
114
|
+
@report[key] = { error: error }
|
115
|
+
end
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
117
|
+
def check_dir(dirpath)
|
118
|
+
return nil if dirpath.nil?
|
119
|
+
|
120
|
+
unless File.exist?(dirpath)
|
121
|
+
begin
|
122
|
+
FileUtils.mkdir_p(dirpath)
|
123
|
+
rescue StandardError => _e
|
124
|
+
return nil
|
125
|
+
end
|
124
126
|
end
|
125
|
-
|
126
|
-
return File.dirname(dirpath) unless File.directory?(dirpath)
|
127
|
-
return dirpath
|
128
|
-
end
|
127
|
+
return File.dirname(dirpath) unless File.directory?(dirpath)
|
129
128
|
|
130
|
-
|
129
|
+
return dirpath
|
130
|
+
end
|
131
|
+
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module DumpCommand
|
2
|
-
|
3
2
|
def self.mysql(database:, username: 'root', password: nil, dump_options: nil, outfile:)
|
4
3
|
params = []
|
5
4
|
params << "--databases '#{database}'"
|
@@ -16,5 +15,4 @@ module DumpCommand
|
|
16
15
|
params << dump_options if dump_options
|
17
16
|
return "PGPASSWORD=#{password} pg_dump #{params.join(' ')} | bzip2 > '#{outfile}'"
|
18
17
|
end
|
19
|
-
|
20
|
-
end
|
18
|
+
end
|
data/lib/backupper/mailer.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'mail'
|
2
2
|
|
3
3
|
class Mailer
|
4
|
-
|
5
4
|
def self.send(from:, to:, password:, report:)
|
6
5
|
options = {
|
7
6
|
address: 'smtp.gmail.com',
|
@@ -17,47 +16,47 @@ class Mailer
|
|
17
16
|
Mail.deliver do
|
18
17
|
to to
|
19
18
|
from from
|
20
|
-
subject
|
21
|
-
body
|
19
|
+
subject self.subject(report)
|
20
|
+
body self.body(report)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
|
-
|
24
|
+
class << self
|
25
|
+
private
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
27
|
+
def body(report)
|
28
|
+
b = []
|
29
|
+
report.each do |k, data|
|
30
|
+
s = ''
|
31
|
+
if data[:error]
|
32
|
+
s << "❌ #{k}\n"
|
33
|
+
s << '=' * 80 << "\n"
|
34
|
+
s << "Backup FAILED!\n"
|
35
|
+
s << " error: #{data[:error]}\n"
|
36
|
+
else
|
37
|
+
s << "️✅ #{k}\n"
|
38
|
+
s << '=' * 80 << "\n"
|
39
|
+
s << "Backup SUCCESS!\n"
|
40
|
+
s << " dump size: #{data[:size]} MB\n"
|
41
|
+
s << " time: #{data[:time]} seconds\n"
|
42
|
+
s << " dump saved in: #{data[:path]}\n"
|
43
|
+
if data[:extra_copy]
|
44
|
+
s << " extra copy in: #{data[:extra_copy]}\n"
|
45
|
+
else
|
46
|
+
s << " no extra copy has been made\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
b << s
|
48
50
|
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
52
|
-
return "Report for backups (#{Time.now})\n\n#{b.join("\n\n")}"
|
53
|
-
end
|
51
|
+
return "Report for backups (#{Time.now})\n\n#{b.join("\n\n")}"
|
52
|
+
end
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
def subject(report)
|
55
|
+
errors = report.select { |_k, v| v[:error] }.size
|
56
|
+
icon = '✅'
|
57
|
+
icon = '⚠️' if errors > 0
|
58
|
+
icon = '❌' if errors == report.size
|
59
|
+
return "[Backupper] #{report.size - errors}/#{report.size} backups successfully completed #{icon}"
|
60
|
+
end
|
61
61
|
end
|
62
|
-
|
63
|
-
end
|
62
|
+
end
|
data/lib/backupper/version.rb
CHANGED
metadata
CHANGED
@@ -1,57 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backupper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pioz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: mail
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.7'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: sshkit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.15'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.15'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +80,8 @@ dependencies:
|
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '10.0'
|
69
|
-
description: Backupper is a tool to backup all your databases spread
|
83
|
+
description: Backupper is a tool to backup all your databases spread all over the
|
84
|
+
world
|
70
85
|
email:
|
71
86
|
- enrico.pilotto@uqido.com
|
72
87
|
executables:
|
@@ -76,6 +91,7 @@ extra_rdoc_files: []
|
|
76
91
|
files:
|
77
92
|
- ".gitignore"
|
78
93
|
- Gemfile
|
94
|
+
- Gemfile.lock
|
79
95
|
- LICENSE.txt
|
80
96
|
- README.md
|
81
97
|
- Rakefile
|
@@ -106,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
122
|
- !ruby/object:Gem::Version
|
107
123
|
version: '0'
|
108
124
|
requirements: []
|
109
|
-
|
110
|
-
rubygems_version: 2.6.13
|
125
|
+
rubygems_version: 3.0.2
|
111
126
|
signing_key:
|
112
127
|
specification_version: 4
|
113
128
|
summary: Tool to backup databases
|