module YARD module Server # Short circuits a request by raising an error. This exception is caught # by {Commands::Base#call} to immedaitely end a request and return a response. class FinishRequest < RuntimeError; end # Raises an error if a resource is not found. This exception is caught by # {Commands::Base#call} to immediately end a request and return a 404 response # code. If a message is provided, the body is set to the exception message. class NotFoundError < RuntimeError; end # This class implements the bridge between the {Router} and the server # backend for a specific server type. YARD implements concrete adapters # for WEBrick and Rack respectively, though other adapters can be made # for other server architectures. # # == Subclassing Notes # To create a concrete adapter class, implement the {#start} method to # initiate the server backend. # # @abstract class Adapter # @return [String] the location where static files are located, if any. # To set this field on initialization, pass +:DocumentRoot+ to the # +server_opts+ argument in {#initialize} attr_accessor :document_root # @return [Hash{String=>Array}] a map of libraries. # @see LibraryVersion LibraryVersion for information on building a list of libraries # @see #add_library attr_accessor :libraries # @return [Hash] options passed and processed by adapters. The actual # options mostly depend on the adapters themselves. attr_accessor :options # @return [Hash] a set of options to pass to the server backend. Note # that +:DocumentRoot+ also sets the {#document_root}. attr_accessor :server_options # @return [Router] the router object used to route URLs to commands attr_accessor :router # Performs any global initialization for the adapter. # @note If you subclass this method, make sure to call +super+. # @return [void] def self.setup Templates::Template.extra_includes |= [YARD::Server::DocServerHelper] Templates::Engine.template_paths |= [File.dirname(__FILE__) + '/templates'] end # Performs any global shutdown procedures for the adapter. # @note If you subclass this method, make sure to call +super+. # @return [void] def self.shutdown Templates::Template.extra_includes -= [YARD::Server::DocServerHelper] Templates::Engine.template_paths -= [File.dirname(__FILE__) + '/templates'] end # Creates a new adapter object # # @param [Hash{String=>Array}] libs a list of libraries, # see {#libraries} for formulating this list. # @param [Hash] opts extra options to pass to the adapter # @option opts [Class] :router (Router) the router class to initialize as the # adapter's router. # @option opts [Boolean] :caching (false) whether or not caching is enabled # @option opts [Boolean] :single_library (false) whether to server documentation # for a single or multiple libraries (changes URL structure) def initialize(libs, opts = {}, server_opts = {}) self.class.setup self.libraries = libs self.options = opts self.server_options = server_opts self.document_root = server_options[:DocumentRoot] self.router = (options[:router] || Router).new(self) options[:adapter] = self log.debug "Serving libraries using #{self.class}: #{libraries.keys.join(', ')}" log.debug "Caching on" if options[:caching] log.debug "Document root: #{document_root}" if document_root end # Adds a library to the {#libraries} mapping for a given library object. # @example Adding a new library to an adapter # adapter.add_library LibraryVersion.new('mylib', '1.0', '/path/to/.yardoc') # @param [LibraryVersion] library a library to add def add_library(library) libraries[library.name] ||= [] libraries[library.name] |= [library] end # Implement this method to connect your adapter to your server. # @abstract def start raise NotImplementedError end end end end