Skip to content

Commit f859682

Browse files
author
Dieter Späth
committed
refactoring settings
1 parent 4566111 commit f859682

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1348
-546
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ platforms :rbx do
1414
gem 'rubinius-developer_tools'
1515
gem 'racc'
1616
end
17+

lib/grape.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require 'hashie'
99
require 'set'
1010
require 'active_support/core_ext/hash/indifferent_access'
11+
require 'active_support/core_ext/object/deep_dup'
1112
require 'active_support/ordered_hash'
1213
require 'active_support/core_ext/object/conversions'
1314
require 'active_support/core_ext/array/extract_options'
@@ -92,11 +93,16 @@ module Versioner
9293
end
9394

9495
module Util
95-
autoload :HashStack, 'grape/util/hash_stack'
96+
autoload :LoggingValue, 'grape/util/logging_value'
97+
autoload :InheritableValues, 'grape/util/inheritable_values'
98+
autoload :StackableValues, 'grape/util/stackable_values'
99+
autoload :InheritableSetting, 'grape/util/inheritable_setting'
96100
end
97101

98102
module DSL
103+
autoload :API, 'grape/dsl/api'
99104
autoload :Callbacks, 'grape/dsl/callbacks'
105+
autoload :Settings, 'grape/dsl/settings'
100106
autoload :Configuration, 'grape/dsl/configuration'
101107
autoload :InsideRoute, 'grape/dsl/inside_route'
102108
autoload :Helpers, 'grape/dsl/helpers'

lib/grape/api.rb

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,13 @@ module Grape
33
# creating Grape APIs.Users should subclass this
44
# class in order to build an API.
55
class API
6-
extend Grape::Middleware::Auth::DSL
7-
8-
include Grape::DSL::Validations
9-
include Grape::DSL::Callbacks
10-
include Grape::DSL::Configuration
11-
include Grape::DSL::Helpers
12-
include Grape::DSL::Middleware
13-
include Grape::DSL::RequestResponse
14-
include Grape::DSL::Routing
6+
include Grape::DSL::API
157

168
class << self
179
attr_reader :instance
18-
1910
LOCK = Mutex.new
2011

2112
def reset!
22-
@settings = Grape::Util::HashStack.new
2313
@route_set = Rack::Mount::RouteSet.new
2414
@endpoints = []
2515
@routes = nil
@@ -47,34 +37,19 @@ def call!(env)
4737
#
4838
# @param name [Symbol] Purely placebo, just allows to to name the scope to make the code more readable.
4939
def scope(name = nil, &block)
50-
nest(block)
40+
within_namespace do
41+
nest(block)
42+
end
5143
end
5244

5345
def cascade(value = nil)
5446
if value.nil?
55-
settings.key?(:cascade) ? !!settings[:cascade] : true
47+
inheritable_setting.namespace_inheritable.keys.include?(:cascade) ? !!namespace_inheritable(:cascade) : true
5648
else
57-
set(:cascade, value)
49+
namespace_inheritable(:cascade, value)
5850
end
5951
end
6052

61-
# Set a configuration value for this namespace.
62-
#
63-
# @param key [Symbol] The key of the configuration variable.
64-
# @param value [Object] The value to which to set the configuration variable.
65-
def set(key, value)
66-
settings[key.to_sym] = value
67-
end
68-
69-
# Add to a configuration value for this
70-
# namespace.
71-
#
72-
# @param key [Symbol] The key of the configuration variable.
73-
# @param value [Object] The value to which to set the configuration variable.
74-
def imbue(key, value)
75-
settings.imbue(key, value)
76-
end
77-
7853
protected
7954

8055
def prepare_routes
@@ -91,10 +66,8 @@ def prepare_routes
9166
def nest(*blocks, &block)
9267
blocks.reject! { |b| b.nil? }
9368
if blocks.any?
94-
settings.push # create a new context to eval the follow
9569
instance_eval(&block) if block_given?
9670
blocks.each { |b| instance_eval(&b) }
97-
settings.pop # when finished, we pop the context
9871
reset_validations!
9972
else
10073
instance_eval(&block)
@@ -106,12 +79,14 @@ def inherited(subclass)
10679
subclass.logger = logger.clone
10780
end
10881

109-
def inherit_settings(other_stack)
110-
settings.prepend other_stack
82+
def inherit_settings(other_settings)
83+
top_level_setting.inherit_from other_settings.point_in_time_copy
84+
11185
endpoints.each do |e|
112-
e.settings.prepend(other_stack)
113-
e.options[:app].inherit_settings(other_stack) if e.options[:app].respond_to?(:inherit_settings, true)
86+
e.reset_routes!
11487
end
88+
89+
@routes = nil
11590
end
11691
end
11792

@@ -121,6 +96,7 @@ def initialize
12196
self.class.endpoints.each do |endpoint|
12297
endpoint.mount_in(@route_set)
12398
end
99+
124100
@route_set.freeze
125101
end
126102

@@ -139,8 +115,8 @@ def call(env)
139115
# errors from reaching upstream. This is effectivelly done by unsetting
140116
# X-Cascade. Default :cascade is true.
141117
def cascade?
142-
return !!self.class.settings[:cascade] if self.class.settings.key?(:cascade)
143-
return !!self.class.settings[:version_options][:cascade] if self.class.settings[:version_options] && self.class.settings[:version_options].key?(:cascade)
118+
return !!self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.keys.include?(:cascade)
119+
return !!self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options) && self.class.namespace_inheritable(:version_options).key?(:cascade)
144120
true
145121
end
146122

@@ -154,6 +130,7 @@ def cascade?
154130
# cannot handle.
155131
def add_head_not_allowed_methods_and_options_methods
156132
methods_per_path = {}
133+
157134
self.class.endpoints.each do |endpoint|
158135
routes = endpoint.routes
159136
routes.each do |route|
@@ -169,13 +146,14 @@ def add_head_not_allowed_methods_and_options_methods
169146
without_versioning do
170147
methods_per_path.each do |path, methods|
171148
allowed_methods = methods.dup
172-
unless self.class.settings[:do_not_route_head]
149+
unless self.class.namespace_inheritable(:do_not_route_head)
173150
allowed_methods |= ['HEAD'] if allowed_methods.include?('GET')
174151
end
175152

176153
allow_header = (['OPTIONS'] | allowed_methods).join(', ')
177-
unless self.class.settings[:do_not_route_options]
154+
unless self.class.namespace_inheritable(:do_not_route_options)
178155
unless allowed_methods.include?('OPTIONS')
156+
# require 'pry-byebug'; binding.pry
179157
self.class.options(path, {}) do
180158
header 'Allow', allow_header
181159
status 204
@@ -185,7 +163,7 @@ def add_head_not_allowed_methods_and_options_methods
185163
end
186164

187165
not_allowed_methods = %w(GET PUT POST DELETE PATCH HEAD) - allowed_methods
188-
not_allowed_methods << 'OPTIONS' if self.class.settings[:do_not_route_options]
166+
not_allowed_methods << 'OPTIONS' if self.class.namespace_inheritable(:do_not_route_options)
189167
self.class.route(not_allowed_methods, path) do
190168
header 'Allow', allow_header
191169
status 405
@@ -196,9 +174,16 @@ def add_head_not_allowed_methods_and_options_methods
196174
end
197175

198176
def without_versioning(&block)
199-
self.class.settings.push(version: nil, version_options: nil)
177+
old_version = self.class.namespace_inheritable(:version)
178+
old_version_options = self.class.namespace_inheritable(:version_options)
179+
180+
self.class.namespace_inheritable_to_nil(:version)
181+
self.class.namespace_inheritable_to_nil(:version_options)
182+
200183
yield
201-
self.class.settings.pop
184+
185+
self.class.namespace_inheritable(:version, old_version)
186+
self.class.namespace_inheritable(:version_options, old_version_options)
202187
end
203188
end
204189
end

lib/grape/dsl/api.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'active_support/concern'
2+
3+
module Grape
4+
module DSL
5+
module API
6+
extend ActiveSupport::Concern
7+
8+
include Grape::Middleware::Auth::DSL
9+
10+
include Grape::DSL::Validations
11+
include Grape::DSL::Callbacks
12+
include Grape::DSL::Configuration
13+
include Grape::DSL::Helpers
14+
include Grape::DSL::Middleware
15+
include Grape::DSL::RequestResponse
16+
include Grape::DSL::Routing
17+
end
18+
end
19+
end

lib/grape/dsl/callbacks.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@ module DSL
55
module Callbacks
66
extend ActiveSupport::Concern
77

8+
include Grape::DSL::Configuration
9+
810
module ClassMethods
911
def before(&block)
10-
imbue(:befores, [block])
12+
namespace_stackable(:befores, block)
1113
end
1214

1315
def before_validation(&block)
14-
imbue(:before_validations, [block])
16+
namespace_stackable(:before_validations, block)
1517
end
1618

1719
def after_validation(&block)
18-
imbue(:after_validations, [block])
20+
namespace_stackable(:after_validations, block)
1921
end
2022

2123
def after(&block)
22-
imbue(:afters, [block])
24+
namespace_stackable(:afters, block)
2325
end
2426
end
2527
end

lib/grape/dsl/configuration.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,33 @@ module Configuration
77

88
module ClassMethods
99
attr_writer :logger
10-
attr_reader :settings
10+
# attr_reader :settings
11+
12+
include Grape::DSL::Settings
1113

1214
def logger(logger = nil)
1315
if logger
14-
@logger = logger
16+
global_setting(:logger, logger)
1517
else
16-
@logger ||= Logger.new($stdout)
18+
global_setting(:logger, Logger.new($stdout)) unless global_setting(:logger)
19+
global_setting(:logger)
1720
end
1821
end
1922

2023
# Add a description to the next namespace or function.
2124
def desc(description, options = {})
22-
@last_description = options.merge(description: description)
25+
namespace_setting :description, options.merge(description: description)
26+
route_setting :description, options.merge(description: description)
2327
end
2428
end
29+
30+
module_function
31+
32+
def stacked_hash_to_hash(settings)
33+
return nil if settings.nil? || settings.blank?
34+
35+
settings.each_with_object(ActiveSupport::OrderedHash.new) { |(value), result| result.deep_merge!(value) }
36+
end
2537
end
2638
end
2739
end

lib/grape/dsl/helpers.rb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Grape
44
module DSL
55
module Helpers
66
extend ActiveSupport::Concern
7+
include Grape::DSL::Configuration
78

89
module ClassMethods
910
# Add helper methods that will be accessible from any
@@ -27,23 +28,21 @@ module ClassMethods
2728
#
2829
def helpers(new_mod = nil, &block)
2930
if block_given? || new_mod
30-
mod = settings.peek[:helpers] || Module.new
31+
mod = new_mod || Module.new
3132
if new_mod
3233
inject_api_helpers_to_mod(new_mod) if new_mod.is_a?(BaseHelper)
33-
mod.class_eval do
34-
include new_mod
35-
end
3634
end
3735
if block_given?
3836
inject_api_helpers_to_mod(mod) do
3937
mod.class_eval(&block)
4038
end
4139
end
42-
set(:helpers, mod)
40+
41+
namespace_stackable(:helpers, mod)
4342
else
4443
mod = Module.new
45-
settings.stack.each do |s|
46-
mod.send :include, s[:helpers] if s[:helpers]
44+
namespace_stackable(:helpers).each do |mod_to_include|
45+
mod.send :include, mod_to_include
4746
end
4847
change!
4948
mod
@@ -77,7 +76,7 @@ def api_changed(new_api)
7776

7877
def process_named_params
7978
if @named_params && @named_params.any?
80-
api.imbue(:named_params, @named_params)
79+
api.namespace_stackable(:named_params, @named_params)
8180
end
8281
end
8382
end

lib/grape/dsl/inside_route.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module Grape
44
module DSL
55
module InsideRoute
66
extend ActiveSupport::Concern
7+
include Grape::DSL::Settings
78

89
# A filtering method that will return a hash
910
# consisting only of keys that have been declared by a
@@ -18,8 +19,8 @@ def declared(params, options = {}, declared_params = nil)
1819
options[:include_missing] = true unless options.key?(:include_missing)
1920
options[:include_parent_namespaces] = true unless options.key?(:include_parent_namespaces)
2021
if declared_params.nil?
21-
declared_params = !options[:include_parent_namespaces] ? settings[:declared_params] :
22-
settings.gather(:declared_params)
22+
declared_params = (!options[:include_parent_namespaces] ? route_setting(:declared_params) :
23+
(route_setting(:saved_declared_params) || [])).flatten(1) || []
2324
end
2425

2526
unless declared_params
@@ -61,7 +62,7 @@ def version
6162
# @param message [String] The message to display.
6263
# @param status [Integer] the HTTP Status Code. Defaults to default_error_status, 500 if not set.
6364
def error!(message, status = nil, headers = nil)
64-
self.status(status || settings[:default_error_status])
65+
self.status(status || namespace_inheritable(:default_error_status))
6566
throw :error, message: message, status: self.status, headers: headers
6667
end
6768

@@ -214,7 +215,7 @@ def entity_class_for_obj(object, options)
214215
end
215216

216217
object_class.ancestors.each do |potential|
217-
entity_class ||= (settings[:representations] || {})[potential]
218+
entity_class ||= (Grape::DSL::Configuration.stacked_hash_to_hash(namespace_stackable(:representations)) || {})[potential]
218219
end
219220

220221
entity_class ||= object_class.const_get(:Entity) if object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent)

lib/grape/dsl/middleware.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module DSL
55
module Middleware
66
extend ActiveSupport::Concern
77

8+
include Grape::DSL::Configuration
9+
810
module ClassMethods
911
# Apply a custom middleware to the API. Applies
1012
# to the current namespace and any children, but
@@ -15,17 +17,15 @@ module ClassMethods
1517
def use(middleware_class, *args, &block)
1618
arr = [middleware_class, *args]
1719
arr << block if block_given?
18-
imbue(:middleware, [arr])
20+
21+
namespace_stackable(:middleware, arr)
1922
end
2023

2124
# Retrieve an array of the middleware classes
2225
# and arguments that are currently applied to the
2326
# application.
2427
def middleware
25-
settings.stack.inject([]) do |a, s|
26-
a += s[:middleware] if s[:middleware]
27-
a
28-
end
28+
namespace_stackable(:middleware) || []
2929
end
3030
end
3131
end

0 commit comments

Comments
 (0)