require 'logger' require 'shellwords' module Daemonic class Configuration Invalid = Class.new(ArgumentError) attr_reader :eventual_config, :given_options def initialize(given_options, pwd) @given_options = given_options @pwd = pwd @eventual_config = {} end def command self[:command] end def daemonize? self[:daemonize] end def config_file self[:config_file] end def workers Integer(self[:workers] || "1") end def reload @eventual_config = {} @logger = nil load_options defaults load_options given_options load_options config_file_options if config_file load_options given_options logger.debug { to_h.inspect } validate end def working_dir self[:working_dir] end def program_name self[:program_name] || File.basename(working_dir) end def pidfile self[:pidfile] || File.join(working_dir, "tmp/#{program_name}.pid") end def logfile self[:logfile] || STDOUT end def logger @logger ||= ::Logger.new(logfile).tap { |logger| logger.formatter = proc { |severity, datetime, progname, msg| "[#{severity}] [#{datetime}] [#{program_name}] [#{Process.pid}] #{msg}\n" } logger.level = ::Logger.const_get(loglevel) } end def to_h eventual_config end def loglevel (self[:loglevel] || "INFO").to_s.upcase end protected def [](key) eventual_config[key.to_s] end def []=(key, value) eventual_config[key.to_s] = value end private def load_options(options) options.each do |key, value| self[key] = value end end def config_file_options contents = File.open(config_file, 'r:utf-8').read args = Shellwords.split(contents) CLI.parse(args) end def validate raise Invalid, "No command specified" if command.nil? end def defaults { :workers => 1, :working_dir => @pwd } end end end