configurability 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
-