lib/gdk/backup.rb (66 lines of code) (raw):
# frozen_string_literal: true
require 'pathname'
module GDK
class Backup
SourceFileOutsideOfGdk = Class.new(StandardError)
SourceFileDoesntExist = Class.new(StandardError)
attr_reader :source_file
def self.backup_root
GDK.root.join('.backups')
end
def initialize(source_file)
@source_file = Pathname.new(source_file.to_s).expand_path
validate!
end
def backup!(advise: true)
ensure_backup_directory_exists
make_backup_of_source_file
advise_user_backup if advise
true
end
def restore!(advise: true)
return false unless destination_file.exist?
restore_backup
advise_user_restore if advise
true
end
def destination_file
@destination_file ||= backup_root.join("#{relative_source_file.to_s.gsub('/', '__')}.#{Time.now.strftime('%Y%m%d%H%M%S')}")
end
def relative_source_file
@relative_source_file ||= source_file.relative_path_from(GDK.root)
end
def recover_cmd_string
<<~CMD
cp -f '#{destination_file}' \\
'#{source_file}'
CMD
end
private
def relative_destination_file
@relative_destination_file ||= destination_file.relative_path_from(GDK.root)
end
def validate!
raise SourceFileDoesntExist unless source_file.exist?
raise SourceFileOutsideOfGdk unless source_file.to_s.start_with?(GDK.root.to_s)
true
end
def backup_root
@backup_root ||= self.class.backup_root
end
def ensure_backup_directory_exists
backup_root.mkpath
end
def advise_user_backup
GDK::Output.info("A backup of '#{relative_source_file}' has been made at '#{relative_destination_file}'.")
end
def advise_user_restore
GDK::Output.info("Backup '#{relative_destination_file}' has been restored to '#{relative_source_file}'.")
end
def make_backup_of_source_file
FileUtils.mv(source_file.to_s, destination_file.to_s)
end
def restore_backup
FileUtils.cp(destination_file.to_s, source_file.to_s)
end
end
end