configurable 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Help/Command Line.rdoc +141 -0
  2. data/Help/Config Syntax.rdoc +229 -0
  3. data/Help/Config Types.rdoc +143 -0
  4. data/{History → History.rdoc} +9 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.rdoc +144 -0
  7. data/lib/configurable.rb +7 -270
  8. data/lib/configurable/class_methods.rb +344 -367
  9. data/lib/configurable/config_classes.rb +3 -0
  10. data/lib/configurable/config_classes/list_config.rb +26 -0
  11. data/lib/configurable/config_classes/nest_config.rb +50 -0
  12. data/lib/configurable/config_classes/scalar_config.rb +91 -0
  13. data/lib/configurable/config_hash.rb +87 -112
  14. data/lib/configurable/config_types.rb +6 -0
  15. data/lib/configurable/config_types/boolean_type.rb +22 -0
  16. data/lib/configurable/config_types/float_type.rb +11 -0
  17. data/lib/configurable/config_types/integer_type.rb +11 -0
  18. data/lib/configurable/config_types/nest_type.rb +39 -0
  19. data/lib/configurable/config_types/object_type.rb +58 -0
  20. data/lib/configurable/config_types/string_type.rb +15 -0
  21. data/lib/configurable/conversions.rb +91 -0
  22. data/lib/configurable/module_methods.rb +0 -1
  23. data/lib/configurable/version.rb +1 -5
  24. metadata +73 -30
  25. data/README +0 -207
  26. data/lib/cdoc.rb +0 -413
  27. data/lib/cdoc/cdoc_html_generator.rb +0 -38
  28. data/lib/cdoc/cdoc_html_template.rb +0 -42
  29. data/lib/config_parser.rb +0 -563
  30. data/lib/config_parser/option.rb +0 -108
  31. data/lib/config_parser/switch.rb +0 -44
  32. data/lib/config_parser/utils.rb +0 -177
  33. data/lib/configurable/config.rb +0 -97
  34. data/lib/configurable/indifferent_access.rb +0 -35
  35. data/lib/configurable/nest_config.rb +0 -78
  36. data/lib/configurable/ordered_hash_patch.rb +0 -85
  37. data/lib/configurable/utils.rb +0 -186
  38. data/lib/configurable/validation.rb +0 -768
@@ -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