robinsp-backitup 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +14 -0
- data/Rakefile +16 -0
- data/backitup.gemspec +36 -0
- data/bin/backitup +3 -0
- data/lib/back_it_up/command.rb +21 -0
- data/lib/back_it_up/config.rb +55 -0
- data/lib/back_it_up/file_packager.rb +38 -0
- data/lib/back_it_up/runner.rb +11 -0
- data/lib/back_it_up.rb +3 -0
- data/spec/config_spec.rb +104 -0
- data/spec/file_packager_spec.rb +67 -0
- data/spec/runner_spec.rb +51 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/test-config.backitup +11 -0
- metadata +84 -0
data/Manifest
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
bin/backitup
|
2
|
+
spec/test-config.backitup
|
3
|
+
spec/file_packager_spec.rb
|
4
|
+
spec/config_spec.rb
|
5
|
+
spec/runner_spec.rb
|
6
|
+
spec/spec.opts
|
7
|
+
spec/spec_helper.rb
|
8
|
+
Rakefile
|
9
|
+
Manifest
|
10
|
+
lib/back_it_up.rb
|
11
|
+
lib/back_it_up/config.rb
|
12
|
+
lib/back_it_up/file_packager.rb
|
13
|
+
lib/back_it_up/command.rb
|
14
|
+
lib/back_it_up/runner.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('backitup', '0.0.1') do |p|
|
6
|
+
p.description = "Simple backup"
|
7
|
+
p.url = "http://github.com/robinsp/backitup"
|
8
|
+
p.author = "Robin Spainhour"
|
9
|
+
p.email = "robin@robinspainhour.com"
|
10
|
+
p.ignore_pattern = ["tmp/*"]
|
11
|
+
p.dependencies = ["rubyzip"]
|
12
|
+
end
|
13
|
+
|
14
|
+
Spec::Rake::SpecTask.new do |t|
|
15
|
+
t.warning = true
|
16
|
+
end
|
data/backitup.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{backitup}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Robin Spainhour"]
|
9
|
+
s.date = %q{2009-05-27}
|
10
|
+
s.default_executable = %q{backitup}
|
11
|
+
s.description = %q{Simple backup}
|
12
|
+
s.email = %q{robin@robinspainhour.com}
|
13
|
+
s.executables = ["backitup"]
|
14
|
+
s.extra_rdoc_files = ["bin/backitup", "lib/back_it_up.rb", "lib/back_it_up/config.rb", "lib/back_it_up/file_packager.rb", "lib/back_it_up/command.rb", "lib/back_it_up/runner.rb"]
|
15
|
+
s.files = ["bin/backitup", "spec/test-config.backitup", "spec/file_packager_spec.rb", "spec/config_spec.rb", "spec/runner_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "Rakefile", "Manifest", "lib/back_it_up.rb", "lib/back_it_up/config.rb", "lib/back_it_up/file_packager.rb", "lib/back_it_up/command.rb", "lib/back_it_up/runner.rb", "backitup.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://github.com/robinsp/backitup}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Backitup"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{backitup}
|
21
|
+
s.rubygems_version = %q{1.3.2}
|
22
|
+
s.summary = %q{Simple backup}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 3
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
+
s.add_runtime_dependency(%q<rubyzip>, [">= 0"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<rubyzip>, [">= 0"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<rubyzip>, [">= 0"])
|
35
|
+
end
|
36
|
+
end
|
data/bin/backitup
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'back_it_up'
|
2
|
+
|
3
|
+
module BackItUp
|
4
|
+
class Command
|
5
|
+
def self.run!(args=ARGV)
|
6
|
+
filename = args.shift
|
7
|
+
if filename == nil || filename == ""
|
8
|
+
usage
|
9
|
+
else
|
10
|
+
BackItUp::Runner.new(filename)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.usage
|
16
|
+
puts "Usage: backitup config-file"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
BackItUp::Command.run!
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module BackItUp
|
2
|
+
class Config
|
3
|
+
attr_reader :files, :dirs, :dest_filename
|
4
|
+
|
5
|
+
def initialize(file_handle)
|
6
|
+
@files = []
|
7
|
+
@dirs = []
|
8
|
+
|
9
|
+
file_content = ""
|
10
|
+
|
11
|
+
while l = file_handle.gets do
|
12
|
+
file_content << l
|
13
|
+
end
|
14
|
+
|
15
|
+
eval(file_content)
|
16
|
+
end
|
17
|
+
|
18
|
+
def backup
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
|
22
|
+
# Full path and name of the package file to create.
|
23
|
+
# A timestamp will be appended to the filename and the extension is
|
24
|
+
# determined by the packager used.
|
25
|
+
#
|
26
|
+
# # Using the zip packager with a destination file setting:
|
27
|
+
# /var/backup/mybackup
|
28
|
+
#
|
29
|
+
# # ...then the final result might be:
|
30
|
+
# /var/backup/mybackup_200900527_053032.zip
|
31
|
+
def destination_file(filename)
|
32
|
+
raise "Invalid destination file." if File.directory?(filename)
|
33
|
+
@dest_filename = filename
|
34
|
+
end
|
35
|
+
|
36
|
+
def file(filename = nil)
|
37
|
+
|
38
|
+
unless (filename == "" || filename == nil)
|
39
|
+
if File.exists?(filename)
|
40
|
+
if File.directory? filename
|
41
|
+
@dirs << filename
|
42
|
+
else
|
43
|
+
@files << filename
|
44
|
+
end
|
45
|
+
|
46
|
+
else
|
47
|
+
puts "WARNING: File #{filename} could not be found"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method :dir, :file
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'zip/zip'
|
3
|
+
|
4
|
+
module BackItUp
|
5
|
+
class FilePackager
|
6
|
+
INVALID_CONFIG_MSG = "Invalid config"
|
7
|
+
attr_reader :produced_file
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
raise INVALID_CONFIG_MSG if config == nil || !config.is_a?(Config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def package
|
15
|
+
target_filename = create_target_filename
|
16
|
+
|
17
|
+
prefix = File.basename(target_filename, ".zip")
|
18
|
+
|
19
|
+
Zip::ZipFile.open(target_filename, Zip::ZipFile::CREATE) do |zip|
|
20
|
+
@config.files.each do |filename|
|
21
|
+
zip.add("./#{prefix}#{filename}", filename)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
@produced_file = target_filename
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
def create_target_filename
|
30
|
+
@config.dest_filename + "_#{timestamp}" + ".zip"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def timestamp
|
35
|
+
Time.now.strftime("%Y%m%d_%H%M%S")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BackItUp
|
2
|
+
class Runner
|
3
|
+
def initialize(filename)
|
4
|
+
raise "Couldn't find file #{filename}" unless File.exists?(filename)
|
5
|
+
|
6
|
+
file = File.open(filename)
|
7
|
+
config = Config.new(file)
|
8
|
+
puts "Wrote backup to: #{ FilePackager.new(config).package }"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/back_it_up.rb
ADDED
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe BackItUp::Config do
|
4
|
+
|
5
|
+
it "should eval the file content" do
|
6
|
+
file = mock('mock-file')
|
7
|
+
file.expects(:gets).twice.returns("file 'string'", nil)
|
8
|
+
|
9
|
+
BackItUp::Config.any_instance.expects(:file).with("string")
|
10
|
+
BackItUp::Config.new(file)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to handle our test config" do
|
14
|
+
test_file = File.dirname(__FILE__) + "/test-config.backitup"
|
15
|
+
|
16
|
+
BackItUp::Config.new(File.open(test_file))
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "" do
|
20
|
+
before do
|
21
|
+
mock_file = mock('mock-file')
|
22
|
+
mock_file.stubs(:gets).returns(nil)
|
23
|
+
@config = BackItUp::Config.new(mock_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have empty array of files by default" do
|
27
|
+
@config.files.should == []
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have empty array of dirs by default" do
|
31
|
+
@config.dirs.should == []
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "destination_file()" do
|
35
|
+
|
36
|
+
it "should save the filename to dest_filename attribute" do
|
37
|
+
filename = File.expand_path(File.dirname(__FILE__) + "backup")
|
38
|
+
@config.destination_file(filename)
|
39
|
+
@config.dest_filename.should == filename
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should fail if filename is an existing directory" do
|
43
|
+
filename = File.expand_path(File.dirname(__FILE__) )
|
44
|
+
lambda { @config.destination_file(filename) }.should raise_error("Invalid destination file.")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "backup()" do
|
49
|
+
it "should yield to block" do
|
50
|
+
test_value = false
|
51
|
+
|
52
|
+
@config.backup do
|
53
|
+
test_value = true
|
54
|
+
end
|
55
|
+
|
56
|
+
test_value.should be_true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "file()" do
|
61
|
+
before do
|
62
|
+
@valid_file = File.expand_path(File.dirname(__FILE__) + '/test-config.backitup')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should warn if file doesn't exist" do
|
66
|
+
file_name = "should-not-exist"
|
67
|
+
BackItUp::Config.any_instance.expects(:puts).with("WARNING: File should-not-exist could not be found")
|
68
|
+
@config.file(file_name)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not add non-existning files to files attribute" do
|
72
|
+
file_name = "should-not-exist"
|
73
|
+
@config.file(file_name)
|
74
|
+
@config.files.should be_empty
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should allow nil file name argument" do
|
78
|
+
@config.file
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should check if file exists" do
|
82
|
+
File.expects(:exists?).with("filename").returns(false)
|
83
|
+
@config.file("filename")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should add the file to the files array" do
|
87
|
+
@config.file(@valid_file)
|
88
|
+
@config.files.pop.should == @valid_file
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should check if file argument is directory" do
|
92
|
+
File.expects(:directory?).returns(false)
|
93
|
+
@config.file(@valid_file)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should add directories to dirs array" do
|
97
|
+
File.stubs(:directory?).returns(true)
|
98
|
+
@config.file(@valid_file)
|
99
|
+
@config.dirs.pop.should == @valid_file
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe BackItUp::FilePackager do
|
4
|
+
describe "constructor" do
|
5
|
+
it "should fail if initialized with nil config" do
|
6
|
+
lambda { BackItUp::FilePackager.new(nil) }.should raise_error(BackItUp::FilePackager::INVALID_CONFIG_MSG )
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should fail if initialized without config" do
|
10
|
+
lambda { BackItUp::FilePackager.new("a string") }.should raise_error(BackItUp::FilePackager::INVALID_CONFIG_MSG )
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "package()" do
|
15
|
+
before do
|
16
|
+
@first_file_to_add = "/etc/passwd"
|
17
|
+
@second_file_to_add = "/etc/httpd/apache.cfg"
|
18
|
+
|
19
|
+
@configured_dst_filename = "/backups/a-file-name"
|
20
|
+
mock_config = mock
|
21
|
+
mock_config.stubs(:is_a? => true)
|
22
|
+
mock_config.stubs(:dest_filename).returns(@configured_dst_filename)
|
23
|
+
mock_config.stubs(:files).returns([@first_file_to_add, @second_file_to_add])
|
24
|
+
|
25
|
+
@mock_zip = mock("mock-zip")
|
26
|
+
@mock_zip.stubs(:add)
|
27
|
+
Zip::ZipFile.stubs(:open).yields(@mock_zip)
|
28
|
+
|
29
|
+
@packager = BackItUp::FilePackager.new(mock_config)
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should use the destination_file setting from config" do
|
34
|
+
@packager.package.should =~ /^#{@configured_dst_filename}/
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should append timestamp and zip suffix to destination file name from config" do
|
38
|
+
@packager.package.should =~ /^#{@configured_dst_filename}_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9].zip/
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return name of produced file" do
|
42
|
+
@packager.package.should_not be_nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should set the produced_file attribute" do
|
46
|
+
@packager.package.should == @packager.produced_file
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should create the file package" do
|
50
|
+
Zip::ZipFile.expects(:open).with() do |name, type|
|
51
|
+
(name =~ /^#{@configured_dst_filename}/ && type == Zip::ZipFile::CREATE)
|
52
|
+
end
|
53
|
+
|
54
|
+
@packager.package
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should add files to the zip" do
|
58
|
+
prefix = "./#{File.basename(@configured_dst_filename)}"
|
59
|
+
|
60
|
+
@mock_zip.expects(:add).with( regexp_matches(/^#{prefix}.*#{@first_file_to_add}$/), @first_file_to_add )
|
61
|
+
@mock_zip.expects(:add).with( regexp_matches(/^#{prefix}.*#{@second_file_to_add}$/), @second_file_to_add )
|
62
|
+
|
63
|
+
@packager.package
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe BackItUp::Runner do
|
4
|
+
|
5
|
+
it "should require valid file name to initialize" do
|
6
|
+
name_of_invalid_file = "invalidfile.text"
|
7
|
+
lambda {BackItUp::Runner.new(name_of_invalid_file)}.should raise_error("Couldn't find file #{name_of_invalid_file}")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "with valid file" do
|
11
|
+
before do
|
12
|
+
@package_result_filename = "package_result_filename"
|
13
|
+
|
14
|
+
File.stubs(:exists?).returns(true)
|
15
|
+
@filename = "a-file-name"
|
16
|
+
|
17
|
+
@file = mock('fake file handle')
|
18
|
+
File.stubs(:open).with(@filename).returns(@file)
|
19
|
+
|
20
|
+
@mock_config = mock('mock-config')
|
21
|
+
BackItUp::Config.stubs(:new).returns(@mock_config)
|
22
|
+
|
23
|
+
@mock_packager
|
24
|
+
@mock_packager.stubs(:package).returns(@package_result_filename)
|
25
|
+
BackItUp::FilePackager.stubs(:new).returns(@mock_packager)
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
it "should create Config with file handle" do
|
30
|
+
BackItUp::Config.expects(:new).with( @file ).returns(@mock_config)
|
31
|
+
BackItUp::Runner.new(@filename)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should create Packager with Config" do
|
35
|
+
BackItUp::FilePackager.expects(:new).with(@mock_config)
|
36
|
+
BackItUp::Runner.new(@filename)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should start packaging" do
|
40
|
+
@mock_packager.expects(:package)
|
41
|
+
BackItUp::Runner.new(@filename)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should print name of packaged file" do
|
45
|
+
BackItUp::Runner.any_instance.expects(:puts).with {|s| s =~ /#{@package_result_filename}/ }
|
46
|
+
BackItUp::Runner.new(@filename)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: robinsp-backitup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Robin Spainhour
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-27 00:00:00 -07:00
|
13
|
+
default_executable: backitup
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rubyzip
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Simple backup
|
26
|
+
email: robin@robinspainhour.com
|
27
|
+
executables:
|
28
|
+
- backitup
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- bin/backitup
|
33
|
+
- lib/back_it_up.rb
|
34
|
+
- lib/back_it_up/config.rb
|
35
|
+
- lib/back_it_up/file_packager.rb
|
36
|
+
- lib/back_it_up/command.rb
|
37
|
+
- lib/back_it_up/runner.rb
|
38
|
+
files:
|
39
|
+
- bin/backitup
|
40
|
+
- spec/test-config.backitup
|
41
|
+
- spec/file_packager_spec.rb
|
42
|
+
- spec/config_spec.rb
|
43
|
+
- spec/runner_spec.rb
|
44
|
+
- spec/spec.opts
|
45
|
+
- spec/spec_helper.rb
|
46
|
+
- Rakefile
|
47
|
+
- Manifest
|
48
|
+
- lib/back_it_up.rb
|
49
|
+
- lib/back_it_up/config.rb
|
50
|
+
- lib/back_it_up/file_packager.rb
|
51
|
+
- lib/back_it_up/command.rb
|
52
|
+
- lib/back_it_up/runner.rb
|
53
|
+
- backitup.gemspec
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/robinsp/backitup
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options:
|
58
|
+
- --line-numbers
|
59
|
+
- --inline-source
|
60
|
+
- --title
|
61
|
+
- Backitup
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "1.2"
|
75
|
+
version:
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
rubyforge_project: backitup
|
79
|
+
rubygems_version: 1.2.0
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Simple backup
|
83
|
+
test_files: []
|
84
|
+
|