From dcd0f7f07fa4acb25e7c7556335e0fb525600c72 Mon Sep 17 00:00:00 2001 From: eproulx Date: Mon, 8 May 2023 16:41:30 +0200 Subject: [PATCH 1/9] Replace deep_mergeable_hash.rb and deep_symbolize_hash.rb by ActiveSupport functions Use each_with_object instead of each/inject etc ... --- lib/grape.rb | 3 +- lib/grape/content_types.rb | 4 +-- lib/grape/dsl/settings.rb | 8 ++--- lib/grape/endpoint.rb | 7 ++-- lib/grape/exceptions/validation_errors.rb | 7 +--- .../hash_with_indifferent_access.rb | 6 ++-- lib/grape/extensions/deep_mergeable_hash.rb | 21 ------------ lib/grape/extensions/deep_symbolize_hash.rb | 32 ------------------- lib/grape/extensions/hash.rb | 11 +++---- lib/grape/extensions/hashie/mash.rb | 6 ++-- lib/grape/formatter/serializable_hash.rb | 14 ++++---- lib/grape/middleware/versioner/header.rb | 25 ++++++--------- lib/grape/util/lazy_value.rb | 14 ++------ lib/grape/util/strict_hash_configuration.rb | 7 ++-- .../validations/types/custom_type_coercer.rb | 18 ++--------- 15 files changed, 42 insertions(+), 141 deletions(-) delete mode 100644 lib/grape/extensions/deep_mergeable_hash.rb delete mode 100644 lib/grape/extensions/deep_symbolize_hash.rb diff --git a/lib/grape.rb b/lib/grape.rb index f51a2e8b07..db82f5e1aa 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -20,6 +20,7 @@ require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/object/blank' @@ -92,8 +93,6 @@ module Exceptions module Extensions extend ::ActiveSupport::Autoload eager_autoload do - autoload :DeepMergeableHash - autoload :DeepSymbolizeHash autoload :Hash end module ActiveSupport diff --git a/lib/grape/content_types.rb b/lib/grape/content_types.rb index 2c19f97317..322ff6fe0a 100644 --- a/lib/grape/content_types.rb +++ b/lib/grape/content_types.rb @@ -17,9 +17,7 @@ module ContentTypes class << self def content_types_for_settings(settings) - return if settings.blank? - - settings.each_with_object({}) { |value, result| result.merge!(value) } + settings&.inject(:merge!) end def content_types_for(from_settings) diff --git a/lib/grape/dsl/settings.rb b/lib/grape/dsl/settings.rb index e5ffb80904..5c145a4675 100644 --- a/lib/grape/dsl/settings.rb +++ b/lib/grape/dsl/settings.rb @@ -109,13 +109,9 @@ def namespace_reverse_stackable_with_hash(key) settings = get_or_set :namespace_reverse_stackable, key, nil return if settings.blank? - result = {} - settings.each do |setting| - setting.each do |field, value| - result[field] ||= value - end + settings.each_with_object({}) do |setting, result| + result.merge!(setting) { |_k, s1, _s2| s1 } end - result end # (see #unset_global_setting) diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index d0eaee5cd5..0f2fc83d2e 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -171,10 +171,9 @@ def to_routes end def prepare_routes_requirements - endpoint_requirements = options[:route_options][:requirements] || {} - all_requirements = (namespace_stackable(:namespace).map(&:requirements) << endpoint_requirements) - all_requirements.reduce({}) do |base_requirements, single_requirements| - base_requirements.merge!(single_requirements) + {}.merge!(*namespace_stackable(:namespace).map(&:requirements)).tap do |requirements| + endpoint_requirements = options.dig(:route_options, :requirements) + requirements.merge!(endpoint_requirements) if endpoint_requirements end end diff --git a/lib/grape/exceptions/validation_errors.rb b/lib/grape/exceptions/validation_errors.rb index 20f7dd2bfd..23ed6028a6 100644 --- a/lib/grape/exceptions/validation_errors.rb +++ b/lib/grape/exceptions/validation_errors.rb @@ -13,12 +13,7 @@ class ValidationErrors < Grape::Exceptions::Base attr_reader :errors def initialize(errors: [], headers: {}, **_options) - @errors = {} - errors.each do |validation_error| - @errors[validation_error.params] ||= [] - @errors[validation_error.params] << validation_error - end - + @errors = errors.group_by(&:params) super message: full_messages.join(', '), status: 400, headers: headers end diff --git a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb index d412c91dda..19dd0b6606 100644 --- a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +++ b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb @@ -16,9 +16,9 @@ def params_builder end def build_params - params = ::ActiveSupport::HashWithIndifferentAccess.new(rack_params) - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] - params + ::ActiveSupport::HashWithIndifferentAccess.new(rack_params).tap do |params| + params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + end end end end diff --git a/lib/grape/extensions/deep_mergeable_hash.rb b/lib/grape/extensions/deep_mergeable_hash.rb deleted file mode 100644 index 825bbe8922..0000000000 --- a/lib/grape/extensions/deep_mergeable_hash.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Grape - module Extensions - class DeepMergeableHash < ::Hash - def deep_merge!(other_hash) - other_hash.each_pair do |current_key, other_value| - this_value = self[current_key] - - self[current_key] = if this_value.is_a?(::Hash) && other_value.is_a?(::Hash) - this_value.deep_merge(other_value) - else - other_value - end - end - - self - end - end - end -end diff --git a/lib/grape/extensions/deep_symbolize_hash.rb b/lib/grape/extensions/deep_symbolize_hash.rb deleted file mode 100644 index 6c131a97b9..0000000000 --- a/lib/grape/extensions/deep_symbolize_hash.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Grape - module Extensions - module DeepSymbolizeHash - def self.deep_symbolize_keys_in(object) - case object - when ::Hash - object.each_with_object({}) do |(key, value), new_hash| - new_hash[symbolize_key(key)] = deep_symbolize_keys_in(value) - end - when ::Array - object.map { |element| deep_symbolize_keys_in(element) } - else - object - end - end - - def self.symbolize_key(key) - if key.is_a?(Symbol) - key - elsif key.is_a?(String) - key.to_sym - elsif key.respond_to?(:to_sym) - key.to_sym - else - key - end - end - end - end -end diff --git a/lib/grape/extensions/hash.rb b/lib/grape/extensions/hash.rb index 990dddfbcf..e24470134c 100644 --- a/lib/grape/extensions/hash.rb +++ b/lib/grape/extensions/hash.rb @@ -11,13 +11,10 @@ module ParamBuilder end def build_params - params = Grape::Extensions::DeepMergeableHash[rack_params] - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] - post_process_params(params) - end - - def post_process_params(params) - Grape::Extensions::DeepSymbolizeHash.deep_symbolize_keys_in(params) + rack_params.dup.tap do |params| + params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + params.deep_symbolize_keys! + end end end end diff --git a/lib/grape/extensions/hashie/mash.rb b/lib/grape/extensions/hashie/mash.rb index 545e71952e..dfbdb6f315 100644 --- a/lib/grape/extensions/hashie/mash.rb +++ b/lib/grape/extensions/hashie/mash.rb @@ -15,9 +15,9 @@ def params_builder end def build_params - params = ::Hashie::Mash.new(rack_params) - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] - params + ::Hashie::Mash.new(rack_params).tap do |params| + params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + end end end end diff --git a/lib/grape/formatter/serializable_hash.rb b/lib/grape/formatter/serializable_hash.rb index d9c1dad64b..cb9bfb7c14 100644 --- a/lib/grape/formatter/serializable_hash.rb +++ b/lib/grape/formatter/serializable_hash.rb @@ -15,24 +15,24 @@ def call(object, _env) private def serializable?(object) - object.respond_to?(:serializable_hash) || (object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash }) || object.is_a?(Hash) + object.respond_to?(:serializable_hash) || array_serializable?(object) || object.is_a?(Hash) end def serialize(object) if object.respond_to? :serializable_hash object.serializable_hash - elsif object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash } + elsif array_serializable?(object) object.map(&:serializable_hash) elsif object.is_a?(Hash) - h = {} - object.each_pair do |k, v| - h[k] = serialize(v) - end - h + object.transform_values { |v| serialize(v) } else object end end + + def array_serializable?(object) + object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash } + end end end end diff --git a/lib/grape/middleware/versioner/header.rb b/lib/grape/middleware/versioner/header.rb index caba4398c9..cdfe9eca0b 100644 --- a/lib/grape/middleware/versioner/header.rb +++ b/lib/grape/middleware/versioner/header.rb @@ -101,25 +101,18 @@ def fail_with_invalid_version_header!(message) end def available_media_types - available_media_types = [] - - content_types.each_key do |extension| - versions.reverse_each do |version| - available_media_types += [ - "application/vnd.#{vendor}-#{version}+#{extension}", - "application/vnd.#{vendor}-#{version}" - ] + [].tap do|available_media_types| + content_types.each_key do |extension| + versions.reverse_each do |version| + available_media_types << "application/vnd.#{vendor}-#{version}+#{extension}" + available_media_types << "application/vnd.#{vendor}-#{version}" + end + available_media_types << "application/vnd.#{vendor}+#{extension}" end - available_media_types << "application/vnd.#{vendor}+#{extension}" - end - - available_media_types << "application/vnd.#{vendor}" - content_types.each_value do |media_type| - available_media_types << media_type + available_media_types << "application/vnd.#{vendor}" + available_media_types.concat(content_types.values.flatten) end - - available_media_types.flatten end def headers_contain_wrong_vendor? diff --git a/lib/grape/util/lazy_value.rb b/lib/grape/util/lazy_value.rb index af3017e32d..cc732562f9 100644 --- a/lib/grape/util/lazy_value.rb +++ b/lib/grape/util/lazy_value.rb @@ -70,29 +70,21 @@ def initialize(array) end def evaluate - evaluated = [] - @value_hash.each_with_index do |value, index| - evaluated[index] = value.evaluate - end - evaluated + @value_hash.map(&:evaluate) end end class LazyValueHash < LazyValueEnumerable def initialize(hash) super - @value_hash = {}.with_indifferent_access + @value_hash = ActiveSupport::HashWithIndifferentAccess.new hash.each do |key, value| self[key] = value end end def evaluate - evaluated = {}.with_indifferent_access - @value_hash.each do |key, value| - evaluated[key] = value.evaluate - end - evaluated + @value_hash.transform_values(&:evaluate) end end end diff --git a/lib/grape/util/strict_hash_configuration.rb b/lib/grape/util/strict_hash_configuration.rb index 3d096897a7..26a866e8a8 100644 --- a/lib/grape/util/strict_hash_configuration.rb +++ b/lib/grape/util/strict_hash_configuration.rb @@ -66,11 +66,10 @@ def self.nested_settings_methods(setting_name, new_config_class) end define_method :to_hash do - merge_hash = {} - setting_name.each_key { |k| merge_hash[k] = send("#{k}_context").to_hash } - @settings.to_hash.merge( - merge_hash + setting_name.each_key.with_object({}) do |k, merge_hash| + merge_hash[k] = send("#{k}_context").to_hash + end ) end end diff --git a/lib/grape/validations/types/custom_type_coercer.rb b/lib/grape/validations/types/custom_type_coercer.rb index a761ee130b..b0a1e54be4 100644 --- a/lib/grape/validations/types/custom_type_coercer.rb +++ b/lib/grape/validations/types/custom_type_coercer.rb @@ -141,7 +141,7 @@ def enforce_symbolized_keys(type, method) lambda do |val| method.call(val).tap do |new_val| new_val.map do |item| - item.is_a?(Hash) ? symbolize_keys(item) : item + item.is_a?(Hash) ? item.deep_symbolize_keys : item end end end @@ -149,7 +149,7 @@ def enforce_symbolized_keys(type, method) # Hash objects are processed directly elsif type == Hash lambda do |val| - symbolize_keys method.call(val) + method.call(val).deep_symbolize_keys end # Simple types are not processed. @@ -158,20 +158,6 @@ def enforce_symbolized_keys(type, method) method end end - - def symbolize_keys!(hash) - hash.each_key do |key| - hash[key.to_sym] = hash.delete(key) if key.respond_to?(:to_sym) - end - hash - end - - def symbolize_keys(hash) - hash.inject({}) do |new_hash, (key, value)| - new_key = key.respond_to?(:to_sym) ? key.to_sym : key - new_hash.merge!(new_key => value) - end - end end end end From 0686bc0b3992ff145faa275c7b6f54fb18064732 Mon Sep 17 00:00:00 2001 From: eproulx Date: Mon, 8 May 2023 17:16:05 +0200 Subject: [PATCH 2/9] Replace if env[...] by env.key? Use deep_dup instead of dup for rack_params --- lib/grape.rb | 1 + lib/grape/dsl/inside_route.rb | 2 +- lib/grape/error_formatter/base.rb | 2 +- .../extensions/active_support/hash_with_indifferent_access.rb | 2 +- lib/grape/extensions/hash.rb | 4 ++-- lib/grape/extensions/hashie/mash.rb | 2 +- lib/grape/middleware/formatter.rb | 2 +- spec/grape/api_spec.rb | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/grape.rb b/lib/grape.rb index db82f5e1aa..0cf7d80e99 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -17,6 +17,7 @@ require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/hash/conversions' +require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/indifferent_access' diff --git a/lib/grape/dsl/inside_route.rb b/lib/grape/dsl/inside_route.rb index a54967ead3..a2fd74a6d2 100644 --- a/lib/grape/dsl/inside_route.rb +++ b/lib/grape/dsl/inside_route.rb @@ -433,7 +433,7 @@ def entity_class_for_obj(object, options) # the given entity_class. def entity_representation_for(entity_class, object, options) embeds = { env: env } - embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION] + embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION) entity_class.represent(object, **embeds.merge(options)) end end diff --git a/lib/grape/error_formatter/base.rb b/lib/grape/error_formatter/base.rb index f0c802a456..2a1e758eba 100644 --- a/lib/grape/error_formatter/base.rb +++ b/lib/grape/error_formatter/base.rb @@ -27,7 +27,7 @@ def present(message, env) if presenter embeds = { env: env } - embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION] + embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION) presented_message = presenter.represent(presented_message, embeds).serializable_hash end diff --git a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb index 19dd0b6606..2129e1c80a 100644 --- a/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +++ b/lib/grape/extensions/active_support/hash_with_indifferent_access.rb @@ -17,7 +17,7 @@ def params_builder def build_params ::ActiveSupport::HashWithIndifferentAccess.new(rack_params).tap do |params| - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) end end end diff --git a/lib/grape/extensions/hash.rb b/lib/grape/extensions/hash.rb index e24470134c..3ad07b210e 100644 --- a/lib/grape/extensions/hash.rb +++ b/lib/grape/extensions/hash.rb @@ -11,8 +11,8 @@ module ParamBuilder end def build_params - rack_params.dup.tap do |params| - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + rack_params.deep_dup.tap do |params| + params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) params.deep_symbolize_keys! end end diff --git a/lib/grape/extensions/hashie/mash.rb b/lib/grape/extensions/hashie/mash.rb index dfbdb6f315..b6ae5061b1 100644 --- a/lib/grape/extensions/hashie/mash.rb +++ b/lib/grape/extensions/hashie/mash.rb @@ -16,7 +16,7 @@ def params_builder def build_params ::Hashie::Mash.new(rack_params).tap do |params| - params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS] + params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) end end end diff --git a/lib/grape/middleware/formatter.rb b/lib/grape/middleware/formatter.rb index e242cc0e20..06d9a4931d 100644 --- a/lib/grape/middleware/formatter.rb +++ b/lib/grape/middleware/formatter.rb @@ -103,7 +103,7 @@ def read_rack_input(body) begin body = (env[Grape::Env::API_REQUEST_BODY] = parser.call(body, env)) if body.is_a?(Hash) - env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env[Grape::Env::RACK_REQUEST_FORM_HASH] + env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env.key?(Grape::Env::RACK_REQUEST_FORM_HASH) env[Grape::Env::RACK_REQUEST_FORM_HASH].merge(body) else body diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index 008a420260..44dc83153e 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -3311,7 +3311,7 @@ def static it 'is able to cascade' do subject.mount lambda { |env| headers = {} - headers['X-Cascade'] == 'pass' unless env['PATH_INFO'].include?('boo') + headers['X-Cascade'] == 'pass' if env['PATH_INFO'].exclude?('boo') [200, headers, ['Farfegnugen']] } => '/' From 90a2e4c37e0ccbe56f2668e32052cb1504c5767f Mon Sep 17 00:00:00 2001 From: eproulx Date: Mon, 8 May 2023 17:18:10 +0200 Subject: [PATCH 3/9] Use presence instead of ternary Replace unless present? by if blank? --- lib/grape/content_types.rb | 6 +----- lib/grape/exceptions/base.rb | 2 +- lib/grape/middleware/auth/base.rb | 2 +- lib/grape/middleware/versioner/header.rb | 3 +-- lib/grape/validations/validators/base.rb | 2 +- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/grape/content_types.rb b/lib/grape/content_types.rb index 322ff6fe0a..c6f295154a 100644 --- a/lib/grape/content_types.rb +++ b/lib/grape/content_types.rb @@ -21,11 +21,7 @@ def content_types_for_settings(settings) end def content_types_for(from_settings) - if from_settings.present? - from_settings - else - Grape::ContentTypes::CONTENT_TYPES.merge(default_elements) - end + from_settings.presence || Grape::ContentTypes::CONTENT_TYPES.merge(default_elements) end end end diff --git a/lib/grape/exceptions/base.rb b/lib/grape/exceptions/base.rb index 31848a94f4..f03c0a80c2 100644 --- a/lib/grape/exceptions/base.rb +++ b/lib/grape/exceptions/base.rb @@ -73,7 +73,7 @@ def translate(key, **options) options = options.dup options[:default] &&= options[:default].to_s message = ::I18n.translate(key, **options) - message.present? ? message : fallback_message(key, **options) + message.presence || fallback_message(key, **options) end def fallback_message(key, **options) diff --git a/lib/grape/middleware/auth/base.rb b/lib/grape/middleware/auth/base.rb index 081613c920..67a1a53bbf 100644 --- a/lib/grape/middleware/auth/base.rb +++ b/lib/grape/middleware/auth/base.rb @@ -28,7 +28,7 @@ def _call(env) strategy_info = Grape::Middleware::Auth::Strategies[options[:type]] - throw(:error, status: 401, message: 'API Authorization Failed.') unless strategy_info.present? + throw(:error, status: 401, message: 'API Authorization Failed.') if strategy_info.blank? strategy = strategy_info.create(@app, options) do |*args| auth_proc_context.instance_exec(*args, &auth_proc) diff --git a/lib/grape/middleware/versioner/header.rb b/lib/grape/middleware/versioner/header.rb index cdfe9eca0b..4f88278bbd 100644 --- a/lib/grape/middleware/versioner/header.rb +++ b/lib/grape/middleware/versioner/header.rb @@ -57,8 +57,7 @@ def strict_accept_header_presence_check end def strict_version_vendor_accept_header_presence_check - return unless versions.present? - return if an_accept_header_with_version_and_vendor_is_present? + return if versions.blank? || an_accept_header_with_version_and_vendor_is_present? fail_with_invalid_accept_header!('API vendor or version not found.') end diff --git a/lib/grape/validations/validators/base.rb b/lib/grape/validations/validators/base.rb index 2c8403bbc5..86813bf9be 100644 --- a/lib/grape/validations/validators/base.rb +++ b/lib/grape/validations/validators/base.rb @@ -71,7 +71,7 @@ def self.convert_to_short_name(klass) end def self.inherited(klass) - return unless klass.name.present? + return if klass.name.blank? Validations.register_validator(convert_to_short_name(klass), klass) end From beb332f4fa879a742f4f9b057bc3a9dfa79abccc Mon Sep 17 00:00:00 2001 From: eproulx Date: Mon, 8 May 2023 17:20:08 +0200 Subject: [PATCH 4/9] Replace !include? by exclude? --- lib/grape/dsl/inside_route.rb | 2 +- lib/grape/exceptions/base.rb | 2 +- lib/grape/middleware/versioner/header.rb | 2 +- lib/grape/validations/params_scope.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/grape/dsl/inside_route.rb b/lib/grape/dsl/inside_route.rb index a2fd74a6d2..e2ee006c78 100644 --- a/lib/grape/dsl/inside_route.rb +++ b/lib/grape/dsl/inside_route.rb @@ -103,7 +103,7 @@ def handle_passed_param(params_nested_path, has_passed_children = false, &_block if type == 'Hash' && !has_children {} - elsif type == 'Array' || (type&.start_with?('[') && !type&.include?(',')) + elsif type == 'Array' || (type&.start_with?('[') && type&.exclude?(',')) [] elsif type == 'Set' || type&.start_with?('# Date: Tue, 9 May 2023 18:46:48 +0200 Subject: [PATCH 5/9] Use ActiveSupport duplicable? --- lib/grape.rb | 1 + .../validators/default_validator.rb | 22 ++----------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/lib/grape.rb b/lib/grape.rb index 0cf7d80e99..89ec272821 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -25,6 +25,7 @@ require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/hash/slice' require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/duplicable' require 'active_support/dependencies/autoload' require 'active_support/notifications' require 'i18n' diff --git a/lib/grape/validations/validators/default_validator.rb b/lib/grape/validations/validators/default_validator.rb index 8ed5936756..4058d7b1dd 100644 --- a/lib/grape/validations/validators/default_validator.rb +++ b/lib/grape/validations/validators/default_validator.rb @@ -12,10 +12,10 @@ def initialize(attrs, options, required, scope, **opts) def validate_param!(attr_name, params) params[attr_name] = if @default.is_a? Proc @default.call - elsif @default.frozen? || !duplicatable?(@default) + elsif @default.frozen? || !@default.duplicable? @default else - duplicate(@default) + @default.dup end end @@ -27,24 +27,6 @@ def validate!(params) validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil? end end - - private - - # return true if we might be able to dup this object - def duplicatable?(obj) - !obj.nil? && - obj != true && - obj != false && - !obj.is_a?(Symbol) && - !obj.is_a?(Numeric) - end - - # make a best effort to dup the object - def duplicate(obj) - obj.dup - rescue TypeError - obj - end end end end From c7d8310e4aad87e4c23d5a42170695219691fb24 Mon Sep 17 00:00:00 2001 From: eproulx Date: Tue, 9 May 2023 19:04:19 +0200 Subject: [PATCH 6/9] Fix rubocop and update CHANGELOG --- CHANGELOG.md | 1 + lib/grape.rb | 1 - lib/grape/middleware/versioner/header.rb | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d93ea868d..73c356ebe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * [#2310](https://github.com/ruby-grape/grape/pull/2310): Fix YARD docs markdown rendering - [@duffn](https://github.com/duffn). * [#2317](https://github.com/ruby-grape/grape/pull/2317): Remove maruku and rubocop-ast as direct development/testing dependencies - [@ericproulx](https://github.com/ericproulx). * [#2292](https://github.com/ruby-grape/grape/pull/2292): Introduce Docker to local development - [@ericproulx](https://github.com/ericproulx). +* [#2326](https://github.com/ruby-grape/grape/pull/2326): Use ActiveSupport extensions - [@ericproulx](https://github.com/ericproulx). * Your contribution here. #### Fixes diff --git a/lib/grape.rb b/lib/grape.rb index 89ec272821..ed309e16f5 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -17,7 +17,6 @@ require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/array/wrap' require 'active_support/core_ext/hash/conversions' -require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/hash/deep_merge' require 'active_support/core_ext/hash/except' require 'active_support/core_ext/hash/indifferent_access' diff --git a/lib/grape/middleware/versioner/header.rb b/lib/grape/middleware/versioner/header.rb index 991ce27461..785f392e4f 100644 --- a/lib/grape/middleware/versioner/header.rb +++ b/lib/grape/middleware/versioner/header.rb @@ -100,7 +100,7 @@ def fail_with_invalid_version_header!(message) end def available_media_types - [].tap do|available_media_types| + [].tap do |available_media_types| content_types.each_key do |extension| versions.reverse_each do |version| available_media_types << "application/vnd.#{vendor}-#{version}+#{extension}" From be8dc68df33a68055335093ebb08aa92b8c3d3ef Mon Sep 17 00:00:00 2001 From: eproulx Date: Sat, 13 May 2023 14:07:48 +0200 Subject: [PATCH 7/9] Add minimal version for ActiveSupport >=5 --- grape.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grape.gemspec b/grape.gemspec index bee87fbc6a..e79e1c0ed4 100644 --- a/grape.gemspec +++ b/grape.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| 'source_code_uri' => "https://github.com/ruby-grape/grape/tree/v#{s.version}" } - s.add_runtime_dependency 'activesupport' + s.add_runtime_dependency 'activesupport', '>= 5' s.add_runtime_dependency 'builder' s.add_runtime_dependency 'dry-types', '>= 1.1' s.add_runtime_dependency 'mustermann-grape', '~> 1.0.0' From f0b71ad682161cac6fd414560f9fea5cd2419624 Mon Sep 17 00:00:00 2001 From: eproulx Date: Sun, 14 May 2023 17:34:44 +0200 Subject: [PATCH 8/9] Remove extra * in CHANGELOG --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3882e16aaa..ee5cd369ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,6 @@ * [#2325](https://github.com/ruby-grape/grape/pull/2325): Change edge test workflows only run on demand - [@dblock](https://github.com/dblock). * [#2324](https://github.com/ruby-grape/grape/pull/2324): Expose default in the description dsl - [@dhruvCW](https://github.com/dhruvCW). * [#2326](https://github.com/ruby-grape/grape/pull/2326): Use ActiveSupport extensions - [@ericproulx](https://github.com/ericproulx). -* * Your contribution here. #### Fixes From 6408f32096d8c7a1a25207480fa40473ba54388c Mon Sep 17 00:00:00 2001 From: Eric Proulx Date: Mon, 15 May 2023 22:36:01 +0200 Subject: [PATCH 9/9] Next version 1.8.0 --- CHANGELOG.md | 2 +- README.md | 2 +- lib/grape/version.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30ed1bce5e..b862edf6a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.2 (Next) +### 1.8.0 (Next) #### Features diff --git a/README.md b/README.md index 8ff988925d..a334a72a88 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ content negotiation, versioning and much more. ## Stable Release -You're reading the documentation for the next release of Grape, which should be **1.7.2**. +You're reading the documentation for the next release of Grape, which should be **1.8.0**. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. The current stable release is [1.7.1](https://github.com/ruby-grape/grape/blob/v1.7.1/README.md). diff --git a/lib/grape/version.rb b/lib/grape/version.rb index 6b84a9611f..64b7c47854 100644 --- a/lib/grape/version.rb +++ b/lib/grape/version.rb @@ -2,5 +2,5 @@ module Grape # The current version of Grape. - VERSION = '1.7.2' + VERSION = '1.8.0' end