yard 0.8.2.1 → 0.8.3

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 (72) hide show
  1. data/ChangeLog +246 -0
  2. data/README.md +12 -2
  3. data/Rakefile +19 -51
  4. data/benchmarks/format_args.rb +3 -3
  5. data/benchmarks/pathname_vs_string.rb +4 -4
  6. data/benchmarks/template_format.rb +1 -1
  7. data/docs/Templates.md +21 -21
  8. data/docs/WhatsNew.md +16 -2
  9. data/lib/yard.rb +23 -3
  10. data/lib/yard/autoload.rb +14 -13
  11. data/lib/yard/cli/command.rb +11 -3
  12. data/lib/yard/cli/command_parser.rb +4 -4
  13. data/lib/yard/cli/config.rb +2 -2
  14. data/lib/yard/cli/diff.rb +60 -16
  15. data/lib/yard/cli/graph.rb +5 -2
  16. data/lib/yard/cli/help.rb +1 -1
  17. data/lib/yard/cli/list.rb +2 -2
  18. data/lib/yard/cli/server.rb +80 -13
  19. data/lib/yard/cli/stats.rb +8 -8
  20. data/lib/yard/cli/yardoc.rb +32 -78
  21. data/lib/yard/cli/yardopts_command.rb +109 -0
  22. data/lib/yard/cli/yri.rb +2 -2
  23. data/lib/yard/code_objects/base.rb +3 -1
  24. data/lib/yard/code_objects/extra_file_object.rb +45 -6
  25. data/lib/yard/core_ext/file.rb +1 -1
  26. data/lib/yard/docstring.rb +10 -1
  27. data/lib/yard/i18n/locale.rb +11 -3
  28. data/lib/yard/i18n/message.rb +1 -1
  29. data/lib/yard/logging.rb +32 -7
  30. data/lib/yard/parser/ruby/ruby_parser.rb +8 -3
  31. data/lib/yard/parser/source_parser.rb +1 -2
  32. data/lib/yard/rake/yardoc_task.rb +1 -2
  33. data/lib/yard/registry.rb +20 -1
  34. data/lib/yard/registry_store.rb +15 -1
  35. data/lib/yard/rubygems/backports/gem.rb +6 -5
  36. data/lib/yard/rubygems/backports/source_index.rb +17 -0
  37. data/lib/yard/rubygems/doc_manager.rb +1 -1
  38. data/lib/yard/server/commands/static_file_command.rb +17 -10
  39. data/lib/yard/server/library_version.rb +2 -2
  40. data/lib/yard/server/rack_adapter.rb +3 -3
  41. data/lib/yard/server/templates/default/layout/html/setup.rb +1 -1
  42. data/lib/yard/tags/directives.rb +1 -1
  43. data/lib/yard/templates/helpers/html_helper.rb +6 -4
  44. data/lib/yard/templates/template.rb +13 -1
  45. data/lib/yard/version.rb +3 -0
  46. data/spec/cli/config_spec.rb +2 -2
  47. data/spec/cli/diff_spec.rb +110 -23
  48. data/spec/cli/graph_spec.rb +12 -5
  49. data/spec/cli/help_spec.rb +1 -1
  50. data/spec/cli/server_spec.rb +243 -153
  51. data/spec/cli/stats_spec.rb +1 -1
  52. data/spec/cli/yardoc_spec.rb +36 -0
  53. data/spec/code_objects/base_spec.rb +15 -0
  54. data/spec/code_objects/constants_spec.rb +1 -1
  55. data/spec/code_objects/extra_file_object_spec.rb +15 -3
  56. data/spec/docstring_parser_spec.rb +4 -0
  57. data/spec/docstring_spec.rb +18 -0
  58. data/spec/handlers/module_function_handler_spec.rb +23 -0
  59. data/spec/i18n/locale_spec.rb +7 -1
  60. data/spec/parser/ruby/ruby_parser_spec.rb +26 -0
  61. data/spec/parser/source_parser_spec.rb +18 -6
  62. data/spec/rake/yardoc_task_spec.rb +28 -19
  63. data/spec/registry_spec.rb +34 -0
  64. data/spec/registry_store_spec.rb +10 -0
  65. data/spec/rubygems/doc_manager_spec.rb +1 -1
  66. data/spec/server/commands/static_file_command_spec.rb +3 -3
  67. data/spec/spec_helper.rb +22 -3
  68. data/spec/templates/helpers/html_helper_spec.rb +10 -8
  69. data/templates/default/fulldoc/html/frames.erb +1 -1
  70. data/templates/default/fulldoc/html/setup.rb +1 -1
  71. data/yard.gemspec +24 -0
  72. metadata +7 -5
@@ -22,7 +22,7 @@ class File
22
22
  break if from[0] != to[0]
23
23
  from.shift; to.shift
24
24
  end
25
- fname = from.pop
25
+ from.pop
26
26
  join(*(from.map { RELATIVE_PARENTDIR } + to))
27
27
  end
28
28
 
@@ -173,7 +173,9 @@ module YARD
173
173
  end
174
174
  end
175
175
  @summary = self[0..idx]
176
- @summary += '.' unless @summary.empty?
176
+ if !@summary.empty? && @summary !~ /\A\s*\{include:.+\}\s*\Z/
177
+ @summary += '.'
178
+ end
177
179
  @summary
178
180
  end
179
181
 
@@ -191,6 +193,13 @@ module YARD
191
193
  unless tag.docstring.blank?
192
194
  tag_text += "\n" + tag.docstring.all.gsub(/\r?\n/, "\n ")
193
195
  end
196
+ when Tags::OptionTag
197
+ tag_text = "@#{tag.tag_name} #{tag.name}"
198
+ tag_text += ' [' + tag.pair.types.join(', ') + ']' if tag.pair.types
199
+ tag_text += ' ' + tag.pair.name.to_s if tag.pair.name
200
+ tag_text += "\n " if tag.name && tag.text
201
+ tag_text += ' (' + tag.pair.defaults.join(', ') + ')' if tag.pair.defaults
202
+ tag_text += " " + tag.pair.text.strip.gsub(/\n/, "\n ") if tag.pair.text
194
203
  else
195
204
  tag_text = '@' + tag.tag_name
196
205
  tag_text += ' [' + tag.types.join(', ') + ']' if tag.types
@@ -1,6 +1,3 @@
1
- require "gettext/tools/poparser"
2
- require "gettext/runtime/mofile"
3
-
4
1
  module YARD
5
2
  module I18n
6
3
  # +Locale+ is a unit of translation. It has {#name} and a set of
@@ -28,9 +25,20 @@ module YARD
28
25
  # {#name}.po.
29
26
  # @return [Boolean] +true+ if PO file exists, +false+ otherwise.
30
27
  def load(locale_directory)
28
+ return false if @name.nil?
29
+
31
30
  po_file = File.join(locale_directory, "#{@name}.po")
32
31
  return false unless File.exist?(po_file)
33
32
 
33
+ begin
34
+ require "gettext/tools/poparser"
35
+ require "gettext/runtime/mofile"
36
+ rescue LoadError
37
+ log.warn "Need gettext gem for i18n feature:"
38
+ log.warn " gem install gettext"
39
+ return false
40
+ end
41
+
34
42
  parser = GetText::PoParser.new
35
43
  parser.report_warning = false
36
44
  data = GetText::MoFile.new
@@ -11,7 +11,7 @@ module YARD
11
11
  attr_reader :id
12
12
 
13
13
  # @return [Set] the set of locations. Location is an array of
14
- # path and line number where the message is appered.
14
+ # path and line number where the message is appeared.
15
15
  attr_reader :locations
16
16
 
17
17
  # @return [Set] the set of comments for the messages.
data/lib/yard/logging.rb CHANGED
@@ -22,7 +22,8 @@ module YARD
22
22
  # @return [Boolean] whether progress indicators should be shown when
23
23
  # logging CLIs (by default this is off).
24
24
  def show_progress
25
- return false if RUBY18 # threading is too ineffective for progress support
25
+ return false if YARD.ruby18? # threading is too ineffective for progress support
26
+ return false if YARD.windows? # windows has poor ANSI support
26
27
  return false unless io.tty? # no TTY support on IO
27
28
  return false if level > WARN # no progress in verbose/debug modes
28
29
  @show_progress
@@ -86,7 +87,7 @@ module YARD
86
87
  if defined?(::Encoding)
87
88
  icon = PROGRESS_INDICATORS[@progress_indicator] + " "
88
89
  end
89
- self << "\e[2K\e[?25l\e[1m#{icon}#{msg}\e[0m\r"
90
+ print("\e[2K\e[?25l\e[1m#{icon}#{msg}\e[0m\r")
90
91
  @mutex.synchronize do
91
92
  @progress_msg = msg
92
93
  @progress_indicator += 1
@@ -105,19 +106,32 @@ module YARD
105
106
  # @since 0.8.2
106
107
  def clear_progress
107
108
  return unless show_progress
108
- self << "\e[?25h\e[2K"
109
+ print_no_newline("\e[?25h\e[2K")
109
110
  @progress_msg = nil
110
111
  end
111
112
 
112
- # Displays an unformatted line to the logger output stream. Similar to
113
- # the +#<<+ method, but adds a newline.
113
+ # Displays an unformatted line to the logger output stream, adding
114
+ # a newline.
114
115
  # @param [String] msg the message to display
115
116
  # @return [void]
116
117
  # @since 0.8.2
117
- def puts(msg)
118
- self << "#{msg}\n"
118
+ def puts(msg = '')
119
+ print("#{msg}\n")
119
120
  end
120
121
 
122
+ alias_method :print_no_newline, :<<
123
+ private :print_no_newline
124
+
125
+ # Displays an unformatted line to the logger output stream.
126
+ # @param [String] msg the message to display
127
+ # @return [void]
128
+ # @since 0.8.2
129
+ def print(msg = '')
130
+ clear_line
131
+ print_no_newline(msg)
132
+ end
133
+ alias_method :<<, :print
134
+
121
135
  # Prints the backtrace +exc+ to the logger as error data.
122
136
  #
123
137
  # @param [Array<String>] exc the backtrace list
@@ -156,6 +170,17 @@ module YARD
156
170
 
157
171
  private
158
172
 
173
+ # Override this internal Logger method to clear line
174
+ def add(*args)
175
+ clear_line
176
+ super(*args)
177
+ end
178
+
179
+ def clear_line
180
+ return unless @progress_msg
181
+ print_no_newline("\e[2K\r")
182
+ end
183
+
159
184
  # Log format (from Logger implementation). Used by Logger internally
160
185
  def format_log(sev, time, prog, msg)
161
186
  "[#{sev.downcase}]: #{msg}\n"
@@ -498,7 +498,7 @@ module YARD
498
498
 
499
499
  hash_flag = $1 == '##' ? true : false
500
500
 
501
- if append_comment && @comments_last_column == column
501
+ if append_comment && @comments_last_column && @comments_last_column == column
502
502
  @comments.delete(lineno - 1)
503
503
  @comments_flags[lineno] = @comments_flags[lineno - 1]
504
504
  @comments_flags.delete(lineno - 1)
@@ -515,6 +515,7 @@ module YARD
515
515
 
516
516
  def on_embdoc_beg(text)
517
517
  visit_ns_token(:embdoc_beg, text)
518
+ @embdoc_start = charno-text.length
518
519
  @embdoc = ""
519
520
  end
520
521
 
@@ -525,7 +526,10 @@ module YARD
525
526
 
526
527
  def on_embdoc_end(text)
527
528
  visit_ns_token(:embdoc_end, text)
529
+ @comments_last_column = nil
528
530
  @comments[lineno] = @embdoc
531
+ @comments_range[lineno] = @embdoc_start...charno
532
+ @embdoc_start = nil
529
533
  @embdoc = nil
530
534
  end
531
535
 
@@ -535,8 +539,9 @@ module YARD
535
539
 
536
540
  def insert_comments
537
541
  root.traverse do |node|
538
- next if node.type == :list || node.parent.type != :list
539
- (node.line - 2).upto(node.line) do |line|
542
+ next if node.type == :comment || node.type == :list || node.parent.type != :list
543
+ # check upwards from line before node; check node's line at the end
544
+ ((node.line-1).downto(node.line-2).to_a + [node.line]).each do |line|
540
545
  comment = @comments[line]
541
546
  if comment && !comment.empty?
542
547
  add_comment(line, node)
@@ -100,7 +100,7 @@ module YARD
100
100
  end
101
101
  files = [paths].flatten.
102
102
  map {|p| File.directory?(p) ? "#{p}/**/*.{rb,c}" : p }.
103
- map {|p| p.include?("*") ? Dir[p] : p }.flatten.
103
+ map {|p| p.include?("*") ? Dir[p].sort_by {|f| f.length } : p }.flatten.
104
104
  reject {|p| !File.file?(p) || excluded.any? {|re| p =~ re } }
105
105
 
106
106
  log.enter_level(level) do
@@ -360,7 +360,6 @@ module YARD
360
360
  # @return [void]
361
361
  def parse_in_order(*files)
362
362
  global_state = OpenStruct.new
363
- files = files.sort_by {|x| x.length if x }
364
363
 
365
364
  before_parse_list_callbacks.each do |cb|
366
365
  return if cb.call(files, global_state) == false
@@ -64,9 +64,8 @@ module YARD
64
64
  task(name) do
65
65
  before.call if before.is_a?(Proc)
66
66
  yardoc = YARD::CLI::Yardoc.new
67
- yardoc.parse_arguments *(options + files)
68
67
  yardoc.options[:verifier] = verifier if verifier
69
- yardoc.run
68
+ yardoc.run *(options + files)
70
69
  after.call if after.is_a?(Proc)
71
70
  end
72
71
  end
data/lib/yard/registry.rb CHANGED
@@ -31,6 +31,7 @@ module YARD
31
31
  module Registry
32
32
  DEFAULT_YARDOC_FILE = ".yardoc"
33
33
  LOCAL_YARDOC_INDEX = File.expand_path('~/.yard/gem_index')
34
+ DEFAULT_PO_DIR = "po"
34
35
 
35
36
  extend Enumerable
36
37
 
@@ -96,7 +97,7 @@ module YARD
96
97
  # @raise [ArgumentError] if files is not a String or Array
97
98
  def load(files = [], reparse = false)
98
99
  if files.is_a?(Array)
99
- if File.exists?(yardoc_file) && !reparse
100
+ if File.exist?(yardoc_file) && !reparse
100
101
  load_yardoc
101
102
  else
102
103
  size = thread_local_store.keys.size
@@ -239,6 +240,13 @@ module YARD
239
240
  # @return [CodeObjects::RootObject] the root object in the namespace
240
241
  def root; thread_local_store[:root] end
241
242
 
243
+ # @param [String] name the locale name.
244
+ # @return [I18n::Locale] the locale object for +name+.
245
+ # @since 0.8.3
246
+ def locale(name)
247
+ thread_local_store.locale(name)
248
+ end
249
+
242
250
  # Attempts to find an object by name starting at +namespace+, performing
243
251
  # a lookup similar to Ruby's method of resolving a constant in a namespace.
244
252
  #
@@ -347,6 +355,17 @@ module YARD
347
355
  thread_local_store.proxy_types
348
356
  end
349
357
 
358
+ # @group I18n features
359
+
360
+ # Gets/sets the directory that has LANG.po files
361
+ # @return [String] the directory that has .po files
362
+ attr_accessor :po_dir
363
+ undef po_dir, po_dir=
364
+ def po_dir=(dir) Thread.current[:__yard_po_dir__] = dir end
365
+ def po_dir
366
+ Thread.current[:__yard_po_dir__] ||= DEFAULT_PO_DIR
367
+ end
368
+
350
369
  # @group Legacy Methods
351
370
 
352
371
  # The registry singleton instance.
@@ -19,6 +19,7 @@ module YARD
19
19
  @notfound = {}
20
20
  @loaded_objects = 0
21
21
  @available_objects = 0
22
+ @locales = {}
22
23
  @store[:root] = CodeObjects::RootObject.allocate
23
24
  @store[:root].send(:initialize, nil, :root)
24
25
  end
@@ -108,6 +109,13 @@ module YARD
108
109
  # @return [CodeObjects::RootObject] the root object
109
110
  def root; @store[:root] end
110
111
 
112
+ # @param [String] name the locale name.
113
+ # @return [I18n::Locale] the locale object for +name+.
114
+ # @since 0.8.3
115
+ def locale(name)
116
+ @locales[name] ||= load_locale(name)
117
+ end
118
+
111
119
  # @param [String, nil] file the name of the yardoc db to load
112
120
  # @return [Boolean] whether the database was loaded
113
121
  def load(file = nil)
@@ -283,6 +291,12 @@ module YARD
283
291
  end
284
292
  end
285
293
 
294
+ def load_locale(name)
295
+ locale = I18n::Locale.new(name)
296
+ locale.load(Registry.po_dir)
297
+ locale
298
+ end
299
+
286
300
  def all_disk_objects
287
301
  Dir.glob(File.join(objects_path, '**/*')).select {|f| File.file?(f) }
288
302
  end
@@ -302,4 +316,4 @@ module YARD
302
316
  end
303
317
  end
304
318
  end
305
- end
319
+ end
@@ -1,8 +1,9 @@
1
1
  module Gem
2
- ##
3
- # Returns the Gem::SourceIndex of specifications that are in the Gem.path
4
-
5
- def self.source_index
6
- @@source_index ||= SourceIndex.from_installed_gems
2
+ class << self
3
+ undef source_index if method_defined?(:source_index)
4
+ # Returns the Gem::SourceIndex of specifications that are in the Gem.path
5
+ def source_index
6
+ @@source_index ||= SourceIndex.from_installed_gems
7
+ end
7
8
  end
8
9
  end
@@ -18,6 +18,15 @@ require 'rubygems/specification'
18
18
  # YAMLized source index objects to load properly.
19
19
 
20
20
  class Gem::SourceIndex
21
+ # Undef old methods
22
+ alias old_initialize initialize
23
+ undef old_initialize
24
+ %w(all_gems prerelease_gems load_gems_in latest_specs prerelease_specs
25
+ released_specs add_spec add_specs remove_spec each specification
26
+ index_signature gem_signature size length find_name search released_gems
27
+ refresh! outdated == dump gems spec_dirs spec_dirs=).each do |meth|
28
+ undef_method(meth) if method_defined?(meth)
29
+ end
21
30
 
22
31
  include Enumerable
23
32
 
@@ -29,6 +38,14 @@ class Gem::SourceIndex
29
38
  attr_accessor :spec_dirs
30
39
 
31
40
  class << self
41
+ # Undef old methods
42
+ %w(from_installed_gems installed_spec_directories
43
+ from_gems_in load_specification).each do |meth|
44
+ if instance_methods(true).find {|m| m.to_s == meth }
45
+ undef_method(meth)
46
+ end
47
+ end
48
+
32
49
  ##
33
50
  # Factory method to construct a source index instance for a given
34
51
  # path.
@@ -3,7 +3,7 @@ require 'rubygems/doc_manager'
3
3
 
4
4
  class Gem::DocManager
5
5
  def self.load_yardoc
6
- require File.dirname(__FILE__) + '/../../yard'
6
+ require File.expand_path(File.join(File.dirname(__FILE__), *%w(.. .. yard)))
7
7
  end
8
8
 
9
9
  def run_yardoc(*args)
@@ -13,22 +13,29 @@ module YARD
13
13
  # extra path, use {YARD::Server.register_static_path} rather than
14
14
  # modifying this constant directly. Also note that files in the
15
15
  # document root will always take precedence over these paths.
16
- STATIC_PATHS = [
17
- File.join(YARD::TEMPLATE_ROOT, 'default', 'fulldoc', 'html'),
18
- File.join(File.dirname(__FILE__), '..', 'templates', 'default', 'fulldoc', 'html')
19
- ]
16
+ STATIC_PATHS = []
20
17
 
21
18
  def run
19
+ assets_template = Templates::Engine.template(:default, :fulldoc, :html)
22
20
  path = File.cleanpath(request.path).gsub(%r{^(../)+}, '')
21
+
22
+ file = nil
23
23
  ([adapter.document_root] + STATIC_PATHS.reverse).compact.each do |path_prefix|
24
24
  file = File.join(path_prefix, path)
25
- if File.exist?(file)
26
- ext = "." + (request.path[/\.(\w+)$/, 1] || "html")
27
- headers['Content-Type'] = mime_type(ext, DefaultMimeTypes)
28
- self.body = File.read(file)
29
- return
30
- end
25
+ break if File.exist?(file)
26
+ file = nil
31
27
  end
28
+
29
+ # Search in default/fulldoc/html template if nothing in static asset paths
30
+ file ||= assets_template.find_file(path)
31
+
32
+ if file
33
+ ext = "." + (request.path[/\.(\w+)$/, 1] || "html")
34
+ headers['Content-Type'] = mime_type(ext, DefaultMimeTypes)
35
+ self.body = File.read(file)
36
+ return
37
+ end
38
+
32
39
  favicon?
33
40
  self.status = 404
34
41
  end
@@ -162,7 +162,7 @@ module YARD
162
162
  def prepare!
163
163
  return if yardoc_file
164
164
  meth = "load_yardoc_from_#{source}"
165
- send(meth) if respond_to?(meth)
165
+ send(meth) if respond_to?(meth, true)
166
166
  end
167
167
 
168
168
  # @return [Gem::Specification] a gemspec object for a given library. Used
@@ -220,7 +220,7 @@ module YARD
220
220
 
221
221
  def load_source_path
222
222
  meth = "source_path_for_#{source}"
223
- send(meth) if respond_to?(meth)
223
+ send(meth) if respond_to?(meth, true)
224
224
  end
225
225
  end
226
226
  end
@@ -69,12 +69,12 @@ module YARD
69
69
 
70
70
  def print_start_message(server)
71
71
  opts = server.default_options.merge(server.options)
72
- puts ">> YARD #{YARD::VERSION} documentation server at http://#{opts[:Host]}:#{opts[:Port]}"
72
+ log.puts ">> YARD #{YARD::VERSION} documentation server at http://#{opts[:Host]}:#{opts[:Port]}"
73
73
 
74
74
  # Only happens for Mongrel
75
75
  return unless server.server.to_s == "Rack::Handler::Mongrel"
76
- puts ">> #{server.server.class_name} web server (running on Rack)"
77
- puts ">> Listening on #{opts[:Host]}:#{opts[:Port]}, CTRL+C to stop"
76
+ log.puts ">> #{server.server.class_name} web server (running on Rack)"
77
+ log.puts ">> Listening on #{opts[:Host]}:#{opts[:Port]}, CTRL+C to stop"
78
78
  end
79
79
  end
80
80
  end
@@ -1,5 +1,5 @@
1
1
  def javascripts
2
- super + %w(js/autocomplete.js js/live.js)
2
+ super + %w(js/autocomplete.js)
3
3
  end
4
4
 
5
5
  def stylesheets