lib/yard/server/router.rb in yard-0.9.18 vs lib/yard/server/router.rb in yard-0.9.19
- old
+ new
@@ -1,187 +1,187 @@
-# frozen_string_literal: true
-module YARD
- module Server
- # A router class implements the logic used to recognize a request for a specific
- # URL and run specific {Commands::Base commands}.
- #
- # == Subclassing Notes
- # To create a custom router, subclass this class and pass it into the adapter
- # options through {Adapter#initialize} or by directly modifying {Adapter#router}.
- #
- # The most general customization is to change the URL prefixes recognized by
- # routing, which can be done by overriding {#docs_prefix}, {#list_prefix},
- # {#static_prefix}, and {#search_prefix}.
- #
- # == Implementing Custom Caching
- # By default, the Router class performs static disk-based caching on all
- # requests through the +#check_static_cache+. To override this behaviour,
- # or create your own caching mechanism, mixin your own custom module with
- # this method implemented as per {StaticCaching#check_static_cache}.
- #
- # @example Creating a subclassed router
- # # Adds 'my' to all routing prefixes
- # class MyRouter < YARD::Server::Router
- # def docs_prefix; 'mydocs' end
- # def list_prefix; 'mylist' end
- # def static_prefix; 'mystatic' end
- # def search_prefix; 'mysearch' end
- # end
- #
- # # Using it:
- # WebrickAdapter.new(libraries, :router => MyRouter).start
- class Router
- include StaticCaching
- include Commands
-
- # @return [Adapter Dependent] the request data coming in with the routing
- attr_accessor :request
-
- # @return [Adapter] the adapter used by the router
- attr_accessor :adapter
-
- # Creates a new router for a specific adapter
- #
- # @param [Adapter] adapter the adapter to route requests to
- def initialize(adapter)
- self.adapter = adapter
- end
-
- # Perform routing on a specific request, serving the request as a static
- # file through {Commands::RootRequestCommand} if no route is found.
- #
- # @param [Adapter Dependent] request the request object
- # @return [Array(Numeric,Hash,Array)] the Rack-style server response data
- def call(request)
- self.request = request
- result = check_static_cache || route
- result ? result : RootRequestCommand.new(adapter.options).call(request)
- end
-
- # @group Route Prefixes
-
- # @return [String] the URI prefix for all object documentation requests
- def docs_prefix; 'docs' end
-
- # @return [String] the URI prefix for all class/method/file list requests
- def list_prefix; 'list' end
-
- # @return [String] the URI prefix for all search requests
- def search_prefix; 'search' end
-
- # @return [String] the URI prefix for all static assets (templates)
- def static_prefix; 'static' end
-
- # @group Routing Methods
-
- # @return [Array(LibraryVersion, Array<String>)] the library followed
- # by the rest of the path components in the request path. LibraryVersion
- # will be nil if no matching library was found.
- def parse_library_from_path(paths)
- return [adapter.libraries.values.first.first, paths] if adapter.options[:single_library]
- library = nil
- paths = paths.dup
- libs = adapter.libraries[paths.first]
- if libs
- paths.shift
- library = libs.find {|l| l.version == paths.first }
- if library
- request.version_supplied = true if request
- paths.shift
- else # use the last lib in the list
- request.version_supplied = false if request
- library = libs.last
- end
- end
- [library, paths]
- end
-
- protected
-
- # Performs routing algorithm to find which prefix is called, first
- # parsing out library name/version information.
- #
- # @return [Array(Numeric,Hash,Array<String>)] the Rack-style response
- # @return [nil] if no route is matched
- def route(path = request.path_info)
- path = path.gsub(%r{//+}, '/').gsub(%r{^/|/$}, '')
- return route_index if path.empty? || path == docs_prefix
- case path
- when %r{^(#{docs_prefix}|#{list_prefix}|#{search_prefix}|#{static_prefix})(/.*|$)}
- prefix = $1
- paths = $2.gsub(%r{^/|/$}, '').split('/')
- library, paths = *parse_library_from_path(paths)
- return unless library
- return case prefix
- when docs_prefix; route_docs(library, paths)
- when list_prefix; route_list(library, paths)
- when search_prefix; route_search(library, paths)
- when static_prefix; route_static(library, paths)
- end
- end
- nil
- end
-
- # Routes requests from {#docs_prefix} and calls the appropriate command
- # @param [LibraryVersion] library the library to route for
- # @param [Array<String>] paths path components (split by '/')
- # @return (see #route)
- def route_docs(library, paths)
- return route_index if library.nil?
- case paths.first
- when "frames"
- paths.shift
- cmd = DisplayObjectCommand
- when "file"
- paths.shift
- cmd = DisplayFileCommand
- else
- cmd = DisplayObjectCommand
- end
- cmd = cmd.new(final_options(library, paths))
- cmd.call(request)
- end
-
- # Routes for the index of a library / multiple libraries
- # @return (see #route)
- def route_index
- if adapter.options[:single_library]
- route_docs(adapter.libraries.values.first.first, [])
- else
- LibraryIndexCommand.new(adapter.options.merge(:path => '')).call(request)
- end
- end
-
- # Routes requests from {#list_prefix} and calls the appropriate command
- # @param (see #route_docs)
- # @return (see #route_docs)
- def route_list(library, paths)
- return if paths.empty?
- ListCommand.new(final_options(library, paths)).call(request)
- end
-
- # Routes requests from {#search_prefix} and calls the appropriate command
- # @param (see #route_docs)
- # @return (see #route_docs)
- def route_search(library, paths)
- return unless paths.empty?
- SearchCommand.new(final_options(library, paths)).call(request)
- end
-
- def route_static(library, paths)
- StaticFileCommand.new(final_options(library, paths)).call(request)
- end
-
- # @group Utility Methods
-
- # Adds extra :library/:path option keys to the adapter options.
- # Use this method when passing options to a command.
- #
- # @param (see #route_docs)
- # @return [Hash] finalized options
- def final_options(library, paths)
- path = File.cleanpath(paths.join('/')).gsub(%r{^(\.\./)+}, '')
- adapter.options.merge(:library => library, :path => path)
- end
- end
- end
-end
+# frozen_string_literal: true
+module YARD
+ module Server
+ # A router class implements the logic used to recognize a request for a specific
+ # URL and run specific {Commands::Base commands}.
+ #
+ # == Subclassing Notes
+ # To create a custom router, subclass this class and pass it into the adapter
+ # options through {Adapter#initialize} or by directly modifying {Adapter#router}.
+ #
+ # The most general customization is to change the URL prefixes recognized by
+ # routing, which can be done by overriding {#docs_prefix}, {#list_prefix},
+ # {#static_prefix}, and {#search_prefix}.
+ #
+ # == Implementing Custom Caching
+ # By default, the Router class performs static disk-based caching on all
+ # requests through the +#check_static_cache+. To override this behaviour,
+ # or create your own caching mechanism, mixin your own custom module with
+ # this method implemented as per {StaticCaching#check_static_cache}.
+ #
+ # @example Creating a subclassed router
+ # # Adds 'my' to all routing prefixes
+ # class MyRouter < YARD::Server::Router
+ # def docs_prefix; 'mydocs' end
+ # def list_prefix; 'mylist' end
+ # def static_prefix; 'mystatic' end
+ # def search_prefix; 'mysearch' end
+ # end
+ #
+ # # Using it:
+ # WebrickAdapter.new(libraries, :router => MyRouter).start
+ class Router
+ include StaticCaching
+ include Commands
+
+ # @return [Adapter Dependent] the request data coming in with the routing
+ attr_accessor :request
+
+ # @return [Adapter] the adapter used by the router
+ attr_accessor :adapter
+
+ # Creates a new router for a specific adapter
+ #
+ # @param [Adapter] adapter the adapter to route requests to
+ def initialize(adapter)
+ self.adapter = adapter
+ end
+
+ # Perform routing on a specific request, serving the request as a static
+ # file through {Commands::RootRequestCommand} if no route is found.
+ #
+ # @param [Adapter Dependent] request the request object
+ # @return [Array(Numeric,Hash,Array)] the Rack-style server response data
+ def call(request)
+ self.request = request
+ result = check_static_cache || route
+ result ? result : RootRequestCommand.new(adapter.options).call(request)
+ end
+
+ # @group Route Prefixes
+
+ # @return [String] the URI prefix for all object documentation requests
+ def docs_prefix; 'docs' end
+
+ # @return [String] the URI prefix for all class/method/file list requests
+ def list_prefix; 'list' end
+
+ # @return [String] the URI prefix for all search requests
+ def search_prefix; 'search' end
+
+ # @return [String] the URI prefix for all static assets (templates)
+ def static_prefix; 'static' end
+
+ # @group Routing Methods
+
+ # @return [Array(LibraryVersion, Array<String>)] the library followed
+ # by the rest of the path components in the request path. LibraryVersion
+ # will be nil if no matching library was found.
+ def parse_library_from_path(paths)
+ return [adapter.libraries.values.first.first, paths] if adapter.options[:single_library]
+ library = nil
+ paths = paths.dup
+ libs = adapter.libraries[paths.first]
+ if libs
+ paths.shift
+ library = libs.find {|l| l.version == paths.first }
+ if library
+ request.version_supplied = true if request
+ paths.shift
+ else # use the last lib in the list
+ request.version_supplied = false if request
+ library = libs.last
+ end
+ end
+ [library, paths]
+ end
+
+ protected
+
+ # Performs routing algorithm to find which prefix is called, first
+ # parsing out library name/version information.
+ #
+ # @return [Array(Numeric,Hash,Array<String>)] the Rack-style response
+ # @return [nil] if no route is matched
+ def route(path = request.path_info)
+ path = path.gsub(%r{//+}, '/').gsub(%r{^/|/$}, '')
+ return route_index if path.empty? || path == docs_prefix
+ case path
+ when %r{^(#{docs_prefix}|#{list_prefix}|#{search_prefix}|#{static_prefix})(/.*|$)}
+ prefix = $1
+ paths = $2.gsub(%r{^/|/$}, '').split('/')
+ library, paths = *parse_library_from_path(paths)
+ return unless library
+ return case prefix
+ when docs_prefix; route_docs(library, paths)
+ when list_prefix; route_list(library, paths)
+ when search_prefix; route_search(library, paths)
+ when static_prefix; route_static(library, paths)
+ end
+ end
+ nil
+ end
+
+ # Routes requests from {#docs_prefix} and calls the appropriate command
+ # @param [LibraryVersion] library the library to route for
+ # @param [Array<String>] paths path components (split by '/')
+ # @return (see #route)
+ def route_docs(library, paths)
+ return route_index if library.nil?
+ case paths.first
+ when "frames"
+ paths.shift
+ cmd = DisplayObjectCommand
+ when "file"
+ paths.shift
+ cmd = DisplayFileCommand
+ else
+ cmd = DisplayObjectCommand
+ end
+ cmd = cmd.new(final_options(library, paths))
+ cmd.call(request)
+ end
+
+ # Routes for the index of a library / multiple libraries
+ # @return (see #route)
+ def route_index
+ if adapter.options[:single_library]
+ route_docs(adapter.libraries.values.first.first, [])
+ else
+ LibraryIndexCommand.new(adapter.options.merge(:path => '')).call(request)
+ end
+ end
+
+ # Routes requests from {#list_prefix} and calls the appropriate command
+ # @param (see #route_docs)
+ # @return (see #route_docs)
+ def route_list(library, paths)
+ return if paths.empty?
+ ListCommand.new(final_options(library, paths)).call(request)
+ end
+
+ # Routes requests from {#search_prefix} and calls the appropriate command
+ # @param (see #route_docs)
+ # @return (see #route_docs)
+ def route_search(library, paths)
+ return unless paths.empty?
+ SearchCommand.new(final_options(library, paths)).call(request)
+ end
+
+ def route_static(library, paths)
+ StaticFileCommand.new(final_options(library, paths)).call(request)
+ end
+
+ # @group Utility Methods
+
+ # Adds extra :library/:path option keys to the adapter options.
+ # Use this method when passing options to a command.
+ #
+ # @param (see #route_docs)
+ # @return [Hash] finalized options
+ def final_options(library, paths)
+ path = File.cleanpath(paths.join('/')).gsub(%r{^(\.\./)+}, '')
+ adapter.options.merge(:library => library, :path => path)
+ end
+ end
+ end
+end