configurable 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Help/Command Line.rdoc +141 -0
- data/Help/Config Syntax.rdoc +229 -0
- data/Help/Config Types.rdoc +143 -0
- data/{History → History.rdoc} +9 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +144 -0
- data/lib/configurable.rb +7 -270
- data/lib/configurable/class_methods.rb +344 -367
- data/lib/configurable/config_classes.rb +3 -0
- data/lib/configurable/config_classes/list_config.rb +26 -0
- data/lib/configurable/config_classes/nest_config.rb +50 -0
- data/lib/configurable/config_classes/scalar_config.rb +91 -0
- data/lib/configurable/config_hash.rb +87 -112
- data/lib/configurable/config_types.rb +6 -0
- data/lib/configurable/config_types/boolean_type.rb +22 -0
- data/lib/configurable/config_types/float_type.rb +11 -0
- data/lib/configurable/config_types/integer_type.rb +11 -0
- data/lib/configurable/config_types/nest_type.rb +39 -0
- data/lib/configurable/config_types/object_type.rb +58 -0
- data/lib/configurable/config_types/string_type.rb +15 -0
- data/lib/configurable/conversions.rb +91 -0
- data/lib/configurable/module_methods.rb +0 -1
- data/lib/configurable/version.rb +1 -5
- metadata +73 -30
- data/README +0 -207
- data/lib/cdoc.rb +0 -413
- data/lib/cdoc/cdoc_html_generator.rb +0 -38
- data/lib/cdoc/cdoc_html_template.rb +0 -42
- data/lib/config_parser.rb +0 -563
- data/lib/config_parser/option.rb +0 -108
- data/lib/config_parser/switch.rb +0 -44
- data/lib/config_parser/utils.rb +0 -177
- data/lib/configurable/config.rb +0 -97
- data/lib/configurable/indifferent_access.rb +0 -35
- data/lib/configurable/nest_config.rb +0 -78
- data/lib/configurable/ordered_hash_patch.rb +0 -85
- data/lib/configurable/utils.rb +0 -186
- data/lib/configurable/validation.rb +0 -768
data/lib/cdoc.rb
DELETED
@@ -1,413 +0,0 @@
|
|
1
|
-
# RDoc creates a namespace conflict with IRB within 'rdoc/parsers/parse_rb'
|
2
|
-
# In that file, RubyToken and RubyLex get defined in the Object namespace,
|
3
|
-
# which will conflict with prior definitions from, for instance, IRB.
|
4
|
-
#
|
5
|
-
# This code redefines the RDoc RubyToken and RubyLex within the RDoc
|
6
|
-
# namespace. RDoc is not affected because all includes and uses of
|
7
|
-
# RubyToken and RubyLex are set when RDoc is loaded. The single exception
|
8
|
-
# I know of are several calls to class methods of RubyLex (ex RubyLex.debug?).
|
9
|
-
# These calls will be routed to the existing RubyLex.
|
10
|
-
#
|
11
|
-
# Uses of the existing RubyToken and RubyLex (as by irb) should be
|
12
|
-
# unaffected as the constants are reset after RDoc loads.
|
13
|
-
#
|
14
|
-
if Object.const_defined?(:RubyToken) || Object.const_defined?(:RubyLex)
|
15
|
-
class Object # :nodoc:
|
16
|
-
old_ruby_token = const_defined?(:RubyToken) ? remove_const(:RubyToken) : nil
|
17
|
-
old_ruby_lex = const_defined?(:RubyLex) ? remove_const(:RubyLex) : nil
|
18
|
-
|
19
|
-
require 'rdoc/rdoc'
|
20
|
-
|
21
|
-
# if by chance rdoc has ALREADY been loaded then requiring
|
22
|
-
# rdoc will not reset RubyToken and RubyLex... in this case
|
23
|
-
# the old constants are what you want.
|
24
|
-
new_ruby_token = const_defined?(:RubyToken) ? remove_const(:RubyToken) : old_ruby_token
|
25
|
-
new_ruby_lex = const_defined?(:RubyLex) ? remove_const(:RubyLex) : old_ruby_lex
|
26
|
-
|
27
|
-
RDoc.const_set(:RubyToken, new_ruby_token)
|
28
|
-
RDoc.const_set(:RubyLex, new_ruby_lex)
|
29
|
-
|
30
|
-
const_set(:RubyToken, old_ruby_token) unless old_ruby_token == nil
|
31
|
-
const_set(:RubyLex, old_ruby_lex) unless old_ruby_lex == nil
|
32
|
-
end
|
33
|
-
else
|
34
|
-
require 'rdoc/rdoc'
|
35
|
-
|
36
|
-
if Object.const_defined?(:RubyToken) && !RDoc.const_defined?(:RubyToken)
|
37
|
-
class Object # :nodoc:
|
38
|
-
RDoc.const_set(:RubyToken, remove_const(:RubyToken))
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
if Object.const_defined?(:RubyLex) && !RDoc.const_defined?(:RubyLex)
|
43
|
-
class Object # :nodoc:
|
44
|
-
RDoc.const_set(:RubyLex, remove_const(:RubyLex))
|
45
|
-
RDoc::RubyLex.const_set(:RubyLex, RDoc::RubyLex)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
unless Object.const_defined?(:TokenStream)
|
51
|
-
TokenStream = RDoc::TokenStream
|
52
|
-
Options = RDoc::Options
|
53
|
-
end
|
54
|
-
|
55
|
-
# CDoc hooks into and extends RDoc to make Configurable documentation available
|
56
|
-
# as attributes. CDoc provides an extension to the standard RDoc HTMLGenerator
|
57
|
-
# and template.
|
58
|
-
#
|
59
|
-
# === Usage
|
60
|
-
# To generate task documentation with configuration information, CDoc must be
|
61
|
-
# loaded and the appropriate flags passed to rdoc . Essentially what you want
|
62
|
-
# is:
|
63
|
-
#
|
64
|
-
# % rdoc --fmt cdoc --template cdoc/cdoc_html_template [file_names....]
|
65
|
-
#
|
66
|
-
# Unfortunately, there is no way to load or require a file into the rdoc
|
67
|
-
# utility directly; the above code causes an 'Invalid output formatter' error.
|
68
|
-
# However, CDoc is easy to utilize from a Rake::RDocTask:
|
69
|
-
#
|
70
|
-
# require 'rake'
|
71
|
-
# require 'rake/rdoctask'
|
72
|
-
#
|
73
|
-
# desc 'Generate documentation.'
|
74
|
-
# Rake::RDocTask.new(:rdoc) do |rdoc|
|
75
|
-
# require 'cdoc'
|
76
|
-
# rdoc.template = 'cdoc/cdoc_html_template'
|
77
|
-
# rdoc.options << '--fmt' << 'cdoc'
|
78
|
-
#
|
79
|
-
# # specify whatever else you need
|
80
|
-
# # rdoc.rdoc_files.include(...)
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# Now execute the rake task like:
|
84
|
-
#
|
85
|
-
# % rake rdoc
|
86
|
-
#
|
87
|
-
# === Implementation
|
88
|
-
#
|
89
|
-
# RDoc is a beast to utilize in a non-standard way. One way to make RDoc parse
|
90
|
-
# unexpected flags like 'config' or 'config_attr' is to use the '--accessor'
|
91
|
-
# option (see 'rdoc --help' or the RDoc documentation for more details).
|
92
|
-
#
|
93
|
-
# CDoc hooks into the '--accessor' parsing process to pull out configuration
|
94
|
-
# attributes and format them into their own Configuration section on an RDoc
|
95
|
-
# html page. When 'cdoc' is specified as an rdoc option, CDoc in effect sets
|
96
|
-
# accessor flags for all the standard Task configuration methods, and then
|
97
|
-
# extends the RDoc::RubyParser handle these specially.
|
98
|
-
#
|
99
|
-
# If cdoc is not specified as the rdoc format, CDoc does not affect the RDoc
|
100
|
-
# output. Similarly, the configuration attributes will not appear in the
|
101
|
-
# output unless you specify a template that utilizes them.
|
102
|
-
#
|
103
|
-
# ==== Namespace conflicts
|
104
|
-
#
|
105
|
-
# RDoc creates a namespace conflict with other libraries that define RubyToken
|
106
|
-
# and RubyLex in the Object namespace (the prime example being IRB). CDoc checks
|
107
|
-
# for such a conflict and redfines the RDoc versions of RubyToken and RubyLex
|
108
|
-
# within the RDoc namespace. Essentially:
|
109
|
-
#
|
110
|
-
# original constant redefined constant
|
111
|
-
# RubyToken RDoc::RubyToken
|
112
|
-
# RubyLex RDoc::RubyLex
|
113
|
-
#
|
114
|
-
# The redefinition should not affect the existing (non RDoc) RubyToken and
|
115
|
-
# RubyLex constants, but if you directly use the RDoc versions after loading
|
116
|
-
# CDoc, you should be aware that they must be accessed through the new
|
117
|
-
# constants. Unfortunatley the trick is not seamless. The RDoc RubyLex makes
|
118
|
-
# a few calls to the RubyLex class method 'debug?'... these will be issued to
|
119
|
-
# the existing (non RDoc) RubyLex method and not the redefined
|
120
|
-
# RDoc::RubyLex.debug?
|
121
|
-
#
|
122
|
-
# In addition, because of the RubyLex calls, the RDoc::RubyLex cannot be fully
|
123
|
-
# hidden when CDoc is loaded before the conflicting RubyLex; you cannot load
|
124
|
-
# CDoc before loading IRB without raising warnings.
|
125
|
-
#
|
126
|
-
# Luckily all these troubles can be avoided very easily by not loading CDoc or
|
127
|
-
# RDoc when you're in irb. On the plus side, going against what I just said,
|
128
|
-
# you can now access/use RDoc within irb by requiring <tt>'cdoc'</tt>.
|
129
|
-
#
|
130
|
-
#--
|
131
|
-
# Note that tap-0.10.0 heavily refactored CDoc functionality out of the old CDoc
|
132
|
-
# and into Lazydoc, and changed the declaration syntax for configurations. These
|
133
|
-
# changes also affected the implementation of CDoc. Mostly the changes are hacks
|
134
|
-
# to get the old system to work in the new system... as hacky as the old CDoc was,
|
135
|
-
# now this CDoc is hacky AND may have cruft. Until it breaks completely, I leave
|
136
|
-
# it as is... ugly and hard to fathom.
|
137
|
-
#
|
138
|
-
module CDoc
|
139
|
-
|
140
|
-
# Encasulates information about the configuration. Designed to be utilized
|
141
|
-
# by the CDocHTMLGenerator as similarly as possible to standard attributes.
|
142
|
-
class ConfigAttr < RDoc::Attr # :nodoc:
|
143
|
-
# Contains the actual declaration for the config attribute. ex: "c [:key, 'value'] # comment"
|
144
|
-
attr_accessor :config_declaration, :default
|
145
|
-
|
146
|
-
def initialize(*args)
|
147
|
-
@comment = nil # suppress a warning in Ruby 1.9
|
148
|
-
super
|
149
|
-
end
|
150
|
-
|
151
|
-
alias original_comment comment
|
152
|
-
|
153
|
-
def desc
|
154
|
-
case text.to_s
|
155
|
-
when /^#--(.*)/ then $1.strip
|
156
|
-
when /^#(.*)/ then $1.strip
|
157
|
-
else
|
158
|
-
nil
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# The description for the config. Comment is formed from the standard
|
163
|
-
# attribute comment and the text following the attribute, which is slightly
|
164
|
-
# different than normal:
|
165
|
-
#
|
166
|
-
# # standard comment
|
167
|
-
# attr_accessor :attribute
|
168
|
-
#
|
169
|
-
# # standard comment
|
170
|
-
# config_accessor :config # ...added to standard comment
|
171
|
-
#
|
172
|
-
# c [:key, 'value'] # hence you can comment inline like this.
|
173
|
-
#
|
174
|
-
# The comments for each of these will be:
|
175
|
-
# attribute:: standard comment
|
176
|
-
# config:: standard comment ...added to standard comment
|
177
|
-
# key:: hence you can comment inline like this.
|
178
|
-
#
|
179
|
-
def comment(add_default=true)
|
180
|
-
# this would include the trailing comment...
|
181
|
-
# text_comment = text.to_s.sub(/^#--.*/m, '')
|
182
|
-
#original_comment.to_s + text_comment + (default && add_default ? " (#{default})" : "")
|
183
|
-
comment = original_comment.to_s.strip
|
184
|
-
comment = desc.to_s if comment.empty?
|
185
|
-
comment + (default && add_default ? " (<tt>#{default}</tt>)" : "")
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
module CodeObjectAccess # :nodoc:
|
190
|
-
def comment_sections(section_regexp=//, normalize_comments=false)
|
191
|
-
res = {}
|
192
|
-
|
193
|
-
section = nil
|
194
|
-
lines = []
|
195
|
-
comment_lines = comment.split(/\r?\n/)
|
196
|
-
comment_lines << nil
|
197
|
-
comment_lines.each do |line|
|
198
|
-
case line
|
199
|
-
when nil, /^\s*#\s*=+(.*)/
|
200
|
-
next_section = (line == nil ? nil : $1.to_s.strip)
|
201
|
-
|
202
|
-
if section =~ section_regexp
|
203
|
-
lines << "" unless normalize_comments
|
204
|
-
res[section] = lines.join("\n") unless section == nil
|
205
|
-
end
|
206
|
-
|
207
|
-
section = next_section
|
208
|
-
lines = []
|
209
|
-
else
|
210
|
-
if normalize_comments
|
211
|
-
line =~ /^\s*#\s?(.*)/
|
212
|
-
line = $1.to_s
|
213
|
-
end
|
214
|
-
|
215
|
-
lines << line
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
res
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
module ClassModuleAccess # :nodoc:
|
224
|
-
def find_class_or_module_named(name)
|
225
|
-
return self if full_name == name
|
226
|
-
(@classes.values + @modules.values).each do |c|
|
227
|
-
res = c.find_class_or_module_named(name)
|
228
|
-
return res if res
|
229
|
-
end
|
230
|
-
nil
|
231
|
-
end
|
232
|
-
|
233
|
-
def configurations
|
234
|
-
@attributes.select do |attribute|
|
235
|
-
attribute.kind_of?(CDoc::ConfigAttr)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def find_configuration_named(name)
|
240
|
-
@attributes.each do |attribute|
|
241
|
-
next unless attribute.kind_of?(CDoc::ConfigAttr)
|
242
|
-
return attribute if attribute.name == name
|
243
|
-
end
|
244
|
-
nil
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
# Overrides the new method automatically extend the new object with
|
249
|
-
# ConfigParser. Intended to be used like:
|
250
|
-
# RDoc::RubyParser.extend InitializeConfigParser
|
251
|
-
module InitializeConfigParser # :nodoc:
|
252
|
-
def new(*args)
|
253
|
-
parser = super
|
254
|
-
parser.extend ConfigParser
|
255
|
-
#parser.config_mode = 'config_accessor'
|
256
|
-
parser
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
# Provides methods extending an RDoc::RubyParser such that the parser will produce
|
261
|
-
# CDoc::ConfigAttr instances in the place of RDoc::Attr instances during attribute
|
262
|
-
# parsing.
|
263
|
-
module ConfigParser # :nodoc:
|
264
|
-
include RDoc::RubyToken
|
265
|
-
include TokenStream
|
266
|
-
|
267
|
-
CONFIG_ACCESSORS = ['config', 'config_attr']
|
268
|
-
|
269
|
-
# Gets tokens until the next TkNL
|
270
|
-
def get_tk_to_nl
|
271
|
-
tokens = []
|
272
|
-
while !(tk = get_tk).kind_of?(TkNL)
|
273
|
-
tokens.push tk
|
274
|
-
end
|
275
|
-
unget_tk(tk)
|
276
|
-
tokens
|
277
|
-
end
|
278
|
-
|
279
|
-
# Works like the original parse_attr_accessor, except that the arg
|
280
|
-
# name is parsed from the config syntax and added attribute will
|
281
|
-
# be a CDoc::ConfigAttr. For example:
|
282
|
-
#
|
283
|
-
# class ConfigClass
|
284
|
-
# include Configurable
|
285
|
-
# config :key, 'value' # comment
|
286
|
-
# end
|
287
|
-
#
|
288
|
-
# produces an attribute named :key in the current config_rw mode.
|
289
|
-
#
|
290
|
-
# (see 'rdoc/parsers/parse_rb' line 2509)
|
291
|
-
def parse_config(context, single, tk, comment)
|
292
|
-
tks = get_tk_to_nl
|
293
|
-
|
294
|
-
key_tk = nil
|
295
|
-
value_tk = nil
|
296
|
-
|
297
|
-
tks.each do |token|
|
298
|
-
next if token.kind_of?(TkSPACE)
|
299
|
-
|
300
|
-
if key_tk == nil
|
301
|
-
case token
|
302
|
-
when TkSYMBOL then key_tk = token
|
303
|
-
when TkLPAREN then next
|
304
|
-
else break
|
305
|
-
end
|
306
|
-
else
|
307
|
-
case token
|
308
|
-
when TkCOMMA then value_tk = token
|
309
|
-
else
|
310
|
-
value_tk = token if value_tk.kind_of?(TkCOMMA)
|
311
|
-
break
|
312
|
-
end
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
text = ""
|
317
|
-
if tks.last.kind_of?(TkCOMMENT)
|
318
|
-
text = tks.last.text.chomp("\n").chomp("\r")
|
319
|
-
unget_tk(tks.last)
|
320
|
-
|
321
|
-
# If nodoc is given, don't document
|
322
|
-
|
323
|
-
tmp = RDoc::CodeObject.new
|
324
|
-
read_documentation_modifiers(tmp, RDoc::ATTR_MODIFIERS)
|
325
|
-
text = nil unless tmp.document_self
|
326
|
-
end
|
327
|
-
|
328
|
-
tks.reverse_each {|token| unget_tk(token) }
|
329
|
-
return if key_tk == nil || text == nil
|
330
|
-
|
331
|
-
arg = key_tk.text[1..-1]
|
332
|
-
default = nil
|
333
|
-
if value_tk
|
334
|
-
if text =~ /(.*):no_default:(.*)/
|
335
|
-
text = $1 + $2
|
336
|
-
else
|
337
|
-
default = value_tk.text
|
338
|
-
end
|
339
|
-
end
|
340
|
-
att = CDoc::ConfigAttr.new(text, arg, "RW", comment)
|
341
|
-
att.config_declaration = get_tkread
|
342
|
-
att.default = default
|
343
|
-
|
344
|
-
context.add_attribute(att)
|
345
|
-
end
|
346
|
-
|
347
|
-
# Overrides the standard parse_attr_accessor method to hook in parsing
|
348
|
-
# of the config accessors. If the input token is not named as one of the
|
349
|
-
# CONFIG_ACCESSORS, it will be processed normally.
|
350
|
-
def parse_attr_accessor(context, single, tk, comment)
|
351
|
-
case tk.name
|
352
|
-
when 'config', 'config_attr'
|
353
|
-
parse_config(context, single, tk, comment)
|
354
|
-
else
|
355
|
-
super
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
# Register the CDoc generator (in case you want to actually use it).
|
362
|
-
# method echos RDoc generator registration (see 'rdoc/rdoc' line 76)
|
363
|
-
Generator = Struct.new(:file_name, :class_name, :key)
|
364
|
-
RDoc::RDoc::GENERATORS['cdoc'] = Generator.new(
|
365
|
-
"cdoc/cdoc_html_generator.rb",
|
366
|
-
"CDocHTMLGenerator".intern,
|
367
|
-
"cdoc")
|
368
|
-
|
369
|
-
# Add the extended accessors to context classes.
|
370
|
-
module RDoc # :nodoc:
|
371
|
-
class CodeObject # :nodoc:
|
372
|
-
include CDoc::CodeObjectAccess
|
373
|
-
end
|
374
|
-
|
375
|
-
class ClassModule # :nodoc:
|
376
|
-
include CDoc::ClassModuleAccess
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
# Override methods in Options to in effect incorporate the accessor
|
381
|
-
# flags for CDoc parsing. (see 'rdoc/options') Raise an error if an
|
382
|
-
# accessor flag has already been specified.
|
383
|
-
class Options # :nodoc:
|
384
|
-
alias cdoc_original_parse parse
|
385
|
-
|
386
|
-
def parse(argv, generators)
|
387
|
-
cdoc_original_parse(argv, generators)
|
388
|
-
return unless @generator_name == 'cdoc'
|
389
|
-
|
390
|
-
accessors = CDoc::ConfigParser::CONFIG_ACCESSORS
|
391
|
-
|
392
|
-
# check the config_accessor_flags for accessor conflicts
|
393
|
-
extra_accessor_flags.each_pair do |accessor, flag|
|
394
|
-
if accessors.include?(accessor)
|
395
|
-
raise OptionList.error("cdoc format already handles the accessor '#{accessor}'")
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
# extra_accessors will be nil if no extra accessors were
|
400
|
-
# specifed, otherwise it'll be a regexp like /^(...)$/
|
401
|
-
# the string subset assumes
|
402
|
-
# regexp.to_s # => /(?-mix:^(...)$)/
|
403
|
-
@extra_accessors ||= /^()$/
|
404
|
-
current_accessors_str = @extra_accessors.to_s[9..-4]
|
405
|
-
|
406
|
-
# echos the Regexp production code in rdoc/options.rb
|
407
|
-
# (see the parse method, line 501)
|
408
|
-
re = '^(' + current_accessors_str + accessors.map{|a| Regexp.quote(a)}.join('|') + ')$'
|
409
|
-
@extra_accessors = Regexp.new(re)
|
410
|
-
|
411
|
-
RDoc::RubyParser.extend CDoc::InitializeConfigParser
|
412
|
-
end
|
413
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'rdoc/generators/html_generator'
|
2
|
-
|
3
|
-
# Defines a specialized generator so it can be called for using a --fmt option.
|
4
|
-
class CDocHTMLGenerator < Generators::HTMLGenerator # :nodoc:
|
5
|
-
end
|
6
|
-
|
7
|
-
module Generators # :nodoc:
|
8
|
-
const_set(:RubyToken, RDoc::RubyToken)
|
9
|
-
|
10
|
-
class HtmlClass < ContextUser # :nodoc:
|
11
|
-
alias cdoc_original_value_hash value_hash
|
12
|
-
|
13
|
-
def value_hash
|
14
|
-
# split attributes into configurations and regular attributes
|
15
|
-
configurations, attributes = @context.attributes.partition do |attribute|
|
16
|
-
attribute.kind_of?(CDoc::ConfigAttr)
|
17
|
-
end
|
18
|
-
|
19
|
-
# set the context attributes to JUST the regular
|
20
|
-
# attributes and process as usual.
|
21
|
-
@context.attributes.clear.concat attributes
|
22
|
-
values = cdoc_original_value_hash
|
23
|
-
|
24
|
-
# set the context attributes to the configurations
|
25
|
-
# and echo the regular processing to produce a list
|
26
|
-
# of configurations
|
27
|
-
@context.attributes.clear.concat configurations
|
28
|
-
@context.sections.each_with_index do |section, i|
|
29
|
-
secdata = values["sections"][i]
|
30
|
-
|
31
|
-
al = build_attribute_list(section)
|
32
|
-
secdata["configurations"] = al unless al.empty?
|
33
|
-
end
|
34
|
-
|
35
|
-
values
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|