configurability 1.1.0 → 1.2.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 CHANGED
Binary file
data/ChangeLog CHANGED
@@ -1,8 +1,68 @@
1
+ 2012-04-25 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * bin/configurability:
4
+ Add first version of a command-line utility
5
+ [ad1ff0049fcf] [tip]
6
+
7
+ * .hgtags:
8
+ Added tag v1.1.0 for changeset 070e4bfc8e55
9
+ [cc2d783fd316] [github/master]
10
+
11
+ * .hgsigs:
12
+ Added signature for changeset 2e082d901553
13
+ [070e4bfc8e55] [v1.1.0]
14
+
15
+ * History.rdoc:
16
+ Updated date of the release in history file
17
+ [2e082d901553]
18
+
19
+ * .rvm.gems, spec/configurability/config_spec.rb,
20
+ spec/configurability/deferredconfig_spec.rb:
21
+ Fixed spec-order bug.
22
+ [25ed7bedbb94]
23
+
24
+ * lib/configurability.rb:
25
+ Improve the log message for omitted config sections
26
+ [e56100a012e3]
27
+
28
+ 2012-04-23 Michael Granger <ged@FaerieMUD.org>
29
+
30
+ * Rakefile:
31
+ Activate the :deveiate Hoe plugin in the Rakefile.
32
+ [4aa3a6d50599]
33
+
34
+ 2012-04-18 Michael Granger <ged@FaerieMUD.org>
35
+
36
+ * README.rdoc, Rakefile:
37
+ Fix a FIXME, use fivefish if available.
38
+ [0644d0a8ff3e]
39
+
40
+ * History.rdoc, README.rdoc, lib/configurability.rb:
41
+ Update the README, bump the minor version, update history.
42
+
43
+ Still needs more documentation updates before release, especially
44
+ the README.
45
+ [dce671bc85e1]
46
+
47
+ * lib/configurability.rb, spec/configurability_spec.rb:
48
+ Added defaults-gathering API
49
+ [af3f708c9372]
50
+
51
+ * .rvm.gems, lib/configurability/config.rb,
52
+ spec/configurability/config_spec.rb, spec/lib/helpers.rb:
53
+ Updating some specs
54
+ [4a7df2547d13]
55
+
56
+ * Manifest.txt, lib/configurability.rb, lib/configurability/config.rb,
57
+ lib/configurability/logformatter.rb, lib/configurability/logging.rb:
58
+ Extracted logging out into a mixin
59
+ [47fe73c22f31]
60
+
1
61
  2012-03-13 Michael Granger <ged@FaerieMUD.org>
2
62
 
3
63
  * .hgtags:
4
64
  Added tag v1.0.10 for changeset f95c9b9cfc25
5
- [e4af16343901] [tip]
65
+ [e4af16343901]
6
66
 
7
67
  * .hgsigs:
8
68
  Added signature for changeset 0dcd8dcebc87
data/History.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == v1.2.0 [2012-05-09] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ - Added a command-line utility.
4
+ - Convert logging to use Loggability.
5
+
6
+
1
7
  == v1.1.0 [2012-04-25] Michael Granger <ged@FaerieMUD.org>
2
8
 
3
9
  Add a 'defaults' API that allows defaults to be gathered from any
data/Manifest.txt CHANGED
@@ -4,13 +4,13 @@ LICENSE
4
4
  Manifest.txt
5
5
  README.rdoc
6
6
  Rakefile
7
+ bin/configurability
7
8
  examples/basicconfig.rb
8
9
  examples/config.yml
9
10
  lib/configurability.rb
10
11
  lib/configurability/behavior.rb
11
12
  lib/configurability/config.rb
12
13
  lib/configurability/deferredconfig.rb
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/Rakefile CHANGED
@@ -22,6 +22,8 @@ hoespec = Hoe.spec 'configurability' do
22
22
 
23
23
  self.developer 'Michael Granger', 'ged@FaerieMUD.org'
24
24
 
25
+ self.dependency 'loggability', '~> 0.1'
26
+
25
27
  self.dependency 'rspec', '~> 2.4', :developer
26
28
  self.dependency 'simplecov', '~> 0.3', :developer
27
29
 
@@ -0,0 +1,335 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set nosta noet ts=4 sw=4:
3
+
4
+ require 'configurability'
5
+ require 'configurability/config'
6
+ require 'trollop'
7
+ require 'highline'
8
+
9
+ # Have to do it this way to avoid the vendored 'sysexits' under OSX.
10
+ gem 'sysexits'
11
+ require 'sysexits'
12
+
13
+
14
+ # A tool for setting up and running Configurability apps
15
+ class Configurability::Command
16
+ extend ::Sysexits,
17
+ Loggability
18
+ include Sysexits
19
+
20
+ # Loggability API -- log messages through the Configurability module's logger
21
+ log_to :configurability
22
+
23
+ # Make a HighLine color scheme
24
+ COLOR_SCHEME = HighLine::ColorScheme.new do |scheme|
25
+ scheme[:header] = [ :bold, :yellow ]
26
+ scheme[:subheader] = [ :bold, :white ]
27
+ scheme[:key] = [ :white ]
28
+ scheme[:value] = [ :bold, :white ]
29
+ scheme[:error] = [ :red ]
30
+ scheme[:warning] = [ :yellow ]
31
+ scheme[:message] = [ :reset ]
32
+ end
33
+
34
+
35
+ # Class instance variables
36
+ @command_help = Hash.new {|h,k| h[k] = { :desc => nil, :usage => ''} }
37
+ @prompt = @option_parser = nil
38
+
39
+
40
+ ### Run the utility with the given +args+.
41
+ def self::run( args )
42
+ HighLine.color_scheme = COLOR_SCHEME
43
+
44
+ oparser = self.make_option_parser
45
+ opts = Trollop.with_standard_exception_handling( oparser ) do
46
+ oparser.parse( args )
47
+ end
48
+
49
+ command = oparser.leftovers.shift
50
+ self.new( opts ).run( command, *oparser.leftovers )
51
+ exit :ok
52
+
53
+ rescue => err
54
+ self.log.fatal "Oops: %s: %s" % [ err.class.name, err.message ]
55
+ self.log.debug { ' ' + err.backtrace.join("\n ") }
56
+
57
+ exit :software_error
58
+ end
59
+
60
+
61
+ ### Return a String that describes the available commands, e.g., for the 'help'
62
+ ### command.
63
+ def self::make_command_table
64
+ commands = self.available_commands
65
+
66
+ # Build the command table
67
+ col1len = commands.map( &:length ).max
68
+ return commands.collect do |cmd|
69
+ helptext = self.help( cmd.to_sym ) or next # no help == invisible command
70
+ "%s %s" % [
71
+ self.prompt.color(cmd.rjust(col1len), :key),
72
+ self.prompt.color(helptext, :value)
73
+ ]
74
+ end.compact
75
+ end
76
+
77
+
78
+ ### Return an Array of the available commands.
79
+ def self::available_commands
80
+ return self.public_instance_methods( false ).
81
+ map( &:to_s ).
82
+ grep( /_command$/ ).
83
+ map {|methodname| methodname.sub(/_command$/, '') }.
84
+ sort
85
+ end
86
+
87
+
88
+ ### Create and configure a command-line option parser for the command.
89
+ ### Returns a Trollop::Parser.
90
+ def self::make_option_parser
91
+ unless @option_parser
92
+ progname = File.basename( $0 )
93
+
94
+ # Make a list of the log level names and the available commands
95
+ loglevels = Loggability::LOG_LEVELS.
96
+ sort_by {|name,lvl| lvl }.
97
+ collect {|name,lvl| name.to_s }.
98
+ join( ', ' )
99
+ command_table = self.make_command_table
100
+
101
+ @option_parser = Trollop::Parser.new do
102
+ banner "Configurability Reports"
103
+
104
+ text ''
105
+ command_table.each {|line| text(line) }
106
+ text ''
107
+
108
+ text 'Global Options'
109
+ opt :require, "Require one or more additional libraries.",
110
+ :multi => true, :type => :string
111
+ opt :include, "Add additional directories to the load path.",
112
+ :multi => true, :type => :string, :short => :I
113
+ text ''
114
+
115
+ text 'Other Options:'
116
+ opt :debug, "Turn debugging on. Also sets the --loglevel to 'debug'."
117
+ opt :loglevel, "Set the logging level. Must be one of: #{loglevels}",
118
+ :default => Configurability.logger.level.to_s
119
+ end
120
+ end
121
+
122
+ return @option_parser
123
+ end
124
+
125
+
126
+ ### Add a help string for the given +command+.
127
+ def self::help( command, helpstring=nil )
128
+ if helpstring
129
+ @command_help[ command.to_sym ][:desc] = helpstring
130
+ end
131
+
132
+ return @command_help[ command.to_sym ][:desc]
133
+ end
134
+
135
+
136
+ ### Add/fetch the +usagestring+ for +command+.
137
+ def self::usage( command, usagestring=nil )
138
+ if usagestring
139
+ prefix = usagestring[ /\A(\s+)/, 1 ]
140
+ usagestring.gsub!( /^#{prefix}/m, '' ) if prefix
141
+
142
+ @command_help[ command.to_sym ][:usage] = usagestring
143
+ end
144
+
145
+ return @command_help[ command.to_sym ][:usage]
146
+ end
147
+
148
+
149
+ ### Return the global Highline prompt object, creating it if necessary.
150
+ def self::prompt
151
+ unless @prompt
152
+ @prompt = HighLine.new
153
+
154
+ columns = @prompt.output_cols.nonzero? || 80
155
+ rows = @prompt.output_rows.nonzero? || 1000
156
+
157
+ @prompt.page_at = rows - 5
158
+ @prompt.wrap_at = columns - 2
159
+ end
160
+
161
+ return @prompt
162
+ end
163
+
164
+
165
+ #################################################################
166
+ ### I N S T A N C E M E T H O D S
167
+ #################################################################
168
+
169
+ ### Create a new instance of the command and set it up with the given
170
+ ### +options+.
171
+ def initialize( options )
172
+ Loggability.format_with( :color ) if $stderr.tty?
173
+ @options = options
174
+
175
+ if @options.debug
176
+ $DEBUG = true
177
+ $VERBOSE = true
178
+ Loggability.level = :debug
179
+ elsif @options.loglevel
180
+ Loggability.level = @options.loglevel
181
+ end
182
+
183
+ self.log.debug "Options are: %p" % [ options ]
184
+ end
185
+
186
+
187
+ ######
188
+ public
189
+ ######
190
+
191
+ # The Trollop options hash the command will read its configuration from
192
+ attr_reader :options
193
+
194
+
195
+ # Delegate the instance #prompt method to the class method instead
196
+ define_method( :prompt, &self.method(:prompt) )
197
+
198
+
199
+ ### Run the command with the specified +command+ and +args+.
200
+ def run( command, *args )
201
+ command ||= 'info'
202
+ cmd_method = nil
203
+ loglevel = Configurability.logger.level
204
+
205
+ # Unshift directories to the load path specified with -I
206
+ self.options[:include].each do |path|
207
+ dirs = path.split( File::PATH_SEPARATOR )
208
+ self.log.debug "Prepending %p to the load path..." % [ dirs ]
209
+ $LOAD_PATH.unshift( *dirs )
210
+ end
211
+
212
+ # Require libraries specified with -r
213
+ self.options[:require].each do |lib|
214
+ $stderr.puts "Requiring %p..." % [ lib ]
215
+ require( lib )
216
+ end
217
+
218
+ Loggability.level = loglevel
219
+ begin
220
+ cmd_method = self.method( "#{command}_command" )
221
+ rescue NameError => err
222
+ error "No such command %p" % [ command ]
223
+ exit :usage
224
+ end
225
+
226
+ cmd_method.call( *args )
227
+ end
228
+
229
+
230
+ #
231
+ # Commands
232
+ #
233
+
234
+ ### The 'help' command
235
+ def help_command( *args )
236
+
237
+ # Subcommand help
238
+ if !args.empty?
239
+ command = args.shift
240
+
241
+ if self.class.available_commands.include?( command )
242
+ header( self.class.help(command) )
243
+ desc = "\n" + 'Usage: ' + command + ' ' + self.class.usage(command) + "\n"
244
+ message( desc )
245
+ else
246
+ error "No such command %p" % [ command ]
247
+ end
248
+
249
+ # Help by itself show the table of available commands
250
+ else
251
+ command_table = self.class.make_command_table
252
+ header "Available Commands"
253
+ message( *command_table )
254
+ end
255
+
256
+ end
257
+ help :help, "Show help for a single COMMAND if given, or list available commands if not"
258
+ usage :help, "[COMMAND]"
259
+
260
+
261
+ ### The 'info' command
262
+ def info_command( *args )
263
+ header "Configurability Report"
264
+
265
+ cobjects = Configurability.configurable_objects
266
+
267
+ if cobjects.empty?
268
+ message "No objects extended with Configurability were loaded.",
269
+ "You can use the -I and -r flags to include library paths",
270
+ "and require libraries."
271
+ else
272
+ colwidth = cobjects.map {|obj| obj.config_key.length }.max
273
+ colwidth = 10 if colwidth < 10
274
+
275
+ subheader "%*s %s" % [ colwidth, "Config Key", "Configurable Object" ]
276
+ cobjects.each do |obj|
277
+ message "%*s : %p" % [ colwidth, obj.config_key, obj ]
278
+ end
279
+ end
280
+ end
281
+ help :info, "Show objects with Configurability in loaded code. Use -r " +
282
+ "to require additional libraries."
283
+
284
+
285
+ ### The 'version' command
286
+ def version_command( *args )
287
+ message( "<%= color 'Version:', :header %> " + Configurability.version_string(true) )
288
+ end
289
+ help :version, "Prints the Ruby-Mongrel2 version."
290
+
291
+
292
+ #
293
+ # Helper methods
294
+ #
295
+
296
+
297
+
298
+ #
299
+ # Utility methods
300
+ #
301
+
302
+ ### Output normal output
303
+ def message( *parts )
304
+ self.prompt.say( parts.map(&:to_s).join($/) )
305
+ end
306
+
307
+
308
+ ### Output the given +text+ highlighted as a header.
309
+ def header( text )
310
+ message( self.prompt.color(text, :header) )
311
+ end
312
+
313
+
314
+ ### Output the given +text+ highlighted as a subheader.
315
+ def subheader( text )
316
+ message( self.prompt.color(text, :subheader) )
317
+ end
318
+
319
+
320
+ ### Output the given +text+ highlighted as an error.
321
+ def error( text )
322
+ message( self.prompt.color(text, :error) )
323
+ end
324
+
325
+
326
+ ### Output the given +items+ as a columnar list.
327
+ def list( *items )
328
+ message( self.prompt.list(items.flatten.compact.map(&:to_s), :columns_down) )
329
+ end
330
+
331
+ end # class Configurability::Command
332
+
333
+
334
+ Configurability::Command.run( ARGV.dup )
335
+
@@ -1,24 +1,27 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'loggability'
3
4
  require 'yaml'
4
5
 
5
6
  # A configuration mixin for Ruby classes.
6
- #
7
+ #
7
8
  # == Author/s
8
- #
9
+ #
9
10
  # * Michael Granger <ged@FaerieMUD.org>
10
- #
11
+ #
11
12
  module Configurability
13
+ extend Loggability
12
14
 
13
- # Library version constant
14
- VERSION = '1.1.0'
15
15
 
16
- # Version-control revision constant
17
- REVISION = %q$Revision: e56100a012e3 $
16
+ # Loggability API -- set up a Loggability logger for the library
17
+ log_as :configurability
18
18
 
19
19
 
20
- require 'configurability/logging'
21
- extend Configurability::Logging
20
+ # Library version constant
21
+ VERSION = '1.2.0'
22
+
23
+ # Version-control revision constant
24
+ REVISION = %q$Revision: 6b5e075386ee $
22
25
 
23
26
  require 'configurability/deferredconfig'
24
27
 
@@ -9,12 +9,12 @@ require 'logger'
9
9
  require 'configurability'
10
10
 
11
11
  # A configuration object class for systems with Configurability
12
- #
12
+ #
13
13
  # == Author/s
14
14
  #
15
15
  # * Michael Granger <ged@FaerieMUD.org>
16
16
  # * Mahlon E. Smith <mahlon@martini.nu>
17
- #
17
+ #
18
18
  # This class also delegates some of its methods to the underlying struct:
19
19
  #
20
20
  # [Configurability::Config::Struct#to_hash]
@@ -33,9 +33,14 @@ require 'configurability'
33
33
  # #[] (delegated to its internal Struct)
34
34
  # [Configurability::Config::Struct#[]=]
35
35
  # #[]= (delegated to its internal Struct)
36
- #
36
+ #
37
37
  class Configurability::Config
38
- extend Forwardable
38
+ extend Forwardable,
39
+ Loggability
40
+
41
+
42
+ # Loggability API -- set up logging through the Configurability module's logger
43
+ log_to :configurability
39
44
 
40
45
 
41
46
  #############################################################
data/spec/lib/helpers.rb CHANGED
@@ -19,120 +19,37 @@ require 'yaml'
19
19
 
20
20
  SimpleCov.start do
21
21
  add_filter '/spec/'
22
- add_filter '/textmate-command/'
23
22
  end
24
23
  require 'configurability'
25
24
 
26
25
 
27
- # An alternate formatter for Logger instances that outputs +div+ HTML
28
- # fragments.
29
- class HtmlLogFormatter < Logger::Formatter
30
- include ERB::Util # for html_escape()
31
-
32
- # The default HTML fragment that'll be used as the template for each log message.
33
- HTML_LOG_FORMAT = %q{
34
- <div class="log-message %5$s">
35
- <span class="log-time">%1$s.%2$06d</span>
36
- [
37
- <span class="log-pid">%3$d</span>
38
- /
39
- <span class="log-tid">%4$s</span>
40
- ]
41
- <span class="log-level">%5$s</span>
42
- :
43
- <span class="log-name">%6$s</span>
44
- <span class="log-message-text">%7$s</span>
45
- </div>
46
- }
47
-
48
- ### Override the logging formats with ones that generate HTML fragments
49
- def initialize( logger, format=HTML_LOG_FORMAT ) # :notnew:
50
- @logger = logger
51
- @format = format
52
- super()
53
- end
54
-
55
-
56
- ######
57
- public
58
- ######
59
-
60
- # The HTML fragment that will be used as a format() string for the log
61
- attr_accessor :format
62
-
63
-
64
- ### Return a log message composed out of the arguments formatted using the
65
- ### formatter's format string
66
- def call( severity, time, progname, msg )
67
- args = [
68
- time.strftime( '%Y-%m-%d %H:%M:%S' ), # %1$s
69
- time.usec, # %2$d
70
- Process.pid, # %3$d
71
- Thread.current == Thread.main ? 'main' : Thread.object_id, # %4$s
72
- severity.downcase, # %5$s
73
- progname, # %6$s
74
- html_escape( msg ).gsub(/\n/, '<br />') # %7$s
75
- ]
76
-
77
- return self.format % args
78
- end
79
-
80
- end # class HtmlLogFormatter
81
-
82
26
  ### RSpec helper functions.
83
27
  module Configurability::SpecHelpers
84
28
 
85
- LEVEL = {
86
- :debug => Logger::DEBUG,
87
- :info => Logger::INFO,
88
- :warn => Logger::WARN,
89
- :error => Logger::ERROR,
90
- :fatal => Logger::FATAL,
91
- }
92
-
93
- class ArrayLogger
94
- ### Create a new ArrayLogger that will append content to +array+.
95
- def initialize( array )
96
- @array = array
97
- end
98
-
99
- ### Write the specified +message+ to the array.
100
- def write( message )
101
- @array << message
102
- end
103
-
104
- ### No-op -- this is here just so Logger doesn't complain
105
- def close; end
106
-
107
- end # class ArrayLogger
108
-
109
-
110
29
  ###############
111
30
  module_function
112
31
  ###############
113
32
 
114
33
  ### Reset the logging subsystem to its default state.
115
34
  def reset_logging
116
- Configurability.reset_logger
35
+ Loggability.formatter = nil
36
+ Loggability.output_to( $stderr )
37
+ Loggability.level = :fatal
117
38
  end
118
39
 
119
40
 
120
41
  ### Alter the output of the default log formatter to be pretty in SpecMate output
121
- def setup_logging( level=Logger::FATAL )
122
-
123
- # Turn symbol-style level config into Logger's expected Fixnum level
124
- level = LEVEL[ level ] if LEVEL.key?( level )
42
+ def setup_logging( level=:fatal )
125
43
 
126
44
  # Only do this when executing from a spec in TextMate
127
45
  if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
128
- Thread.current['logger-output'] = []
129
- logdevice = ArrayLogger.new( Thread.current['logger-output'] )
130
- Configurability.logger = Logger.new( logdevice )
131
- Configurability.logger.formatter = HtmlLogFormatter.new( Configurability.logger )
46
+ logarray = []
47
+ Thread.current['logger-output'] = logarray
48
+ Loggability.output_to( logarray )
49
+ Loggability.format_as( :html )
50
+ Loggability.level = :debug
132
51
  else
133
- logger = Logger.new( $stderr )
134
- Configurability.logger = logger
135
- Configurability.logger.level = level
52
+ Loggability.level = level
136
53
  end
137
54
  end
138
55
 
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.1.0
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -36,8 +36,24 @@ cert_chain:
36
36
  YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
37
37
  Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
38
38
  cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
- date: 2012-04-26 00:00:00.000000000 Z
39
+ date: 2012-05-09 00:00:00.000000000 Z
40
40
  dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: loggability
43
+ requirement: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '0.1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: '0.1'
41
57
  - !ruby/object:Gem::Dependency
42
58
  name: hoe-mercurial
43
59
  requirement: !ruby/object:Gem::Requirement
@@ -61,7 +77,7 @@ dependencies:
61
77
  requirements:
62
78
  - - ~>
63
79
  - !ruby/object:Gem::Version
64
- version: 0.0.1
80
+ version: 0.1.0
65
81
  type: :development
66
82
  prerelease: false
67
83
  version_requirements: !ruby/object:Gem::Requirement
@@ -69,7 +85,7 @@ dependencies:
69
85
  requirements:
70
86
  - - ~>
71
87
  - !ruby/object:Gem::Version
72
- version: 0.0.1
88
+ version: 0.1.0
73
89
  - !ruby/object:Gem::Dependency
74
90
  name: rdoc
75
91
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +162,8 @@ description: ! 'Configurability is a unified, unintrusive, assume-nothing config
146
162
  single action.'
147
163
  email:
148
164
  - ged@FaerieMUD.org
149
- executables: []
165
+ executables:
166
+ - configurability
150
167
  extensions: []
151
168
  extra_rdoc_files:
152
169
  - History.rdoc
@@ -159,13 +176,13 @@ files:
159
176
  - Manifest.txt
160
177
  - README.rdoc
161
178
  - Rakefile
179
+ - bin/configurability
162
180
  - examples/basicconfig.rb
163
181
  - examples/config.yml
164
182
  - lib/configurability.rb
165
183
  - lib/configurability/behavior.rb
166
184
  - lib/configurability/config.rb
167
185
  - lib/configurability/deferredconfig.rb
168
- - lib/configurability/logging.rb
169
186
  - spec/configurability/config_spec.rb
170
187
  - spec/configurability/deferredconfig_spec.rb
171
188
  - spec/configurability_spec.rb
@@ -196,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
213
  version: '0'
197
214
  requirements: []
198
215
  rubyforge_project: configurability
199
- rubygems_version: 1.8.21
216
+ rubygems_version: 1.8.24
200
217
  signing_key:
201
218
  specification_version: 3
202
219
  summary: Configurability is a unified, unintrusive, assume-nothing configuration system
metadata.gz.sig CHANGED
@@ -1,2 +1 @@
1
- J:5��I�(e��} �=�2?ޛv 9.^�|
2
- G �XK�"��&��G�Yl��N�У����P��t�x$��v;��=߈��PA�� @X��tN����u����1��y�x~�ˣ+F��K) �FO��>�ص�woٸ�^��w�>�l��7T�L �`�_�m�
1
+ A=��%���ۋc����M� 2V������J}2�q�NCL5�nW�]9��h ����;�5'�G�g��l�M!Ǝ ���k��q���0"��}�F��� �TTn^&f�h+����r���<P���/��tG9�67!�t��0��c� sY�]� c�n��B!�„�a!Yc��>3�8W[ÅVIA�D�}+��
@@ -1,300 +0,0 @@
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( '&', '&amp;' ).
292
- gsub( '<', '&lt;' ).
293
- gsub( '>', '&gt;' )
294
- end
295
-
296
- end # class HtmlFormatter
297
-
298
-
299
- end # module Configurability
300
-