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