module Picnic
# Provides an interface for accessing your Picnic app's configuration file.
#
# Usage example:
#
# # Load the configuration from /etc/foo/config.yml
# Conf.load('foo')
#
# # The contents of config.yml is now available as follows:
# puts Conf[:server]
# puts Conf[:authentication][:username]
# # ... etc.
class Conf
$CONF ||= HashWithIndifferentAccess.new
$CONF[:log] ||= HashWithIndifferentAccess.new
$CONF[:log][:file] ||= STDOUT
$CONF[:log][:level] ||= 'DEBUG'
$CONF[:uri_path] ||= "/"
# Read a configuration option.
#
# For example:
# puts Conf[:server]
def self.[](key)
$CONF[key]
end
# Another way of reading a configuration option.
#
# The following statements are equivalent:
# puts Conf[:server]
# puts Conf.server
def self.method_missing(method, *args)
self[method]
end
# Returns the path to your application's example config file.
#
# The example config file should be in the root directory of
# your application's distribution package and should be called
# config.example.yml. This file is used as a template
# for your app's configuration, to be customized by the end
# user.
def self.example_config_file_path
if $APP_PATH
app_path = File.expand_path($APP_PATH)
else
caller.last =~ /^(.*?):\d+$/
app_path = File.dirname(File.expand_path($1))
end
app_path+'/../config.example.yml'
end
# Copies the example config file into the appropriate
# configuration directory.
#
# +app+:: The name of your application. For example: foo
# +dest_conf_file:: The path where the example conf file should be copied to.
# For example: /etc/foo/config.yml
def self.copy_example_config_file(app, dest_conf_file)
require 'fileutils'
example_conf_file = example_config_file_path
puts "\n#{app.to_s.upcase} SERVER HAS NOT YET BEEN CONFIGURED!!!\n"
puts "\nAttempting to copy sample configuration from '#{example_conf_file}' to '#{dest_conf_file}'...\n"
unless File.exists? example_conf_file
puts "\nThe example conf file does not exist! The author of #{app} may have forgotten to include it. You'll have to create the config file manually.\n"
exit 2
end
begin
dest_conf_file_dir = File.dirname(dest_conf_file)
FileUtils.mkpath(dest_conf_file_dir) unless File.exists? dest_conf_file_dir
FileUtils.cp(example_conf_file, dest_conf_file)
rescue Errno::EACCES
puts "\nIt appears that you do not have permissions to create the '#{dest_conf_file}' file. Try running this command using sudo (as root).\n"
exit 2
rescue => e
puts "\nFor some reason the '#{dest_conf_file}' file could not be created (#{e})."
puts "You'll have to copy the file manually. Use '#{example_conf_file}' as a template.\n"
exit 2
end
puts "\nA sample configuration has been created for you in '#{dest_conf_file}'. Please edit this file to" +
" suit your needs and then run #{app} again.\n"
exit 1
end
# Loads the configuration from the yaml file for the given app.
#
# app should be the name of your app; for example: foo.
#
# By default, the configuration will be loaded from /etc//config.yml.
# You can override this by setting a global $CONFIG_FILE variable.
def self.load(app)
conf_file = $CONFIG_FILE || "/etc/#{app.to_s.downcase}/config.yml"
puts "Loading configuration for #{app} from '#{conf_file}'..."
begin
conf_file = etc_conf = conf_file
unless File.exists? conf_file
# can use local config.yml file in case we're running non-gem installation
conf_file = File.dirname(File.expand_path(__FILE__))+"/../../config.yml"
end
unless File.exists? conf_file
copy_example_config_file(app, etc_conf)
end
loaded_conf = HashWithIndifferentAccess.new(YAML.load_file(conf_file))
if $CONF
$CONF = HashWithIndifferentAccess.new($CONF)
$CONF = $CONF.merge(loaded_conf)
else
$CONF = loaded_conf
end
$CONF[:log][:file] = STDOUT unless $CONF[:log][:file]
rescue
raise "Your #{app} configuration may be invalid."+
" Please double-check check your config.yml file."+
" Make sure that you are using spaces instead of tabs for your indentation!!" +
"\n\nTHE UNDERLYING ERROR WAS:\n#{$!}"
end
end
end
end