lib/roda.rb in roda-2.29.0 vs lib/roda.rb in roda-3.0.0

- old
+ new

@@ -1,10 +1,10 @@ # frozen-string-literal: true require "rack" require "thread" -require "roda/version" +require_relative "roda/version" # The main class for Roda. Roda is built completely out of plugins, with the # default plugin being Roda::RodaPlugins::Base, so this class is mostly empty # except for some constants. class Roda @@ -100,13 +100,15 @@ end # Deprecate the constant with the given name in the given module, # if the ruby version supports it. def self.deprecate_constant(mod, name) + # :nocov: if RUBY_VERSION >= '2.3' mod.deprecate_constant(name) end + # :nocov: end # The base plugin for Roda, implementing all default functionality. # Methods are put into a plugin so future plugins can easily override # them and call super to get the default behavior. @@ -175,11 +177,11 @@ subclass.instance_variable_set(:@route_block, @route_block) subclass.send(:build_rack_app) request_class = Class.new(self::RodaRequest) request_class.roda_class = subclass - request_class.match_pattern_cache = thread_safe_cache + request_class.match_pattern_cache = RodaCache.new subclass.const_set(:RodaRequest, request_class) response_class = Class.new(self::RodaResponse) response_class.roda_class = subclass subclass.const_set(:RodaResponse, response_class) @@ -221,20 +223,21 @@ def route(&block) @route_block = block build_rack_app end - # A new thread safe cache instance. This is a method so it can be - # easily overridden for alternative implementations. def thread_safe_cache + # :nocov: + RodaPlugins.warn "Roda.thread_safe_cache is deprecated and will be removed from Roda 3.1." RodaCache.new + # :nocov: end # Add a middleware to use for the rack application. Must be # called before calling #route to have an effect. Example: # - # Roda.use Rack::Session::Cookie, :secret=>ENV['secret'] + # Roda.use Rack::Session::Cookie, secret: ENV['secret'] def use(*args, &block) @middleware << [args, block].freeze build_rack_app end @@ -355,31 +358,10 @@ end # Instance methods for RodaRequest, mostly related to handling routing # for the request. module RequestMethods - PATH_INFO = "PATH_INFO".freeze - RodaPlugins.deprecate_constant(self, :PATH_INFO) - SCRIPT_NAME = "SCRIPT_NAME".freeze - RodaPlugins.deprecate_constant(self, :SCRIPT_NAME) - REQUEST_METHOD = "REQUEST_METHOD".freeze - RodaPlugins.deprecate_constant(self, :REQUEST_METHOD) - EMPTY_STRING = "".freeze - RodaPlugins.deprecate_constant(self, :EMPTY_STRING) - SLASH = "/".freeze - RodaPlugins.deprecate_constant(self, :SLASH) - COLON = ":".freeze - RodaPlugins.deprecate_constant(self, :COLON) - SEGMENT = "([^\\/]+)".freeze - RodaPlugins.deprecate_constant(self, :SEGMENT) - TERM_INSPECT = "TERM".freeze - RodaPlugins.deprecate_constant(self, :TERM_INSPECT) - GET_REQUEST_METHOD = 'GET'.freeze - RodaPlugins.deprecate_constant(self, :GET_REQUEST_METHOD) - SESSION_KEY = 'rack.session'.freeze - RodaPlugins.deprecate_constant(self, :SESSION_KEY) - TERM = Object.new def TERM.inspect "TERM" end TERM.freeze @@ -609,11 +591,11 @@ # Return the Roda class related to this request. def roda_class self.class.roda_class end - # Routing matches that only matches +GET+ requests where the current + # Match method that only matches +GET+ requests where the current # path is +/+. If it matches, the match block is executed, and when # the match block returns, the rack response is returned. # # [r.request_method, r.remaining_path] # # => ['GET', '/'] @@ -720,18 +702,20 @@ # Integer :: Match an integer segment, yielding result to block as an integer # String :: Match any non-empty segment, yielding result to block as a string def _match_class(klass) meth = :"_match_class_#{klass}" if respond_to?(meth, true) + # Allow calling private methods, as match methods are generally private send(meth) else unsupported_matcher(klass) end end # Match the given hash if all hash matchers match. def _match_hash(hash) + # Allow calling private methods, as match methods are generally private hash.all?{|k,v| send("match_#{k}", v)} end # Match integer segment, and yield resulting value as an # integer. @@ -747,39 +731,18 @@ # Match the given string to the request path. Regexp escapes the # string so that regexp metacharacters are not matched, and recognizes # colon tokens for placeholders. def _match_string(str) - if str.index(":") && placeholder_string_matcher? - # RODA3: Remove - not_warned = true - consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/) do |m| - match = $1 - if not_warned - nor_warned = false - RodaPlugins.warn("Placeholder symbol matchers are deprecated by default and will be removed in Roda 3 (matcher used: #{str.inspect}). Use the placeholder_symbol_matchers plugin or split the string and use separate symbol matchers or String class matchers for the placeholders") - end - _match_symbol_regexp(match) - end}) - else - rp = @remaining_path - if rp.start_with?("/#{str}") - last = str.length + 1 - case rp[last] - when "/" - @remaining_path = rp[last, rp.length] - when nil - @remaining_path = "" - when Integer - # :nocov: - # RODA3: Remove - # Ruby 1.8 support - if rp[last].chr == "/" - @remaining_path = rp[last, rp.length] - end - # :nocov: - end + rp = @remaining_path + if rp.start_with?("/#{str}") + last = str.length + 1 + case rp[last] + when "/" + @remaining_path = rp[last, rp.length] + when nil + @remaining_path = "" end end end # Match the given symbol if any segment matches. @@ -799,15 +762,10 @@ end # Match any nonempty segment. This should be called without an argument. alias _match_class_String _match_symbol - # RODA3: Remove - def _match_symbol_regexp(s) - "([^\\/]+)" - end - # The base remaining path to use. def _remaining_path(env) env["PATH_INFO"] end @@ -836,15 +794,11 @@ when String result when nil, false # nothing else - if roda_class.opts[:unsupported_block_result] == :raise - raise RodaError, "unsupported block result: #{result.inspect}" - else - RodaPlugins.warn("Unsupported match block return result: #{result.inspect}. This is currently ignored, but will raise an error in Roda 3. Have the block return nil or false to ignore the result.") - end + raise RodaError, "unsupported block result: #{result.inspect}" end end # Attempts to match the pattern to the current path. If there is no # match, returns false without changes. Otherwise, modifies @@ -944,20 +898,19 @@ end # Whether string matchers are used verbatim, without handling # placeholders via colons. def placeholder_string_matcher? - !roda_class.opts[:verbatim_string_matcher] + # :nocov: + RodaPlugins.warn "Roda::RodaRequest.placeholder_string_matcher? is deprecated and will be removed from Roda 3.1." + false + # :nocov: end # Handle an unsupported matcher. def unsupported_matcher(matcher) - if roda_class.opts[:unsupported_matcher] == :raise - raise RodaError, "unsupported matcher: #{matcher.inspect}" - end - RodaPlugins.warn("Unsupported matcher used: #{matcher.inspect}. This currently always matches, but will raise an error in Roda 3. Switch to using true if you want the matcher to always match.") - matcher + raise RodaError, "unsupported matcher: #{matcher.inspect}" end end # Class methods for RodaResponse module ResponseClassMethods @@ -973,16 +926,9 @@ end # Instance methods for RodaResponse module ResponseMethods DEFAULT_HEADERS = {"Content-Type" => "text/html".freeze}.freeze - - CONTENT_LENGTH = "Content-Length".freeze - RodaPlugins.deprecate_constant(self, :CONTENT_LENGTH) - CONTENT_TYPE = "Content-Type".freeze - RodaPlugins.deprecate_constant(self, :CONTENT_TYPE) - LOCATION = "Location".freeze - RodaPlugins.deprecate_constant(self, :LOCATION) # The body for the current response. attr_reader :body # The hash of response headers for the current response.