diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d02d5998..5054c1dac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * [#2089](https://github.com/ruby-grape/grape/pull/2089): Specify order of mounting Grape with Rack::Cascade in README - [@jonmchan](https://github.com/jonmchan). * [#2083](https://github.com/ruby-grape/grape/pull/2083): Set `Cache-Control` header only for streamed responses - [@stanhu](https://github.com/stanhu). * [#2092](https://github.com/ruby-grape/grape/pull/2092): Correct an example params in Include Missing doc - [@huyvohcmc](https://github.com/huyvohcmc). +* [#2091](https://github.com/ruby-grape/grape/pull/2091): Fix ruby 2.7 keyword deprecations - [@dim](https://github.com/dim). ### 1.4.0 (2020/07/10) diff --git a/lib/grape/api.rb b/lib/grape/api.rb index 507b221871..45dd76c74d 100644 --- a/lib/grape/api.rb +++ b/lib/grape/api.rb @@ -90,7 +90,7 @@ def const_missing(*args) # For instance, a descripcion could be done using: `desc configuration[:description]` if it may vary # depending on where the endpoint is mounted. Use with care, if you find yourself using configuration # too much, you may actually want to provide a new API rather than remount it. - def mount_instance(opts = {}) + def mount_instance(**opts) instance = Class.new(@base_parent) instance.configuration = Grape::Util::EndpointConfiguration.new(opts[:configuration] || {}) instance.base = self diff --git a/lib/grape/dsl/routing.rb b/lib/grape/dsl/routing.rb index b2f955cc0a..76a22a79f0 100644 --- a/lib/grape/dsl/routing.rb +++ b/lib/grape/dsl/routing.rb @@ -79,7 +79,7 @@ def do_not_route_options! namespace_inheritable(:do_not_route_options, true) end - def mount(mounts, opts = {}) + def mount(mounts, **opts) mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair) mounts.each_pair do |app, path| if app.respond_to?(:mount_instance) @@ -170,9 +170,7 @@ def namespace(space = nil, options = {}, &block) previous_namespace_description = @namespace_description @namespace_description = (@namespace_description || {}).deep_merge(namespace_setting(:description) || {}) nest(block) do - if space - namespace_stackable(:namespace, Namespace.new(space, **options)) - end + namespace_stackable(:namespace, Namespace.new(space, **options)) if space end @namespace_description = previous_namespace_description end diff --git a/lib/grape/middleware/base.rb b/lib/grape/middleware/base.rb index 2b5657e734..e21a94e9e9 100644 --- a/lib/grape/middleware/base.rb +++ b/lib/grape/middleware/base.rb @@ -14,7 +14,7 @@ class Base # @param [Rack Application] app The standard argument for a Rack middleware. # @param [Hash] options A hash of options, simply stored for use by subclasses. - def initialize(app, options = {}) + def initialize(app, **options) @app = app @options = default_options.merge(options) @app_response = nil diff --git a/lib/grape/middleware/error.rb b/lib/grape/middleware/error.rb index 6d816f14f3..54bded3c87 100644 --- a/lib/grape/middleware/error.rb +++ b/lib/grape/middleware/error.rb @@ -19,11 +19,11 @@ def default_options rescue_subclasses: true, # rescue subclasses of exceptions listed rescue_options: { backtrace: false, # true to display backtrace, true to let Grape handle Grape::Exceptions - original_exception: false, # true to display exception + original_exception: false # true to display exception }, rescue_handlers: {}, # rescue handler blocks base_only_rescue_handlers: {}, # rescue handler blocks rescuing only the base class - all_rescue_handler: nil, # rescue handler block to rescue from all exceptions + all_rescue_handler: nil # rescue handler block to rescue from all exceptions } end @@ -38,15 +38,15 @@ def call!(env) error_response(catch(:error) do return @app.call(@env) end) - rescue Exception => error # rubocop:disable Lint/RescueException + rescue Exception => e # rubocop:disable Lint/RescueException handler = - rescue_handler_for_base_only_class(error.class) || - rescue_handler_for_class_or_its_ancestor(error.class) || - rescue_handler_for_grape_exception(error.class) || - rescue_handler_for_any_class(error.class) || + rescue_handler_for_base_only_class(e.class) || + rescue_handler_for_class_or_its_ancestor(e.class) || + rescue_handler_for_grape_exception(e.class) || + rescue_handler_for_any_class(e.class) || raise - run_rescue_handler(handler, error) + run_rescue_handler(handler, e) end end @@ -65,15 +65,13 @@ def error_response(error = {}) message = error[:message] || options[:default_message] headers = { Grape::Http::Headers::CONTENT_TYPE => content_type } headers.merge!(error[:headers]) if error[:headers].is_a?(Hash) - backtrace = error[:backtrace] || error[:original_exception] && error[:original_exception].backtrace || [] + backtrace = error[:backtrace] || error[:original_exception]&.backtrace || [] original_exception = error.is_a?(Exception) ? error : error[:original_exception] || nil rack_response(format_message(message, backtrace, original_exception), status, headers) end def rack_response(message, status = options[:default_status], headers = { Grape::Http::Headers::CONTENT_TYPE => content_type }) - if headers[Grape::Http::Headers::CONTENT_TYPE] == TEXT_HTML - message = ERB::Util.html_escape(message) - end + message = ERB::Util.html_escape(message) if headers[Grape::Http::Headers::CONTENT_TYPE] == TEXT_HTML Rack::Response.new([message], status, headers) end diff --git a/lib/grape/middleware/stack.rb b/lib/grape/middleware/stack.rb index 488a514985..b725e87874 100644 --- a/lib/grape/middleware/stack.rb +++ b/lib/grape/middleware/stack.rb @@ -6,11 +6,12 @@ module Middleware # It allows to insert and insert after class Stack class Middleware - attr_reader :args, :block, :klass + attr_reader :args, :opts, :block, :klass - def initialize(klass, *args, &block) + def initialize(klass, *args, **opts, &block) @klass = klass - @args = args + @args = args + @opts = opts @block = block end @@ -30,6 +31,18 @@ def ==(other) def inspect klass.to_s end + + if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7') + def use_in(builder) + block ? builder.use(klass, *args, **opts, &block) : builder.use(klass, *args, **opts) + end + else + def use_in(builder) + args = self.args + args += [opts] unless opts.empty? + block ? builder.use(klass, *args, &block) : builder.use(klass, *args) + end + end end include Enumerable @@ -90,7 +103,7 @@ def merge_with(middleware_specs) def build(builder = Rack::Builder.new) others.shift(others.size).each(&method(:merge_with)) middlewares.each do |m| - m.block ? builder.use(m.klass, *m.args, &m.block) : builder.use(m.klass, *m.args) + m.use_in(builder) end builder end diff --git a/lib/grape/request.rb b/lib/grape/request.rb index 62a6cd3144..b547797482 100644 --- a/lib/grape/request.rb +++ b/lib/grape/request.rb @@ -8,7 +8,7 @@ class Request < Rack::Request alias rack_params params - def initialize(env, options = {}) + def initialize(env, **options) extend options[:build_params_with] || Grape.config.param_builder super(env) end diff --git a/lib/grape/router.rb b/lib/grape/router.rb index c5d9e96422..8c5dce872d 100644 --- a/lib/grape/router.rb +++ b/lib/grape/router.rb @@ -47,7 +47,7 @@ def append(route) def associate_routes(pattern, **options) @neutral_regexes << Regexp.new("(?<_#{@neutral_map.length}>)#{pattern.to_regexp}") - @neutral_map << Grape::Router::AttributeTranslator.new(options.merge(pattern: pattern, index: @neutral_map.length)) + @neutral_map << Grape::Router::AttributeTranslator.new(**options, pattern: pattern, index: @neutral_map.length) end def call(env) diff --git a/lib/grape/router/attribute_translator.rb b/lib/grape/router/attribute_translator.rb index 93d112fcb4..88003887c6 100644 --- a/lib/grape/router/attribute_translator.rb +++ b/lib/grape/router/attribute_translator.rb @@ -23,7 +23,7 @@ class AttributeTranslator ROUTER_ATTRIBUTES = %i[pattern index].freeze - def initialize(attributes = {}) + def initialize(**attributes) @attributes = attributes end @@ -37,7 +37,7 @@ def to_h attributes end - def method_missing(method_name, *args) # rubocop:disable Style/MethodMissing + def method_missing(method_name, *args) if setter?(method_name[-1]) attributes[method_name[0..-1]] = *args else diff --git a/lib/grape/util/base_inheritable.rb b/lib/grape/util/base_inheritable.rb index d5c86beeda..5db6e3455d 100644 --- a/lib/grape/util/base_inheritable.rb +++ b/lib/grape/util/base_inheritable.rb @@ -9,8 +9,8 @@ class BaseInheritable # @param inherited_values [Object] An object implementing an interface # of the Hash class. - def initialize(inherited_values = {}) - @inherited_values = inherited_values + def initialize(inherited_values = nil) + @inherited_values = inherited_values || {} @new_values = {} end diff --git a/lib/grape/validations/validators/as.rb b/lib/grape/validations/validators/as.rb index 07ac8006d3..77cef5f1cc 100644 --- a/lib/grape/validations/validators/as.rb +++ b/lib/grape/validations/validators/as.rb @@ -3,7 +3,7 @@ module Grape module Validations class AsValidator < Base - def initialize(attrs, options, required, scope, opts = {}) + def initialize(attrs, options, required, scope, **opts) @renamed_options = options super end diff --git a/lib/grape/validations/validators/base.rb b/lib/grape/validations/validators/base.rb index 034a66e5a0..4799f49238 100644 --- a/lib/grape/validations/validators/base.rb +++ b/lib/grape/validations/validators/base.rb @@ -13,7 +13,7 @@ class Base # @param required [Boolean] attribute(s) are required or optional # @param scope [ParamsScope] parent scope for this Validator # @param opts [Hash] additional validation options - def initialize(attrs, options, required, scope, opts = {}) + def initialize(attrs, options, required, scope, **opts) @attrs = Array(attrs) @option = options @required = required @@ -47,9 +47,7 @@ def validate!(params) next if !@scope.required? && empty_val next unless @scope.meets_dependency?(val, params) begin - if @required || val.respond_to?(:key?) && val.key?(attr_name) - validate_param!(attr_name, val) - end + validate_param!(attr_name, val) if @required || val.respond_to?(:key?) && val.key?(attr_name) rescue Grape::Exceptions::Validation => e array_errors << e end diff --git a/lib/grape/validations/validators/default.rb b/lib/grape/validations/validators/default.rb index ee620db460..79d6951f37 100644 --- a/lib/grape/validations/validators/default.rb +++ b/lib/grape/validations/validators/default.rb @@ -3,7 +3,7 @@ module Grape module Validations class DefaultValidator < Base - def initialize(attrs, options, required, scope, opts = {}) + def initialize(attrs, options, required, scope, **opts) @default = options super end @@ -21,9 +21,7 @@ def validate_param!(attr_name, params) def validate!(params) attrs = SingleAttributeIterator.new(self, @scope, params) attrs.each do |resource_params, attr_name| - if resource_params.is_a?(Hash) && resource_params[attr_name].nil? - validate_param!(attr_name, resource_params) - end + validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil? end end diff --git a/lib/grape/validations/validators/except_values.rb b/lib/grape/validations/validators/except_values.rb index 4ef94e97a0..5ba1e306b3 100644 --- a/lib/grape/validations/validators/except_values.rb +++ b/lib/grape/validations/validators/except_values.rb @@ -3,7 +3,7 @@ module Grape module Validations class ExceptValuesValidator < Base - def initialize(attrs, options, required, scope, opts = {}) + def initialize(attrs, options, required, scope, **opts) @except = options.is_a?(Hash) ? options[:value] : options super end diff --git a/lib/grape/validations/validators/values.rb b/lib/grape/validations/validators/values.rb index 7889f3badc..f3d676d0b5 100644 --- a/lib/grape/validations/validators/values.rb +++ b/lib/grape/validations/validators/values.rb @@ -3,7 +3,7 @@ module Grape module Validations class ValuesValidator < Base - def initialize(attrs, options, required, scope, opts = {}) + def initialize(attrs, options, required, scope, **opts) if options.is_a?(Hash) @excepts = options[:except] @values = options[:value] diff --git a/spec/grape/middleware/error_spec.rb b/spec/grape/middleware/error_spec.rb index 66901292bf..d586b98204 100644 --- a/spec/grape/middleware/error_spec.rb +++ b/spec/grape/middleware/error_spec.rb @@ -30,7 +30,7 @@ def app opts = options Rack::Builder.app do use Spec::Support::EndpointFaker - use Grape::Middleware::Error, opts + use Grape::Middleware::Error, **opts run ErrorSpec::ErrApp end end diff --git a/spec/grape/middleware/stack_spec.rb b/spec/grape/middleware/stack_spec.rb index e408ef9e89..3833337e47 100644 --- a/spec/grape/middleware/stack_spec.rb +++ b/spec/grape/middleware/stack_spec.rb @@ -34,7 +34,8 @@ def initialize(&block) expect { subject.use StackSpec::BarMiddleware, false, my_arg: 42 } .to change { subject.size }.by(1) expect(subject.last).to eq(StackSpec::BarMiddleware) - expect(subject.last.args).to eq([false, { my_arg: 42 }]) + expect(subject.last.args).to eq([false]) + expect(subject.last.opts).to eq(my_arg: 42) end it 'pushes a middleware class with block arguments onto the stack' do diff --git a/spec/support/versioned_helpers.rb b/spec/support/versioned_helpers.rb index f3055c6e52..8d7c07f184 100644 --- a/spec/support/versioned_helpers.rb +++ b/spec/support/versioned_helpers.rb @@ -6,7 +6,7 @@ module Support module Helpers # Returns the path with options[:version] prefixed if options[:using] is :path. # Returns normal path otherwise. - def versioned_path(options = {}) + def versioned_path(**options) case options[:using] when :path File.join('/', options[:prefix] || '', options[:version], options[:path]) @@ -43,13 +43,11 @@ def versioned_headers(**options) end end - def versioned_get(path, version_name, version_options = {}) + def versioned_get(path, version_name, **version_options) path = versioned_path(version_options.merge(version: version_name, path: path)) headers = versioned_headers(**version_options.merge(version: version_name)) params = {} - if version_options[:using] == :param - params = { version_options[:parameter] => version_name } - end + params = { version_options[:parameter] => version_name } if version_options[:using] == :param get path, params, headers end end