tap 0.7.9 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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