configurable 0.7.0 → 1.0.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.
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