lib/yard/server/library_version.rb in yard-0.9.4 vs lib/yard/server/library_version.rb in yard-0.9.5
- old
+ new
@@ -1,6 +1,7 @@
require 'fileutils'
+require 'thread'
module YARD
module Server
# This exception is raised when {LibraryVersion#prepare!} fails, or discovers
# that the library is not "prepared" to be served by
@@ -142,10 +143,17 @@
other.version == version && other.yardoc_file == yardoc_file
end
alias == eql?
alias equal? eql?
+ # @return [Boolean] whether the library has been completely processed
+ # and is ready to be served
+ def ready?
+ return false if yardoc_file.nil?
+ serializer.complete?
+ end
+
# @note You should not directly override this method. Instead, implement
# +load_yardoc_from_SOURCENAME+ when implementing loading for a specific
# source type. See the {LibraryVersion} documentation for "Implementing
# a Custom Library Source"
#
@@ -158,30 +166,45 @@
# @raise [LibraryNotPreparedError] if the library is not ready to be
# displayed. Usually when raising this error, you would simultaneously
# begin preparing the library for subsequent requests, although this
# is not necessary.
def prepare!
- return if yardoc_file
+ return if ready?
meth = "load_yardoc_from_#{source}"
send(meth) if respond_to?(meth, true)
end
# @return [Gem::Specification] a gemspec object for a given library. Used
# for :gem source types.
# @return [nil] if there is no installed gem for the library
def gemspec
ver = version ? "= #{version}" : ">= 0"
- Gem.source_index.find_name(name, ver).first
+ Gem.source_index.find_name(name, ver).last
end
protected
+ @@chdir_mutex = Mutex.new
+
# Called when a library of source type "disk" is to be prepared. In this
- # case, the {#yardoc_file} should already be set, so nothing needs to be
- # done.
+ # case, the {#yardoc_file} should already be set, but the library may not
+ # be prepared. Run preparation if not done.
+ #
+ # @raise [LibraryNotPreparedError] if the yardoc file has not been
+ # prepared.
def load_yardoc_from_disk
- nil
+ return if ready?
+
+ @@chdir_mutex.synchronize do
+ Dir.chdir(source_path_for_disk) do
+ Thread.new do
+ CLI::Yardoc.run('--no-stats', '-n', '-b', yardoc_file)
+ end
+ end
+ end
+
+ raise LibraryNotPreparedError
end
# Called when a library of source type "gem" is to be prepared. In this
# case, the {#yardoc_file} needs to point to the correct location for
# the installed gem. The yardoc file is built if it has not been done.
@@ -190,22 +213,22 @@
# yardoc file.
def load_yardoc_from_gem
require 'rubygems'
ver = version ? "= #{version}" : ">= 0"
self.yardoc_file = Registry.yardoc_file_for_gem(name, ver)
- unless yardoc_file && File.directory?(yardoc_file)
+ return if ready?
+
+ @@chdir_mutex.synchronize do
Thread.new do
# Build gem docs on demand
log.debug "Building gem docs for #{to_s(false)}"
CLI::Gems.run(name, ver)
self.yardoc_file = Registry.yardoc_file_for_gem(name, ver)
- FileUtils.touch(File.join(yardoc_file, 'complete'))
end
end
- unless yardoc_file && File.exist?(File.join(yardoc_file, 'complete'))
- raise LibraryNotPreparedError
- end
+
+ raise LibraryNotPreparedError
end
# @return [String] the source path for a disk source
def source_path_for_disk
File.dirname(yardoc_file) if yardoc_file
@@ -219,9 +242,14 @@
private
def load_source_path
meth = "source_path_for_#{source}"
send(meth) if respond_to?(meth, true)
+ end
+
+ def serializer
+ return if yardoc_file.nil?
+ @serializer ||= Serializers::YardocSerializer.new(yardoc_file)
end
end
end
end
\ No newline at end of file