configurability 1.0.10 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/History.rdoc +8 -0
- data/Manifest.txt +1 -1
- data/README.rdoc +28 -12
- data/Rakefile +2 -0
- data/lib/configurability.rb +74 -32
- data/lib/configurability/config.rb +15 -1
- data/lib/configurability/logging.rb +300 -0
- data/spec/configurability/config_spec.rb +41 -29
- data/spec/configurability/deferredconfig_spec.rb +1 -1
- data/spec/configurability_spec.rb +73 -0
- data/spec/lib/helpers.rb +4 -0
- metadata +68 -34
- metadata.gz.sig +0 -0
- data/lib/configurability/logformatter.rb +0 -60
    
        data.tar.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/History.rdoc
    CHANGED
    
    | @@ -1,3 +1,11 @@ | |
| 1 | 
            +
            == v1.1.0 [2012-04-25] Michael Granger <ged@FaerieMUD.org>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Add a 'defaults' API that allows defaults to be gathered from any
         | 
| 4 | 
            +
            object with configurability and merged into a hash keyed by the
         | 
| 5 | 
            +
            object's config_key. This hash can be used to generate an initial
         | 
| 6 | 
            +
            unified config file for all configurable parts of a given system.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
             | 
| 1 9 | 
             
            == v1.0.10 [2012-03-13] Michael Granger <ged@FaerieMUD.org>
         | 
| 2 10 |  | 
| 3 11 | 
             
            - Fix log level message.
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -10,7 +10,7 @@ lib/configurability.rb | |
| 10 10 | 
             
            lib/configurability/behavior.rb
         | 
| 11 11 | 
             
            lib/configurability/config.rb
         | 
| 12 12 | 
             
            lib/configurability/deferredconfig.rb
         | 
| 13 | 
            -
            lib/configurability/ | 
| 13 | 
            +
            lib/configurability/logging.rb
         | 
| 14 14 | 
             
            spec/configurability/config_spec.rb
         | 
| 15 15 | 
             
            spec/configurability/deferredconfig_spec.rb
         | 
| 16 16 | 
             
            spec/configurability_spec.rb
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -1,14 +1,19 @@ | |
| 1 1 | 
             
            = Configurability
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            home :: https://bitbucket.org/ged/configurability
         | 
| 4 | 
            +
            code :: https://bitbucket.org/ged/configurability
         | 
| 5 | 
            +
            docs :: http://deveiate.org/code/configurability
         | 
| 6 | 
            +
            github :: https://github.com/ged/configurability
         | 
| 4 7 |  | 
| 5 8 |  | 
| 6 9 | 
             
            == Description
         | 
| 7 10 |  | 
| 8 | 
            -
            Configurability is a  | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
            configuration  | 
| 11 | 
            +
            Configurability is a unified, unintrusive, assume-nothing configuration system
         | 
| 12 | 
            +
            for Ruby. It lets you keep the configuration for multiple objects in a single
         | 
| 13 | 
            +
            config file, load the file when it's convenient for you, and distribute the
         | 
| 14 | 
            +
            configuration when you're ready, sending it everywhere it needs to go with a
         | 
| 15 | 
            +
            single action.
         | 
| 16 | 
            +
             | 
| 12 17 |  | 
| 13 18 |  | 
| 14 19 | 
             
            == Installation
         | 
| @@ -93,6 +98,9 @@ as a Symbol: | |
| 93 98 |  | 
| 94 99 | 
             
            === Changing How an Object Is Configured
         | 
| 95 100 |  | 
| 101 | 
            +
            [:FIXME:] Explain the 'at least once' configuration call, and how to handle
         | 
| 102 | 
            +
            being called with 'nil'.
         | 
| 103 | 
            +
             | 
| 96 104 | 
             
            You can also change what happens when an object is configured by implementing
         | 
| 97 105 | 
             
            a `#configure` method that takes the config section as an argument:
         | 
| 98 106 |  | 
| @@ -216,19 +224,27 @@ then dump it to a YAML string: | |
| 216 224 |  | 
| 217 225 | 
             
                config.dump
         | 
| 218 226 | 
             
            	# => "--- \ndatabase: \n  development: \n    adapter: sqlite3\n   
         | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 227 | 
            +
            		database: db/dev.db\n    pool: 5\n    timeout: 5000\n  testing: \n   
         | 
| 228 | 
            +
            		adapter: mysql\n    database: t_fixedassets\n    pool: 2\n    timeout:
         | 
| 229 | 
            +
            		5000\n  production: \n    adapter: postgres\n    database:
         | 
| 230 | 
            +
            		fixedassets\n    pool: 25\n    timeout: 50\nldap: \n  uri:
         | 
| 231 | 
            +
            		ldap://ldap.acme.com/dc=acme,dc=com\n  bind_dn:
         | 
| 232 | 
            +
            		cn=web,dc=acme,dc=com\n  bind_pass: Mut@ge.Mix@ge\nbranding: \n 
         | 
| 233 | 
            +
            		header: \"#333\"\n  title: \"#dedede\"\n  anchor: \"#9fc8d4\"\n"
         | 
| 226 234 |  | 
| 227 235 | 
             
            or write it back to the file it was loaded from:
         | 
| 228 236 |  | 
| 229 237 | 
             
            	config.write
         | 
| 230 238 |  | 
| 231 239 |  | 
| 240 | 
            +
            == Configuration Defaults
         | 
| 241 | 
            +
             | 
| 242 | 
            +
            Configurability also supports an API for generating a new config file with
         | 
| 243 | 
            +
            defaults for all objects with Configurability.
         | 
| 244 | 
            +
             | 
| 245 | 
            +
            [:FIXME:] Finish up the documentation
         | 
| 246 | 
            +
             | 
| 247 | 
            +
             | 
| 232 248 | 
             
            == Development
         | 
| 233 249 |  | 
| 234 250 | 
             
            You can submit bug reports, suggestions, clone it with Mercurial, and
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -10,6 +10,7 @@ end | |
| 10 10 | 
             
            Hoe.plugin :mercurial
         | 
| 11 11 | 
             
            Hoe.plugin :yard
         | 
| 12 12 | 
             
            Hoe.plugin :signing
         | 
| 13 | 
            +
            Hoe.plugin :deveiate
         | 
| 13 14 |  | 
| 14 15 | 
             
            Hoe.plugins.delete :rubyforge
         | 
| 15 16 |  | 
| @@ -25,6 +26,7 @@ hoespec = Hoe.spec 'configurability' do | |
| 25 26 | 
             
            	self.dependency 'simplecov', '~> 0.3', :developer
         | 
| 26 27 |  | 
| 27 28 | 
             
            	self.spec_extras[:licenses] = ["BSD"]
         | 
| 29 | 
            +
            	self.spec_extras[:rdoc_options] = ['-f', 'fivefish', '-t', 'Configurability Toolkit']
         | 
| 28 30 | 
             
            	self.require_ruby_version( '>= 1.8.7' )
         | 
| 29 31 |  | 
| 30 32 | 
             
            	self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
         | 
    
        data/lib/configurability.rb
    CHANGED
    
    | @@ -11,14 +11,19 @@ require 'yaml' | |
| 11 11 | 
             
            module Configurability
         | 
| 12 12 |  | 
| 13 13 | 
             
            	# Library version constant
         | 
| 14 | 
            -
            	VERSION = '1.0 | 
| 14 | 
            +
            	VERSION = '1.1.0'
         | 
| 15 15 |  | 
| 16 16 | 
             
            	# Version-control revision constant
         | 
| 17 | 
            -
            	REVISION = %q$Revision:  | 
| 17 | 
            +
            	REVISION = %q$Revision: e56100a012e3 $
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
            	require 'configurability/logging'
         | 
| 21 | 
            +
            	extend Configurability::Logging
         | 
| 18 22 |  | 
| 19 | 
            -
            	require 'configurability/logformatter'
         | 
| 20 23 | 
             
            	require 'configurability/deferredconfig'
         | 
| 21 24 |  | 
| 25 | 
            +
            	autoload :Config, 'configurability/config'
         | 
| 26 | 
            +
             | 
| 22 27 |  | 
| 23 28 | 
             
            	### The objects that have had Configurability added to them
         | 
| 24 29 | 
             
            	@configurable_objects = []
         | 
| @@ -31,16 +36,6 @@ module Configurability | |
| 31 36 | 
             
            	### are the config section it was called with
         | 
| 32 37 | 
             
            	@configured = Hash.new( false )
         | 
| 33 38 |  | 
| 34 | 
            -
            	### Logging
         | 
| 35 | 
            -
            	@default_logger = Logger.new( $stderr )
         | 
| 36 | 
            -
            	@default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
         | 
| 37 | 
            -
             | 
| 38 | 
            -
            	@default_log_formatter = Configurability::LogFormatter.new( @default_logger )
         | 
| 39 | 
            -
            	@default_logger.formatter = @default_log_formatter
         | 
| 40 | 
            -
             | 
| 41 | 
            -
            	@logger = @default_logger
         | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 39 | 
             
            	class << self
         | 
| 45 40 |  | 
| 46 41 | 
             
            		# the Array of objects that have had Configurability added to them
         | 
| @@ -52,17 +47,15 @@ module Configurability | |
| 52 47 | 
             
            		# the hash of configure methods => config sections which have already been installed
         | 
| 53 48 | 
             
            		attr_reader :configured
         | 
| 54 49 |  | 
| 55 | 
            -
             | 
| 56 | 
            -
            		# reset
         | 
| 57 | 
            -
            		attr_accessor :default_log_formatter
         | 
| 50 | 
            +
            	end
         | 
| 58 51 |  | 
| 59 | 
            -
            		# the logger that will be used when the logging subsystem is reset
         | 
| 60 | 
            -
            		attr_accessor :default_logger
         | 
| 61 52 |  | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
            		 | 
| 53 | 
            +
            	### Get the library version. If +include_buildnum+ is true, the version string will
         | 
| 54 | 
            +
            	### include the VCS rev ID.
         | 
| 55 | 
            +
            	def self::version_string( include_buildnum=false )
         | 
| 56 | 
            +
            		vstring = "%s %s" % [ self.name, VERSION ]
         | 
| 57 | 
            +
            		vstring << " (build %s)" % [ REVISION[/: ([[:xdigit:]]+)/, 1] || '0' ] if include_buildnum
         | 
| 58 | 
            +
            		return vstring
         | 
| 66 59 | 
             
            	end
         | 
| 67 60 |  | 
| 68 61 |  | 
| @@ -128,14 +121,6 @@ module Configurability | |
| 128 121 | 
             
            	end
         | 
| 129 122 |  | 
| 130 123 |  | 
| 131 | 
            -
            	### Reset the global logger object to the default
         | 
| 132 | 
            -
            	def self::reset_logger
         | 
| 133 | 
            -
            		self.logger = self.default_logger
         | 
| 134 | 
            -
            		self.logger.level = Logger::WARN
         | 
| 135 | 
            -
            		self.logger.formatter = self.default_log_formatter
         | 
| 136 | 
            -
            	end
         | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 124 | 
             
            	### Install the appropriate section of the +config+ into the given +object+.
         | 
| 140 125 | 
             
            	def self::install_config( config, object )
         | 
| 141 126 | 
             
            		section = object.config_key.to_sym
         | 
| @@ -155,8 +140,7 @@ module Configurability | |
| 155 140 | 
             
            				section = nil
         | 
| 156 141 | 
             
            			end
         | 
| 157 142 | 
             
            		else
         | 
| 158 | 
            -
            			self.log.info "   | 
| 159 | 
            -
            				[ section, config ]
         | 
| 143 | 
            +
            			self.log.info "  no %p section in %p; configuring with nil" % [ section, config ]
         | 
| 160 144 | 
             
            			section = nil
         | 
| 161 145 | 
             
            		end
         | 
| 162 146 |  | 
| @@ -174,10 +158,42 @@ module Configurability | |
| 174 158 | 
             
            	end
         | 
| 175 159 |  | 
| 176 160 |  | 
| 161 | 
            +
            	### Gather defaults from objects with Configurability in the given +collection+
         | 
| 162 | 
            +
            	### object. Objects that wish to add a section to the defaults should implement
         | 
| 163 | 
            +
            	### a #defaults method in the same scope as #configure that returns the Hash of
         | 
| 164 | 
            +
            	### default, or set one of the constants in the default implementation of
         | 
| 165 | 
            +
            	### #defaults. The hash for each object will be merged into the +collection+
         | 
| 166 | 
            +
            	### via #merge!.
         | 
| 167 | 
            +
            	def self::gather_defaults( collection={} )
         | 
| 168 | 
            +
            		self.configurable_objects.each do |obj|
         | 
| 169 | 
            +
            			next unless obj.respond_to?( :defaults )
         | 
| 170 | 
            +
            			unless subhash = obj.defaults
         | 
| 171 | 
            +
            				Configurability.log.warn "No defaults for %p; skipping" % [ obj ]
         | 
| 172 | 
            +
            				next
         | 
| 173 | 
            +
            			end
         | 
| 174 | 
            +
            			section = obj.config_key.to_sym
         | 
| 175 | 
            +
             | 
| 176 | 
            +
            			collection.merge!( section => subhash )
         | 
| 177 | 
            +
            		end
         | 
| 178 | 
            +
             | 
| 179 | 
            +
            		return collection
         | 
| 180 | 
            +
            	end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
             | 
| 183 | 
            +
            	### Gather the default configuration in a Configurability::Config object and return it.
         | 
| 184 | 
            +
            	def self::default_config
         | 
| 185 | 
            +
            		return self.gather_defaults( Configurability::Config.new )
         | 
| 186 | 
            +
            	end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
             | 
| 177 189 | 
             
            	#############################################################
         | 
| 178 190 | 
             
            	### A P P E N D E D	  M E T H O D S
         | 
| 179 191 | 
             
            	#############################################################
         | 
| 180 192 |  | 
| 193 | 
            +
            	#
         | 
| 194 | 
            +
            	# :section: Configuration API
         | 
| 195 | 
            +
            	#
         | 
| 196 | 
            +
             | 
| 181 197 | 
             
            	### Get (and optionally set) the +config_key+ (a Symbol).
         | 
| 182 198 | 
             
            	def config_key( sym=nil )
         | 
| 183 199 | 
             
            		@config_key = sym unless sym.nil?
         | 
| @@ -198,5 +214,31 @@ module Configurability | |
| 198 214 | 
             
            	end
         | 
| 199 215 |  | 
| 200 216 |  | 
| 217 | 
            +
            	#
         | 
| 218 | 
            +
            	# :section: Configuration Defaults API
         | 
| 219 | 
            +
            	#
         | 
| 220 | 
            +
             | 
| 221 | 
            +
            	### The default implementation of the method called by ::gather_defaults when
         | 
| 222 | 
            +
            	### gathering configuration defaults. This method expects either a
         | 
| 223 | 
            +
            	### +DEFAULT_CONFIG+ or a +CONFIG_DEFAULTS+ constant to contain the configuration
         | 
| 224 | 
            +
            	### defaults, and will just return +nil+ if neither exists.
         | 
| 225 | 
            +
            	def defaults
         | 
| 226 | 
            +
             | 
| 227 | 
            +
            		return nil unless respond_to?( :const_defined? )
         | 
| 228 | 
            +
             | 
| 229 | 
            +
            		Configurability.log.debug "Looking for defaults in %p's constants." % [ self ]
         | 
| 230 | 
            +
            		if self.const_defined?( :DEFAULT_CONFIG )
         | 
| 231 | 
            +
            			Configurability.log.debug "  found DEFAULT_CONFIG"
         | 
| 232 | 
            +
            			return self.const_get( :DEFAULT_CONFIG ).dup
         | 
| 233 | 
            +
            		elsif self.const_defined?( :CONFIG_DEFAULTS )
         | 
| 234 | 
            +
            			Configurability.log.debug "  found CONFIG_DEFAULTS"
         | 
| 235 | 
            +
            			return self.const_get( :CONFIG_DEFAULTS ).dup
         | 
| 236 | 
            +
            		else
         | 
| 237 | 
            +
            			Configurability.log.debug "  no default constants."
         | 
| 238 | 
            +
            			return nil
         | 
| 239 | 
            +
            		end
         | 
| 240 | 
            +
            	end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
             | 
| 201 243 | 
             
            end # module Configurability
         | 
| 202 244 |  | 
| @@ -140,9 +140,17 @@ class Configurability::Config | |
| 140 140 | 
             
            	### Write the configuration object using the specified name and any
         | 
| 141 141 | 
             
            	### additional +args+.
         | 
| 142 142 | 
             
            	def write( path=@path, *args )
         | 
| 143 | 
            +
            		unless path.is_a?( String ) || path.is_a?( Pathname )
         | 
| 144 | 
            +
            			args.unshift( path )
         | 
| 145 | 
            +
            			path = @path
         | 
| 146 | 
            +
            		end
         | 
| 147 | 
            +
             | 
| 143 148 | 
             
            		raise ArgumentError,
         | 
| 144 149 | 
             
            			"No name associated with this config." unless path
         | 
| 145 | 
            -
             | 
| 150 | 
            +
             | 
| 151 | 
            +
            		self.log.info "Writing config to %s with args: %p" % [ path, args ]
         | 
| 152 | 
            +
            		path = Pathname( path )
         | 
| 153 | 
            +
            		path.open( File::WRONLY|File::CREAT|File::TRUNC, *args ) do |ofh|
         | 
| 146 154 | 
             
            			ofh.print( self.dump )
         | 
| 147 155 | 
             
            		end
         | 
| 148 156 | 
             
            	end
         | 
| @@ -254,6 +262,12 @@ class Configurability::Config | |
| 254 262 | 
             
            	end
         | 
| 255 263 |  | 
| 256 264 |  | 
| 265 | 
            +
            	### Delegate logging to the module's Logger.
         | 
| 266 | 
            +
            	def log
         | 
| 267 | 
            +
            		Configurability.logger
         | 
| 268 | 
            +
            	end
         | 
| 269 | 
            +
             | 
| 270 | 
            +
             | 
| 257 271 | 
             
            	#######
         | 
| 258 272 | 
             
            	private
         | 
| 259 273 | 
             
            	#######
         | 
| @@ -0,0 +1,300 @@ | |
| 1 | 
            +
            # -*- ruby -*-
         | 
| 2 | 
            +
            # vim: set nosta noet ts=4 sw=4:
         | 
| 3 | 
            +
            # encoding: utf-8
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require 'logger'
         | 
| 6 | 
            +
            require 'date'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'configurability' unless defined?( Configurability )
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            # A mixin that provides a top-level logging subsystem based on Logger.
         | 
| 12 | 
            +
            module Configurability::Logging
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            	### Logging
         | 
| 15 | 
            +
            	# Log levels
         | 
| 16 | 
            +
            	LOG_LEVELS = {
         | 
| 17 | 
            +
            		'debug' => Logger::DEBUG,
         | 
| 18 | 
            +
            		'info'  => Logger::INFO,
         | 
| 19 | 
            +
            		'warn'  => Logger::WARN,
         | 
| 20 | 
            +
            		'error' => Logger::ERROR,
         | 
| 21 | 
            +
            		'fatal' => Logger::FATAL,
         | 
| 22 | 
            +
            	}.freeze
         | 
| 23 | 
            +
            	LOG_LEVEL_NAMES = LOG_LEVELS.invert.freeze
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
            	### Inclusion hook
         | 
| 27 | 
            +
            	def self::extended( mod )
         | 
| 28 | 
            +
            		super
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            		class << mod
         | 
| 31 | 
            +
            			# the log formatter that will be used when the logging subsystem is reset
         | 
| 32 | 
            +
            			attr_accessor :default_log_formatter
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            			# the logger that will be used when the logging subsystem is reset
         | 
| 35 | 
            +
            			attr_accessor :default_logger
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            			# the logger that's currently in effect
         | 
| 38 | 
            +
            			attr_accessor :logger
         | 
| 39 | 
            +
            			alias_method :log, :logger
         | 
| 40 | 
            +
            			alias_method :log=, :logger=
         | 
| 41 | 
            +
            		end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            		mod.default_logger = mod.logger = Logger.new( $stderr )
         | 
| 44 | 
            +
            		mod.default_logger.level = case
         | 
| 45 | 
            +
            			when $DEBUG then Logger::DEBUG
         | 
| 46 | 
            +
            			when $VERBOSE then Logger::INFO
         | 
| 47 | 
            +
            			else Logger::WARN end
         | 
| 48 | 
            +
            		mod.default_log_formatter = Configurability::Logging::Formatter.new( mod.default_logger )
         | 
| 49 | 
            +
            	end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
             | 
| 52 | 
            +
            	### Reset the global logger object to the default
         | 
| 53 | 
            +
            	def reset_logger
         | 
| 54 | 
            +
            		self.logger = self.default_logger
         | 
| 55 | 
            +
            		self.logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
         | 
| 56 | 
            +
            		self.logger.formatter = self.default_log_formatter
         | 
| 57 | 
            +
            	end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
             | 
| 60 | 
            +
            	### Returns +true+ if the global logger has not been set to something other than
         | 
| 61 | 
            +
            	### the default one.
         | 
| 62 | 
            +
            	def using_default_logger?
         | 
| 63 | 
            +
            		return self.logger == self.default_logger
         | 
| 64 | 
            +
            	end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
             | 
| 67 | 
            +
            	# A alternate formatter for Logger instances.
         | 
| 68 | 
            +
            	class Formatter < Logger::Formatter
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            		# The format to output unless debugging is turned on
         | 
| 71 | 
            +
            		DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            		# The format to output if debugging is turned on
         | 
| 74 | 
            +
            		DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
         | 
| 75 | 
            +
             | 
| 76 | 
            +
             | 
| 77 | 
            +
            		### Initialize the formatter with a reference to the logger so it can check for log level.
         | 
| 78 | 
            +
            		def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
         | 
| 79 | 
            +
            			@logger       = logger
         | 
| 80 | 
            +
            			@format       = format
         | 
| 81 | 
            +
            			@debug_format = debug
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            			super()
         | 
| 84 | 
            +
            		end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            		######
         | 
| 87 | 
            +
            		public
         | 
| 88 | 
            +
            		######
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            		# The Logger object associated with the formatter
         | 
| 91 | 
            +
            		attr_accessor :logger
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            		# The logging format string
         | 
| 94 | 
            +
            		attr_accessor :format
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            		# The logging format string that's used when outputting in debug mode
         | 
| 97 | 
            +
            		attr_accessor :debug_format
         | 
| 98 | 
            +
             | 
| 99 | 
            +
             | 
| 100 | 
            +
            		### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
         | 
| 101 | 
            +
            		### using FORMAT if it's anything less verbose.
         | 
| 102 | 
            +
            		def call( severity, time, progname, msg )
         | 
| 103 | 
            +
            			args = [
         | 
| 104 | 
            +
            				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
         | 
| 105 | 
            +
            				time.usec,                                                    # %2$d
         | 
| 106 | 
            +
            				Process.pid,                                                  # %3$d
         | 
| 107 | 
            +
            				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
         | 
| 108 | 
            +
            				severity,                                                     # %5$s
         | 
| 109 | 
            +
            				progname,                                                     # %6$s
         | 
| 110 | 
            +
            				msg                                                           # %7$s
         | 
| 111 | 
            +
            			]
         | 
| 112 | 
            +
             | 
| 113 | 
            +
            			if @logger.level == Logger::DEBUG
         | 
| 114 | 
            +
            				return self.debug_format % args
         | 
| 115 | 
            +
            			else
         | 
| 116 | 
            +
            				return self.format % args
         | 
| 117 | 
            +
            			end
         | 
| 118 | 
            +
            		end
         | 
| 119 | 
            +
            	end # class Formatter
         | 
| 120 | 
            +
             | 
| 121 | 
            +
             | 
| 122 | 
            +
            	# A ANSI-colorized formatter for Logger instances.
         | 
| 123 | 
            +
            	class ColorFormatter < Logger::Formatter
         | 
| 124 | 
            +
             | 
| 125 | 
            +
            		# Set some ANSI escape code constants (Shamelessly stolen from Perl's
         | 
| 126 | 
            +
            		# Term::ANSIColor by Russ Allbery <rra@stanford.edu> and Zenin <zenin@best.com>
         | 
| 127 | 
            +
            		ANSI_ATTRIBUTES = {
         | 
| 128 | 
            +
            			'clear'      => 0,
         | 
| 129 | 
            +
            			'reset'      => 0,
         | 
| 130 | 
            +
            			'bold'       => 1,
         | 
| 131 | 
            +
            			'dark'       => 2,
         | 
| 132 | 
            +
            			'underline'  => 4,
         | 
| 133 | 
            +
            			'underscore' => 4,
         | 
| 134 | 
            +
            			'blink'      => 5,
         | 
| 135 | 
            +
            			'reverse'    => 7,
         | 
| 136 | 
            +
            			'concealed'  => 8,
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            			'black'      => 30,   'on_black'   => 40,
         | 
| 139 | 
            +
            			'red'        => 31,   'on_red'     => 41,
         | 
| 140 | 
            +
            			'green'      => 32,   'on_green'   => 42,
         | 
| 141 | 
            +
            			'yellow'     => 33,   'on_yellow'  => 43,
         | 
| 142 | 
            +
            			'blue'       => 34,   'on_blue'    => 44,
         | 
| 143 | 
            +
            			'magenta'    => 35,   'on_magenta' => 45,
         | 
| 144 | 
            +
            			'cyan'       => 36,   'on_cyan'    => 46,
         | 
| 145 | 
            +
            			'white'      => 37,   'on_white'   => 47
         | 
| 146 | 
            +
            		}
         | 
| 147 | 
            +
             | 
| 148 | 
            +
             | 
| 149 | 
            +
            		### Create a string that contains the ANSI codes specified and return it
         | 
| 150 | 
            +
            		def self::ansi_code( *attributes )
         | 
| 151 | 
            +
            			attributes.flatten!
         | 
| 152 | 
            +
            			attributes.collect! {|at| at.to_s }
         | 
| 153 | 
            +
            			return '' unless /(?:vt10[03]|xterm(?:-color)?|linux|screen)/i =~ ENV['TERM']
         | 
| 154 | 
            +
            			attributes = ANSI_ATTRIBUTES.values_at( *attributes ).compact.join(';')
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            			if attributes.empty?
         | 
| 157 | 
            +
            				return ''
         | 
| 158 | 
            +
            			else
         | 
| 159 | 
            +
            				return "\e[%sm" % attributes
         | 
| 160 | 
            +
            			end
         | 
| 161 | 
            +
            		end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
             | 
| 164 | 
            +
            		### Colorize the given +string+ with the specified +attributes+ and
         | 
| 165 | 
            +
            		### return it, handling line-endings, color reset, etc.
         | 
| 166 | 
            +
            		def self::colorize( *args )
         | 
| 167 | 
            +
            			string = ''
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            			if block_given?
         | 
| 170 | 
            +
            				string = yield
         | 
| 171 | 
            +
            			else
         | 
| 172 | 
            +
            				string = args.shift
         | 
| 173 | 
            +
            			end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            			ending = string[/(\s)$/] || ''
         | 
| 176 | 
            +
            			string = string.rstrip
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            			return self.ansi_code( args.flatten ) + string + self.ansi_code( 'reset' ) + ending
         | 
| 179 | 
            +
            		end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
             | 
| 182 | 
            +
            		# Color settings
         | 
| 183 | 
            +
            		LEVEL_FORMATS = {
         | 
| 184 | 
            +
            			:debug => colorize( :bold, :black ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"},
         | 
| 185 | 
            +
            			:info  => colorize( :normal ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
         | 
| 186 | 
            +
            			:warn  => colorize( :bold, :yellow ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
         | 
| 187 | 
            +
            			:error => colorize( :red ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
         | 
| 188 | 
            +
            			:fatal => colorize( :bold, :red, :on_white ) {"[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"},
         | 
| 189 | 
            +
            		}
         | 
| 190 | 
            +
             | 
| 191 | 
            +
             | 
| 192 | 
            +
            		### Initialize the formatter with a reference to the logger so it can check for log level.
         | 
| 193 | 
            +
            		def initialize( logger, settings={} ) # :notnew:
         | 
| 194 | 
            +
            			settings = LEVEL_FORMATS.merge( settings )
         | 
| 195 | 
            +
             | 
| 196 | 
            +
            			@logger   = logger
         | 
| 197 | 
            +
            			@settings = settings
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            			super()
         | 
| 200 | 
            +
            		end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
            		######
         | 
| 203 | 
            +
            		public
         | 
| 204 | 
            +
            		######
         | 
| 205 | 
            +
             | 
| 206 | 
            +
            		# The Logger object associated with the formatter
         | 
| 207 | 
            +
            		attr_accessor :logger
         | 
| 208 | 
            +
             | 
| 209 | 
            +
            		# The formats, by level
         | 
| 210 | 
            +
            		attr_accessor :settings
         | 
| 211 | 
            +
             | 
| 212 | 
            +
             | 
| 213 | 
            +
            		### Log using the format associated with the severity
         | 
| 214 | 
            +
            		def call( severity, time, progname, msg )
         | 
| 215 | 
            +
            			args = [
         | 
| 216 | 
            +
            				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
         | 
| 217 | 
            +
            				time.usec,                                                    # %2$d
         | 
| 218 | 
            +
            				Process.pid,                                                  # %3$d
         | 
| 219 | 
            +
            				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
         | 
| 220 | 
            +
            				severity,                                                     # %5$s
         | 
| 221 | 
            +
            				progname,                                                     # %6$s
         | 
| 222 | 
            +
            				msg                                                           # %7$s
         | 
| 223 | 
            +
            			]
         | 
| 224 | 
            +
             | 
| 225 | 
            +
            			return self.settings[ severity.downcase.to_sym ] % args
         | 
| 226 | 
            +
            		end
         | 
| 227 | 
            +
             | 
| 228 | 
            +
            	end # class Formatter
         | 
| 229 | 
            +
             | 
| 230 | 
            +
             | 
| 231 | 
            +
            	# An alternate formatter for Logger instances that outputs +div+ HTML
         | 
| 232 | 
            +
            	# fragments.
         | 
| 233 | 
            +
            	class HtmlFormatter < Logger::Formatter
         | 
| 234 | 
            +
             | 
| 235 | 
            +
            		# The default HTML fragment that'll be used as the template for each log message.
         | 
| 236 | 
            +
            		HTML_LOG_FORMAT = %q{
         | 
| 237 | 
            +
            		<div class="log-message %5$s">
         | 
| 238 | 
            +
            			<span class="log-time">%1$s.%2$06d</span>
         | 
| 239 | 
            +
            			[
         | 
| 240 | 
            +
            				<span class="log-pid">%3$d</span>
         | 
| 241 | 
            +
            				/
         | 
| 242 | 
            +
            				<span class="log-tid">%4$s</span>
         | 
| 243 | 
            +
            			]
         | 
| 244 | 
            +
            			<span class="log-level">%5$s</span>
         | 
| 245 | 
            +
            			:
         | 
| 246 | 
            +
            			<span class="log-name">%6$s</span>
         | 
| 247 | 
            +
            			<span class="log-message-text">%7$s</span>
         | 
| 248 | 
            +
            		</div>
         | 
| 249 | 
            +
            		}
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            		### Override the logging formats with ones that generate HTML fragments
         | 
| 252 | 
            +
            		def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
         | 
| 253 | 
            +
            			@logger = logger
         | 
| 254 | 
            +
            			@format = format
         | 
| 255 | 
            +
            			super()
         | 
| 256 | 
            +
            		end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
             | 
| 259 | 
            +
            		######
         | 
| 260 | 
            +
            		public
         | 
| 261 | 
            +
            		######
         | 
| 262 | 
            +
             | 
| 263 | 
            +
            		# The HTML fragment that will be used as a format() string for the log
         | 
| 264 | 
            +
            		attr_accessor :format
         | 
| 265 | 
            +
             | 
| 266 | 
            +
             | 
| 267 | 
            +
            		### Return a log message composed out of the arguments formatted using the
         | 
| 268 | 
            +
            		### formatter's format string
         | 
| 269 | 
            +
            		def call( severity, time, progname, msg )
         | 
| 270 | 
            +
            			args = [
         | 
| 271 | 
            +
            				time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
         | 
| 272 | 
            +
            				time.usec,                                                    # %2$d
         | 
| 273 | 
            +
            				Process.pid,                                                  # %3$d
         | 
| 274 | 
            +
            				Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
         | 
| 275 | 
            +
            				severity.downcase,                                                     # %5$s
         | 
| 276 | 
            +
            				progname,                                                     # %6$s
         | 
| 277 | 
            +
            				escape_html( msg ).gsub(/\n/, '<br />')                       # %7$s
         | 
| 278 | 
            +
            			]
         | 
| 279 | 
            +
             | 
| 280 | 
            +
            			return self.format % args
         | 
| 281 | 
            +
            		end
         | 
| 282 | 
            +
             | 
| 283 | 
            +
             | 
| 284 | 
            +
            		#######
         | 
| 285 | 
            +
            		private
         | 
| 286 | 
            +
            		#######
         | 
| 287 | 
            +
             | 
| 288 | 
            +
            		### Escape any HTML special characters in +string+.
         | 
| 289 | 
            +
            		def escape_html( string )
         | 
| 290 | 
            +
            			return string.
         | 
| 291 | 
            +
            				gsub( '&', '&' ).
         | 
| 292 | 
            +
            				gsub( '<', '<'  ).
         | 
| 293 | 
            +
            				gsub( '>', '>'  )
         | 
| 294 | 
            +
            		end
         | 
| 295 | 
            +
             | 
| 296 | 
            +
            	end # class HtmlFormatter
         | 
| 297 | 
            +
             | 
| 298 | 
            +
             | 
| 299 | 
            +
            end # module Configurability
         | 
| 300 | 
            +
             | 
| @@ -10,7 +10,6 @@ BEGIN { | |
| 10 10 | 
             
            	$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
         | 
| 11 11 | 
             
            }
         | 
| 12 12 |  | 
| 13 | 
            -
            require 'tempfile'
         | 
| 14 13 | 
             
            require 'logger'
         | 
| 15 14 | 
             
            require 'fileutils'
         | 
| 16 15 | 
             
            require 'rspec'
         | 
| @@ -48,6 +47,11 @@ describe Configurability::Config do | |
| 48 47 | 
             
            		setup_logging( :fatal )
         | 
| 49 48 | 
             
            	end
         | 
| 50 49 |  | 
| 50 | 
            +
            	after( :each ) do
         | 
| 51 | 
            +
            		Configurability.configurable_objects.clear
         | 
| 52 | 
            +
            		Configurability.reset
         | 
| 53 | 
            +
            	end
         | 
| 54 | 
            +
             | 
| 51 55 | 
             
            	after( :all ) do
         | 
| 52 56 | 
             
            		reset_logging()
         | 
| 53 57 | 
             
            	end
         | 
| @@ -135,7 +139,7 @@ describe Configurability::Config do | |
| 135 139 |  | 
| 136 140 | 
             
            	context "created with in-memory YAML source" do
         | 
| 137 141 |  | 
| 138 | 
            -
            		before(:each) do
         | 
| 142 | 
            +
            		before( :each ) do
         | 
| 139 143 | 
             
            			@config = Configurability::Config.new( TEST_CONFIG )
         | 
| 140 144 | 
             
            		end
         | 
| 141 145 |  | 
| @@ -206,7 +210,7 @@ describe Configurability::Config do | |
| 206 210 |  | 
| 207 211 | 
             
            	# saving if changed since loaded
         | 
| 208 212 | 
             
            	context " whose internal values have been changed since loaded" do
         | 
| 209 | 
            -
            		before(:each) do
         | 
| 213 | 
            +
            		before( :each ) do
         | 
| 210 214 | 
             
            			@config = Configurability::Config.new( TEST_CONFIG )
         | 
| 211 215 | 
             
            			@config.section.subsection.anothersection = 11451
         | 
| 212 216 | 
             
            		end
         | 
| @@ -226,42 +230,50 @@ describe Configurability::Config do | |
| 226 230 |  | 
| 227 231 | 
             
            	# loading from a file
         | 
| 228 232 | 
             
            	context " loaded from a file" do
         | 
| 229 | 
            -
            		before(:all) do
         | 
| 230 | 
            -
            			 | 
| 231 | 
            -
            			@tmpfile | 
| 232 | 
            -
            			@tmpfile. | 
| 233 | 
            +
            		before( :all ) do
         | 
| 234 | 
            +
            			filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
         | 
| 235 | 
            +
            			@tmpfile = Pathname( filename )
         | 
| 236 | 
            +
            			@tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
         | 
| 233 237 | 
             
            		end
         | 
| 234 238 |  | 
| 235 | 
            -
            		after(:all) do
         | 
| 236 | 
            -
            			@tmpfile. | 
| 239 | 
            +
            		after( :all ) do
         | 
| 240 | 
            +
            			@tmpfile.unlink
         | 
| 237 241 | 
             
            		end
         | 
| 238 242 |  | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 241 | 
            -
            			@config = Configurability::Config.load( @tmpfile.path )
         | 
| 243 | 
            +
            		before( :each ) do
         | 
| 244 | 
            +
            			@config = Configurability::Config.load( @tmpfile.to_s )
         | 
| 242 245 | 
             
            		end
         | 
| 243 246 |  | 
| 244 247 |  | 
| 245 248 | 
             
            		### Specifications
         | 
| 246 249 | 
             
            		it "remembers which file it was loaded from" do
         | 
| 247 | 
            -
            			@config.path.should ==  | 
| 250 | 
            +
            			@config.path.should == @tmpfile.expand_path
         | 
| 248 251 | 
             
            		end
         | 
| 249 252 |  | 
| 250 253 | 
             
            		it "writes itself back to the same file by default" do
         | 
| 251 254 | 
             
            			@config.port = 114411
         | 
| 252 255 | 
             
            			@config.write
         | 
| 253 | 
            -
            			otherconfig = Configurability::Config.load( @tmpfile. | 
| 256 | 
            +
            			otherconfig = Configurability::Config.load( @tmpfile.to_s )
         | 
| 254 257 |  | 
| 255 258 | 
             
            			otherconfig.port.should == 114411
         | 
| 256 259 | 
             
            		end
         | 
| 257 260 |  | 
| 261 | 
            +
            		it "can be written to a different file" do
         | 
| 262 | 
            +
            			path = Dir::Tmpname.make_tmpname( './another-', '.config' )
         | 
| 263 | 
            +
             | 
| 264 | 
            +
            			@config.write( path )
         | 
| 265 | 
            +
            			File.read( path ).should =~ /section:\n  subsection/
         | 
| 266 | 
            +
             | 
| 267 | 
            +
            			File.unlink( path )
         | 
| 268 | 
            +
            		end
         | 
| 269 | 
            +
             | 
| 258 270 | 
             
            		it "includes the name of the file in its inspect output" do
         | 
| 259 | 
            -
            			@config.inspect.should include( File.basename(@tmpfile. | 
| 271 | 
            +
            			@config.inspect.should include( File.basename(@tmpfile.to_s) )
         | 
| 260 272 | 
             
            		end
         | 
| 261 273 |  | 
| 262 274 | 
             
            		it "yields itself if a block is given at load-time" do
         | 
| 263 275 | 
             
            			yielded_self = nil
         | 
| 264 | 
            -
            			config = Configurability::Config.load( @tmpfile. | 
| 276 | 
            +
            			config = Configurability::Config.load( @tmpfile.to_s ) do
         | 
| 265 277 | 
             
            				yielded_self = self
         | 
| 266 278 | 
             
            			end
         | 
| 267 279 | 
             
            			yielded_self.should equal( config )
         | 
| @@ -270,7 +282,7 @@ describe Configurability::Config do | |
| 270 282 | 
             
            		it "passes itself as the block argument if a block of arity 1 is given at load-time" do
         | 
| 271 283 | 
             
            			arg_self = nil
         | 
| 272 284 | 
             
            			yielded_self = nil
         | 
| 273 | 
            -
            			config = Configurability::Config.load( @tmpfile. | 
| 285 | 
            +
            			config = Configurability::Config.load( @tmpfile.to_s ) do |arg|
         | 
| 274 286 | 
             
            				yielded_self = self
         | 
| 275 287 | 
             
            				arg_self = arg
         | 
| 276 288 | 
             
            			end
         | 
| @@ -288,23 +300,23 @@ describe Configurability::Config do | |
| 288 300 |  | 
| 289 301 | 
             
            	# reload if file changes
         | 
| 290 302 | 
             
            	context " whose file changes after loading" do
         | 
| 291 | 
            -
            		before(:all) do
         | 
| 292 | 
            -
            			 | 
| 293 | 
            -
            			@tmpfile | 
| 294 | 
            -
            			@tmpfile. | 
| 303 | 
            +
            		before( :all ) do
         | 
| 304 | 
            +
            			filename = Dir::Tmpname.make_tmpname( './test', '.conf' )
         | 
| 305 | 
            +
            			@tmpfile = Pathname( filename )
         | 
| 306 | 
            +
            			@tmpfile.open( 'w', 0644 ) {|io| io.print(TEST_CONFIG) }
         | 
| 295 307 | 
             
            		end
         | 
| 296 308 |  | 
| 297 | 
            -
            		after(:all) do
         | 
| 298 | 
            -
            			@tmpfile. | 
| 309 | 
            +
            		after( :all ) do
         | 
| 310 | 
            +
            			@tmpfile.unlink
         | 
| 299 311 | 
             
            		end
         | 
| 300 312 |  | 
| 301 313 |  | 
| 302 | 
            -
            		before(:each) do
         | 
| 314 | 
            +
            		before( :each ) do
         | 
| 303 315 | 
             
            			old_date = Time.now - 3600
         | 
| 304 | 
            -
            			File.utime( old_date, old_date, @tmpfile. | 
| 305 | 
            -
            			@config = Configurability::Config.load( @tmpfile. | 
| 316 | 
            +
            			File.utime( old_date, old_date, @tmpfile.to_s )
         | 
| 317 | 
            +
            			@config = Configurability::Config.load( @tmpfile.to_s )
         | 
| 306 318 | 
             
            			now = Time.now + 10
         | 
| 307 | 
            -
            			File.utime( now, now, @tmpfile. | 
| 319 | 
            +
            			File.utime( now, now, @tmpfile.to_s )
         | 
| 308 320 | 
             
            		end
         | 
| 309 321 |  | 
| 310 322 |  | 
| @@ -324,7 +336,7 @@ describe Configurability::Config do | |
| 324 336 | 
             
            		end
         | 
| 325 337 |  | 
| 326 338 | 
             
            		it "reapplies its defaults when reloading" do
         | 
| 327 | 
            -
            			config = Configurability::Config.load( @tmpfile. | 
| 339 | 
            +
            			config = Configurability::Config.load( @tmpfile.to_s, :defaultskey => 8 )
         | 
| 328 340 | 
             
            			config.reload
         | 
| 329 341 | 
             
            			config.defaultskey.should == 8
         | 
| 330 342 | 
             
            		end
         | 
| @@ -333,7 +345,7 @@ describe Configurability::Config do | |
| 333 345 |  | 
| 334 346 | 
             
            	# merging
         | 
| 335 347 | 
             
            	context " created by merging two other configs" do
         | 
| 336 | 
            -
            		before(:each) do
         | 
| 348 | 
            +
            		before( :each ) do
         | 
| 337 349 | 
             
            			@config1 = Configurability::Config.new
         | 
| 338 350 | 
             
            			@config2 = Configurability::Config.new( TEST_CONFIG )
         | 
| 339 351 | 
             
            			@merged = @config1.merge( @config2 )
         | 
| @@ -36,7 +36,7 @@ describe Configurability::DeferredConfig do | |
| 36 36 | 
             
            	end
         | 
| 37 37 |  | 
| 38 38 | 
             
            	it "calls Configurability.install_config with itself when a 'configure' method is defined" do
         | 
| 39 | 
            -
            		config =  | 
| 39 | 
            +
            		config = { :testing => :testing_config }
         | 
| 40 40 | 
             
            		Configurability.configure_objects( config )
         | 
| 41 41 |  | 
| 42 42 | 
             
            		a_class = Class.new do
         | 
| @@ -287,6 +287,79 @@ describe Configurability do | |
| 287 287 |  | 
| 288 288 | 
             
            	end
         | 
| 289 289 |  | 
| 290 | 
            +
             | 
| 291 | 
            +
            	describe "defaults hash" do
         | 
| 292 | 
            +
             | 
| 293 | 
            +
            		it "can generate a Hash of defaults for all objects with Configurability" do
         | 
| 294 | 
            +
            			Configurability.gather_defaults.should be_a( Hash )
         | 
| 295 | 
            +
            		end
         | 
| 296 | 
            +
             | 
| 297 | 
            +
            		it "fetches defaults from a CONFIG_DEFAULTS constant if the object defines one" do
         | 
| 298 | 
            +
            			klass = Class.new do
         | 
| 299 | 
            +
            				extend Configurability
         | 
| 300 | 
            +
            				config_key :testconfig
         | 
| 301 | 
            +
            				self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
         | 
| 302 | 
            +
            				Configurability.log.debug "Defaults: %p" % [ self.defaults ]
         | 
| 303 | 
            +
            			end
         | 
| 304 | 
            +
             | 
| 305 | 
            +
            			Configurability.gather_defaults.should include( :testconfig )
         | 
| 306 | 
            +
            			Configurability.gather_defaults[:testconfig].should == klass.const_get( :CONFIG_DEFAULTS )
         | 
| 307 | 
            +
            			Configurability.gather_defaults[:testconfig].should_not be( klass.const_get(:CONFIG_DEFAULTS) )
         | 
| 308 | 
            +
            		end
         | 
| 309 | 
            +
             | 
| 310 | 
            +
            		it "fetches defaults from a DEFAULT_CONFIG constant if the object defines one" do
         | 
| 311 | 
            +
            			klass = Class.new do
         | 
| 312 | 
            +
            				extend Configurability
         | 
| 313 | 
            +
            				config_key :testconfig
         | 
| 314 | 
            +
            				self::DEFAULT_CONFIG = { :two => 2, :types => {:two => true} }
         | 
| 315 | 
            +
            			end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
            			Configurability.gather_defaults.should include( :testconfig )
         | 
| 318 | 
            +
            			Configurability.gather_defaults[:testconfig].should == klass.const_get( :DEFAULT_CONFIG )
         | 
| 319 | 
            +
            			Configurability.gather_defaults[:testconfig].should_not be( klass.const_get(:DEFAULT_CONFIG) )
         | 
| 320 | 
            +
            		end
         | 
| 321 | 
            +
             | 
| 322 | 
            +
            		it "fetches defaults from a #defaults method if the object implements one" do
         | 
| 323 | 
            +
            			klass = Class.new do
         | 
| 324 | 
            +
            				extend Configurability
         | 
| 325 | 
            +
            				config_key :otherconfig
         | 
| 326 | 
            +
            				def self::defaults; { :other => true }; end
         | 
| 327 | 
            +
            			end
         | 
| 328 | 
            +
             | 
| 329 | 
            +
            			Configurability.gather_defaults.should include( :otherconfig )
         | 
| 330 | 
            +
            			Configurability.gather_defaults[:otherconfig].should == klass.defaults
         | 
| 331 | 
            +
            			Configurability.gather_defaults[:otherconfig].should_not be( klass.defaults )
         | 
| 332 | 
            +
            		end
         | 
| 333 | 
            +
             | 
| 334 | 
            +
            		it "can return a Configurability::Config object with defaults, too" do
         | 
| 335 | 
            +
            			klass1 = Class.new do
         | 
| 336 | 
            +
            				extend Configurability
         | 
| 337 | 
            +
            				config_key :testconfig
         | 
| 338 | 
            +
            				self::CONFIG_DEFAULTS = { :one => 1, :types => {:one => true} }
         | 
| 339 | 
            +
            			end
         | 
| 340 | 
            +
            			klass2 = Class.new do
         | 
| 341 | 
            +
            				extend Configurability
         | 
| 342 | 
            +
            				config_key :testconfig
         | 
| 343 | 
            +
            				self::DEFAULT_CONFIG = { :two => 2, :types => {:two => true} }
         | 
| 344 | 
            +
            			end
         | 
| 345 | 
            +
            			klass3 = Class.new do
         | 
| 346 | 
            +
            				extend Configurability
         | 
| 347 | 
            +
            				config_key :otherconfig
         | 
| 348 | 
            +
            				def self::defaults; { :other => true }; end
         | 
| 349 | 
            +
            			end
         | 
| 350 | 
            +
             | 
| 351 | 
            +
            			config = Configurability.default_config
         | 
| 352 | 
            +
             | 
| 353 | 
            +
            			config.should be_a( Configurability::Config )
         | 
| 354 | 
            +
            			config.testconfig.one.should == 1
         | 
| 355 | 
            +
            			config.testconfig.two.should == 2
         | 
| 356 | 
            +
            			config.testconfig.types.one.should be_true()
         | 
| 357 | 
            +
            			config.testconfig.types.two.should be_true()
         | 
| 358 | 
            +
            			config.otherconfig.other.should be_true()
         | 
| 359 | 
            +
            		end
         | 
| 360 | 
            +
             | 
| 361 | 
            +
            	end
         | 
| 362 | 
            +
             | 
| 290 363 | 
             
            end
         | 
| 291 364 |  | 
| 292 365 | 
             
            # vim: set nosta noet ts=4 sw=4:
         | 
    
        data/spec/lib/helpers.rb
    CHANGED
    
    | @@ -142,6 +142,10 @@ end | |
| 142 142 | 
             
            RSpec.configure do |config|
         | 
| 143 143 | 
             
            	config.mock_with( :rspec )
         | 
| 144 144 | 
             
            	config.include( Configurability::SpecHelpers )
         | 
| 145 | 
            +
            	config.treat_symbols_as_metadata_keys_with_true_values = true
         | 
| 146 | 
            +
             | 
| 147 | 
            +
            	config.filter_run_excluding :only_ruby_19 if RUBY_VERSION < '1.9.2'
         | 
| 148 | 
            +
             | 
| 145 149 | 
             
            end
         | 
| 146 150 |  | 
| 147 151 | 
             
            # vim: set nosta noet ts=4 sw=4:
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: configurability
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0 | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -36,22 +36,27 @@ cert_chain: | |
| 36 36 | 
             
              YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
         | 
| 37 37 | 
             
              Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
         | 
| 38 38 | 
             
              cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
         | 
| 39 | 
            -
            date: 2012- | 
| 39 | 
            +
            date: 2012-04-26 00:00:00.000000000 Z
         | 
| 40 40 | 
             
            dependencies:
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: hoe-mercurial
         | 
| 43 | 
            -
              requirement:  | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                none: false
         | 
| 45 45 | 
             
                requirements:
         | 
| 46 46 | 
             
                - - ~>
         | 
| 47 47 | 
             
                  - !ruby/object:Gem::Version
         | 
| 48 | 
            -
                    version: 1. | 
| 48 | 
            +
                    version: 1.4.0
         | 
| 49 49 | 
             
              type: :development
         | 
| 50 50 | 
             
              prerelease: false
         | 
| 51 | 
            -
              version_requirements:  | 
| 51 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 52 | 
            +
                none: false
         | 
| 53 | 
            +
                requirements:
         | 
| 54 | 
            +
                - - ~>
         | 
| 55 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 56 | 
            +
                    version: 1.4.0
         | 
| 52 57 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 53 58 | 
             
              name: hoe-highline
         | 
| 54 | 
            -
              requirement:  | 
| 59 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 55 60 | 
             
                none: false
         | 
| 56 61 | 
             
                requirements:
         | 
| 57 62 | 
             
                - - ~>
         | 
| @@ -59,10 +64,31 @@ dependencies: | |
| 59 64 | 
             
                    version: 0.0.1
         | 
| 60 65 | 
             
              type: :development
         | 
| 61 66 | 
             
              prerelease: false
         | 
| 62 | 
            -
              version_requirements:  | 
| 67 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 68 | 
            +
                none: false
         | 
| 69 | 
            +
                requirements:
         | 
| 70 | 
            +
                - - ~>
         | 
| 71 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 72 | 
            +
                    version: 0.0.1
         | 
| 73 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 74 | 
            +
              name: rdoc
         | 
| 75 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 76 | 
            +
                none: false
         | 
| 77 | 
            +
                requirements:
         | 
| 78 | 
            +
                - - ~>
         | 
| 79 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 80 | 
            +
                    version: '3.10'
         | 
| 81 | 
            +
              type: :development
         | 
| 82 | 
            +
              prerelease: false
         | 
| 83 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 84 | 
            +
                none: false
         | 
| 85 | 
            +
                requirements:
         | 
| 86 | 
            +
                - - ~>
         | 
| 87 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 88 | 
            +
                    version: '3.10'
         | 
| 63 89 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 64 90 | 
             
              name: rspec
         | 
| 65 | 
            -
              requirement:  | 
| 91 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 66 92 | 
             
                none: false
         | 
| 67 93 | 
             
                requirements:
         | 
| 68 94 | 
             
                - - ~>
         | 
| @@ -70,10 +96,15 @@ dependencies: | |
| 70 96 | 
             
                    version: '2.4'
         | 
| 71 97 | 
             
              type: :development
         | 
| 72 98 | 
             
              prerelease: false
         | 
| 73 | 
            -
              version_requirements:  | 
| 99 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 100 | 
            +
                none: false
         | 
| 101 | 
            +
                requirements:
         | 
| 102 | 
            +
                - - ~>
         | 
| 103 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 104 | 
            +
                    version: '2.4'
         | 
| 74 105 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 75 106 | 
             
              name: simplecov
         | 
| 76 | 
            -
              requirement:  | 
| 107 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 77 108 | 
             
                none: false
         | 
| 78 109 | 
             
                requirements:
         | 
| 79 110 | 
             
                - - ~>
         | 
| @@ -81,44 +112,45 @@ dependencies: | |
| 81 112 | 
             
                    version: '0.3'
         | 
| 82 113 | 
             
              type: :development
         | 
| 83 114 | 
             
              prerelease: false
         | 
| 84 | 
            -
              version_requirements:  | 
| 85 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 86 | 
            -
              name: rdoc
         | 
| 87 | 
            -
              requirement: &70327439149040 !ruby/object:Gem::Requirement
         | 
| 115 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 88 116 | 
             
                none: false
         | 
| 89 117 | 
             
                requirements:
         | 
| 90 118 | 
             
                - - ~>
         | 
| 91 119 | 
             
                  - !ruby/object:Gem::Version
         | 
| 92 | 
            -
                    version: '3 | 
| 93 | 
            -
              type: :development
         | 
| 94 | 
            -
              prerelease: false
         | 
| 95 | 
            -
              version_requirements: *70327439149040
         | 
| 120 | 
            +
                    version: '0.3'
         | 
| 96 121 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 97 122 | 
             
              name: hoe
         | 
| 98 | 
            -
              requirement:  | 
| 123 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 99 124 | 
             
                none: false
         | 
| 100 125 | 
             
                requirements:
         | 
| 101 126 | 
             
                - - ~>
         | 
| 102 127 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: ' | 
| 128 | 
            +
                    version: '3.0'
         | 
| 104 129 | 
             
              type: :development
         | 
| 105 130 | 
             
              prerelease: false
         | 
| 106 | 
            -
              version_requirements:  | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 131 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 132 | 
            +
                none: false
         | 
| 133 | 
            +
                requirements:
         | 
| 134 | 
            +
                - - ~>
         | 
| 135 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 136 | 
            +
                    version: '3.0'
         | 
| 137 | 
            +
            description: ! 'Configurability is a unified, unintrusive, assume-nothing configuration
         | 
| 138 | 
            +
              system
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              for Ruby. It lets you keep the configuration for multiple objects in a single
         | 
| 109 141 |  | 
| 110 | 
            -
               | 
| 142 | 
            +
              config file, load the file when it''s convenient for you, and distribute the
         | 
| 111 143 |  | 
| 112 | 
            -
              configuration | 
| 144 | 
            +
              configuration when you''re ready, sending it everywhere it needs to go with a
         | 
| 113 145 |  | 
| 114 | 
            -
               | 
| 146 | 
            +
              single action.'
         | 
| 115 147 | 
             
            email:
         | 
| 116 148 | 
             
            - ged@FaerieMUD.org
         | 
| 117 149 | 
             
            executables: []
         | 
| 118 150 | 
             
            extensions: []
         | 
| 119 151 | 
             
            extra_rdoc_files:
         | 
| 120 | 
            -
            - Manifest.txt
         | 
| 121 152 | 
             
            - History.rdoc
         | 
| 153 | 
            +
            - Manifest.txt
         | 
| 122 154 | 
             
            - README.rdoc
         | 
| 123 155 | 
             
            files:
         | 
| 124 156 | 
             
            - ChangeLog
         | 
| @@ -133,19 +165,21 @@ files: | |
| 133 165 | 
             
            - lib/configurability/behavior.rb
         | 
| 134 166 | 
             
            - lib/configurability/config.rb
         | 
| 135 167 | 
             
            - lib/configurability/deferredconfig.rb
         | 
| 136 | 
            -
            - lib/configurability/ | 
| 168 | 
            +
            - lib/configurability/logging.rb
         | 
| 137 169 | 
             
            - spec/configurability/config_spec.rb
         | 
| 138 170 | 
             
            - spec/configurability/deferredconfig_spec.rb
         | 
| 139 171 | 
             
            - spec/configurability_spec.rb
         | 
| 140 172 | 
             
            - spec/lib/helpers.rb
         | 
| 141 173 | 
             
            - .gemtest
         | 
| 142 | 
            -
            homepage:  | 
| 174 | 
            +
            homepage: https://bitbucket.org/ged/configurability
         | 
| 143 175 | 
             
            licenses:
         | 
| 144 176 | 
             
            - BSD
         | 
| 145 177 | 
             
            post_install_message: 
         | 
| 146 178 | 
             
            rdoc_options:
         | 
| 147 | 
            -
            -  | 
| 148 | 
            -
            -  | 
| 179 | 
            +
            - -f
         | 
| 180 | 
            +
            - fivefish
         | 
| 181 | 
            +
            - -t
         | 
| 182 | 
            +
            - Configurability Toolkit
         | 
| 149 183 | 
             
            require_paths:
         | 
| 150 184 | 
             
            - lib
         | 
| 151 185 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| @@ -162,9 +196,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 162 196 | 
             
                  version: '0'
         | 
| 163 197 | 
             
            requirements: []
         | 
| 164 198 | 
             
            rubyforge_project: configurability
         | 
| 165 | 
            -
            rubygems_version: 1.8. | 
| 199 | 
            +
            rubygems_version: 1.8.21
         | 
| 166 200 | 
             
            signing_key: 
         | 
| 167 201 | 
             
            specification_version: 3
         | 
| 168 | 
            -
            summary: Configurability is a  | 
| 169 | 
            -
               | 
| 202 | 
            +
            summary: Configurability is a unified, unintrusive, assume-nothing configuration system
         | 
| 203 | 
            +
              for Ruby
         | 
| 170 204 | 
             
            test_files: []
         | 
    
        metadata.gz.sig
    CHANGED
    
    | Binary file | 
| @@ -1,60 +0,0 @@ | |
| 1 | 
            -
            #!/usr/bin/env ruby
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require 'logger'
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            require 'configurability'
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            # A custom log-formatter class for 
         | 
| 8 | 
            -
            class Configurability::LogFormatter < Logger::Formatter
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            	# The format to output unless debugging is turned on
         | 
| 11 | 
            -
            	DEFAULT_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s -- %7$s\n"
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            	# The format to output if debugging is turned on
         | 
| 14 | 
            -
            	DEFAULT_DEBUG_FORMAT = "[%1$s.%2$06d %3$d/%4$s] %5$5s {%6$s} -- %7$s\n"
         | 
| 15 | 
            -
             | 
| 16 | 
            -
             | 
| 17 | 
            -
            	### Initialize the formatter with a reference to the logger so it can check for log level.
         | 
| 18 | 
            -
            	def initialize( logger, format=DEFAULT_FORMAT, debug=DEFAULT_DEBUG_FORMAT ) # :notnew:
         | 
| 19 | 
            -
            		@logger       = logger
         | 
| 20 | 
            -
            		@format       = format
         | 
| 21 | 
            -
            		@debug_format = debug
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            		super()
         | 
| 24 | 
            -
            	end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
            	######
         | 
| 27 | 
            -
            	public
         | 
| 28 | 
            -
            	######
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            	# The Logger object associated with the formatter
         | 
| 31 | 
            -
            	attr_accessor :logger
         | 
| 32 | 
            -
             | 
| 33 | 
            -
            	# The logging format string
         | 
| 34 | 
            -
            	attr_accessor :format
         | 
| 35 | 
            -
             | 
| 36 | 
            -
            	# The logging format string that's used when outputting in debug mode
         | 
| 37 | 
            -
            	attr_accessor :debug_format
         | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
            	### Log using either the DEBUG_FORMAT if the associated logger is at ::DEBUG level or
         | 
| 41 | 
            -
            	### using FORMAT if it's anything less verbose.
         | 
| 42 | 
            -
            	def call( severity, time, progname, msg )
         | 
| 43 | 
            -
            		args = [
         | 
| 44 | 
            -
            			time.strftime( '%Y-%m-%d %H:%M:%S' ),                         # %1$s
         | 
| 45 | 
            -
            			time.usec,                                                    # %2$d
         | 
| 46 | 
            -
            			Process.pid,                                                  # %3$d
         | 
| 47 | 
            -
            			Thread.current == Thread.main ? 'main' : Thread.object_id,    # %4$s
         | 
| 48 | 
            -
            			severity,                                                     # %5$s
         | 
| 49 | 
            -
            			progname,                                                     # %6$s
         | 
| 50 | 
            -
            			msg                                                           # %7$s
         | 
| 51 | 
            -
            		]
         | 
| 52 | 
            -
             | 
| 53 | 
            -
            		if @logger.level == Logger::DEBUG
         | 
| 54 | 
            -
            			return self.debug_format % args
         | 
| 55 | 
            -
            		else
         | 
| 56 | 
            -
            			return self.format % args
         | 
| 57 | 
            -
            		end
         | 
| 58 | 
            -
            	end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
            end # class Configurability::LogFormatter
         |