bibliotech 0.2.13 → 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/default_configuration/config.yaml +3 -0
- data/lib/bibliotech/application.rb +25 -2
- data/lib/bibliotech/backups/file_record.rb +7 -1
- data/lib/bibliotech/backups/prune_list.rb +3 -1
- data/lib/bibliotech/backups/pruner.rb +17 -9
- data/lib/bibliotech/backups/scheduler.rb +4 -3
- data/lib/bibliotech/command_generator.rb +15 -3
- data/lib/bibliotech/config.rb +35 -5
- data/lib/bibliotech/logger.rb +36 -0
- data/spec/bibliotech/backup_pruner_spec.rb +121 -6
- data/spec/bibliotech/backup_scheduler_spec.rb +2 -2
- data/spec/bibliotech/config_spec.rb +2 -4
- data/spec/spec_helper.rb +4 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07e130f15c7d64d6bd751f7663a913adb30a5551
|
4
|
+
data.tar.gz: efc5d69b6b40c211c0959020bfaf7ab46044ec56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95ac9c114a022bbbda10710e62a4f9191aa242f7f9c4b68aa8fd9576424c65309e168bbc5b0ed0e5727477af76be81017cd71ceeca87e2c25cd1488d57e0a2b3
|
7
|
+
data.tar.gz: 88626b4a157c11e5d4294bfd3aa8a7b730db4f685c5e755a83f87935e27cd42a37b7fc00a44a95be0342489689e68278411b73ccd68d24d17c46d21d0f951a83
|
@@ -2,9 +2,12 @@ require 'bibliotech'
|
|
2
2
|
require 'caliph'
|
3
3
|
require 'valise'
|
4
4
|
require 'bibliotech/backups/pruner'
|
5
|
+
require 'bibliotech/logger'
|
5
6
|
|
6
7
|
module BiblioTech
|
7
8
|
class Application
|
9
|
+
include Logging
|
10
|
+
|
8
11
|
attr_accessor :config_path, :config_hash
|
9
12
|
attr_writer :shell
|
10
13
|
|
@@ -30,7 +33,19 @@ module BiblioTech
|
|
30
33
|
end
|
31
34
|
|
32
35
|
def config
|
33
|
-
@memos[:config] ||=
|
36
|
+
@memos[:config] ||=
|
37
|
+
begin
|
38
|
+
Config.new(valise).tap do |config|
|
39
|
+
setup_logger(config)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_logger(config)
|
45
|
+
logger = Logger.new(config.log_target)
|
46
|
+
logger.level = config.log_level
|
47
|
+
BiblioTech::Logging.logger = logger
|
48
|
+
log.info("Started logging")
|
34
49
|
end
|
35
50
|
|
36
51
|
def commands
|
@@ -59,6 +74,7 @@ module BiblioTech
|
|
59
74
|
|
60
75
|
def create_backup(options)
|
61
76
|
time = Time.now.utc
|
77
|
+
log.warn{ "Creating a backup at #{time}" }
|
62
78
|
pruner = pruner(options)
|
63
79
|
return unless pruner.backup_needed?(time)
|
64
80
|
options["backups"] ||= options[:backups] || {}
|
@@ -68,25 +84,32 @@ module BiblioTech
|
|
68
84
|
|
69
85
|
#pull a dump from a remote
|
70
86
|
def get(remote, options)
|
87
|
+
log.warn{ "Getting a dump from #{remote}" }
|
71
88
|
@shell.run(commands.fetch(remote, options))
|
72
89
|
end
|
73
90
|
|
74
91
|
#push a dump to a remote
|
75
92
|
def send(remote, options)
|
93
|
+
log.warn{ "Sending a dump to #{remote}" }
|
76
94
|
@shell.run(commands.push(remote, options))
|
77
95
|
end
|
78
96
|
|
79
97
|
#clean up the DB dumps
|
80
98
|
def prune(options=nil)
|
99
|
+
log.warn{ "Pruning DB records" }
|
81
100
|
pruner(options || {}).go
|
82
101
|
end
|
83
102
|
|
84
103
|
#return the latest dump of the DB
|
85
104
|
def latest(options = nil)
|
86
|
-
|
105
|
+
log.info{ "Getting most recent DB dump" }
|
106
|
+
pruner(options || {}).most_recent.path.tap do |latest|
|
107
|
+
log.info{ " #{latest}" }
|
108
|
+
end
|
87
109
|
end
|
88
110
|
|
89
111
|
def remote_cli(remote, command, *options)
|
112
|
+
log.warn{ "Running #{command} on #{remote}" }
|
90
113
|
@shell.run(commands.remote_cli(remote, command, *options))
|
91
114
|
end
|
92
115
|
end
|
@@ -1,16 +1,22 @@
|
|
1
1
|
module BiblioTech
|
2
2
|
module Backups
|
3
3
|
class FileRecord
|
4
|
-
attr_accessor :path, :timestamp, :keep
|
4
|
+
attr_accessor :path, :timestamp, :keep, :scheduled_by
|
5
5
|
|
6
6
|
def initialize(path, timestamp)
|
7
7
|
@path, @timestamp = path, timestamp
|
8
8
|
@keep = false
|
9
|
+
@scheduled_by = []
|
9
10
|
end
|
10
11
|
|
11
12
|
def keep?
|
12
13
|
!!@keep
|
13
14
|
end
|
15
|
+
|
16
|
+
def in_schedule(name)
|
17
|
+
@scheduled_by << name
|
18
|
+
@keep = true
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'bibliotech/backups/prune_list'
|
2
2
|
require 'bibliotech/backups/file_record'
|
3
|
-
require 'bibliotech/
|
3
|
+
require 'bibliotech/logger'
|
4
4
|
|
5
5
|
module BiblioTech
|
6
6
|
module Backups
|
7
7
|
class Pruner
|
8
|
+
include Logging
|
8
9
|
def initialize(config)
|
9
10
|
@config = config
|
10
11
|
end
|
@@ -19,18 +20,17 @@ module BiblioTech
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def schedules
|
22
|
-
@schedules ||=
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
23
|
+
@schedules ||= config.prune_schedules
|
24
|
+
end
|
25
|
+
|
26
|
+
def frequency
|
27
|
+
@frequency ||= config.backup_frequency
|
28
28
|
end
|
29
29
|
|
30
30
|
def backup_needed?(time)
|
31
31
|
most_recent = most_recent()
|
32
32
|
return true if most_recent.nil?
|
33
|
-
(time - most_recent.timestamp) > (
|
33
|
+
(time - most_recent.timestamp) > (frequency * 60)
|
34
34
|
end
|
35
35
|
|
36
36
|
def list
|
@@ -50,11 +50,19 @@ module BiblioTech
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def filename_for(time)
|
53
|
-
PruneList.filename_for(
|
53
|
+
PruneList.filename_for(name, time)
|
54
54
|
end
|
55
55
|
|
56
56
|
def pruneable
|
57
57
|
mark_list
|
58
|
+
if list.empty?
|
59
|
+
log.warn{ "No backup files in #{path} / #{name} !" }
|
60
|
+
end
|
61
|
+
list.each do |record|
|
62
|
+
log.info{
|
63
|
+
"#{record.path} #{record.timestamp} #{record.keep ? "kept: #{record.scheduled_by.inspect}" : "discarding"}"
|
64
|
+
}
|
65
|
+
end
|
58
66
|
list.select do |record|
|
59
67
|
!record.keep?
|
60
68
|
end
|
@@ -3,9 +3,10 @@ require 'bibliotech/backups/file_record'
|
|
3
3
|
module BiblioTech
|
4
4
|
module Backups
|
5
5
|
class Scheduler
|
6
|
-
attr_accessor :frequency, :limit
|
6
|
+
attr_accessor :frequency, :limit, :name
|
7
7
|
|
8
|
-
def initialize(frequency, limit)
|
8
|
+
def initialize(name, frequency, limit)
|
9
|
+
@name = name
|
9
10
|
@frequency, @limit = frequency, limit
|
10
11
|
@limit = nil if limit == "all"
|
11
12
|
end
|
@@ -51,7 +52,7 @@ module BiblioTech
|
|
51
52
|
closest = file_list.first
|
52
53
|
|
53
54
|
if (time - closest.timestamp) < freq_seconds
|
54
|
-
closest.
|
55
|
+
closest.in_schedule(name)
|
55
56
|
end
|
56
57
|
time -= freq_seconds
|
57
58
|
end
|
@@ -3,11 +3,13 @@ require 'caliph'
|
|
3
3
|
require 'bibliotech/builders/gzip'
|
4
4
|
require 'bibliotech/builders/postgres'
|
5
5
|
require 'bibliotech/builders/mysql'
|
6
|
+
require 'bibliotech/logger'
|
6
7
|
|
7
8
|
module BiblioTech
|
8
9
|
class CommandGenerator
|
9
10
|
|
10
11
|
include Caliph::CommandLineDSL
|
12
|
+
include Logging
|
11
13
|
|
12
14
|
attr_accessor :config
|
13
15
|
|
@@ -19,14 +21,18 @@ module BiblioTech
|
|
19
21
|
options = config.merge(options || {})
|
20
22
|
command = cmd
|
21
23
|
command = Builders::Export.for(options).go(command)
|
22
|
-
Builders::FileOutput.for(options).go(command)
|
24
|
+
Builders::FileOutput.for(options).go(command).tap do |cmd|
|
25
|
+
log.info{ cmd.command }
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
def import(options = nil)
|
26
30
|
options = config.merge(options || {})
|
27
31
|
command = cmd()
|
28
32
|
command = Builders::Import.for(options).go(command)
|
29
|
-
Builders::FileInput.for(options).go(command)
|
33
|
+
Builders::FileInput.for(options).go(command).tap do |cmd|
|
34
|
+
log.info{ cmd.command }
|
35
|
+
end
|
30
36
|
end
|
31
37
|
|
32
38
|
def fetch(remote, filename, options = nil)
|
@@ -39,6 +45,8 @@ module BiblioTech
|
|
39
45
|
options.optionally{ cmd.options << "-i #{options.id_file(remote)}" }
|
40
46
|
cmd.options << options.remote_file(remote, filename)
|
41
47
|
cmd.options << local_path
|
48
|
+
end.tap do |cmd|
|
49
|
+
log.info{ cmd.command }
|
42
50
|
end
|
43
51
|
end
|
44
52
|
|
@@ -47,6 +55,8 @@ module BiblioTech
|
|
47
55
|
cmd("scp") do |cmd|
|
48
56
|
cmd.options << options.local_file(filename)
|
49
57
|
cmd.options << options.remote_file(remote, filename)
|
58
|
+
end.tap do |cmd|
|
59
|
+
log.info{ cmd.command }
|
50
60
|
end
|
51
61
|
end
|
52
62
|
|
@@ -74,7 +84,9 @@ module BiblioTech
|
|
74
84
|
cmd.options << "-o #{opt}"
|
75
85
|
end
|
76
86
|
end
|
77
|
-
end - escaped_command(command_on_remote)
|
87
|
+
end - escaped_command(command_on_remote).tap do |cmd|
|
88
|
+
log.info{ cmd.command }
|
89
|
+
end
|
78
90
|
end
|
79
91
|
|
80
92
|
def wipe()
|
data/lib/bibliotech/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'bibliotech/backups/scheduler'
|
2
|
+
|
1
3
|
module BiblioTech
|
2
4
|
class Config
|
3
5
|
class MissingConfig < KeyError; end
|
@@ -12,6 +14,8 @@ module BiblioTech
|
|
12
14
|
:rsa_files => [ "rsa_files" ] ,
|
13
15
|
:ssh_options => [ "ssh_options" ] ,
|
14
16
|
:fetch_dir => [ "fetched_dir" ] ,
|
17
|
+
:log_target => [ "log" , "target" ],
|
18
|
+
:log_level => [ "log" , "level" ],
|
15
19
|
:file => [ "backups" , "file" ] ,
|
16
20
|
:filename => [ "backups" , "filename" ] ,
|
17
21
|
:backup_path => [ "backups" , "dir" ] ,
|
@@ -113,6 +117,32 @@ module BiblioTech
|
|
113
117
|
extract(steps, ["remotes"] + steps)
|
114
118
|
end
|
115
119
|
|
120
|
+
def log_target
|
121
|
+
target_path = local_get(:log_target)
|
122
|
+
case target_path
|
123
|
+
when "STDERR", "stderr"
|
124
|
+
return $stderr
|
125
|
+
when "STDOUT", "stdout"
|
126
|
+
return $stdout
|
127
|
+
else
|
128
|
+
require 'fileutils'
|
129
|
+
FileUtils.mkdir_p(File.dirname(target_path))
|
130
|
+
return File.open(target_path, "a")
|
131
|
+
end
|
132
|
+
rescue
|
133
|
+
warn "Trouble opening configured log file - logging to stderr"
|
134
|
+
warn $!.inspect
|
135
|
+
return $STDERR
|
136
|
+
end
|
137
|
+
|
138
|
+
def log_level
|
139
|
+
level = "debug"
|
140
|
+
optionally do
|
141
|
+
level = local_get(:log_level)
|
142
|
+
end
|
143
|
+
return BiblioTech::Logging.log_level(level)
|
144
|
+
end
|
145
|
+
|
116
146
|
def ssh_options(for_remote)
|
117
147
|
steps = steps_for(:ssh_options) + [for_remote]
|
118
148
|
steps_chain =
|
@@ -202,7 +232,7 @@ module BiblioTech
|
|
202
232
|
@backup_frequency ||= regularize_frequency(local_get(:backup_frequency))
|
203
233
|
end
|
204
234
|
|
205
|
-
def
|
235
|
+
def prune_schedules
|
206
236
|
local_get(:prune_schedule).map do |frequency, limit|
|
207
237
|
real_frequency = regularize_frequency(frequency)
|
208
238
|
unless real_frequency % backup_frequency == 0
|
@@ -215,11 +245,11 @@ module BiblioTech
|
|
215
245
|
else
|
216
246
|
Integer(limit)
|
217
247
|
end
|
218
|
-
[real_frequency, limit]
|
219
|
-
end.sort_by do |frequency, limit|
|
248
|
+
[frequency, real_frequency, limit]
|
249
|
+
end.sort_by do |freq_name, frequency, limit|
|
220
250
|
frequency
|
221
|
-
end.
|
222
|
-
|
251
|
+
end.map do |freq_name, frequency, limit|
|
252
|
+
Backups::Scheduler.new(freq_name, frequency, limit)
|
223
253
|
end
|
224
254
|
end
|
225
255
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module BiblioTech
|
4
|
+
module Logging
|
5
|
+
def self.logger
|
6
|
+
return @logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.logger=(value)
|
10
|
+
@logger = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def log
|
14
|
+
return BiblioTech::Logging.logger
|
15
|
+
end
|
16
|
+
module_function :log
|
17
|
+
|
18
|
+
def self.log_level(string)
|
19
|
+
case string
|
20
|
+
when /fatal/i
|
21
|
+
Logger::FATAL
|
22
|
+
when /error/i
|
23
|
+
Logger::ERROR
|
24
|
+
when /warn/i
|
25
|
+
Logger::WARN
|
26
|
+
when /info/i
|
27
|
+
Logger::INFO
|
28
|
+
when /debug/i
|
29
|
+
Logger::DEBUG
|
30
|
+
else
|
31
|
+
Logger::DEBUG
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bibliotech/application'
|
2
2
|
require 'bibliotech/backups/pruner'
|
3
|
+
require 'bibliotech/backups/scheduler'
|
3
4
|
require 'file-sandbox'
|
4
5
|
module BiblioTech
|
5
6
|
describe Backups::Pruner do
|
@@ -7,6 +8,7 @@ module BiblioTech
|
|
7
8
|
|
8
9
|
before :each do
|
9
10
|
sandbox.new :directory => "db_backups"
|
11
|
+
sandbox.new :file => '.bibliotech/config.yaml', :with_contents => "log:\n target: ../tmp/test.log"
|
10
12
|
end
|
11
13
|
|
12
14
|
let :app do
|
@@ -17,13 +19,17 @@ module BiblioTech
|
|
17
19
|
{:daily => 100}
|
18
20
|
end
|
19
21
|
|
22
|
+
let :config do
|
23
|
+
double(Config).tap do |config|
|
24
|
+
allow(config).to receive(:backup_path){ "db_backups" }
|
25
|
+
allow(config).to receive(:backup_name){ "testing" }
|
26
|
+
allow(config).to receive(:backup_frequency){ 60 * 24 }
|
27
|
+
allow(config).to receive(:schedules){ [ Backup::Scheduler.new("daily", 60 * 24, 100) ] }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
20
31
|
let :pruner do
|
21
|
-
|
22
|
-
:frequency => "daily",
|
23
|
-
:prefix => "testing",
|
24
|
-
:keep => schedule,
|
25
|
-
:dir => "db_backups"
|
26
|
-
}})
|
32
|
+
Backups::Pruner.new(config)
|
27
33
|
end
|
28
34
|
|
29
35
|
it "should generate a filename for current time" do
|
@@ -65,6 +71,115 @@ module BiblioTech
|
|
65
71
|
expect(pruner.backup_needed?(Time.now.utc)).to be_truthy
|
66
72
|
end
|
67
73
|
end
|
74
|
+
|
75
|
+
context "marking for pruning" do
|
76
|
+
before :each do
|
77
|
+
allow(config).to receive(:prune_schedules){
|
78
|
+
[
|
79
|
+
Backups::Scheduler.new("hourlies", 60, 48),
|
80
|
+
Backups::Scheduler.new("dailies", 24 * 60, 14),
|
81
|
+
Backups::Scheduler.new("weeklies", 7 * 24 * 60, 8),
|
82
|
+
Backups::Scheduler.new("monthlies", 30 * 24 * 60, nil)
|
83
|
+
]
|
84
|
+
}
|
85
|
+
|
86
|
+
Logging.log.debug{ "Start test" }
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should have schedules" do
|
90
|
+
expect(pruner.schedules.length).to eq(4)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should keep single backup" do
|
94
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(Time.now.utc)}"
|
95
|
+
|
96
|
+
expect(pruner.pruneable).to be_empty
|
97
|
+
|
98
|
+
expect(pruner.list.length).to eq(1)
|
99
|
+
pruner.list.each do |record|
|
100
|
+
expect(record.keep?).to eq(true)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should keep 48 hours of backup" do
|
105
|
+
now = Time.now.utc
|
106
|
+
(0..47).each do |interval|
|
107
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(Time.now.utc - interval * 60 * 60)}"
|
108
|
+
end
|
109
|
+
|
110
|
+
expect(pruner.pruneable).to be_empty
|
111
|
+
|
112
|
+
expect(pruner.list.length).to eq(48)
|
113
|
+
pruner.list.each do |record|
|
114
|
+
expect(record.keep?).to eq(true)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should prune old backups" do
|
119
|
+
now = Time.now.utc
|
120
|
+
(0..470).each do |interval|
|
121
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(now - interval * 60 * 60)}"
|
122
|
+
end
|
123
|
+
|
124
|
+
expect(pruner.pruneable.length).to eq(471 - 48 - (14 - 2) - 1) # 2 dailies hourly etc.
|
125
|
+
|
126
|
+
expect(pruner.list.length).to eq(471)
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
context "repruning" do
|
131
|
+
shared_examples_for "well mannered pruner" do
|
132
|
+
it "should not re-prune old backups" do
|
133
|
+
(0..47).each do |interval|
|
134
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(now - interval * 60 * 60)}"
|
135
|
+
end
|
136
|
+
(0..11).each do |interval|
|
137
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(now - 48 * 60 * 60 - interval * 24 * 60 * 60)}"
|
138
|
+
end
|
139
|
+
sandbox.new :file => "db_backups/#{pruner.filename_for(now - 48 * 60 * 60 - 12 * 24 * 60 * 60 - 7 * 24 * 60 * 60)}"
|
140
|
+
|
141
|
+
expect(pruner.pruneable).to be_empty
|
142
|
+
|
143
|
+
expect(pruner.list.length).to eq(48 + 12 + 1)
|
144
|
+
pruner.list.each do |record|
|
145
|
+
expect(record.keep?).to eq(true)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "right now" do
|
151
|
+
it_behaves_like "well mannered pruner" do
|
152
|
+
let :now do
|
153
|
+
Time.now.utc
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "30 minutes ago" do
|
159
|
+
it_behaves_like "well mannered pruner" do
|
160
|
+
let :now do
|
161
|
+
Time.now.utc - 30 * 60
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "60 minutes ago" do
|
167
|
+
it_behaves_like "well mannered pruner" do
|
168
|
+
let :now do
|
169
|
+
Time.now.utc - 60 * 60
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "90 minutes ago" do
|
175
|
+
it_behaves_like "well mannered pruner" do
|
176
|
+
let :now do
|
177
|
+
Time.now.utc - 90 * 60
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
68
183
|
end
|
69
184
|
|
70
185
|
describe Backups::PruneList do
|
@@ -23,7 +23,7 @@ module BiblioTech::Backups
|
|
23
23
|
|
24
24
|
describe "without a limit" do
|
25
25
|
let :scheduler do
|
26
|
-
Scheduler.new(60, nil)
|
26
|
+
Scheduler.new("hourly", 60, nil)
|
27
27
|
end
|
28
28
|
|
29
29
|
context "when there's more than enough backups" do
|
@@ -39,7 +39,7 @@ module BiblioTech::Backups
|
|
39
39
|
|
40
40
|
describe "with a limit" do
|
41
41
|
let :scheduler do
|
42
|
-
Scheduler.new(60, 8)
|
42
|
+
Scheduler.new("hourly", 60, 8)
|
43
43
|
end
|
44
44
|
|
45
45
|
context "when there's just enough backups" do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bibliotech
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Dorn
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-09
|
12
|
+
date: 2014-10-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: caliph
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- lib/bibliotech/builders/postgres.rb
|
88
88
|
- lib/bibliotech/builders/mysql.rb
|
89
89
|
- lib/bibliotech/config.rb
|
90
|
+
- lib/bibliotech/logger.rb
|
90
91
|
- lib/bibliotech/command_runner.rb
|
91
92
|
- lib/bibliotech/command_generator.rb
|
92
93
|
- lib/bibliotech/rake_lib.rb
|
@@ -128,7 +129,7 @@ rdoc_options:
|
|
128
129
|
- --main
|
129
130
|
- doc/README
|
130
131
|
- --title
|
131
|
-
- bibliotech-0.
|
132
|
+
- bibliotech-0.3.0 Documentation
|
132
133
|
require_paths:
|
133
134
|
- lib/
|
134
135
|
required_ruby_version: !ruby/object:Gem::Requirement
|