# encoding: utf-8 module Backup module Config # Context for loading user config.rb and model files. class DSL class Error < Backup::Error; end Model = Backup::Model class << self private # List the available database, storage, syncer, compressor, encryptor # and notifier constants. These are used to define constant names within # Backup::Config::DSL so that users may use a constant instead of a string. # Nested namespaces are represented using Hashs. Deep nesting supported. # # Example, instead of: # database "MySQL" do |mysql| # sync_with "RSync::Local" do |rsync| # # You can do: # database MySQL do |mysql| # sync_with RSync::Local do |rsync| # def add_dsl_constants create_modules( DSL, [ # Databases ['MySQL', 'PostgreSQL', 'MongoDB', 'Redis', 'Riak', 'OpenLDAP', 'SQLite', 'RemoteMySQL' ], # Storages ['S3', 'CloudFiles', 'Ninefold', 'Dropbox', 'FTP', 'SFTP', 'SCP', 'RSync', 'Local', 'Qiniu'], # Compressors ['Gzip', 'Bzip2', 'Custom', 'Pbzip2', 'Lzma'], # Encryptors ['OpenSSL', 'GPG'], # Syncers [ { 'Cloud' => ['CloudFiles', 'S3'] }, { 'RSync' => ['Push', 'Pull', 'Local'] } ], # Notifiers ['Mail', 'Twitter', 'Campfire', 'Prowl', 'Hipchat', 'PagerDuty', 'Pushover', 'HttpPost', 'Nagios', 'Slack', 'FlowDock', 'Zabbix', 'Ses', 'DataDog', 'Command'] ] ) end def create_modules(scope, names) names.flatten.each do |name| if name.is_a?(Hash) name.each do |key, val| create_modules(get_or_create_empty_module(scope, key), [val]) end else get_or_create_empty_module(scope, name) end end end def get_or_create_empty_module(scope, const) if scope.const_defined?(const) scope.const_get(const) else scope.const_set(const, Module.new) end end end add_dsl_constants # add constants on load attr_reader :_config_options def initialize @_config_options = {} end # Allow users to set command line path options in config.rb [:root_path, :data_path, :tmp_path].each do |name| define_method name, lambda {|path| _config_options[name] = path } end # Allows users to create preconfigured models. def preconfigure(name, &block) unless name.is_a?(String) && name =~ /^[A-Z]/ raise Error, "Preconfigured model names must be given as a string " + "and start with a capital letter." end if DSL.const_defined?(name) raise Error, "'#{ name }' is already in use " + "and can not be used for a preconfigured model." end DSL.const_set(name, Class.new(Model)) DSL.const_get(name).preconfigure(&block) end end end end