tap 0.7.9 → 0.8.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 (149) hide show
  1. data/History +28 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README +71 -43
  4. data/Rakefile +81 -64
  5. data/Tutorial +235 -0
  6. data/bin/tap +80 -44
  7. data/lib/tap.rb +41 -12
  8. data/lib/tap/app.rb +243 -246
  9. data/lib/tap/file_task.rb +357 -118
  10. data/lib/tap/generator.rb +88 -29
  11. data/lib/tap/generator/generators/config/config_generator.rb +4 -2
  12. data/lib/tap/generator/generators/config/templates/config.erb +1 -2
  13. data/lib/tap/generator/generators/file_task/file_task_generator.rb +3 -18
  14. data/lib/tap/generator/generators/file_task/templates/task.erb +22 -15
  15. data/lib/tap/generator/generators/file_task/templates/test.erb +13 -2
  16. data/{test/test/inference_methods/test_assert_files_exist/input/input_1.txt → lib/tap/generator/generators/generator/USAGE} +0 -0
  17. data/lib/tap/generator/generators/generator/generator_generator.rb +21 -0
  18. data/lib/tap/generator/generators/generator/templates/generator.erb +23 -0
  19. data/lib/tap/generator/generators/generator/templates/usage.erb +1 -0
  20. data/{test/test/inference_methods/test_assert_files_exist/input/input_2.txt → lib/tap/generator/generators/package/USAGE} +0 -0
  21. data/lib/tap/generator/generators/package/package_generator.rb +38 -0
  22. data/lib/tap/generator/generators/package/templates/package.erb +186 -0
  23. data/lib/tap/generator/generators/root/root_generator.rb +14 -9
  24. data/lib/tap/generator/generators/root/templates/Rakefile +20 -14
  25. data/{test/test/inference_methods/test_infer_glob/expected/file.yml → lib/tap/generator/generators/root/templates/ReadMe.txt} +0 -0
  26. data/lib/tap/generator/generators/root/templates/tap.yml +82 -0
  27. data/lib/tap/generator/generators/root/templates/test/tap_test_helper.rb +0 -1
  28. data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +2 -1
  29. data/{test/test/inference_methods/test_infer_glob/expected/file_1.txt → lib/tap/generator/generators/script/USAGE} +0 -0
  30. data/lib/tap/generator/generators/script/script_generator.rb +17 -0
  31. data/lib/tap/generator/generators/script/templates/script.erb +42 -0
  32. data/lib/tap/generator/generators/task/task_generator.rb +1 -1
  33. data/lib/tap/generator/generators/task/templates/task.erb +24 -16
  34. data/lib/tap/generator/generators/task/templates/test.erb +13 -17
  35. data/lib/tap/generator/generators/workflow/templates/task.erb +10 -10
  36. data/lib/tap/generator/generators/workflow/templates/test.erb +1 -1
  37. data/lib/tap/generator/generators/workflow/workflow_generator.rb +3 -18
  38. data/lib/tap/root.rb +108 -146
  39. data/lib/tap/script.rb +362 -0
  40. data/lib/tap/script/console.rb +28 -0
  41. data/lib/tap/script/destroy.rb +13 -1
  42. data/lib/tap/script/generate.rb +13 -1
  43. data/lib/tap/script/run.rb +100 -57
  44. data/lib/tap/support/batch_queue.rb +0 -3
  45. data/lib/tap/support/logger.rb +6 -3
  46. data/lib/tap/support/rake.rb +54 -0
  47. data/lib/tap/support/task_configuration.rb +169 -0
  48. data/lib/tap/support/tdoc.rb +198 -0
  49. data/lib/tap/support/tdoc/config_attr.rb +338 -0
  50. data/lib/tap/support/tdoc/tdoc_html_generator.rb +38 -0
  51. data/lib/tap/support/tdoc/tdoc_html_template.rb +42 -0
  52. data/lib/tap/support/versions.rb +33 -1
  53. data/lib/tap/task.rb +339 -227
  54. data/lib/tap/test.rb +86 -128
  55. data/lib/tap/test/env_vars.rb +16 -5
  56. data/lib/tap/test/file_methods.rb +373 -0
  57. data/lib/tap/test/subset_methods.rb +299 -180
  58. data/lib/tap/version.rb +2 -1
  59. data/lib/tap/workflow.rb +2 -0
  60. data/test/app/lib/app_test_task.rb +1 -0
  61. data/test/app_test.rb +327 -83
  62. data/test/check/binding_eval.rb +23 -0
  63. data/test/check/define_method_check.rb +22 -0
  64. data/test/check/dependencies_check.rb +175 -0
  65. data/test/check/inheritance_check.rb +22 -0
  66. data/test/file_task_test.rb +524 -291
  67. data/test/{test/inference_methods/test_infer_glob/expected/file_2.txt → root/glob/one.txt} +0 -0
  68. data/test/root/glob/two.txt +0 -0
  69. data/test/root_test.rb +330 -262
  70. data/test/script_test.rb +194 -0
  71. data/test/support/audit_test.rb +5 -2
  72. data/test/support/combinator_test.rb +10 -10
  73. data/test/support/rake_test.rb +35 -0
  74. data/test/support/task_configuration_test.rb +272 -0
  75. data/test/support/tdoc_test.rb +363 -0
  76. data/test/support/templater_test.rb +2 -2
  77. data/test/support/versions_test.rb +32 -0
  78. data/test/tap_test_helper.rb +39 -0
  79. data/test/task_base_test.rb +115 -0
  80. data/test/task_class_test.rb +56 -4
  81. data/test/task_execute_test.rb +29 -0
  82. data/test/task_test.rb +89 -70
  83. data/test/test/env_vars_test.rb +48 -0
  84. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/file.txt +0 -0
  85. data/test/test/{inference_methods → file_methods}/test_assert_expected/expected/folder/file.txt +0 -0
  86. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/file.txt +0 -0
  87. data/test/test/{inference_methods → file_methods}/test_assert_expected/input/folder/file.txt +0 -0
  88. data/test/test/file_methods/test_assert_files_exist/input/input_1.txt +0 -0
  89. data/test/test/file_methods/test_assert_files_exist/input/input_2.txt +0 -0
  90. data/test/test/file_methods/test_assert_output_files_equal/expected/one.txt +1 -0
  91. data/test/test/file_methods/test_assert_output_files_equal/expected/two.txt +1 -0
  92. data/test/test/file_methods/test_assert_output_files_equal/input/one.txt +1 -0
  93. data/test/test/file_methods/test_assert_output_files_equal/input/two.txt +1 -0
  94. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_1.txt +0 -0
  95. data/test/test/{inference_methods → file_methods}/test_file_compare/expected/output_2.txt +0 -0
  96. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_1.txt +0 -0
  97. data/test/test/{inference_methods → file_methods}/test_file_compare/input/input_2.txt +0 -0
  98. data/test/test/file_methods/test_infer_glob/expected/file.yml +0 -0
  99. data/test/test/file_methods/test_infer_glob/expected/file_1.txt +0 -0
  100. data/test/test/file_methods/test_infer_glob/expected/file_2.txt +0 -0
  101. data/test/test/file_methods/test_method_glob/expected/file.yml +0 -0
  102. data/test/test/file_methods/test_method_glob/expected/file_1.txt +0 -0
  103. data/test/test/file_methods/test_method_glob/expected/file_2.txt +0 -0
  104. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_1.yml +0 -0
  105. data/test/test/{inference_methods → file_methods}/test_yml_compare/expected/output_2.yml +0 -0
  106. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_1.yml +0 -0
  107. data/test/test/{inference_methods → file_methods}/test_yml_compare/input/input_2.yml +0 -0
  108. data/test/test/file_methods_test.rb +204 -0
  109. data/test/test/subset_methods_test.rb +93 -33
  110. data/test/test/test_assert_expected_result_files/expected/task/name/a.txt +1 -0
  111. data/test/test/test_assert_expected_result_files/expected/task/name/b.txt +1 -0
  112. data/test/test/test_assert_expected_result_files/input/a.txt +1 -0
  113. data/test/test/test_assert_expected_result_files/input/b.txt +1 -0
  114. data/test/test/test_file_task_test/expected/one.txt +1 -0
  115. data/test/test/test_file_task_test/expected/two.txt +1 -0
  116. data/test/test/test_file_task_test/input/one.txt +1 -0
  117. data/test/test/test_file_task_test/input/two.txt +1 -0
  118. data/test/test_test.rb +143 -3
  119. data/test/workflow_test.rb +2 -0
  120. data/vendor/rails_generator.rb +56 -0
  121. data/vendor/rails_generator/base.rb +263 -0
  122. data/vendor/rails_generator/commands.rb +581 -0
  123. data/vendor/rails_generator/generated_attribute.rb +42 -0
  124. data/vendor/rails_generator/lookup.rb +209 -0
  125. data/vendor/rails_generator/manifest.rb +53 -0
  126. data/vendor/rails_generator/options.rb +143 -0
  127. data/vendor/rails_generator/scripts.rb +83 -0
  128. data/vendor/rails_generator/scripts/destroy.rb +7 -0
  129. data/vendor/rails_generator/scripts/generate.rb +7 -0
  130. data/vendor/rails_generator/scripts/update.rb +12 -0
  131. data/vendor/rails_generator/simple_logger.rb +46 -0
  132. data/vendor/rails_generator/spec.rb +44 -0
  133. metadata +180 -196
  134. data/lib/tap/generator/generators/root/templates/app.yml +0 -19
  135. data/lib/tap/generator/generators/root/templates/config/process_tap_request.yml +0 -4
  136. data/lib/tap/generator/generators/root/templates/lib/process_tap_request.rb +0 -26
  137. data/lib/tap/generator/generators/root/templates/public/images/nav.jpg +0 -0
  138. data/lib/tap/generator/generators/root/templates/public/stylesheets/color.css +0 -57
  139. data/lib/tap/generator/generators/root/templates/public/stylesheets/layout.css +0 -108
  140. data/lib/tap/generator/generators/root/templates/public/stylesheets/normalize.css +0 -40
  141. data/lib/tap/generator/generators/root/templates/public/stylesheets/typography.css +0 -21
  142. data/lib/tap/generator/generators/root/templates/server/config/environment.rb +0 -60
  143. data/lib/tap/generator/generators/root/templates/server/lib/tasks/clear_database_prerequisites.rake +0 -5
  144. data/lib/tap/generator/generators/root/templates/server/test/test_helper.rb +0 -53
  145. data/lib/tap/script/server.rb +0 -12
  146. data/lib/tap/support/rap.rb +0 -38
  147. data/lib/tap/test/inference_methods.rb +0 -298
  148. data/test/task/config/task_with_config.yml +0 -1
  149. data/test/test/inference_methods_test.rb +0 -311
@@ -0,0 +1,338 @@
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
+ module Tap
51
+ module Support
52
+ class TDoc
53
+
54
+ # Encasulates information about the configuration. Designed to be utilized
55
+ # by the TDocHTMLGenerator as similarly as possible to standard attributes.
56
+ class ConfigAttr < RDoc::Attr
57
+ # Contains the actual declaration for the config attribute. ex: "c [:key, 'value'] # comment"
58
+ attr_accessor :config_declaration
59
+
60
+ alias original_comment comment
61
+
62
+ def desc
63
+ case text.to_s
64
+ when /^#--(.*)/ then $1.strip
65
+ when /^#(.*)/ then $1.strip
66
+ else
67
+ nil
68
+ end
69
+ end
70
+
71
+ # The description for the config. Comment is formed from the standard
72
+ # attribute comment and the text following the attribute, which is slightly
73
+ # different than normal:
74
+ #
75
+ # # standard comment
76
+ # attr_accessor :attribute
77
+ #
78
+ # # standard comment
79
+ # config_accessor :config # ...added to standard comment
80
+ #
81
+ # c [:key, 'value'] # hence you can comment inline like this.
82
+ #
83
+ # The comments for each of these will be:
84
+ # attribute:: standard comment
85
+ # config:: standard comment ...added to standard comment
86
+ # key:: hence you can comment inline like this.
87
+ #
88
+ def comment
89
+ text_comment = text.to_s.sub(/^#--.*/m, '')
90
+ original_comment.to_s + text_comment
91
+ end
92
+ end
93
+
94
+ module CodeObjectAccess # :nodoc:
95
+ def comment_sections(section_regexp=//, normalize_comments=false)
96
+ res = {}
97
+
98
+ section = nil
99
+ lines = []
100
+ comment_lines = comment.split(/\r?\n/)
101
+ comment_lines << nil
102
+ comment_lines.each do |line|
103
+ case line
104
+ when nil, /^\s*#\s*=+(.*)/
105
+ next_section = (line == nil ? nil : $1.to_s.strip)
106
+
107
+ if section =~ section_regexp
108
+ lines << "" unless normalize_comments
109
+ res[section] = lines.join("\n") unless section == nil
110
+ end
111
+
112
+ section = next_section
113
+ lines = []
114
+ else
115
+ if normalize_comments
116
+ line =~ /^\s*#(.*)/
117
+ line = $1.to_s.strip
118
+ end
119
+
120
+ lines << line
121
+ end
122
+ end
123
+
124
+ res
125
+ end
126
+ end
127
+
128
+ module ClassModuleAccess # :nodoc:
129
+ def find_class_or_module_named(name)
130
+ return self if full_name == name
131
+ (@classes.values + @modules.values).each do |c|
132
+ return c if c.find_class_or_module_named(name)
133
+ end
134
+ nil
135
+ end
136
+
137
+ def configurations
138
+ @attributes.select do |attribute|
139
+ attribute.kind_of?(TDoc::ConfigAttr)
140
+ end
141
+ end
142
+
143
+ def find_configuration_named(name)
144
+ @attributes.each do |attribute|
145
+ next unless attribute.kind_of?(TDoc::ConfigAttr)
146
+ return attribute if attribute.name == name
147
+ end
148
+ nil
149
+ end
150
+ end
151
+
152
+ # Overrides the new method automatically extend the new object with
153
+ # ConfigParser. Intended to be used like:
154
+ # RDoc::RubyParser.extend InitializeConfigParser
155
+ module InitializeConfigParser # :nodoc:
156
+ def new(*args)
157
+ parser = super
158
+ parser.extend ConfigParser
159
+ parser.config_mode = 'config_accessor'
160
+ parser
161
+ end
162
+ end
163
+
164
+ # Provides methods extending an RDoc::RubyParser such that the parser will produce
165
+ # TDoc::ConfigAttr instances in the place of RDoc::Attr instances during attribute
166
+ # parsing.
167
+ module ConfigParser # :nodoc:
168
+ include RDoc::RubyToken
169
+ include TokenStream
170
+
171
+ CONFIG_ACCESSORS = ['config', 'declare_config', 'config_reader', 'config_writer', 'config_accessor']
172
+ attr_accessor :config_mode
173
+
174
+ # Returns the current config_rw mode, based on the config_mode flag.
175
+ def config_rw
176
+ case self.config_mode
177
+ when "config_accessor" then "RW"
178
+ when "declare_config" then nil
179
+ when "config_reader" then "R"
180
+ when "config_writer" then "W"
181
+ else
182
+ raise "unknown config mode: #{self.config_mode}"
183
+ end
184
+ end
185
+
186
+ # Gets tokens until the next TkNL
187
+ def get_tk_to_nl
188
+ tokens = []
189
+ while !(tk = get_tk).kind_of?(TkNL)
190
+ tokens.push tk
191
+ end
192
+ unget_tk(tk)
193
+ tokens
194
+ end
195
+
196
+ # Works like the original parse_attr_accessor, except that the arg
197
+ # name is parsed from the config syntax and added attribute will
198
+ # be a TDoc::ConfigAttr. For example:
199
+ #
200
+ # class TaskDoc < Tap::Task
201
+ # config [:key, 'value'] # comment
202
+ # end
203
+ #
204
+ # produces an attribute named :key in the current config_rw mode.
205
+ #
206
+ # (see 'rdoc/parsers/parse_rb' line 2509)
207
+ def parse_config(context, single, tk, comment)
208
+ tks = get_tk_to_nl
209
+
210
+ text = ""
211
+ if tks.last.kind_of?(TkCOMMENT)
212
+ text = tks.last.text.chomp("\n").chomp("\r")
213
+ unget_tk(tks.last)
214
+
215
+ # If nodoc is given, don't document
216
+
217
+ tmp = RDoc::CodeObject.new
218
+ read_documentation_modifiers(tmp, RDoc::ATTR_MODIFIERS)
219
+ return unless tmp.document_self
220
+ end
221
+
222
+ key_tk = tks.select {|tk| tk.kind_of?(TkSYMBOL)}.first
223
+ return if key_tk.nil?
224
+
225
+ arg = key_tk.text[1..-1]
226
+ att = TDoc::ConfigAttr.new(text, arg, config_rw, comment)
227
+ att.config_declaration = get_tkread
228
+
229
+ # TODO -- it would be nice to read the default value here...
230
+
231
+ context.add_attribute(att)
232
+ end
233
+
234
+ # Works like the original parse_attr_accessor, except that the added
235
+ # attribute will be a TDoc::ConfigAttr. config_mode is updated to the input
236
+ # token name, such that, for example, if tk.name == 'config_accessor'
237
+ # then config_rw will return 'RW'.
238
+ #
239
+ # (see 'rdoc/parsers/parse_rb' line 2509)
240
+ def parse_config_accessor(context, single, tk, comment)
241
+ self.config_mode = tk.name
242
+
243
+ tks = get_tk_to_nl
244
+ is_config_mode_flag = tks.select do |tk|
245
+ !tk.kind_of?(TkSPACE) && !tk.kind_of?(TkCOMMENT)
246
+ end.empty?
247
+
248
+ # If no args are given, take this as a flag for c
249
+ return if is_config_mode_flag
250
+
251
+ tks.reverse_each {|tk| unget_tk(tk) }
252
+ args = parse_symbol_arg
253
+ read = get_tkread
254
+ rw = "?"
255
+
256
+ # If nodoc is given, don't document any of them
257
+
258
+ tmp = RDoc::CodeObject.new
259
+ read_documentation_modifiers(tmp, RDoc::ATTR_MODIFIERS)
260
+ return unless tmp.document_self
261
+
262
+ for name in args
263
+ att = TDoc::ConfigAttr.new(get_tkread, name, config_rw, comment)
264
+ context.add_attribute(att)
265
+ end
266
+ end
267
+
268
+ # Overrides the standard parse_attr_accessor method to hook in parsing
269
+ # of the config accessors. If the input token is not named as one of the
270
+ # CONFIG_ACCESSORS, it will be processed normally.
271
+ def parse_attr_accessor(context, single, tk, comment)
272
+ case tk.name
273
+ when 'config'
274
+ parse_config(context, single, tk, comment)
275
+ when 'declare_config', 'config_reader', 'config_writer', 'config_accessor'
276
+ parse_config_accessor(context, single, tk, comment)
277
+ else
278
+ super
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
285
+
286
+ # Register the TDoc generator (in case you want to actually use it).
287
+ # method echos RDoc generator registration (see 'rdoc/rdoc' line 76)
288
+ Generator = Struct.new(:file_name, :class_name, :key)
289
+ RDoc::RDoc::GENERATORS['tdoc'] = Generator.new(
290
+ "tap/support/tdoc/tdoc_html_generator.rb",
291
+ "TDocHTMLGenerator".intern,
292
+ "tdoc")
293
+
294
+ # Add the extended accessors to context classes.
295
+ module RDoc # :nodoc:
296
+ class CodeObject # :nodoc:
297
+ include Tap::Support::TDoc::CodeObjectAccess
298
+ end
299
+
300
+ class ClassModule # :nodoc:
301
+ include Tap::Support::TDoc::ClassModuleAccess
302
+ end
303
+ end
304
+
305
+ # Override methods in Options to in effect incorporate the accessor
306
+ # flags for TDoc parsing. (see 'rdoc/options') Raise an error if an
307
+ # accessor flag has already been specified.
308
+ class Options # :nodoc:
309
+ alias tdoc_original_parse parse
310
+
311
+ def parse(argv, generators)
312
+ tdoc_original_parse(argv, generators)
313
+ return unless @generator_name == 'tdoc'
314
+
315
+ accessors = Tap::Support::TDoc::ConfigParser::CONFIG_ACCESSORS
316
+
317
+ # check the config_accessor_flags for accessor conflicts
318
+ extra_accessor_flags.each_pair do |accessor, flag|
319
+ if accessors.include?(accessor)
320
+ raise OptionList.error("tdoc format already handles the accessor '#{accessor}'")
321
+ end
322
+ end
323
+
324
+ # extra_accessors will be nil if no extra accessors were
325
+ # specifed, otherwise it'll be a regexp like /^(...)$/
326
+ # the string subset assumes
327
+ # regexp.to_s # => /(?-mix:^(...)$)/
328
+ @extra_accessors ||= /^()$/
329
+ current_accessors_str = @extra_accessors.to_s[9..-4]
330
+
331
+ # echos the Regexp production code in rdoc/options.rb
332
+ # (see the parse method, line 501)
333
+ re = '^(' + current_accessors_str + accessors.map{|a| Regexp.quote(a)}.join('|') + ')$'
334
+ @extra_accessors = Regexp.new(re)
335
+
336
+ RDoc::RubyParser.extend Tap::Support::TDoc::InitializeConfigParser
337
+ end
338
+ end
@@ -0,0 +1,38 @@
1
+ require 'rdoc/generators/html_generator'
2
+
3
+ # Defines a specialized generator so it can be called for using a --fmt option.
4
+ class TDocHTMLGenerator < Generators::HTMLGenerator # :nodoc:
5
+ end
6
+
7
+ module Generators # :nodoc:
8
+ const_set(:RubyToken, RDoc::RubyToken)
9
+
10
+ class HtmlClass < ContextUser # :nodoc:
11
+ alias tdoc_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?(Tap::Support::TDoc::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 = tdoc_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
@@ -0,0 +1,42 @@
1
+ require 'rdoc/generators/template/html/html'
2
+
3
+ #
4
+ # Add a template for documenting configurations. Do so by inserting in the
5
+ # template into the content regions used to template html.
6
+ # (see 'rdoc/generators/html_generator' line 864)
7
+ #
8
+ [
9
+ RDoc::Page::BODY,
10
+ RDoc::Page::FILE_PAGE,
11
+ RDoc::Page::METHOD_LIST].each do |content|
12
+
13
+ # this substitution method duplicates the attribute template for configurations
14
+ # (see rdoc\generators\template\html line 523)
15
+ #
16
+ #IF:attributes
17
+ # <div id="attribute-list">
18
+ # <h3 class="section-bar">Attributes</h3>
19
+ #
20
+ # <div class="name-list">
21
+ # <table>
22
+ #START:attributes
23
+ # <tr class="top-aligned-row context-row">
24
+ # <td class="context-item-name">%name%</td>
25
+ #IF:rw
26
+ # <td class="context-item-value">&nbsp;[%rw%]&nbsp;</td>
27
+ #ENDIF:rw
28
+ #IFNOT:rw
29
+ # <td class="context-item-value">&nbsp;&nbsp;</td>
30
+ #ENDIF:rw
31
+ # <td class="context-item-desc">%a_desc%</td>
32
+ # </tr>
33
+ #END:attributes
34
+ # </table>
35
+ # </div>
36
+ # </div>
37
+ #ENDIF:attributes
38
+ #
39
+ content.gsub!(/IF:attributes.*?ENDIF:attributes/m) do |match|
40
+ match + "\n\n" + match.gsub(/attributes/, 'configurations').gsub(/Attributes/, 'Configurations')
41
+ end
42
+ end
@@ -57,7 +57,39 @@ module Tap
57
57
  #
58
58
  def deversion(path)
59
59
  path =~ /^(.*)-(\d(\.?\d)*)(.*)?/ ? [$1 + $4, $2] : [path, nil]
60
- end
60
+ end
61
+
62
+ # A <=> comparison for versions. compare_versions can take strings,
63
+ # integers, or even arrays representing the parts of a version.
64
+ #
65
+ # compare_versions("1.0.0", "0.9.9") # => 1
66
+ # compare_versions(1.1, 1.1) # => 0
67
+ # compare_versions([0,9], [0,9,1]) # => -1
68
+ def compare_versions(a,b)
69
+ a, b = [a,b].collect {|item| to_integer_array(item) }
70
+
71
+ # equalize the lengths of the integer arrays
72
+ d = b.length - a.length
73
+ case
74
+ when d < 0 then b.concat Array.new(-d, 0)
75
+ when d > 0 then a.concat Array.new(d, 0)
76
+ end
77
+
78
+ a <=> b
79
+ end
80
+
81
+ private
82
+
83
+ # Converts an input argument (typically a string or an array)
84
+ # to an array of integers. Splits version string on "."
85
+ def to_integer_array(arg)
86
+ arr = case arg
87
+ when Array then arg
88
+ else arg.to_s.split('.')
89
+ end
90
+ arr.collect {|i| i.to_i}
91
+ end
92
+
61
93
  end
62
94
  end
63
95
  end