Skip to content

Commit

Permalink
Version 0.1.1
Browse files Browse the repository at this point in the history
* Ability to specify multiple profiles
* Executing without parameters runs all profiles
  • Loading branch information
winton committed Sep 7, 2009
1 parent 096b0ef commit 5d5d0e9
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 55 deletions.
2 changes: 1 addition & 1 deletion gemspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
s.name = GEM_NAME
s.platform = Gem::Platform::RUBY
s.require_path = "lib"
s.version = "0.1.0"
s.version = "0.1.1"
end
88 changes: 54 additions & 34 deletions lib/rbackup.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,81 @@
class RBackup

@@usage = <<-USAGE
Usage:
rbackup [YAML] PROFILE
rbackup [PROFILE]...
YAML
The path to your YAML configuration file.
Default: ~/.rbackup.yml
Example: mate #{File.expand_path(File.dirname(__FILE__) + '/../spec/fixtures/rbackup.yml')}
PROFILE
The name of the profile listed in your YAML configuration.
USAGE

attr_accessor :config, :destination, :exclude, :profile, :source
attr_accessor :profiles, :yaml

def initialize(*args)
if @profile = args.pop
@config = args.pop || File.expand_path("~/.rbackup.yml")
configure
else
error("You must specify a profile.")
@profiles = args
configure
if @profiles.empty?
@profiles = @yaml.keys
end
end

def configure
if File.exists?(@config)
yaml = File.open(@config)
yaml = YAML::load(yaml)
yaml = yaml[profile]
fix = lambda { |path| path.gsub ' ', '\ '}
@destination = fix.call(yaml['destination'])
@exclude = yaml['exclude'].to_a.collect &fix
@source = yaml['source'].to_a.collect &fix
if $TESTING
config = SPEC + '/fixtures/rbackup.yml'
else
config = File.expand_path("~/.rbackup.yml")
end
if File.exists?(config)
@yaml = File.open(config)
@yaml = YAML::load(yaml)
else
error("YAML configuration not found.")
end
end

def error(e)
" Error:\n #{e}\n#{@@usage}"
puts "\n Error:\n #{e}\n#{@@usage}"
exit
end

def esc(paths)
paths = paths.to_a
paths.collect! { |path| path.gsub('SPEC', SPEC) } if $TESTING
paths.collect { |path| path.gsub(' ', '\ ') }.join(' ')
end

def run
options = "--numeric-ids -EaxzS"
# --numeric-ids don't map uid/gid values by user/group name
# -E, --extended-attributes copy extended attributes, resource forks
# -a, --archive recursion and preserve almost everything (-rlptgoD)
# -x, --one-file-system don't cross filesystem boundaries
# -z, --compress compress file data during the transfer
# -S, --sparse handle sparse files efficiently

ex = exclude.collect { |e| "--exclude='#{e}'" }.join(' ')
# --exclude=PATTERN use one of these for each file you want to exclude

`rsync #{options} #{ex} #{source.join(' ')} #{destination}`
@profiles.each do |profile|
if config = yaml[profile]
destination = config['destination']
exclude = config['exclude'].to_a
source = config['source'].to_a

FileUtils.mkdir_p destination

options = "--numeric-ids -EaxzSv"
# --numeric-ids don't map uid/gid values by user/group name
# -E, --extended-attributes copy extended attributes, resource forks
# -a, --archive recursion and preserve almost everything (-rlptgoD)
# -x, --one-file-system don't cross filesystem boundaries
# -z, --compress compress file data during the transfer
# -S, --sparse handle sparse files efficiently
# -v, --verbose verbose

ex = exclude.collect { |e| "--exclude='#{e}'" }.join(' ')
# --exclude=PATTERN use one of these for each file you want to exclude

cmd = "rsync #{options} #{ex} #{esc(source)} #{esc(destination)}"
if $TESTING
`#{cmd}`
else
puts "Executing: #{cmd}"
system(cmd)
end
else
error("Profile #{profile} not found.")
end
end
end
end
4 changes: 2 additions & 2 deletions rbackup.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Gem::Specification.new do |s|
s.name = %q{rbackup}
s.version = "0.1.0"
s.version = "0.1.1"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Winton Welsh"]
Expand All @@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.email = %q{mail@wintoni.us}
s.executables = ["rbackup"]
s.extra_rdoc_files = ["README.markdown"]
s.files = ["bin", "bin/rbackup", "gemspec.rb", "lib", "lib/rbackup.rb", "MIT-LICENSE", "Rakefile", "rbackup.gemspec", "README.markdown", "spec", "spec/fixtures", "spec/fixtures/destination", "spec/fixtures/rbackup.yml", "spec/fixtures/source", "spec/fixtures/source/1.txt", "spec/fixtures/source/2.txt", "spec/rbackup_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
s.files = ["bin", "bin/rbackup", "gemspec.rb", "lib", "lib/rbackup.rb", "MIT-LICENSE", "Rakefile", "rbackup.gemspec", "README.markdown", "spec", "spec/fixtures", "spec/fixtures/destination", "spec/fixtures/rbackup.yml", "spec/fixtures/source", "spec/fixtures/source/1.txt", "spec/fixtures/source/2.txt", "spec/fixtures/source/3.txt", "spec/rbackup_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
s.homepage = %q{http://github.com/winton/rbackup}
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.1}
Expand Down
8 changes: 7 additions & 1 deletion spec/fixtures/rbackup.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
profile_1:
source: SPEC/fixtures/source/*
destination: SPEC/fixtures/destination
exclude: 2.txt
exclude: 2.txt
profile_2:
source: SPEC/fixtures/source/*
destination: SPEC/fixtures/destination
exclude:
- 2.txt
- 3.txt
1 change: 1 addition & 0 deletions spec/fixtures/source/3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3
36 changes: 19 additions & 17 deletions spec/rbackup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@

describe RBackup do
before(:each) do
@rb = RBackup.new(SPEC + '/fixtures/rbackup.yml', 'profile_1')
# Replace SPEC in config paths
replace = lambda { |s| s.gsub('SPEC', SPEC) }
@rb.destination = replace.call(@rb.destination)
@rb.exclude = @rb.exclude.collect &replace
@rb.source = @rb.source.collect &replace
# Empty destination folder
Dir[SPEC + '/fixtures/destination/*'].each do |path|
FileUtils.rm_rf(path)
end
# Debug
# debug @rb.destination
# debug @rb.exclude
# debug @rb.source
end

it "should load the YAML configuration" do
@rb.destination.should == "#{SPEC}/fixtures/destination"
@rb.exclude.should == [ "2.txt" ]
@rb.source.should == [ "#{SPEC}/fixtures/source/*" ]
it "should backup all profiles" do
RBackup.new.run
File.exists?(SPEC + '/fixtures/destination/1.txt').should == true
File.exists?(SPEC + '/fixtures/destination/2.txt').should == false
File.exists?(SPEC + '/fixtures/destination/3.txt').should == true
File.read(SPEC + '/fixtures/destination/1.txt').should == '1'
File.read(SPEC + '/fixtures/destination/3.txt').should == '3'
end

it "should backup profile_1" do
RBackup.new('profile_1').run
File.exists?(SPEC + '/fixtures/destination/1.txt').should == true
File.exists?(SPEC + '/fixtures/destination/2.txt').should == false
File.exists?(SPEC + '/fixtures/destination/3.txt').should == true
File.read(SPEC + '/fixtures/destination/1.txt').should == '1'
File.read(SPEC + '/fixtures/destination/3.txt').should == '3'
end

it "should backup" do
@rb.run
it "should backup profile_2" do
RBackup.new('profile_2').run
File.exists?(SPEC + '/fixtures/destination/1.txt').should == true
File.exists?(SPEC + '/fixtures/destination/2.txt').should == false
File.exists?(SPEC + '/fixtures/destination/3.txt').should == false
File.read(SPEC + '/fixtures/destination/1.txt').should == '1'
end
end

0 comments on commit 5d5d0e9

Please sign in to comment.