yard 0.6.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

Files changed (224) hide show
  1. data/.yardopts +1 -0
  2. data/ChangeLog +723 -0
  3. data/README.md +16 -6
  4. data/docs/CodeObjects.md +10 -16
  5. data/docs/GettingStarted.md +232 -32
  6. data/docs/Glossary.md +1 -2
  7. data/docs/Handlers.md +10 -16
  8. data/docs/Overview.md +14 -13
  9. data/docs/Parser.md +13 -22
  10. data/docs/Tags.md +209 -16
  11. data/docs/Templates.md +237 -26
  12. data/docs/WhatsNew.md +178 -2
  13. data/lib/yard.rb +13 -10
  14. data/lib/yard/autoload.rb +22 -18
  15. data/lib/yard/cli/command.rb +13 -12
  16. data/lib/yard/cli/command_parser.rb +20 -19
  17. data/lib/yard/cli/config.rb +19 -19
  18. data/lib/yard/cli/diff.rb +46 -21
  19. data/lib/yard/cli/gems.rb +11 -11
  20. data/lib/yard/cli/graph.rb +13 -13
  21. data/lib/yard/cli/help.rb +1 -1
  22. data/lib/yard/cli/list.rb +22 -0
  23. data/lib/yard/cli/server.rb +17 -17
  24. data/lib/yard/cli/stats.rb +32 -32
  25. data/lib/yard/cli/yardoc.rb +181 -135
  26. data/lib/yard/cli/yri.rb +29 -29
  27. data/lib/yard/code_objects/base.rb +101 -101
  28. data/lib/yard/code_objects/class_object.rb +20 -20
  29. data/lib/yard/code_objects/constant_object.rb +1 -1
  30. data/lib/yard/code_objects/extended_method_object.rb +5 -5
  31. data/lib/yard/code_objects/extra_file_object.rb +89 -0
  32. data/lib/yard/code_objects/macro_object.rb +215 -0
  33. data/lib/yard/code_objects/method_object.rb +30 -30
  34. data/lib/yard/code_objects/module_object.rb +1 -1
  35. data/lib/yard/code_objects/namespace_object.rb +39 -39
  36. data/lib/yard/code_objects/proxy.rb +38 -38
  37. data/lib/yard/code_objects/root_object.rb +1 -1
  38. data/lib/yard/config.rb +40 -40
  39. data/lib/yard/core_ext/array.rb +2 -2
  40. data/lib/yard/core_ext/file.rb +11 -11
  41. data/lib/yard/core_ext/insertion.rb +10 -10
  42. data/lib/yard/core_ext/module.rb +2 -2
  43. data/lib/yard/core_ext/string.rb +2 -2
  44. data/lib/yard/core_ext/symbol_hash.rb +14 -14
  45. data/lib/yard/docstring.rb +122 -54
  46. data/lib/yard/globals.rb +2 -2
  47. data/lib/yard/handlers/base.rb +216 -127
  48. data/lib/yard/handlers/processor.rb +65 -27
  49. data/lib/yard/handlers/ruby/alias_handler.rb +6 -3
  50. data/lib/yard/handlers/ruby/attribute_handler.rb +7 -6
  51. data/lib/yard/handlers/ruby/base.rb +50 -31
  52. data/lib/yard/handlers/ruby/class_condition_handler.rb +11 -11
  53. data/lib/yard/handlers/ruby/class_handler.rb +10 -10
  54. data/lib/yard/handlers/ruby/class_variable_handler.rb +3 -3
  55. data/lib/yard/handlers/ruby/constant_handler.rb +7 -7
  56. data/lib/yard/handlers/ruby/exception_handler.rb +2 -2
  57. data/lib/yard/handlers/ruby/extend_handler.rb +1 -1
  58. data/lib/yard/handlers/ruby/legacy/alias_handler.rb +8 -5
  59. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +6 -5
  60. data/lib/yard/handlers/ruby/legacy/base.rb +42 -27
  61. data/lib/yard/handlers/ruby/legacy/class_condition_handler.rb +9 -9
  62. data/lib/yard/handlers/ruby/legacy/class_handler.rb +13 -12
  63. data/lib/yard/handlers/ruby/legacy/class_variable_handler.rb +3 -6
  64. data/lib/yard/handlers/ruby/legacy/constant_handler.rb +5 -8
  65. data/lib/yard/handlers/ruby/legacy/exception_handler.rb +1 -1
  66. data/lib/yard/handlers/ruby/legacy/extend_handler.rb +1 -0
  67. data/lib/yard/handlers/ruby/legacy/macro_handler.rb +40 -0
  68. data/lib/yard/handlers/ruby/legacy/method_handler.rb +10 -10
  69. data/lib/yard/handlers/ruby/legacy/mixin_handler.rb +4 -3
  70. data/lib/yard/handlers/ruby/legacy/module_handler.rb +2 -1
  71. data/lib/yard/handlers/ruby/legacy/private_constant_handler.rb +4 -4
  72. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
  73. data/lib/yard/handlers/ruby/legacy/yield_handler.rb +3 -3
  74. data/lib/yard/handlers/ruby/macro_handler.rb +41 -0
  75. data/lib/yard/handlers/ruby/macro_handler_methods.rb +130 -0
  76. data/lib/yard/handlers/ruby/method_condition_handler.rb +1 -1
  77. data/lib/yard/handlers/ruby/method_handler.rb +13 -13
  78. data/lib/yard/handlers/ruby/mixin_handler.rb +4 -4
  79. data/lib/yard/handlers/ruby/module_handler.rb +2 -1
  80. data/lib/yard/handlers/ruby/private_constant_handler.rb +4 -4
  81. data/lib/yard/handlers/ruby/struct_handler_methods.rb +11 -11
  82. data/lib/yard/handlers/ruby/visibility_handler.rb +1 -1
  83. data/lib/yard/handlers/ruby/yield_handler.rb +5 -5
  84. data/lib/yard/logging.rb +11 -11
  85. data/lib/yard/parser/base.rb +8 -8
  86. data/lib/yard/parser/c_parser.rb +42 -33
  87. data/lib/yard/parser/ruby/ast_node.rb +62 -61
  88. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +66 -66
  89. data/lib/yard/parser/ruby/legacy/ruby_parser.rb +4 -4
  90. data/lib/yard/parser/ruby/legacy/statement.rb +11 -11
  91. data/lib/yard/parser/ruby/legacy/statement_list.rb +15 -15
  92. data/lib/yard/parser/ruby/legacy/token_list.rb +9 -9
  93. data/lib/yard/parser/ruby/ruby_parser.rb +51 -37
  94. data/lib/yard/parser/source_parser.rb +271 -46
  95. data/lib/yard/rake/yardoc_task.rb +18 -17
  96. data/lib/yard/registry.rb +64 -64
  97. data/lib/yard/registry_store.rb +34 -34
  98. data/lib/yard/rubygems/backports.rb +8 -0
  99. data/lib/yard/rubygems/backports/LICENSE.txt +57 -0
  100. data/lib/yard/rubygems/backports/MIT.txt +20 -0
  101. data/lib/yard/rubygems/backports/gem.rb +8 -0
  102. data/lib/yard/rubygems/backports/source_index.rb +353 -0
  103. data/lib/yard/rubygems/specification.rb +2 -2
  104. data/lib/yard/serializers/base.rb +20 -20
  105. data/lib/yard/serializers/file_system_serializer.rb +28 -24
  106. data/lib/yard/serializers/process_serializer.rb +3 -3
  107. data/lib/yard/serializers/stdout_serializer.rb +6 -6
  108. data/lib/yard/serializers/yardoc_serializer.rb +17 -17
  109. data/lib/yard/server/adapter.rb +12 -12
  110. data/lib/yard/server/commands/base.rb +26 -26
  111. data/lib/yard/server/commands/display_file_command.rb +3 -2
  112. data/lib/yard/server/commands/display_object_command.rb +5 -5
  113. data/lib/yard/server/commands/frames_command.rb +1 -1
  114. data/lib/yard/server/commands/library_command.rb +7 -7
  115. data/lib/yard/server/commands/library_index_command.rb +2 -2
  116. data/lib/yard/server/commands/list_command.rb +8 -8
  117. data/lib/yard/server/commands/search_command.rb +8 -8
  118. data/lib/yard/server/commands/static_file_command.rb +3 -3
  119. data/lib/yard/server/doc_server_helper.rb +6 -3
  120. data/lib/yard/server/doc_server_serializer.rb +1 -1
  121. data/lib/yard/server/library_version.rb +45 -45
  122. data/lib/yard/server/rack_adapter.rb +10 -10
  123. data/lib/yard/server/router.rb +28 -28
  124. data/lib/yard/server/static_caching.rb +5 -5
  125. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +3 -3
  126. data/lib/yard/server/templates/default/fulldoc/html/js/live.js +1 -1
  127. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +2 -2
  128. data/lib/yard/server/templates/default/layout/html/headers.erb +13 -8
  129. data/lib/yard/server/templates/default/layout/html/setup.rb +7 -0
  130. data/lib/yard/server/templates/doc_server/full_list/html/full_list.erb +2 -2
  131. data/lib/yard/server/templates/doc_server/full_list/html/setup.rb +14 -4
  132. data/lib/yard/server/templates/doc_server/library_list/html/contents.erb +2 -2
  133. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +2 -2
  134. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +1 -1
  135. data/lib/yard/server/templates/doc_server/search/html/search.erb +1 -1
  136. data/lib/yard/server/webrick_adapter.rb +2 -2
  137. data/lib/yard/tags/default_factory.rb +19 -19
  138. data/lib/yard/tags/default_tag.rb +1 -1
  139. data/lib/yard/tags/library.rb +68 -63
  140. data/lib/yard/tags/option_tag.rb +1 -1
  141. data/lib/yard/tags/overload_tag.rb +9 -9
  142. data/lib/yard/tags/ref_tag_list.rb +2 -2
  143. data/lib/yard/tags/tag.rb +7 -7
  144. data/lib/yard/templates/engine.rb +31 -31
  145. data/lib/yard/templates/erb_cache.rb +1 -1
  146. data/lib/yard/templates/helpers/base_helper.rb +46 -32
  147. data/lib/yard/templates/helpers/filter_helper.rb +2 -2
  148. data/lib/yard/templates/helpers/html_helper.rb +120 -81
  149. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +4 -4
  150. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +9 -9
  151. data/lib/yard/templates/helpers/markup_helper.rb +37 -30
  152. data/lib/yard/templates/helpers/method_helper.rb +7 -7
  153. data/lib/yard/templates/helpers/text_helper.rb +7 -7
  154. data/lib/yard/templates/helpers/uml_helper.rb +3 -3
  155. data/lib/yard/templates/section.rb +14 -14
  156. data/lib/yard/templates/template.rb +54 -54
  157. data/lib/yard/verifier.rb +27 -27
  158. data/spec/cli/list_spec.rb +8 -0
  159. data/spec/cli/yardoc_spec.rb +58 -10
  160. data/spec/code_objects/extra_file_object_spec.rb +132 -0
  161. data/spec/code_objects/macro_object_spec.rb +154 -0
  162. data/spec/docstring_spec.rb +90 -0
  163. data/spec/handlers/base_spec.rb +22 -0
  164. data/spec/handlers/examples/macro_handler_001.rb.txt +73 -0
  165. data/spec/handlers/examples/method_handler_001.rb.txt +17 -0
  166. data/spec/handlers/macro_handler_spec.rb +140 -0
  167. data/spec/handlers/method_handler_spec.rb +28 -0
  168. data/spec/handlers/processor_spec.rb +4 -0
  169. data/spec/handlers/spec_helper.rb +1 -1
  170. data/spec/parser/c_parser_spec.rb +47 -16
  171. data/spec/parser/examples/extrafile.c.txt +8 -0
  172. data/spec/parser/examples/multifile.c.txt +6 -0
  173. data/spec/parser/ruby/ruby_parser_spec.rb +5 -0
  174. data/spec/parser/source_parser_spec.rb +235 -0
  175. data/spec/rake/yardoc_task_spec.rb +22 -17
  176. data/spec/serializers/file_system_serializer_spec.rb +6 -0
  177. data/spec/server/commands/library_command_spec.rb +39 -0
  178. data/spec/spec_helper.rb +14 -0
  179. data/spec/templates/examples/method001.html +6 -6
  180. data/spec/templates/examples/method002.html +4 -4
  181. data/spec/templates/examples/method003.html +10 -10
  182. data/spec/templates/examples/method005.html +2 -2
  183. data/spec/templates/examples/module001.dot +2 -0
  184. data/spec/templates/examples/module001.html +76 -37
  185. data/spec/templates/examples/module001.txt +1 -1
  186. data/spec/templates/helpers/base_helper_spec.rb +7 -2
  187. data/spec/templates/helpers/html_helper_spec.rb +49 -5
  188. data/spec/templates/helpers/markup_helper_spec.rb +9 -8
  189. data/spec/templates/module_spec.rb +7 -0
  190. data/spec/templates/onefile_spec.rb +47 -0
  191. data/templates/default/fulldoc/html/css/style.css +7 -5
  192. data/templates/default/fulldoc/html/full_list.erb +13 -10
  193. data/templates/default/fulldoc/html/full_list_files.erb +1 -1
  194. data/templates/default/fulldoc/html/js/app.js +16 -14
  195. data/templates/default/fulldoc/html/js/full_list.js +7 -6
  196. data/templates/default/fulldoc/html/setup.rb +78 -17
  197. data/templates/default/layout/html/files.erb +1 -1
  198. data/templates/default/layout/html/headers.erb +11 -7
  199. data/templates/default/layout/html/search.erb +4 -4
  200. data/templates/default/layout/html/setup.rb +28 -8
  201. data/templates/default/module/html/inherited_attributes.erb +17 -0
  202. data/templates/default/module/setup.rb +1 -1
  203. data/templates/default/onefile/html/files.erb +2 -2
  204. data/templates/default/onefile/html/layout.erb +1 -1
  205. data/templates/default/onefile/html/setup.rb +7 -5
  206. data/templates/default/tags/html/option.erb +1 -1
  207. data/templates/default/tags/html/tag.erb +3 -3
  208. data/templates/guide/class/html/setup.rb +1 -0
  209. data/templates/guide/docstring/html/setup.rb +1 -0
  210. data/templates/guide/fulldoc/html/css/style.css +91 -0
  211. data/templates/guide/fulldoc/html/js/app.js +33 -0
  212. data/templates/guide/fulldoc/html/setup.rb +54 -0
  213. data/templates/guide/layout/html/layout.erb +81 -0
  214. data/templates/guide/layout/html/setup.rb +24 -0
  215. data/templates/guide/method/html/header.erb +18 -0
  216. data/templates/guide/method/html/setup.rb +21 -0
  217. data/templates/guide/module/html/header.erb +7 -0
  218. data/templates/guide/module/html/method_list.erb +5 -0
  219. data/templates/guide/module/html/setup.rb +26 -0
  220. data/templates/guide/tags/html/setup.rb +8 -0
  221. metadata +40 -7
  222. data/lib/yard/handlers/ruby/legacy/process_handler.rb +0 -13
  223. data/lib/yard/handlers/ruby/process_handler.rb +0 -18
  224. data/spec/handlers/process_handler_spec.rb +0 -17
@@ -3,16 +3,16 @@ module YARD
3
3
  # @since 0.6.0
4
4
  class Stats < Yardoc
5
5
  include Templates::Helpers::BaseHelper
6
-
7
- # Maintains the order in which +stats_for_+ statistics methods should be
6
+
7
+ # Maintains the order in which +stats_for_+ statistics methods should be
8
8
  # printed.
9
- #
9
+ #
10
10
  # @see #print_statistics
11
11
  STATS_ORDER = [:files, :modules, :classes, :constants, :methods]
12
-
12
+
13
13
  # @return [Boolean] whether to parse and load registry
14
14
  attr_accessor :parse
15
-
15
+
16
16
  # @param [Boolean] parse whether to parse and load registry (see {#parse})
17
17
  def initialize(parse = true)
18
18
  super()
@@ -20,16 +20,16 @@ module YARD
20
20
  @undoc_list = nil
21
21
  @compact = false
22
22
  end
23
-
23
+
24
24
  def description
25
25
  "Prints documentation statistics on a set of files"
26
26
  end
27
-
27
+
28
28
  # Runs the commandline utility, parsing arguments and generating
29
29
  # output if set.
30
- #
30
+ #
31
31
  # @param [Array<String>] args the list of arguments
32
- # @return [void]
32
+ # @return [void]
33
33
  def run(*args)
34
34
  parse_arguments(*args)
35
35
 
@@ -41,13 +41,13 @@ module YARD
41
41
  YARD.parse(files, excluded)
42
42
  Registry.save(use_cache) if save_yardoc
43
43
  end
44
-
44
+
45
45
  print_statistics
46
46
  print_undocumented_objects
47
47
  end
48
-
48
+
49
49
  # Prints statistics for different object types
50
- #
50
+ #
51
51
  # To add statistics for a specific type, add a method +#stats_for_TYPE+
52
52
  # to this class that calls {#output}.
53
53
  def print_statistics
@@ -64,13 +64,13 @@ module YARD
64
64
  total = (@total - @undocumented).to_f / @total.to_f * 100
65
65
  puts("% 3.2f%% documented" % total)
66
66
  end
67
-
67
+
68
68
  # Prints list of undocumented objects
69
69
  def print_undocumented_objects
70
70
  return if !@undoc_list || @undoc_list.empty?
71
71
  puts
72
72
  puts "Undocumented Objects:"
73
-
73
+
74
74
  objects = @undoc_list.sort_by {|o| o.file }
75
75
  max = objects.sort_by {|o| o.path.length }.last.path.length
76
76
  if @compact
@@ -89,21 +89,21 @@ module YARD
89
89
  end
90
90
  end
91
91
  end
92
-
92
+
93
93
  # @return [Array<CodeObjects::Base>] all the parsed objects in the registry,
94
94
  # removing any objects that are not visible (private, protected) depending
95
95
  # on the arguments passed to the command.
96
96
  def all_objects
97
97
  @all_objects ||= run_verifier Registry.all
98
98
  end
99
-
99
+
100
100
  # Statistics for files
101
101
  def stats_for_files
102
102
  files = []
103
103
  all_objects.each {|o| files |= [o.file] }
104
104
  output "Files", files.size
105
105
  end
106
-
106
+
107
107
  # Statistics for modules
108
108
  def stats_for_modules
109
109
  output "Modules", *type_statistics(:module)
@@ -113,7 +113,7 @@ module YARD
113
113
  def stats_for_classes
114
114
  output "Classes", *type_statistics(:class)
115
115
  end
116
-
116
+
117
117
  # Statistics for constants
118
118
  def stats_for_constants
119
119
  output "Constants", *type_statistics(:constant)
@@ -127,10 +127,10 @@ module YARD
127
127
  @undoc_list |= undoc if @undoc_list
128
128
  output "Methods", objs.size, undoc.size
129
129
  end
130
-
130
+
131
131
  # Prints a statistic to standard out. This method is optimized for
132
132
  # getting Integer values, though it allows any data to be printed.
133
- #
133
+ #
134
134
  # @param [String] name the statistic name
135
135
  # @param [Integer, String] data the numeric (or any) data representing
136
136
  # the statistic. If +data+ is an Integer, it should represent the
@@ -147,16 +147,16 @@ module YARD
147
147
  end
148
148
  puts("%-12s %s" % [name + ":", data])
149
149
  end
150
-
150
+
151
151
  private
152
-
152
+
153
153
  def type_statistics(type)
154
154
  objs = all_objects.select {|m| m.type == type }
155
155
  undoc = objs.find_all {|m| m.docstring.blank? }
156
156
  @undoc_list |= undoc if @undoc_list
157
157
  [objs.size, undoc.size]
158
158
  end
159
-
159
+
160
160
  # Parses commandline options.
161
161
  # @param [Array<String>] args each tokenized argument
162
162
  def optparse(*args)
@@ -172,19 +172,19 @@ module YARD
172
172
  parse_options(opts, args)
173
173
  parse_files(*args) unless args.empty?
174
174
  end
175
-
175
+
176
176
  def general_options(opts)
177
177
  super(opts)
178
-
178
+
179
179
  opts.on('--list-undoc', 'List all undocumented objects') do
180
180
  @undoc_list = []
181
181
  end
182
-
182
+
183
183
  opts.on('--compact', 'Compact undocumented objects listing') do
184
184
  @compact = true
185
185
  end
186
-
187
- opts.on('--no-public', "Don't include public methods in statistics.") do
186
+
187
+ opts.on('--no-public', "Don't include public methods in statistics.") do
188
188
  visibilities.delete(:public)
189
189
  end
190
190
 
@@ -192,15 +192,15 @@ module YARD
192
192
  visibilities.push(:protected)
193
193
  end
194
194
 
195
- opts.on('--private', "Include private methods in statistics.") do
195
+ opts.on('--private', "Include private methods in statistics.") do
196
196
  visibilities.push(:private)
197
197
  end
198
-
198
+
199
199
  opts.on('--no-private', "Don't include objects with @private tag in statistics.") do
200
- options[:verifier].add_expressions '!object.tag(:private) &&
200
+ options[:verifier].add_expressions '!object.tag(:private) &&
201
201
  (object.namespace.type == :proxy || !object.namespace.tag(:private))'
202
202
  end
203
-
203
+
204
204
  opts.on('--query QUERY', "Only includes objects that match a specific query") do |query|
205
205
  options[:verifier].add_expressions(query.taint)
206
206
  end
@@ -6,123 +6,123 @@ module YARD
6
6
  # Yardoc is the default YARD CLI command (+yard doc+ and historic +yardoc+
7
7
  # executable) used to generate and output (mainly) HTML documentation given
8
8
  # a set of source files.
9
- #
9
+ #
10
10
  # == Usage
11
- #
11
+ #
12
12
  # Main usage for this command is:
13
- #
13
+ #
14
14
  # $ yardoc [options] [source_files [- extra_files]]
15
- #
15
+ #
16
16
  # See +yardoc --help+ for details on valid options.
17
- #
17
+ #
18
18
  # == Options File (+.yardopts+)
19
- #
19
+ #
20
20
  # If a +.yardopts+ file is found in the source directory being processed,
21
- # YARD will use the contents of the file as arguments to the command,
21
+ # YARD will use the contents of the file as arguments to the command,
22
22
  # treating newlines as spaces. You can use shell-style quotations to
23
23
  # group space delimited arguments, just like on the command line.
24
- #
24
+ #
25
25
  # A valid +.yardopts+ file might look like:
26
- #
26
+ #
27
27
  # --no-private
28
28
  # --title "My Title"
29
29
  # --exclude foo --exclude bar
30
- # lib/**/*.erb
30
+ # lib/**/*.erb
31
31
  # lib/**/*.rb -
32
32
  # HACKING.rdoc LEGAL COPYRIGHT
33
- #
33
+ #
34
34
  # Note that Yardoc also supports the legacy RDoc style +.document+ file,
35
35
  # though this file can only specify source globs to parse, not options.
36
- #
36
+ #
37
37
  # == Queries (+--query+)
38
- #
38
+ #
39
39
  # Yardoc supports queries to select specific code objects for which to
40
40
  # generate documentation. For example, you might want to generate
41
41
  # documentation only for your public API. If you've documented your public
42
42
  # methods with +@api public+, you can use the following query to select
43
43
  # all of these objects:
44
- #
44
+ #
45
45
  # --query '@api.text == "public"'
46
- #
46
+ #
47
47
  # Note that the syntax for queries is mostly Ruby with a few syntactic
48
48
  # simplifications for meta-data tags. See the {Verifier} class for an
49
- # overview of this syntax.
50
- #
49
+ # overview of this syntax.
50
+ #
51
51
  # == Adding Custom Ad-Hoc Meta-data Tags (+--tag+)
52
- #
53
- # YARD allows specification of {file:docs/Tags.md meta-data tags}
54
- # programmatically via the {YARD::Tags::Library} class, but often this is not
52
+ #
53
+ # YARD allows specification of {file:docs/Tags.md meta-data tags}
54
+ # programmatically via the {YARD::Tags::Library} class, but often this is not
55
55
  # practical for users writing documentation. To make adding custom tags
56
- # easier, Yardoc has a few command-line switches for creating basic tags
56
+ # easier, Yardoc has a few command-line switches for creating basic tags
57
57
  # and displaying them in generated HTML output.
58
- #
59
- # To specify a custom tag to be displayed in output, use any of the
58
+ #
59
+ # To specify a custom tag to be displayed in output, use any of the
60
60
  # following:
61
- #
61
+ #
62
62
  # * +--tag+ TAG:TITLE
63
63
  # * +--name-tag+ TAG:TITLE
64
64
  # * +--type-tag+ TAG:TITLE
65
65
  # * +--type-name-tag+ TAG:TITLE
66
66
  # * +--title-tag+ TAG:TITLE
67
- #
67
+ #
68
68
  # "TAG:TITLE" is of the form: name:"Display Title", for example:
69
- #
69
+ #
70
70
  # --tag overload:"Overloaded Method"
71
- #
71
+ #
72
72
  # See +yardoc --help+ for a description of the various options.
73
- #
73
+ #
74
74
  # Tags added in this way are automatically displayed in output. To add
75
75
  # a meta-data tag that does not show up in output, use +--hide-tag TAG+.
76
76
  # Note that you can also use this option on existing tags to hide
77
77
  # builtin tags, for instance.
78
- #
78
+ #
79
79
  # == Processed Data Storage (+.yardoc+ directory)
80
- #
80
+ #
81
81
  # When Yardoc parses a source directory, it creates a +.yardoc+ directory
82
82
  # (by default, override with +-b+) at the root of the project. This directory
83
83
  # contains marshal dumps for all raw object data in the source, so that
84
84
  # you can access it later for various commands (+stats+, +graph+, etc.).
85
85
  # This directory is also used as a cache for any future calls to +yardoc+
86
86
  # so as to process only the files which have changed since the last call.
87
- #
87
+ #
88
88
  # When Yardoc uses the cache in subsequent calls to +yardoc+, methods
89
89
  # or classes that have been deleted from source since the last parsing
90
90
  # will not be erased from the cache (YARD never deletes objects). In such
91
91
  # a case, you should wipe the cache and do a clean parsing of the source tree.
92
92
  # You can do this by deleting the +.yardoc+ directory manually, or running
93
93
  # Yardoc without +--use-cache+ (+-c+).
94
- #
94
+ #
95
95
  # @since 0.2.1
96
96
  # @see Verifier
97
97
  class Yardoc < Command
98
98
  # The configuration filename to load extra options from
99
99
  DEFAULT_YARDOPTS_FILE = ".yardopts"
100
-
100
+
101
101
  # @return [Hash] the hash of options passed to the template.
102
102
  # @see Templates::Engine#render
103
103
  attr_reader :options
104
-
104
+
105
105
  # @return [Array<String>] list of Ruby source files to process
106
106
  attr_accessor :files
107
-
107
+
108
108
  # @return [Array<String>] list of excluded paths (regexp matches)
109
109
  # @since 0.5.3
110
110
  attr_accessor :excluded
111
-
112
- # @return [Boolean] whether to use the existing yardoc db if the
111
+
112
+ # @return [Boolean] whether to use the existing yardoc db if the
113
113
  # .yardoc already exists. Also makes use of file checksums to
114
114
  # parse only changed files.
115
115
  attr_accessor :use_cache
116
-
116
+
117
117
  # @return [Boolean] whether to parse options from .yardopts
118
118
  attr_accessor :use_yardopts_file
119
-
119
+
120
120
  # @return [Boolean] whether to parse options from .document
121
121
  attr_accessor :use_document_file
122
-
122
+
123
123
  # @return [Boolean] whether objects should be serialized to .yardoc db
124
124
  attr_accessor :save_yardoc
125
-
125
+
126
126
  # @return [Boolean] whether to generate output
127
127
  attr_accessor :generate
128
128
 
@@ -133,37 +133,42 @@ module YARD
133
133
  # The options file name (defaults to {DEFAULT_YARDOPTS_FILE})
134
134
  # @return [String] the filename to load extra options from
135
135
  attr_accessor :options_file
136
-
136
+
137
137
  # Keep track of which visibilities are to be shown
138
138
  # @return [Array<Symbol>] a list of visibilities
139
139
  # @since 0.5.6
140
140
  attr_accessor :visibilities
141
-
141
+
142
142
  # @return [Array<Symbol>] a list of tags to hide from templates
143
143
  # @since 0.6.0
144
144
  attr_accessor :hidden_tags
145
-
145
+
146
146
  # @return [Boolean] whether to print statistics after parsing
147
147
  # @since 0.6.0
148
148
  attr_accessor :statistics
149
-
149
+
150
150
  # @return [Array<String>] a list of assets to copy after generation
151
151
  # @since 0.6.0
152
152
  attr_accessor :assets
153
-
153
+
154
+ # @return [Boolean] whether markup option was specified
155
+ # @since 0.7.0
156
+ attr_accessor :has_markup
157
+
154
158
  # Creates a new instance of the commandline utility
155
159
  def initialize
156
160
  super
157
161
  @options = SymbolHash.new(false)
158
162
  @options.update(
159
- :format => :html,
160
- :template => :default,
163
+ :format => :html,
164
+ :template => :default,
161
165
  :markup => :rdoc, # default is :rdoc but falls back on :none
162
166
  :serializer => YARD::Serializers::FileSystemSerializer.new,
163
167
  :default_return => "Object",
164
168
  :hide_void_return => false,
165
- :no_highlight => false,
169
+ :no_highlight => false,
166
170
  :files => [],
171
+ :title => "Documentation by YARD #{YARD::VERSION}",
167
172
  :verifier => Verifier.new
168
173
  )
169
174
  @visibilities = [:public]
@@ -179,25 +184,29 @@ module YARD
179
184
  @statistics = true
180
185
  @list = false
181
186
  @save_yardoc = true
182
-
187
+ @has_markup = false
188
+
183
189
  if defined?(Encoding)
184
190
  Encoding.default_external, Encoding.default_internal = 'utf-8', 'utf-8'
185
191
  end
186
192
  end
187
-
193
+
188
194
  def description
189
195
  "Generates documentation"
190
196
  end
191
-
197
+
192
198
  # Runs the commandline utility, parsing arguments and generating
193
199
  # output if set.
194
- #
195
- # @param [Array<String>] args the list of arguments
196
- # @return [void]
200
+ #
201
+ # @param [Array<String>] args the list of arguments. If the list only
202
+ # contains a single nil value, skip calling of {#parse_arguments}
203
+ # @return [void]
197
204
  def run(*args)
198
- # fail early if arguments are not valid
199
- return unless parse_arguments(*args)
200
-
205
+ if args.size == 0 || !args.first.nil?
206
+ # fail early if arguments are not valid
207
+ return unless parse_arguments(*args)
208
+ end
209
+
201
210
  checksums = nil
202
211
  if use_cache
203
212
  Registry.load
@@ -205,7 +214,7 @@ module YARD
205
214
  end
206
215
  YARD.parse(files, excluded)
207
216
  Registry.save(use_cache) if save_yardoc
208
-
217
+
209
218
  if generate
210
219
  run_generate(checksums)
211
220
  copy_assets
@@ -219,22 +228,16 @@ module YARD
219
228
  Stats.new(false).run(*args)
220
229
  end
221
230
  end
222
-
231
+
223
232
  true
224
233
  end
225
-
234
+
226
235
  # Parses commandline arguments
227
236
  # @param [Array<String>] args the list of arguments
228
237
  # @return [Boolean] whether or not arguments are valid
229
238
  # @since 0.5.6
230
239
  def parse_arguments(*args)
231
- options[:markup] = nil # reset markup
232
-
233
- # Hack: parse out --no-yardopts, --no-document before parsing files
234
- ['document', 'yardopts'].each do |file|
235
- without, with = args.index("--no-#{file}") || -2, args.index("--#{file}") || -1
236
- send("use_#{file}_file=", false) if without > with
237
- end
240
+ parse_yardopts_options(*args)
238
241
 
239
242
  # Parse files and then command line arguments
240
243
  optparse(*support_rdoc_document_file!) if use_document_file
@@ -242,12 +245,14 @@ module YARD
242
245
  optparse(*args)
243
246
 
244
247
  # Last minute modifications
245
- self.files = ['lib/**/*.rb', 'ext/**/*.c'] if self.files.empty?
248
+ self.files = ['{lib,app}/**/*.rb', 'ext/**/*.c'] if self.files.empty?
246
249
  self.files.delete_if {|x| x =~ /\A\s*\Z/ } # remove empty ones
247
- options[:readme] ||= Dir.glob('README*').first
250
+ readme = Dir.glob('README*').first
251
+ options[:readme] ||= CodeObjects::ExtraFileObject.new(readme) if readme
248
252
  if options[:onefile]
249
253
  options[:files] << options[:readme] if options[:readme]
250
- options[:readme] = Dir.glob(files.first).first
254
+ readme = Dir.glob(files.first).first
255
+ options[:readme] = CodeObjects::ExtraFileObject.new(readme) if readme
251
256
  end
252
257
  Tags::Library.visible_tags -= hidden_tags
253
258
  add_visibility_verifier
@@ -258,27 +263,27 @@ module YARD
258
263
  true
259
264
  end
260
265
  end
261
-
266
+
262
267
  # The list of all objects to process. Override this method to change
263
268
  # which objects YARD should generate documentation for.
264
- #
269
+ #
265
270
  # @deprecated To hide methods use the +@private+ tag instead.
266
271
  # @return [Array<CodeObjects::Base>] a list of code objects to process
267
272
  def all_objects
268
273
  Registry.all(:root, :module, :class)
269
274
  end
270
-
275
+
271
276
  # Parses the .yardopts file for default yard options
272
- # @return [Array<String>] an array of options parsed from .yardopts
277
+ # @return [Array<String>] an array of options parsed from .yardopts
273
278
  def yardopts
274
279
  return [] unless use_yardopts_file
275
280
  File.read_binary(options_file).shell_split
276
281
  rescue Errno::ENOENT
277
282
  []
278
283
  end
279
-
284
+
280
285
  private
281
-
286
+
282
287
  # Generates output for objects
283
288
  # @param [Hash, nil] checksums if supplied, a list of checkums for files.
284
289
  # @return [void]
@@ -302,14 +307,13 @@ module YARD
302
307
  end
303
308
  Templates::Engine.generate(objects, options)
304
309
  end
305
-
310
+
306
311
  # Verifies that the markup options are valid before parsing any code.
307
312
  # Failing early is better than failing late.
308
- #
313
+ #
309
314
  # @return (see YARD::Templates::Helpers::MarkupHelper#load_markup_provider)
310
315
  def verify_markup_options
311
- has_markup = options[:markup] ? true : false
312
- options[:markup] ||= :rdoc
316
+ options[:markup] = :rdoc unless has_markup
313
317
  result, lvl = false, has_markup ? log.level : Logger::FATAL
314
318
  obj = Struct.new(:options).new(options)
315
319
  obj.extend(Templates::Helpers::MarkupHelper)
@@ -323,7 +327,7 @@ module YARD
323
327
  result
324
328
  end
325
329
  end
326
-
330
+
327
331
  # Copies any assets to the output directory
328
332
  # @return [void]
329
333
  # @since 0.6.0
@@ -343,8 +347,22 @@ module YARD
343
347
  def print_list
344
348
  Registry.load_all
345
349
  run_verifier(Registry.all).
346
- sort_by {|item| [item.file, item.line]}.each do |item|
347
- puts "#{item.file}:#{item.line}: #{item}"
350
+ sort_by {|item| [item.file || '', item.line || 0] }.each do |item|
351
+ puts "#{item.file}:#{item.line}: #{item.path}"
352
+ end
353
+ end
354
+
355
+ # Parses out the yardopts/document options
356
+ def parse_yardopts_options(*args)
357
+ opts = OptionParser.new
358
+ yardopts_options(opts)
359
+ begin
360
+ opts.parse(args)
361
+ rescue OptionParser::ParseError => err
362
+ idx = args.index(err.args.first)
363
+ args = args[(idx+1)..-1]
364
+ args.shift while args.first && args.first[0,1] != '-'
365
+ retry
348
366
  end
349
367
  end
350
368
 
@@ -356,38 +374,38 @@ module YARD
356
374
  rescue Errno::ENOENT
357
375
  []
358
376
  end
359
-
377
+
360
378
  # Adds a set of extra documentation files to be processed
361
379
  # @param [Array<String>] files the set of documentation files
362
380
  def add_extra_files(*files)
363
381
  files.map! {|f| f.include?("*") ? Dir.glob(f) : f }.flatten!
364
382
  files.each do |file|
365
383
  if File.file?(file)
366
- options[:files] << file
384
+ options[:files] << CodeObjects::ExtraFileObject.new(file)
367
385
  else
368
386
  log.warn "Could not find extra file: #{file}"
369
387
  end
370
388
  end
371
389
  end
372
-
390
+
373
391
  # Parses the file arguments into Ruby files and extra files, which are
374
392
  # separated by a '-' element.
375
- #
393
+ #
376
394
  # @example Parses a set of Ruby source files
377
395
  # parse_files %w(file1 file2 file3)
378
396
  # @example Parses a set of Ruby files with a separator and extra files
379
397
  # parse_files %w(file1 file2 - extrafile1 extrafile2)
380
398
  # @param [Array<String>] files the list of files to parse
381
- # @return [void]
399
+ # @return [void]
382
400
  def parse_files(*files)
383
401
  seen_extra_files_marker = false
384
-
402
+
385
403
  files.each do |file|
386
404
  if file == "-"
387
405
  seen_extra_files_marker = true
388
406
  next
389
407
  end
390
-
408
+
391
409
  if seen_extra_files_marker
392
410
  add_extra_files(file)
393
411
  else
@@ -395,7 +413,7 @@ module YARD
395
413
  end
396
414
  end
397
415
  end
398
-
416
+
399
417
  # Adds verifier rule for visibilities
400
418
  # @return [void]
401
419
  # @since 0.5.6
@@ -403,26 +421,27 @@ module YARD
403
421
  vis_expr = "object.type != :method || #{visibilities.uniq.inspect}.include?(object.visibility)"
404
422
  options[:verifier].add_expressions(vis_expr)
405
423
  end
406
-
424
+
407
425
  # (see Templates::Helpers::BaseHelper#run_verifier)
408
426
  def run_verifier(list)
409
427
  options[:verifier] ? options[:verifier].run(list) : list
410
428
  end
411
-
429
+
412
430
  # @since 0.6.0
413
431
  def add_tag(tag_data, factory_method = nil)
414
432
  tag, title = *tag_data.split(':')
415
433
  Tags::Library.define_tag(title, tag.to_sym, factory_method)
416
434
  Tags::Library.visible_tags |= [tag.to_sym]
417
435
  end
418
-
436
+
419
437
  # Parses commandline options.
420
438
  # @param [Array<String>] args each tokenized argument
421
439
  def optparse(*args)
422
440
  opts = OptionParser.new
423
441
  opts.banner = "Usage: yard doc [options] [source_files [- extra_files]]"
424
442
 
425
- opts.separator "(if a list of source files is omitted, lib/**/*.rb ext/**/*.c is used.)"
443
+ opts.separator "(if a list of source files is omitted, "
444
+ opts.separator " {lib,app}/**/*.rb ext/**/*.c is used.)"
426
445
  opts.separator ""
427
446
  opts.separator "Example: yardoc -o documentation/ - FAQ LICENSE"
428
447
  opts.separator " The above example outputs documentation for files in"
@@ -446,11 +465,13 @@ module YARD
446
465
  opts.separator ""
447
466
  opts.separator "General Options:"
448
467
 
449
- opts.on('-b', '--db FILE', 'Use a specified .yardoc db to load from or save to. (defaults to .yardoc)') do |yfile|
468
+ opts.on('-b', '--db FILE', 'Use a specified .yardoc db to load from or save to',
469
+ ' (defaults to .yardoc)') do |yfile|
450
470
  YARD::Registry.yardoc_file = yfile
451
471
  end
452
-
453
- opts.on('--[no-]single-db', 'Whether code objects should be stored to single database file (advanced)') do |use_single_db|
472
+
473
+ opts.on('--[no-]single-db', 'Whether code objects should be stored to single',
474
+ ' database file (advanced)') do |use_single_db|
454
475
  Registry.single_object_db = use_single_db
455
476
  end
456
477
 
@@ -458,24 +479,19 @@ module YARD
458
479
  self.generate = false
459
480
  end
460
481
 
461
- opts.on('-c', '--use-cache [FILE]',
462
- "Use the cached .yardoc db to generate documentation. (defaults to no cache)") do |file|
482
+ opts.on('-c', '--use-cache [FILE]',
483
+ "Use the cached .yardoc db to generate documentation.",
484
+ " (defaults to no cache)") do |file|
463
485
  YARD::Registry.yardoc_file = file if file
464
486
  self.use_cache = true
465
487
  end
466
-
488
+
467
489
  opts.on('--no-cache', "Clear .yardoc db before parsing source.") do
468
490
  self.use_cache = false
469
491
  end
470
-
471
- opts.on('--[no-]yardopts', "If arguments should be read from .yardopts file. (defaults to yes)") do |use_yardopts|
472
- self.use_yardopts_file = use_yardopts
473
- end
474
492
 
475
- opts.on('--[no-]document', "If arguments should be read from .document file. (defaults to yes)") do |use_document|
476
- self.use_document_file = use_document
477
- end
478
-
493
+ yardopts_options(opts)
494
+
479
495
  opts.on('--no-save', 'Do not save the parsed data to the yardoc db') do
480
496
  self.save_yardoc = false
481
497
  end
@@ -484,6 +500,25 @@ module YARD
484
500
  self.excluded << path
485
501
  end
486
502
  end
503
+
504
+ # Adds --[no-]yardopts / --[no-]document
505
+ def yardopts_options(opts)
506
+ opts.on('--[no-]yardopts [FILE]',
507
+ "If arguments should be read from FILE",
508
+ " (defaults to yes, FILE defaults to .yardopts)") do |use_yardopts|
509
+ if use_yardopts.is_a?(String)
510
+ self.options_file = use_yardopts
511
+ self.use_yardopts_file = true
512
+ else
513
+ self.use_yardopts_file = (use_yardopts != false)
514
+ end
515
+ end
516
+
517
+ opts.on('--[no-]document', "If arguments should be read from .document file. ",
518
+ " (defaults to yes)") do |use_document|
519
+ self.use_document_file = use_document
520
+ end
521
+ end
487
522
 
488
523
  # Adds output options
489
524
  def output_options(opts)
@@ -499,7 +534,7 @@ module YARD
499
534
  self.list = true
500
535
  end
501
536
 
502
- opts.on('--no-public', "Don't show public methods. (default shows public)") do
537
+ opts.on('--no-public', "Don't show public methods. (default shows public)") do
503
538
  visibilities.delete(:public)
504
539
  end
505
540
 
@@ -507,24 +542,26 @@ module YARD
507
542
  visibilities.push(:protected)
508
543
  end
509
544
 
510
- opts.on('--private', "Show private methods. (default hides private)") do
545
+ opts.on('--private', "Show private methods. (default hides private)") do
511
546
  visibilities.push(:private)
512
547
  end
513
548
 
514
549
  opts.on('--no-private', "Hide objects with @private tag") do
515
- options[:verifier].add_expressions '!object.tag(:private) &&
550
+ options[:verifier].add_expressions '!object.tag(:private) &&
516
551
  (object.namespace.is_a?(CodeObjects::Proxy) || !object.namespace.tag(:private))'
517
552
  end
518
553
 
519
- opts.on('--no-highlight', "Don't highlight code blocks in output.") do
554
+ opts.on('--no-highlight', "Don't highlight code blocks in output.") do
520
555
  options[:no_highlight] = true
521
556
  end
522
557
 
523
- opts.on('--default-return TYPE', "Shown if method has no return type. Defaults to 'Object'") do |type|
558
+ opts.on('--default-return TYPE', "Shown if method has no return type. ",
559
+ " (defaults to 'Object')") do |type|
524
560
  options[:default_return] = type
525
561
  end
526
562
 
527
- opts.on('--hide-void-return', "Hides return types specified as 'void'. Default is shown.") do
563
+ opts.on('--hide-void-return', "Hides return types specified as 'void'. ",
564
+ " (default is shown)") do
528
565
  options[:hide_void_return] = true
529
566
  end
530
567
 
@@ -537,19 +574,22 @@ module YARD
537
574
  options[:title] = title
538
575
  end
539
576
 
540
- opts.on('-r', '--readme FILE', '--main FILE', 'The readme file used as the title page of documentation.') do |readme|
577
+ opts.on('-r', '--readme FILE', '--main FILE', 'The readme file used as the title page',
578
+ ' of documentation.') do |readme|
541
579
  if File.file?(readme)
542
- options[:readme] = readme
543
- else
580
+ options[:readme] = CodeObjects::ExtraFileObject.new(readme)
581
+ else
544
582
  log.warn "Could not find readme file: #{readme}"
545
583
  end
546
584
  end
547
585
 
548
- opts.on('--files FILE1,FILE2,...', 'Any extra comma separated static files to be included (eg. FAQ)') do |files|
586
+ opts.on('--files FILE1,FILE2,...', 'Any extra comma separated static files to be ',
587
+ ' included (eg. FAQ)') do |files|
549
588
  add_extra_files(*files.split(","))
550
589
  end
551
590
 
552
- opts.on('--asset FROM[:TO]', 'A file or directory to copy over to output directory after generating') do |asset|
591
+ opts.on('--asset FROM[:TO]', 'A file or directory to copy over to output ',
592
+ ' directory after generating') do |asset|
553
593
  re = /^(?:\.\.\/|\/)/
554
594
  from, to = *asset.split(':').map {|f| File.cleanpath(f) }
555
595
  to ||= from
@@ -560,22 +600,26 @@ module YARD
560
600
  end
561
601
  end
562
602
 
563
- opts.on('-o', '--output-dir PATH',
603
+ opts.on('-o', '--output-dir PATH',
564
604
  'The output directory. (defaults to ./doc)') do |dir|
565
605
  options[:serializer].basepath = dir
566
606
  end
567
-
568
- opts.on('-m', '--markup MARKUP',
569
- 'Markup style used in documentation, like textile, markdown or rdoc. (defaults to rdoc)') do |markup|
607
+
608
+ opts.on('-m', '--markup MARKUP',
609
+ 'Markup style used in documentation, like textile, ',
610
+ ' markdown or rdoc. (defaults to rdoc)') do |markup|
611
+ self.has_markup = true
570
612
  options[:markup] = markup.to_sym
571
613
  end
572
614
 
573
- opts.on('-M', '--markup-provider MARKUP_PROVIDER',
574
- 'Overrides the library used to process markup formatting (specify the gem name)') do |markup_provider|
615
+ opts.on('-M', '--markup-provider MARKUP_PROVIDER',
616
+ 'Overrides the library used to process markup ',
617
+ ' formatting (specify the gem name)') do |markup_provider|
575
618
  options[:markup_provider] = markup_provider.to_sym
576
619
  end
577
620
 
578
- opts.on('--charset ENC', 'Character set to use for HTML output (default is system locale)') do |encoding|
621
+ opts.on('--charset ENC', 'Character set to use when parsing files ',
622
+ ' (default is system locale)') do |encoding|
579
623
  begin
580
624
  Encoding.default_external, Encoding.default_internal = encoding, encoding
581
625
  rescue ArgumentError => e
@@ -583,22 +627,24 @@ module YARD
583
627
  end
584
628
  end
585
629
 
586
- opts.on('-t', '--template TEMPLATE',
630
+ opts.on('-t', '--template TEMPLATE',
587
631
  'The template to use. (defaults to "default")') do |template|
588
632
  options[:template] = template.to_sym
589
633
  end
590
634
 
591
- opts.on('-p', '--template-path PATH',
592
- 'The template path to look for templates in. (used with -t).') do |path|
635
+ opts.on('-p', '--template-path PATH',
636
+ 'The template path to look for templates in.',
637
+ ' (used with -t).') do |path|
593
638
  next if YARD::Config.options[:safe_mode]
594
639
  YARD::Templates::Engine.register_template_path(path)
595
640
  end
596
641
 
597
- opts.on('-f', '--format FORMAT',
598
- 'The output format for the template. (defaults to html)') do |format|
642
+ opts.on('-f', '--format FORMAT',
643
+ 'The output format for the template.',
644
+ ' (defaults to html)') do |format|
599
645
  options[:format] = format.to_sym
600
646
  end
601
-
647
+
602
648
  opts.on('--no-stats', 'Don\'t print statistics') do
603
649
  self.statistics = false
604
650
  end
@@ -633,7 +679,7 @@ module YARD
633
679
  opts.on('--hide-tag TAG', 'Hides a previously defined tag from templates') do |tag|
634
680
  self.hidden_tags |= [tag.to_sym]
635
681
  end
636
-
682
+
637
683
  opts.on('--transitive-tag TAG', 'Adds a transitive tag') do |tag|
638
684
  Tags::Library.transitive_tags += [tag.to_sym]
639
685
  end