lib/backup/config.rb
require "backup/config/dsl"
require "backup/config/helpers"
module Backup
module Config
class Error < Backup::Error; end
DEFAULTS = {
config_file: "config.rb",
data_path: ".data",
tmp_path: ".tmp"
}
class << self
include Utilities::Helpers
attr_reader :user, :root_path, :config_file, :data_path, :tmp_path
# Loads the user's +config.rb+ and all model files.
def load(options = {})
update(options) # from the command line
unless File.exist?(config_file)
raise Error, "Could not find configuration file: '#{config_file}'."
end
config = File.read(config_file)
version = Backup::VERSION.split(".").first
unless config =~ /^# Backup v#{ version }\.x Configuration$/
raise Error, <<-EOS
Invalid Configuration File
The configuration file at '#{config_file}'
does not appear to be a Backup v#{version}.x configuration file.
If you have upgraded to v#{version}.x from a previous version,
you need to upgrade your configuration file.
Please see the instructions for upgrading in the Backup documentation.
EOS
end
dsl = DSL.new
dsl.instance_eval(config, config_file)
update(dsl._config_options) # from config.rb
update(options) # command line takes precedence
Dir[File.join(File.dirname(config_file), "models", "*.rb")].each do |model|
dsl.instance_eval(File.read(model), model)
end
end
def hostname
@hostname ||= run(utility(:hostname))
end
private
# If :root_path is set in the options, all paths will be updated.
# Otherwise, only the paths given will be updated.
def update(options = {})
root_path = options[:root_path].to_s.strip
new_root = root_path.empty? ? false : set_root_path(root_path)
DEFAULTS.each do |name, ending|
set_path_variable(name, options[name], ending, new_root)
end
end
# Sets the @root_path to the given +path+ and returns it.
# Raises an error if the given +path+ does not exist.
def set_root_path(path)
# allows #reset! to set the default @root_path,
# then use #update to set all other paths,
# without requiring that @root_path exist.
return @root_path if path == @root_path
path = File.expand_path(path)
unless File.directory?(path)
raise Error, <<-EOS
Root Path Not Found
When specifying a --root-path, the path must exist.
Path was: #{path}
EOS
end
@root_path = path
end
def set_path_variable(name, path, ending, root_path)
# strip any trailing '/' in case the user supplied this as part of
# an absolute path, so we can match it against File.expand_path()
path = path.to_s.sub(/\/\s*$/, "").lstrip
new_path = false
# If no path is given, the variable will not be set/updated
# unless a root_path was given. In which case the value will
# be updated with our default ending.
if path.empty?
new_path = File.join(root_path, ending) if root_path
else
# When a path is given, the variable will be set/updated.
# If the path is relative, it will be joined with root_path (if given),
# or expanded relative to PWD.
new_path = File.expand_path(path)
unless path == new_path
new_path = File.join(root_path, path) if root_path
end
end
instance_variable_set(:"@#{name}", new_path) if new_path
end
def reset!
@user = ENV["USER"] || Etc.getpwuid.name
@root_path = File.join(File.expand_path(ENV["HOME"] || ""), "Backup")
update(root_path: @root_path)
end
end
reset! # set defaults on load
end
end