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
data/docs/WhatsNew.md CHANGED
@@ -16,6 +16,7 @@
16
16
  12. **Added line numbers to `yard stats --list-undoc --compact`** (0.8.0)
17
17
  13. **Single object db now default (multi-object db unsupported)** (0.8.0)
18
18
  14. **Added `--api` tag to generate documentation for API sets** (0.8.1)
19
+ 15. **Added `--non-transitive-tag` to disable transitive tag** (0.8.3)
19
20
 
20
21
  ## Directives (new behavioural tag syntax) (0.8.0)
21
22
 
@@ -278,6 +279,19 @@ due to security concerns, whereas `--api` works in either mode.
278
279
  This enables `--api` to function on remote documentation sites like
279
280
  [rubydoc.info](http://rubydoc.info).
280
281
 
282
+ ## Added `--non-transitive-tag` to disable transitive tag (0.8.3)
283
+
284
+ You can now use `--non-transitive-tag` to disable transitivity on
285
+ tags that are defined as transitive by default. For instance, in
286
+ some cases you might not want the @api tag to apply to all methods
287
+ when you define it on a class. Only the class itself has a specific
288
+ @api tag. To do this, you can mark @api as non-transitive with:
289
+
290
+ $ yard doc --non-transitive-tag api --api some_api
291
+
292
+ Which will avoid classifying treating @api as a transitive tag
293
+ when parsing modules and classes.
294
+
281
295
 
282
296
  # What's New in 0.7.x?
283
297
 
@@ -1048,14 +1062,14 @@ New tags (@abstract, @private)
1048
1062
 
1049
1063
  Two new tags were added to the list of builtin meta-tags in YARD. `@abstract`
1050
1064
  marks a class/module/method as abstract while `@private` marks an object
1051
- as "private". The latter tag is unsed in situations where an object is public
1065
+ as "private". The latter tag is used in situations where an object is public
1052
1066
  due to Ruby's own visibility limitations (constants, classes and modules
1053
1067
  can never be private) but not actually part of your public API. You should
1054
1068
  use this tag sparingly, as it is not meant to be an equivalent to RDoc's
1055
1069
  `:nodoc:` tag. Remember, YARD recommends documenting private objects too.
1056
1070
  This tag exists so that you can create a query (`--query !@private`) to
1057
1071
  ignore all of these private objects in your documentation. You can also
1058
- use the new `--no-private` switch, which is a shortcut to the afformentioned
1072
+ use the new `--no-private` switch, which is a shortcut to the aforementioned
1059
1073
  query. You can read more about the new tags in the {file:docs/GettingStarted.md}
1060
1074
  guide.
1061
1075
 
data/lib/yard.rb CHANGED
@@ -1,6 +1,6 @@
1
- module YARD
2
- VERSION = "0.8.2.1"
1
+ require File.expand_path('../yard/version.rb', __FILE__)
3
2
 
3
+ module YARD
4
4
  # The root path for YARD source libraries
5
5
  ROOT = File.expand_path(File.dirname(__FILE__))
6
6
 
@@ -27,10 +27,30 @@ module YARD
27
27
  # (see YARD::Config.load_plugins)
28
28
  # @deprecated Use {Config.load_plugins}
29
29
  def self.load_plugins; YARD::Config.load_plugins end
30
+
31
+ # @return [Boolean] whether YARD is being run inside of Windows
32
+ def self.windows?
33
+ return @windows if defined? @windows
34
+ require 'rbconfig'
35
+ if ::RbConfig::CONFIG['host_os'] =~ /mingw|win32|cygwin/
36
+ @wnidows = true
37
+ else
38
+ @windows = false
39
+ end
40
+ ensure
41
+ @windows ||= false
42
+ end
43
+
44
+ # @return [Boolean] whether YARD is being run in Ruby 1.8 mode
45
+ def self.ruby18?; !ruby19? end
46
+
47
+ # @return [Boolean] whether YARD is being run in Ruby 1.9 mode
48
+ def self.ruby19?; @ruby19 ||= (RUBY_VERSION >= "1.9.1") end
30
49
  end
31
50
 
32
51
  # Keep track of Ruby version for compatibility code
33
- RUBY19, RUBY18 = *(RUBY_VERSION >= "1.9.1" ? [true, false] : [false, true])
52
+ # @deprecated Use {YARD.ruby18?} or {YARD.ruby19?} instead.
53
+ RUBY18, RUBY19 = YARD.ruby18?, YARD.ruby19?
34
54
 
35
55
  # Load Ruby core extension classes
36
56
  Dir.glob(File.join(YARD::ROOT, 'yard', 'core_ext', '*.rb')).each do |file|
data/lib/yard/autoload.rb CHANGED
@@ -3,19 +3,20 @@ def __p(path) File.join(YARD::ROOT, 'yard', *path.split('/')); end
3
3
 
4
4
  module YARD
5
5
  module CLI # Namespace for command-line interface components
6
- autoload :Command, __p('cli/command')
7
- autoload :CommandParser, __p('cli/command_parser')
8
- autoload :Config, __p('cli/config')
9
- autoload :Diff, __p('cli/diff')
10
- autoload :Gems, __p('cli/gems')
11
- autoload :Graph, __p('cli/graph')
12
- autoload :Help, __p('cli/help')
13
- autoload :List, __p('cli/list')
14
- autoload :Server, __p('cli/server')
15
- autoload :Stats, __p('cli/stats')
16
- autoload :Yardoc, __p('cli/yardoc')
17
- autoload :YRI, __p('cli/yri')
18
- autoload :I18n, __p('cli/i18n')
6
+ autoload :Command, __p('cli/command')
7
+ autoload :CommandParser, __p('cli/command_parser')
8
+ autoload :Config, __p('cli/config')
9
+ autoload :Diff, __p('cli/diff')
10
+ autoload :Gems, __p('cli/gems')
11
+ autoload :Graph, __p('cli/graph')
12
+ autoload :Help, __p('cli/help')
13
+ autoload :List, __p('cli/list')
14
+ autoload :Server, __p('cli/server')
15
+ autoload :Stats, __p('cli/stats')
16
+ autoload :Yardoc, __p('cli/yardoc')
17
+ autoload :YardoptsCommand, __p('cli/yardopts_command')
18
+ autoload :YRI, __p('cli/yri')
19
+ autoload :I18n, __p('cli/i18n')
19
20
  end
20
21
 
21
22
  # A "code object" is defined as any entity in the Ruby language.
@@ -41,8 +41,8 @@ module YARD
41
41
  opts.on_tail('--verbose', 'Show more information.') { log.level = Logger::INFO }
42
42
  opts.on_tail('--debug', 'Show debugging information.') { log.level = Logger::DEBUG }
43
43
  opts.on_tail('--backtrace', 'Show stack traces') { log.show_backtraces = true }
44
- opts.on_tail('-v', '--version', 'Show version.') { puts "yard #{YARD::VERSION}"; exit }
45
- opts.on_tail('-h', '--help', 'Show this help.') { puts opts; exit }
44
+ opts.on_tail('-v', '--version', 'Show version.') { log.puts "yard #{YARD::VERSION}"; exit }
45
+ opts.on_tail('-h', '--help', 'Show this help.') { log.puts opts; exit }
46
46
  end
47
47
 
48
48
  # Parses the option and gracefully handles invalid switches
@@ -54,7 +54,7 @@ module YARD
54
54
  def parse_options(opts, args)
55
55
  opts.parse!(args)
56
56
  rescue OptionParser::ParseError => err
57
- log.warn "Unrecognized/#{err.message}"
57
+ unrecognized_option(err)
58
58
  args.shift if args.first && args.first[0,1] != '-'
59
59
  retry
60
60
  end
@@ -71,6 +71,14 @@ module YARD
71
71
  log.error "The file `#{file}' could not be loaded:\n#{load_exception}"
72
72
  exit
73
73
  end
74
+
75
+ # Callback when an unrecognize option is parsed
76
+ #
77
+ # @param [OptionParser::ParseError] err the exception raised by the
78
+ # option parser
79
+ def unrecognized_option(err)
80
+ log.warn "Unrecognized/#{err.message}"
81
+ end
74
82
  end
75
83
  end
76
84
  end
@@ -77,12 +77,12 @@ module YARD
77
77
  def commands; self.class.commands end
78
78
 
79
79
  def list_commands
80
- puts "Usage: yard <command> [options]"
81
- puts
82
- puts "Commands:"
80
+ log.puts "Usage: yard <command> [options]"
81
+ log.puts
82
+ log.puts "Commands:"
83
83
  commands.keys.sort_by {|k| k.to_s }.each do |command_name|
84
84
  command = commands[command_name].new
85
- puts "%-8s %s" % [command_name, command.description]
85
+ log.puts "%-8s %s" % [command_name, command.description]
86
86
  end
87
87
  end
88
88
  end
@@ -61,13 +61,13 @@ module YARD
61
61
 
62
62
  def view_item
63
63
  log.debug "Viewing #{key}"
64
- puts YARD::Config.options[key].inspect
64
+ log.puts YARD::Config.options[key].inspect
65
65
  end
66
66
 
67
67
  def list_configuration
68
68
  log.debug "Listing configuration"
69
69
  require 'yaml'
70
- puts YAML.dump(YARD::Config.options).sub(/\A--.*\n/, '').gsub(/\n\n/, "\n")
70
+ log.puts YAML.dump(YARD::Config.options).sub(/\A--.*\n/, '').gsub(/\n\n/, "\n")
71
71
  end
72
72
 
73
73
  def encode_values
data/lib/yard/cli/diff.rb CHANGED
@@ -12,6 +12,9 @@ module YARD
12
12
  super
13
13
  @list_all = false
14
14
  @use_git = false
15
+ @compact = false
16
+ @modified = true
17
+ @verifier = Verifier.new
15
18
  @old_git_commit = nil
16
19
  @old_path = Dir.pwd
17
20
  log.show_backtraces = true
@@ -25,11 +28,11 @@ module YARD
25
28
  registry = optparse(*args).map do |gemfile|
26
29
  if @use_git
27
30
  load_git_commit(gemfile)
28
- Registry.all.map {|o| o.path }
31
+ all_objects
29
32
  else
30
33
  if load_gem_data(gemfile)
31
34
  log.info "Found #{gemfile}"
32
- Registry.all.map {|o| o.path }
35
+ all_objects
33
36
  else
34
37
  log.error "Cannot find gem #{gemfile}"
35
38
  nil
@@ -39,31 +42,64 @@ module YARD
39
42
 
40
43
  return if registry.size != 2
41
44
 
42
- [ ["Added objects", registry[1] - registry[0]],
43
- ["Removed objects", registry[0] - registry[1]]].each do |name, objects|
45
+ first_object = nil
46
+ [ ["Added objects", "A", added_objects(*registry)],
47
+ ["Modified objects", "M", modified_objects(*registry)],
48
+ ["Removed objects", "D", removed_objects(*registry)]].each do |name, short, objects|
49
+ next if short == "M" && @modified == false
44
50
  next if objects.empty?
45
51
  last_object = nil
46
52
  all_objects_notice = false
47
- puts name + ":"
48
- objects.sort.each do |object|
49
- if !@list_all && last_object && object =~ /#{Regexp.quote last_object}(::|\.|#)/
50
- print " (...)" unless all_objects_notice
53
+ log.puts name + ":" unless @compact
54
+ objects.sort_by {|o| o.path }.each do |object|
55
+ if !@list_all && last_object && object.parent == last_object
56
+ log.print " (...)" unless all_objects_notice
51
57
  all_objects_notice = true
52
58
  next
59
+ elsif @compact
60
+ log.puts if first_object
53
61
  else
54
- puts
62
+ log.puts
55
63
  end
56
64
  all_objects_notice = false
57
- print " " + object
65
+ log.print "" + (@compact ? "#{short} " : " ") +
66
+ object.path + " (#{object.file}:#{object.line})"
58
67
  last_object = object
68
+ first_object = true
69
+ end
70
+ unless @compact
71
+ log.puts; log.puts
59
72
  end
60
- puts
61
- puts
62
73
  end
74
+ log.puts if @compact
63
75
  end
64
76
 
65
77
  private
66
78
 
79
+ def all_objects
80
+ return Registry.all if @verifier.expressions.empty?
81
+ @verifier.run(Registry.all)
82
+ end
83
+
84
+ def added_objects(registry1, registry2)
85
+ registry2.reject {|o| registry1.find {|o2| o2.path == o.path } }
86
+ end
87
+
88
+ def modified_objects(registry1, registry2)
89
+ registry1.select do |obj|
90
+ case obj
91
+ when CodeObjects::MethodObject
92
+ registry2.find {|o| obj == o && o.source != obj.source }
93
+ when CodeObjects::ConstantObject
94
+ registry2.find {|o| obj == o && o.value != obj.value }
95
+ end
96
+ end.compact
97
+ end
98
+
99
+ def removed_objects(registry1, registry2)
100
+ registry1.reject {|o| registry2.find {|o2| o2.path == o.path } }
101
+ end
102
+
67
103
  def load_git_commit(commit)
68
104
  commit_path = 'git_commit' + commit.gsub(/\W/, '_')
69
105
  tmpdir = File.join(Dir.tmpdir, commit_path)
@@ -74,6 +110,7 @@ module YARD
74
110
  Dir.chdir(tmpdir)
75
111
  log.info("git says: " + `git reset --hard #{commit}`.chomp)
76
112
  generate_yardoc(tmpdir)
113
+ ensure
77
114
  Dir.chdir(@old_path)
78
115
  cleanup(commit_path)
79
116
  end
@@ -140,9 +177,9 @@ module YARD
140
177
 
141
178
  def generate_yardoc(dir)
142
179
  olddir = Dir.pwd
143
- Dir.chdir(dir)
144
- log.enter_level(Logger::ERROR) { Yardoc.run('-n', '--no-save') }
145
- Dir.chdir(olddir)
180
+ Dir.chdir(dir) do
181
+ log.enter_level(Logger::ERROR) { Yardoc.run('-n', '--no-save') }
182
+ end
146
183
  end
147
184
 
148
185
  def expand_gem(gemfile, io)
@@ -184,13 +221,20 @@ module YARD
184
221
  opts.on('-a', '--all', 'List all objects, even if they are inside added/removed module/class') do
185
222
  @list_all = true
186
223
  end
224
+ opts.on('--compact', 'Show compact results') { @compact = true }
187
225
  opts.on('--git', 'Compare versions from two git commit/branches') do
188
226
  @use_git = true
189
227
  end
228
+ opts.on('--query QUERY', 'Only diff filtered objects') do |query|
229
+ @verifier.add_expressions(query)
230
+ end
231
+ opts.on('--no-modified', 'Ignore modified objects') do
232
+ @modified = false
233
+ end
190
234
  common_options(opts)
191
235
  parse_options(opts, args)
192
236
  unless args.size == 2
193
- puts opts.banner
237
+ log.puts opts.banner
194
238
  exit(0)
195
239
  end
196
240
 
@@ -20,7 +20,7 @@ module YARD
20
20
  #
21
21
  # @see Graph#run
22
22
  # @since 0.6.0
23
- class Graph < Command
23
+ class Graph < YardoptsCommand
24
24
  # The options parsed out of the commandline.
25
25
  # Default options are:
26
26
  # :format => :dot
@@ -32,6 +32,7 @@ module YARD
32
32
  # Creates a new instance of the command-line utility
33
33
  def initialize
34
34
  super
35
+ @use_document_file = false
35
36
  @options = GraphOptions.new
36
37
  options.reset_defaults
37
38
  options.serializer = YARD::Serializers::StdoutSerializer.new
@@ -48,8 +49,8 @@ module YARD
48
49
  # grapher.run('--private')
49
50
  # @param [Array<String>] args each tokenized argument
50
51
  def run(*args)
52
+ parse_arguments(*args)
51
53
  Registry.load
52
- optparse(*args)
53
54
 
54
55
  contents = objects.map do |o|
55
56
  o.format(options.merge(:serialize => false))
@@ -61,6 +62,8 @@ module YARD
61
62
 
62
63
  private
63
64
 
65
+ def unrecognized_option(err) end
66
+
64
67
  # Parses commandline options.
65
68
  # @param [Array<String>] args each tokenized argument
66
69
  def optparse(*args)
data/lib/yard/cli/help.rb CHANGED
@@ -9,7 +9,7 @@ module YARD
9
9
  if args.first && cmd = CommandParser.commands[args.first.to_sym]
10
10
  cmd.run('--help')
11
11
  else
12
- puts "Command #{args.first} not found." if args.first
12
+ log.puts "Command #{args.first} not found." if args.first
13
13
  CommandParser.run('--help')
14
14
  end
15
15
  end
data/lib/yard/cli/list.rb CHANGED
@@ -11,8 +11,8 @@ module YARD
11
11
  # @return [void]
12
12
  def run(*args)
13
13
  if args.include?('--help')
14
- puts "Usage: yard list [yardoc_options]"
15
- puts "Takes the same arguments as yardoc. See yardoc --help"
14
+ log.puts "Usage: yard list [yardoc_options]"
15
+ log.puts "Takes the same arguments as yardoc. See yardoc --help"
16
16
  else
17
17
  Yardoc.run('-c', '--list', *args)
18
18
  end
@@ -71,18 +71,58 @@ module YARD
71
71
 
72
72
  def add_libraries(args)
73
73
  (0...args.size).step(2) do |index|
74
- library, yardoc = args[index], args[index + 1]
75
- yardoc ||= '.yardoc'
76
- yardoc = File.expand_path(yardoc)
77
- if File.exist?(yardoc)
74
+ library, dir = args[index], args[index + 1]
75
+
76
+ libver = nil
77
+ if dir
78
+ if File.exist?(dir)
79
+ # Provided dir contains a .yardopts file
80
+ libver = create_library_version_if_yardopts_exist(library, dir)
81
+ libver ||= YARD::Server::LibraryVersion.new(library, nil, dir)
82
+ end
83
+ else
84
+ # Check if this dir contains a .yardopts file
85
+ pwd = Dir.pwd
86
+ libver = create_library_version_if_yardopts_exist(library, pwd)
87
+
88
+ # Check default location
89
+ yfile = File.join(pwd, '.yardoc')
90
+ libver ||= YARD::Server::LibraryVersion.new(library, nil, yfile)
91
+ end
92
+
93
+ # Register library
94
+ if libver
95
+ libver.yardoc_file = File.expand_path(libver.yardoc_file) if libver.yardoc_file
96
+ libver.source_path = File.expand_path(libver.source_path) if libver.source_path
78
97
  libraries[library] ||= []
79
- libraries[library] |= [YARD::Server::LibraryVersion.new(library, nil, yardoc)]
98
+ libraries[library] |= [libver]
80
99
  else
81
- log.warn "Cannot find yardoc db for #{library}: #{yardoc}"
100
+ log.warn "Cannot find yardoc db for #{library}: #{dir.inspect}"
82
101
  end
83
102
  end
84
103
  end
85
104
 
105
+ # @param [String] library The library name.
106
+ # @param [String, nil] dir The argument provided on the CLI after the
107
+ # library name. Is supposed to point to either a project directory
108
+ # with a Yard options file, or a yardoc db.
109
+ # @return [LibraryVersion, nil]
110
+ def create_library_version_if_yardopts_exist(library, dir)
111
+ if dir
112
+ options_file = File.join(dir, Yardoc::DEFAULT_YARDOPTS_FILE)
113
+ if File.exist?(options_file)
114
+ # Found yardopts, extract db path
115
+ yfile = extract_db_from_options_file(options_file)
116
+ db = File.expand_path(yfile, dir)
117
+
118
+ # Create libver
119
+ libver = YARD::Server::LibraryVersion.new(library, nil, db)
120
+ libver.source_path = dir
121
+ libver
122
+ end
123
+ end
124
+ end
125
+
86
126
  def add_gems
87
127
  require 'rubygems'
88
128
  Gem.source_index.find_name('').each do |spec|
@@ -94,7 +134,7 @@ module YARD
94
134
  def add_gems_from_gemfile(gemfile = nil)
95
135
  require 'bundler'
96
136
  gemfile ||= "Gemfile"
97
- if File.exists?("#{gemfile}.lock")
137
+ if File.exist?("#{gemfile}.lock")
98
138
  Bundler::LockfileParser.new(File.read("#{gemfile}.lock")).specs.each do |spec|
99
139
  libraries[spec.name] ||= []
100
140
  libraries[spec.name] |= [YARD::Server::LibraryVersion.new(spec.name, spec.version.to_s, nil, :gem)]
@@ -166,18 +206,45 @@ module YARD
166
206
  parse_options(opts, args)
167
207
 
168
208
  if args.empty? && libraries.empty?
169
- if !File.exist? File.expand_path('.yardoc')
170
- log.enter_level(Logger::INFO) do
171
- log.info "No .yardoc file found in current directory, parsing source before starting server..."
172
- end
173
- Yardoc.run('-n')
209
+ # No args - try to use current dir
210
+ add_libraries([File.basename(Dir.pwd), nil])
211
+
212
+ # Generate doc for first time
213
+ libver = libraries.empty? ? nil : libraries.values.first.first
214
+ if libver and !File.exist?(libver.yardoc_file)
215
+ generate_doc_for_first_time(libver)
174
216
  end
175
- add_libraries([File.basename(Dir.pwd), File.expand_path('.yardoc')])
176
217
  else
177
218
  add_libraries(args)
178
219
  options[:single_library] = false if libraries.size > 1
179
220
  end
180
221
  end
222
+
223
+ def generate_doc_for_first_time(libver)
224
+ log.enter_level(Logger::INFO) do
225
+ yardoc_file = libver.yardoc_file.sub /^#{Regexp.quote Dir.pwd}[\\\/]+/, ''
226
+ log.info "No yardoc db found in #{yardoc_file}, parsing source before starting server..."
227
+ end
228
+ Dir.chdir(libver.source_path) do
229
+ Yardoc.run('-n')
230
+ end
231
+ end
232
+
233
+ def extract_db_from_options_file(options_file)
234
+ args = File.read_binary(options_file).shell_split
235
+ db = YARD::Registry.yardoc_file
236
+ opts = OptionParser.new
237
+ opts.on('-b', '--db FILE') {|file| db = file }
238
+
239
+ begin
240
+ opts.parse!(args)
241
+ rescue OptionParser::ParseError
242
+ args.shift if args.first && args.first[0,1] != '-'
243
+ retry
244
+ end
245
+
246
+ db
247
+ end
181
248
  end
182
249
  end
183
250
  end