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 +0 -0
- data/ChangeLog +61 -1
- data/History.rdoc +6 -0
- data/Manifest.txt +1 -1
- data/Rakefile +2 -0
- data/bin/configurability +335 -0
- data/lib/configurability.rb +12 -9
- data/lib/configurability/config.rb +9 -4
- data/spec/lib/helpers.rb +10 -93
- metadata +24 -7
- metadata.gz.sig +1 -2
- data/lib/configurability/logging.rb +0 -300
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]
|
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
data/bin/configurability
ADDED
@@ -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
|
+
|
data/lib/configurability.rb
CHANGED
@@ -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
|
-
#
|
17
|
-
|
16
|
+
# Loggability API -- set up a Loggability logger for the library
|
17
|
+
log_as :configurability
|
18
18
|
|
19
19
|
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
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
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
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.
|
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-
|
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
|
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
|
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.
|
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
|
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( '&', '&' ).
|
292
|
-
gsub( '<', '<' ).
|
293
|
-
gsub( '>', '>' )
|
294
|
-
end
|
295
|
-
|
296
|
-
end # class HtmlFormatter
|
297
|
-
|
298
|
-
|
299
|
-
end # module Configurability
|
300
|
-
|