jeckyl 0.2.7 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Bugs.rdoc +14 -2
- data/Gemfile +4 -2
- data/History.txt +36 -1
- data/bin/jeckyl +89 -57
- data/bin/jeckyl-old +259 -0
- data/lib/jeckyl/helpers.rb +316 -0
- data/lib/jeckyl/version.rb +9 -8
- data/lib/jeckyl.rb +178 -251
- data/spec/jeckyl_spec.rb +25 -1
- data/test/conf.d/jeckyl +11 -2
- data/test/conf.d/jeckyl_alt.rb +55 -0
- data/test/conf.d/merger.rb +1 -1
- data/test/conf.d/not_a_hash +1 -1
- data/test/conf.d/not_positive.rb +1 -0
- data/test/test_command +42 -0
- data/test/test_configurator.rb +39 -5
- metadata +58 -78
data/lib/jeckyl.rb
CHANGED
@@ -11,8 +11,10 @@
|
|
11
11
|
#
|
12
12
|
# == JECKYL
|
13
13
|
#
|
14
|
+
require 'optparse'
|
14
15
|
require 'jeckyl/version'
|
15
16
|
require 'jeckyl/errors'
|
17
|
+
require 'jeckyl/helpers'
|
16
18
|
|
17
19
|
#
|
18
20
|
# The Jeckyl configurator module, which is just a wrapper. See {file:README.md Readme} for details.
|
@@ -37,6 +39,7 @@ module Jeckyl
|
|
37
39
|
#
|
38
40
|
# More details are available in the {file:README.md Readme} file
|
39
41
|
class Config < Hash
|
42
|
+
|
40
43
|
|
41
44
|
# create a configuration hash by evaluating the parameters defined in the given config file.
|
42
45
|
#
|
@@ -66,12 +69,18 @@ module Jeckyl
|
|
66
69
|
# hash for comments accessed with the same symbol
|
67
70
|
@_comments = {}
|
68
71
|
# hash for input defaults
|
69
|
-
@_defaults={}
|
72
|
+
@_defaults = {}
|
73
|
+
# hash for optparse options
|
74
|
+
@_options = {}
|
75
|
+
# hash for short descriptions
|
76
|
+
@_descriptions = {}
|
70
77
|
# save order in which methods are defined for generating config files
|
71
78
|
@_order = Array.new
|
72
79
|
|
73
80
|
# get the defaults defined in the config parser
|
74
81
|
get_defaults(:local=> local, :flag_errors => flag_errors_on_defaults)
|
82
|
+
|
83
|
+
self[:config_files] = Array.new
|
75
84
|
|
76
85
|
return self if config_file.nil?
|
77
86
|
|
@@ -90,20 +99,30 @@ module Jeckyl
|
|
90
99
|
|
91
100
|
# gives access to a hash containing an entry for each parameter and the comments
|
92
101
|
# defined by the class definitions - used internally by class methods
|
93
|
-
def
|
102
|
+
def _comments
|
94
103
|
@_comments
|
95
104
|
end
|
96
105
|
|
97
106
|
# This contains an array of the parameter names - used internally by class methods
|
98
|
-
def
|
107
|
+
def _order
|
99
108
|
@_order
|
100
109
|
end
|
101
110
|
|
102
111
|
# this contains a hash of the defaults for each parameter - used internally by class methods
|
103
|
-
def
|
112
|
+
def _defaults
|
104
113
|
@_defaults
|
105
114
|
end
|
106
115
|
|
116
|
+
# return hash of options - used internally to generate files etc
|
117
|
+
def _options
|
118
|
+
@_options
|
119
|
+
end
|
120
|
+
|
121
|
+
# return has of descriptions
|
122
|
+
def _descriptions
|
123
|
+
@_descriptions
|
124
|
+
end
|
125
|
+
|
107
126
|
# a class method to check a given config file one item at a time
|
108
127
|
#
|
109
128
|
# This evaluates the given config file and reports if there are any errors to the
|
@@ -165,14 +184,26 @@ module Jeckyl
|
|
165
184
|
def self.generate_config(local=false)
|
166
185
|
me = self.new(nil, :local => local)
|
167
186
|
# everything should now exist
|
168
|
-
me.
|
187
|
+
me._order.each do |key|
|
188
|
+
|
189
|
+
if me._descriptions.has_key?(key) then
|
190
|
+
puts "# #{me._descriptions[key]}"
|
191
|
+
puts "#"
|
192
|
+
end
|
169
193
|
|
170
|
-
if me.
|
171
|
-
me.
|
194
|
+
if me._comments.has_key?(key) then
|
195
|
+
me._comments[key].each do |comment|
|
172
196
|
puts "# #{comment}"
|
173
197
|
end
|
174
198
|
end
|
175
|
-
|
199
|
+
# output an option description if needed
|
200
|
+
if me._options.has_key?(key) then
|
201
|
+
puts "#"
|
202
|
+
puts "# Optparse options for this parameter:"
|
203
|
+
puts "# #{me._options[key].join(", ")}"
|
204
|
+
puts "#"
|
205
|
+
end
|
206
|
+
def_value = me._defaults[key]
|
176
207
|
default = def_value.nil? ? '' : def_value.inspect
|
177
208
|
|
178
209
|
puts "##{key.to_s} #{default}"
|
@@ -191,7 +222,7 @@ module Jeckyl
|
|
191
222
|
def self.intersection(full_config)
|
192
223
|
me = self.new # create the defaults for this class
|
193
224
|
my_hash = {}
|
194
|
-
me.
|
225
|
+
me._order.each do |my_key|
|
195
226
|
if full_config.has_key?(my_key) then
|
196
227
|
my_hash[my_key] = full_config[my_key]
|
197
228
|
end
|
@@ -212,6 +243,35 @@ module Jeckyl
|
|
212
243
|
return descs
|
213
244
|
end
|
214
245
|
|
246
|
+
# get a config file option from the given command line args
|
247
|
+
#
|
248
|
+
# This is needed with the optparse methods for obvious reasons - the options
|
249
|
+
# can only be parsed once and you may want to parse them with a config file specified
|
250
|
+
# on the command line. This does it the old-fashioned way and strips the option
|
251
|
+
# from the command line arguments.
|
252
|
+
#
|
253
|
+
# Note that the optparse method also includes this option but just for the benefit of --help
|
254
|
+
#
|
255
|
+
# @param [Array] args which should usually be set to ARGV
|
256
|
+
# @param [String] c_file being the path to the config file, which will be
|
257
|
+
# updated with the command line option if specified.
|
258
|
+
#
|
259
|
+
def self.get_config_opt(args, c_file)
|
260
|
+
#c_file = nil
|
261
|
+
if arg_index = args.index('-c') then
|
262
|
+
# got a -c option so expect a file next
|
263
|
+
c_file = args[arg_index + 1]
|
264
|
+
|
265
|
+
# check the file exists
|
266
|
+
if c_file && FileTest.readable?(c_file) then
|
267
|
+
# it does so strip the args out
|
268
|
+
args.slice!(arg_index, 2)
|
269
|
+
|
270
|
+
end
|
271
|
+
end
|
272
|
+
return [args, c_file]
|
273
|
+
end
|
274
|
+
|
215
275
|
|
216
276
|
# set the prefix to the parameter names that should be used for corresponding
|
217
277
|
# parameter methods defined for a subclass. Parameter names in config files
|
@@ -238,15 +298,23 @@ module Jeckyl
|
|
238
298
|
|
239
299
|
# Read, check and merge another parameter file into this one, being of the same config class.
|
240
300
|
#
|
301
|
+
# If the file does not exist then silently ignore the merge
|
302
|
+
#
|
241
303
|
# @param [String] conf_file - path to file to parse
|
242
304
|
#
|
243
305
|
def merge(conf_file)
|
244
306
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
307
|
+
if conf_file.kind_of?(Hash) then
|
308
|
+
self.merge!(conf_file)
|
309
|
+
else
|
310
|
+
|
311
|
+
return unless FileTest.exists?(conf_file)
|
312
|
+
|
313
|
+
self[:config_files] << conf_file
|
314
|
+
|
315
|
+
# get the values from the config file itself
|
316
|
+
self.instance_eval(File.read(conf_file), conf_file)
|
317
|
+
end
|
250
318
|
rescue SyntaxError => err
|
251
319
|
raise ConfigSyntaxError, err.message
|
252
320
|
rescue Errno::ENOENT
|
@@ -254,12 +322,88 @@ module Jeckyl
|
|
254
322
|
raise ConfigFileMissing, "#{conf_file}"
|
255
323
|
end
|
256
324
|
|
325
|
+
# parse the given command line using the defined options
|
326
|
+
#
|
327
|
+
# @param [Array] args which should usually be ARGV
|
328
|
+
# @yield self and optparse object to allow incidental options to be added
|
329
|
+
# @return false if --help so that the caller can decide what to do (e.g. exit)
|
330
|
+
def optparse(args)
|
331
|
+
|
332
|
+
# ensure calls to parameter methods do not trample on things
|
333
|
+
@_last_symbol = nil
|
334
|
+
|
335
|
+
opts = OptionParser.new
|
336
|
+
# get the prefix for parameter methods (once)
|
337
|
+
prefix = self.prefix
|
338
|
+
|
339
|
+
opts.on('-c', '--config-file [FILENAME]', String, 'specify an alternative config file')
|
340
|
+
|
341
|
+
# need to define usage etc
|
342
|
+
|
343
|
+
# loop through each of the options saved
|
344
|
+
@_options.each_pair do |param, options|
|
345
|
+
|
346
|
+
options << @_descriptions[param] if @_descriptions.has_key?(param)
|
347
|
+
|
348
|
+
# opt_str = ''
|
349
|
+
# options.each do |os|
|
350
|
+
# opt_str << os.inspect
|
351
|
+
# end
|
352
|
+
|
353
|
+
# puts "#{param}: #{opt_str}"
|
354
|
+
|
355
|
+
# get the method itself to call with the given arg
|
356
|
+
pref_method = self.method("#{prefix}_#{param}".to_sym)
|
357
|
+
|
358
|
+
# now process the option
|
359
|
+
opts.on(*options) do |val|
|
360
|
+
# and save the results having passed it through the parameter method
|
361
|
+
self[param] = pref_method.call(val)
|
362
|
+
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# allow non-jeckyl options to be added (without the checks!)
|
367
|
+
if block_given? then
|
368
|
+
# pass out self to allow parameters to be saved and the opts object
|
369
|
+
yield(self, opts)
|
370
|
+
end
|
371
|
+
|
372
|
+
# add in a little bit of help
|
373
|
+
opts.on_tail('-h', '--help', 'you are looking at it') do
|
374
|
+
puts opts
|
375
|
+
return false
|
376
|
+
end
|
377
|
+
|
378
|
+
opts.parse!(args)
|
379
|
+
|
380
|
+
return true
|
381
|
+
|
382
|
+
end
|
383
|
+
|
384
|
+
# output the hash as a formatted set
|
385
|
+
def to_s(opts={})
|
386
|
+
keys = self.keys.collect {|k| k.to_s}
|
387
|
+
cols = 0
|
388
|
+
keys.each {|k| cols = k.length if k.length > cols}
|
389
|
+
keys.sort.each do |key_s|
|
390
|
+
print ' '
|
391
|
+
print key_s.ljust(cols)
|
392
|
+
key = key_s.to_sym
|
393
|
+
desc = @_descriptions[key]
|
394
|
+
value = self[key].inspect
|
395
|
+
print ": #{value}"
|
396
|
+
print " (#{desc})" unless desc.nil?
|
397
|
+
puts
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
257
401
|
|
258
402
|
protected
|
259
403
|
|
260
404
|
# create a description for the current parameter, to be used when generating a config template
|
261
405
|
#
|
262
|
-
# @param [*String] being one or more string arguments that are used to generate config file templates
|
406
|
+
# @param [*String] strings being one or more string arguments that are used to generate config file templates
|
263
407
|
# and documents
|
264
408
|
def comment(*strings)
|
265
409
|
@_comments[@_last_symbol] = strings unless @_last_symbol.nil?
|
@@ -273,244 +417,22 @@ module Jeckyl
|
|
273
417
|
@_defaults[@_last_symbol] = val
|
274
418
|
end
|
275
419
|
|
276
|
-
#
|
277
|
-
|
278
|
-
# file helpers - meanings should be apparent
|
279
|
-
|
280
|
-
# check that the parameter is a directory and that the directory is writable
|
281
|
-
#
|
282
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
283
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
284
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
285
|
-
# the parameter is not validly formed
|
286
|
-
#
|
287
|
-
# @param [String] - path
|
288
|
-
#
|
289
|
-
def a_writable_dir(path)
|
290
|
-
if FileTest.directory?(path) && FileTest.writable?(path) then
|
291
|
-
path
|
292
|
-
else
|
293
|
-
raise_config_error(path, "directory is not writable or does not exist")
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
# check parameter is a readable file
|
420
|
+
# set optparse options for the parameter
|
298
421
|
#
|
299
|
-
#
|
300
|
-
|
301
|
-
|
302
|
-
# the parameter is not validly formed
|
303
|
-
#
|
304
|
-
# @param [String] - path to file
|
305
|
-
#
|
306
|
-
def a_readable_file(path)
|
307
|
-
if FileTest.readable?(path) then
|
308
|
-
path
|
309
|
-
else
|
310
|
-
raise_config_error(path, "file does not exist")
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
# simple type helpers
|
315
|
-
|
316
|
-
# check the parameter is of the required type
|
317
|
-
#
|
318
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
319
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
320
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
321
|
-
# the parameter is not validly formed
|
322
|
-
#
|
323
|
-
# @param [Object] obj to check type of
|
324
|
-
# @param [Class] type, being a class constant such as Numeric, String
|
325
|
-
#
|
326
|
-
def a_type_of(obj, type)
|
327
|
-
if obj.kind_of?(type) then
|
328
|
-
obj
|
329
|
-
else
|
330
|
-
raise_config_error(obj, "value is not of required type: #{type}")
|
331
|
-
end
|
422
|
+
# @param [Array] opts - options using the same format as optparse
|
423
|
+
def option(*opts)
|
424
|
+
@_options[@_last_symbol] = opts unless @_last_symbol.nil?
|
332
425
|
end
|
333
426
|
|
334
|
-
#
|
427
|
+
# set optparse description for the parameter
|
335
428
|
#
|
336
|
-
#
|
337
|
-
|
338
|
-
|
339
|
-
# the parameter is not validly formed
|
340
|
-
#
|
341
|
-
# @param [Numeric] val to check
|
342
|
-
# @param [Numeric] lower bound of range
|
343
|
-
# @param [Numeric] upper bound of range
|
344
|
-
#
|
345
|
-
def in_range(val, lower, upper)
|
346
|
-
raise_syntax_error("#{lower.to_s}..#{upper.to_s} is not a range") unless (lower .. upper).kind_of?(Range)
|
347
|
-
if (lower .. upper) === val then
|
348
|
-
val
|
349
|
-
else
|
350
|
-
raise_config_error(val, "value is not within required range: #{lower.to_s}..#{upper.to_s}")
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
|
355
|
-
# boolean helpers
|
356
|
-
|
357
|
-
# check parameter is a boolean, true or false but not strings "true" or "false"
|
358
|
-
#
|
359
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
360
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
361
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
362
|
-
# the parameter is not validly formed
|
363
|
-
#
|
364
|
-
# @param [Boolean] val to check
|
365
|
-
#
|
366
|
-
def a_boolean(val)
|
367
|
-
if val.kind_of?(TrueClass) || val.kind_of?(FalseClass) then
|
368
|
-
val
|
369
|
-
else
|
370
|
-
raise_config_error(val, "Value is not a Boolean")
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
# check the parameter is a flag, being "true", "false", "yes", "no", "on", "off", or 1 , 0
|
375
|
-
# and return a proper boolean
|
376
|
-
#
|
377
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
378
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
379
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
380
|
-
# the parameter is not validly formed
|
381
|
-
#
|
382
|
-
# @param [String] val to check
|
383
|
-
#
|
384
|
-
def a_flag(val)
|
385
|
-
val = val.downcase if val.kind_of?(String)
|
386
|
-
case val
|
387
|
-
when "true", "yes", "on", 1
|
388
|
-
true
|
389
|
-
when "false", "no", "off", 0
|
390
|
-
false
|
391
|
-
else
|
392
|
-
raise_config_error(val, "Cannot convert to Boolean")
|
393
|
-
end
|
394
|
-
end
|
395
|
-
|
396
|
-
|
397
|
-
# compound objects
|
398
|
-
|
399
|
-
# check the parameter is an array
|
400
|
-
#
|
401
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
402
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
403
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
404
|
-
# the parameter is not validly formed
|
405
|
-
#
|
406
|
-
# @param [Array] ary to check
|
407
|
-
#
|
408
|
-
def an_array(ary)
|
409
|
-
if ary.kind_of?(Array) then
|
410
|
-
ary
|
411
|
-
else
|
412
|
-
raise_config_error(ary, "value is not an Array")
|
413
|
-
end
|
414
|
-
end
|
415
|
-
|
416
|
-
# check the parameter is an array and the array is of the required type
|
417
|
-
#
|
418
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
419
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
420
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
421
|
-
# the parameter is not validly formed
|
422
|
-
#
|
423
|
-
# @param [Array] ary of values to check
|
424
|
-
# @param [Class] type being the class that the values must belong to
|
425
|
-
#
|
426
|
-
def an_array_of(ary, type)
|
427
|
-
raise_syntax_error("Provided a value that is a type: #{type.to_s}") unless type.class == Class
|
428
|
-
if ary.kind_of?(Array) then
|
429
|
-
ary.each do |element|
|
430
|
-
unless element.kind_of?(type) then
|
431
|
-
raise_config_error(element, "element of array is not of type: #{type}")
|
432
|
-
end
|
433
|
-
end
|
434
|
-
return ary
|
435
|
-
else
|
436
|
-
raise_config_error(ary, "value is not an Array")
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
# check the parameter is a hash
|
441
|
-
#
|
442
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
443
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
444
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
445
|
-
# the parameter is not validly formed
|
446
|
-
#
|
447
|
-
# @param [Hash] hsh to check
|
448
|
-
#
|
449
|
-
def a_hash(hsh)
|
450
|
-
if hsh.kind_of?(Hash) then
|
451
|
-
true
|
452
|
-
else
|
453
|
-
raise_config_error(hsh, "value is not a Hash")
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
# strings and text and stuff
|
458
|
-
|
459
|
-
# check the parameter is a string
|
460
|
-
#
|
461
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
462
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
463
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
464
|
-
# the parameter is not validly formed
|
465
|
-
#
|
466
|
-
# @param [String] str to check
|
467
|
-
#
|
468
|
-
def a_string(str)
|
469
|
-
if str.kind_of?(String) then
|
470
|
-
str
|
471
|
-
else
|
472
|
-
raise_config_error(str.to_s, "is not a String")
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
# check the parameter is a string and matches the required pattern
|
477
|
-
#
|
478
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
479
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
480
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
481
|
-
# the parameter is not validly formed
|
482
|
-
#
|
483
|
-
# @param [String] str to match against the pattern
|
484
|
-
# @param [Regexp] pattern to match with
|
485
|
-
#
|
486
|
-
def a_matching_string(str, pattern)
|
487
|
-
raise_syntax_error("Attempt to pattern match without a Regexp") unless pattern.kind_of?(Regexp)
|
488
|
-
if pattern =~ a_string(str) then
|
489
|
-
str
|
490
|
-
else
|
491
|
-
raise_config_error(str, "does not match required pattern: #{pattern.source}")
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
# set membership - set is an array of members, usually symbols
|
496
|
-
#
|
497
|
-
# Jeckyl checking method to be used in parameter methods to check the validity of
|
498
|
-
# given parameters, returning the parameter if valid or else raising an exception
|
499
|
-
# which is either ConfigError if the parameter fails the check or ConfigSyntaxError if
|
500
|
-
# the parameter is not validly formed
|
501
|
-
#
|
502
|
-
# @param [Symbol] symb being the symbol to check
|
503
|
-
# @param [Array] set containing the valid symbols that symb should belong to
|
504
|
-
#
|
505
|
-
def a_member_of(symb, set)
|
506
|
-
raise_syntax_error("Sets to test membership must be arrays") unless set.kind_of?(Array)
|
507
|
-
if set.include?(symb) then
|
508
|
-
symb
|
509
|
-
else
|
510
|
-
raise_config_error(symb, "is not a member of: #{set.join(', ')}")
|
511
|
-
end
|
429
|
+
# @param [Array] str - options using the same format as optparse
|
430
|
+
def describe(str)
|
431
|
+
@_descriptions[@_last_symbol] = str unless @_last_symbol.nil?
|
512
432
|
end
|
513
433
|
|
434
|
+
# add in all the parameter checking helper methods
|
435
|
+
include Jeckyl::Helpers
|
514
436
|
|
515
437
|
private
|
516
438
|
|
@@ -556,15 +478,20 @@ module Jeckyl
|
|
556
478
|
self.class.instance_methods(!local).each do |method_name|
|
557
479
|
if md = /^#{self.prefix}_/.match(method_name) then
|
558
480
|
|
559
|
-
# its a prefixed method so
|
481
|
+
# its a prefixed method so get it
|
560
482
|
|
561
483
|
pref_method = self.method(method_name.to_sym)
|
562
484
|
# get the corresponding symbol for the hash
|
563
485
|
@_last_symbol = md.post_match.to_sym
|
564
486
|
@_order << @_last_symbol
|
565
|
-
# and call the method with
|
566
|
-
# call the
|
567
|
-
#
|
487
|
+
# and call the method with any parameter, which will
|
488
|
+
# call the default method where defined and capture its value
|
489
|
+
# Note that a default is defined in the same terms as the input
|
490
|
+
# to its parameter method, and may therefore need to be processed
|
491
|
+
# by the method to get the desired value. For example, if a parameter
|
492
|
+
# method expects data expressed in MBytes, but passes on bytes then
|
493
|
+
# the method has to be called with the default to get the real or final
|
494
|
+
# default. This is done in the block after this one:
|
568
495
|
begin
|
569
496
|
a_value = pref_method.call(1)
|
570
497
|
rescue Exception
|
data/spec/jeckyl_spec.rb
CHANGED
@@ -7,6 +7,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../test/test_subclass')
|
|
7
7
|
|
8
8
|
conf_path = File.expand_path(File.dirname(__FILE__) + '/../test/conf.d')
|
9
9
|
|
10
|
+
|
10
11
|
describe "Jeckyl" do
|
11
12
|
|
12
13
|
# general tests
|
@@ -30,6 +31,9 @@ describe "Jeckyl" do
|
|
30
31
|
conf[:email].should == "robert@osburn-sharp.ath.cx"
|
31
32
|
conf.has_key?(:sieve).should be_true
|
32
33
|
conf[:config_files].length.should == 1
|
34
|
+
conf[:option_set][:peter].should == 37
|
35
|
+
conf[:offset].should == 134
|
36
|
+
conf[:start_day].should == 6
|
33
37
|
end
|
34
38
|
|
35
39
|
|
@@ -89,6 +93,11 @@ describe "Jeckyl" do
|
|
89
93
|
lambda{conf = TestJeckyl.new(conf_file)}.should raise_error(Jeckyl::ConfigError, /^\[pi\]:.*value is not of required type: Float$/)
|
90
94
|
end
|
91
95
|
|
96
|
+
it "should raise an exception if it gets a negative instead of a positive" do
|
97
|
+
conf_file = conf_path + '/not_positive.rb'
|
98
|
+
lambda{conf = TestJeckyl.new(conf_file)}.should raise_error(Jeckyl::ConfigError, /^\[offset\]:.*value is not a positive number: \-\d+$/)
|
99
|
+
end
|
100
|
+
|
92
101
|
end
|
93
102
|
|
94
103
|
describe "Boolean Parameters" do
|
@@ -114,7 +123,7 @@ describe "Jeckyl" do
|
|
114
123
|
|
115
124
|
it "should raise an exception if it gets a string instead of a hash" do
|
116
125
|
conf_file = conf_path + '/not_a_hash'
|
117
|
-
lambda{conf = TestJeckyl.new(conf_file)}.should raise_error(Jeckyl::ConfigError, /^\[
|
126
|
+
lambda{conf = TestJeckyl.new(conf_file)}.should raise_error(Jeckyl::ConfigError, /^\[option_set\]:.*value is not a Hash$/)
|
118
127
|
end
|
119
128
|
|
120
129
|
it "should raise an exception if it gets an array of strings instead of a integers" do
|
@@ -197,6 +206,21 @@ describe "Jeckyl" do
|
|
197
206
|
conf[:config_files].length.should == 2
|
198
207
|
conf[:pi].should == 3.14592
|
199
208
|
end
|
209
|
+
|
210
|
+
it "should merge another hash" do
|
211
|
+
conf_file = conf_path + '/jeckyl'
|
212
|
+
conf = TestJeckyl.new(conf_file)
|
213
|
+
merge_file = File.join(conf_path, 'merger.rb')
|
214
|
+
merge = TestJeckyl.new(merge_file)
|
215
|
+
conf.merge(merge)
|
216
|
+
conf[:log_dir].should match(/reports$/)
|
217
|
+
conf[:log_level].should == :debug
|
218
|
+
conf[:log_rotation].should == 6
|
219
|
+
conf[:email].should == "robert@osburn-associates.ath.cx"
|
220
|
+
conf[:config_files].length.should == 1
|
221
|
+
conf[:pi].should == 3.14592
|
222
|
+
|
223
|
+
end
|
200
224
|
end
|
201
225
|
|
202
226
|
end
|
data/test/conf.d/jeckyl
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
# Jeckyl test file
|
3
3
|
#
|
4
4
|
|
5
|
+
root = File.expand_path('../..', File.dirname(__FILE__))
|
6
|
+
|
5
7
|
# should be a writable directory
|
6
|
-
log_dir "
|
8
|
+
log_dir File.join(root, "test")
|
7
9
|
|
8
10
|
#should be a valid symbol
|
9
11
|
log_level :verbose
|
@@ -25,7 +27,7 @@ sieve [2, 5, 7, 10, 15]
|
|
25
27
|
|
26
28
|
# hash of anything
|
27
29
|
my_opts = {:peter=>37, :paul=>40, :birds=>true}
|
28
|
-
|
30
|
+
option_set my_opts
|
29
31
|
|
30
32
|
# string formatted as email address
|
31
33
|
email "robert@osburn-sharp.ath.cx"
|
@@ -44,3 +46,10 @@ flag "no"
|
|
44
46
|
flag 1
|
45
47
|
flag 0
|
46
48
|
|
49
|
+
|
50
|
+
# new things
|
51
|
+
offset 134
|
52
|
+
|
53
|
+
start_day 6
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Jeckyl test file
|
3
|
+
#
|
4
|
+
|
5
|
+
root = File.expand_path('../..', File.dirname(__FILE__))
|
6
|
+
|
7
|
+
# should be a writable directory
|
8
|
+
log_dir File.join(root, "test")
|
9
|
+
|
10
|
+
#should be a valid symbol
|
11
|
+
log_level :debug
|
12
|
+
|
13
|
+
# should be an integer
|
14
|
+
log_rotation 10
|
15
|
+
|
16
|
+
# can be a float or any numeric
|
17
|
+
threshold 2.3
|
18
|
+
threshold 9.6
|
19
|
+
|
20
|
+
# must be a float
|
21
|
+
pi 3.1459276
|
22
|
+
|
23
|
+
# array of anything
|
24
|
+
collection ["names", 1, true ]
|
25
|
+
# array of integers
|
26
|
+
sieve [2, 5, 7, 10, 15]
|
27
|
+
|
28
|
+
# hash of anything
|
29
|
+
my_opts = {:peter=>37, :paul=>40, :birds=>true}
|
30
|
+
option_set my_opts
|
31
|
+
|
32
|
+
# string formatted as email address
|
33
|
+
email "robert@osburn-sharp.ath.cx"
|
34
|
+
|
35
|
+
# real booleans
|
36
|
+
debug false
|
37
|
+
debug true
|
38
|
+
|
39
|
+
# generous booleans
|
40
|
+
flag "true"
|
41
|
+
flag "false"
|
42
|
+
flag "off"
|
43
|
+
flag "on"
|
44
|
+
flag "yes"
|
45
|
+
flag "no"
|
46
|
+
flag 1
|
47
|
+
flag 0
|
48
|
+
|
49
|
+
|
50
|
+
# new things
|
51
|
+
offset 134
|
52
|
+
|
53
|
+
start_day 6
|
54
|
+
|
55
|
+
log_level :debug
|
data/test/conf.d/merger.rb
CHANGED