appfuel 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +25 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +19 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +9 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/appfuel.gemspec +42 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/lib/appfuel.rb +210 -0
- data/lib/appfuel/application.rb +4 -0
- data/lib/appfuel/application/app_container.rb +223 -0
- data/lib/appfuel/application/container_class_registration.rb +22 -0
- data/lib/appfuel/application/container_key.rb +201 -0
- data/lib/appfuel/application/qualify_container_key.rb +76 -0
- data/lib/appfuel/application/root.rb +140 -0
- data/lib/appfuel/cli_msg_request.rb +19 -0
- data/lib/appfuel/configuration.rb +14 -0
- data/lib/appfuel/configuration/definition_dsl.rb +175 -0
- data/lib/appfuel/configuration/file_loader.rb +61 -0
- data/lib/appfuel/configuration/populate.rb +95 -0
- data/lib/appfuel/configuration/search.rb +45 -0
- data/lib/appfuel/db_model.rb +16 -0
- data/lib/appfuel/domain.rb +7 -0
- data/lib/appfuel/domain/criteria.rb +436 -0
- data/lib/appfuel/domain/domain_name_parser.rb +44 -0
- data/lib/appfuel/domain/dsl.rb +247 -0
- data/lib/appfuel/domain/entity.rb +242 -0
- data/lib/appfuel/domain/entity_collection.rb +87 -0
- data/lib/appfuel/domain/expr.rb +127 -0
- data/lib/appfuel/domain/value_object.rb +7 -0
- data/lib/appfuel/errors.rb +104 -0
- data/lib/appfuel/feature.rb +2 -0
- data/lib/appfuel/feature/action_loader.rb +25 -0
- data/lib/appfuel/feature/initializer.rb +43 -0
- data/lib/appfuel/handler.rb +6 -0
- data/lib/appfuel/handler/action.rb +17 -0
- data/lib/appfuel/handler/base.rb +103 -0
- data/lib/appfuel/handler/command.rb +18 -0
- data/lib/appfuel/handler/inject_dsl.rb +88 -0
- data/lib/appfuel/handler/validator_dsl.rb +256 -0
- data/lib/appfuel/initialize.rb +70 -0
- data/lib/appfuel/initialize/initializer.rb +68 -0
- data/lib/appfuel/msg_request.rb +207 -0
- data/lib/appfuel/predicates.rb +10 -0
- data/lib/appfuel/presenter.rb +18 -0
- data/lib/appfuel/presenter/base.rb +7 -0
- data/lib/appfuel/repository.rb +73 -0
- data/lib/appfuel/repository/base.rb +72 -0
- data/lib/appfuel/repository/initializer.rb +19 -0
- data/lib/appfuel/repository/mapper.rb +203 -0
- data/lib/appfuel/repository/mapping_dsl.rb +210 -0
- data/lib/appfuel/repository/mapping_entry.rb +76 -0
- data/lib/appfuel/repository/mapping_registry.rb +121 -0
- data/lib/appfuel/repository_runner.rb +60 -0
- data/lib/appfuel/request.rb +53 -0
- data/lib/appfuel/response.rb +96 -0
- data/lib/appfuel/response_handler.rb +79 -0
- data/lib/appfuel/root_module.rb +31 -0
- data/lib/appfuel/run_error.rb +9 -0
- data/lib/appfuel/storage.rb +3 -0
- data/lib/appfuel/storage/db.rb +4 -0
- data/lib/appfuel/storage/db/active_record_model.rb +42 -0
- data/lib/appfuel/storage/db/mapper.rb +213 -0
- data/lib/appfuel/storage/db/migration_initializer.rb +42 -0
- data/lib/appfuel/storage/db/migration_runner.rb +15 -0
- data/lib/appfuel/storage/db/migration_tasks.rb +18 -0
- data/lib/appfuel/storage/db/repository.rb +231 -0
- data/lib/appfuel/storage/db/repository_query.rb +13 -0
- data/lib/appfuel/storage/file.rb +1 -0
- data/lib/appfuel/storage/file/base.rb +32 -0
- data/lib/appfuel/storage/memory.rb +2 -0
- data/lib/appfuel/storage/memory/mapper.rb +30 -0
- data/lib/appfuel/storage/memory/repository.rb +37 -0
- data/lib/appfuel/types.rb +53 -0
- data/lib/appfuel/validation.rb +80 -0
- data/lib/appfuel/validation/validator.rb +59 -0
- data/lib/appfuel/validation/validator_pipe.rb +47 -0
- data/lib/appfuel/version.rb +3 -0
- metadata +335 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
module Appfuel
|
2
|
+
module Handler
|
3
|
+
class Command < Base
|
4
|
+
class << self
|
5
|
+
def resolve_dependencies(results = Dry::Container.new)
|
6
|
+
=begin
|
7
|
+
super
|
8
|
+
resolve_container(results)
|
9
|
+
resolve_domains(results)
|
10
|
+
resolve_db_models(results)
|
11
|
+
resolve_repos(results)
|
12
|
+
results
|
13
|
+
=end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Appfuel
|
2
|
+
module Handler
|
3
|
+
# Allow handlers to inject domains, commands, repositories or anything
|
4
|
+
# that was initialized in the app container. Injections are done in two
|
5
|
+
# steps, first, when the class is loaded in memory the declarations are
|
6
|
+
# converted into fully qualified container keys and second, when the
|
7
|
+
# handler is run they plucked from the app container into a container
|
8
|
+
# dedicated to that one execution.
|
9
|
+
module InjectDsl
|
10
|
+
TYPES = [:domain, :cmd, :repo, :container]
|
11
|
+
|
12
|
+
# Holds a dictionary where the key is the container key and the value
|
13
|
+
# is an an optional alias for the name of the injection to be saved
|
14
|
+
# as. Injections a separated into two categories because domains are
|
15
|
+
# part of the type system (Dry::Types) and therefore kept in its own
|
16
|
+
# container "Types", meaning are fetched differently.
|
17
|
+
#
|
18
|
+
# @return [Hash]
|
19
|
+
def injections
|
20
|
+
@injections ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Dsl to declare a dependency injection. You can inject one of four
|
24
|
+
# types, which are:
|
25
|
+
# domain: these are domains or value object
|
26
|
+
# cmd: commands to be run
|
27
|
+
# repo: repositories to query the persistence layer
|
28
|
+
# container: any initialized container item
|
29
|
+
#
|
30
|
+
# since names an collide you can rename your injection with the
|
31
|
+
# :as option.
|
32
|
+
#
|
33
|
+
# @example of using an alias to rename a domain injection
|
34
|
+
# inject :domain, 'member.user', as: :current_user
|
35
|
+
#
|
36
|
+
# @example of normal domain injection. In this case the name of the
|
37
|
+
# domain with me the base name "user" not "member.user"
|
38
|
+
#
|
39
|
+
# inject :domain, 'member.user'
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# @param type [Symbol] type of injection
|
43
|
+
# @param key [String, Symbol] container key
|
44
|
+
# @param opts [Hash]
|
45
|
+
# @option as [String, Symbol] alternate name for injection
|
46
|
+
# @return nil
|
47
|
+
def inject(type, key, opts = {})
|
48
|
+
unless inject_type?(type)
|
49
|
+
fail "inject type must be #{TYPES.join(",")} #{type} given"
|
50
|
+
end
|
51
|
+
|
52
|
+
cat = case type
|
53
|
+
when :repo then 'repositories'
|
54
|
+
when :cmd then 'commands'
|
55
|
+
when :domain then 'domains'
|
56
|
+
else
|
57
|
+
"container"
|
58
|
+
end
|
59
|
+
|
60
|
+
namespaced_key = qualify_container_key(key, cat)
|
61
|
+
injections[namespaced_key] = opts[:as]
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def resolve_dependencies(container = Dry::Container.new)
|
66
|
+
app_container = Appfuel.app_container
|
67
|
+
injections.each do |key, alias_name|
|
68
|
+
unless app_container.key?(key)
|
69
|
+
fail "Could not inject (#{key}): not registered in app container"
|
70
|
+
end
|
71
|
+
|
72
|
+
basename = key.split('.').last
|
73
|
+
item = app_container[key]
|
74
|
+
container_key = alias_name || basename
|
75
|
+
container.register(container_key, item)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# @param type [Symbol]
|
82
|
+
# @return [Bool]
|
83
|
+
def inject_type?(type)
|
84
|
+
TYPES.include?(type)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
module Appfuel
|
2
|
+
module Handler
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# 1) single block validator. A basic validator that is only used by
|
6
|
+
# that particular interactor
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# validator('foo', fail_fast: true) do
|
10
|
+
#
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# 2) single validator from the features validators located in the app
|
14
|
+
# container under the key "features.<feature-name>.validators.<validator-name>"
|
15
|
+
#
|
16
|
+
# validator 'foo'
|
17
|
+
#
|
18
|
+
# 3) single validator from the global validators located in the app
|
19
|
+
# container under the key "global.validators.<validator-name>"
|
20
|
+
#
|
21
|
+
# validator 'global.foo'
|
22
|
+
#
|
23
|
+
# 4) muliple validators, all are located in the feature namespace
|
24
|
+
# validators 'foo', 'bar', 'baz'
|
25
|
+
#
|
26
|
+
# 5) multiple validators, some in features other in global
|
27
|
+
# validators 'foo', 'global.bar', 'baz'
|
28
|
+
#
|
29
|
+
# 6) a pipe is a closure that lives before a given validator in order
|
30
|
+
# to manipulate the inputs to fit the next validator. it does not validate
|
31
|
+
#
|
32
|
+
# validator_pipe do |inputs, data|
|
33
|
+
#
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# 7) using a pipe when using muliple validators
|
37
|
+
#
|
38
|
+
# validators 'foo', 'pipe.bar', 'base'
|
39
|
+
#
|
40
|
+
# 8) using global pipe in multiple validator declaration
|
41
|
+
# validators 'foo', 'global-pipe.bar', 'base'
|
42
|
+
#
|
43
|
+
# 9) validator_schema is used to use Dry::Validations with out our block
|
44
|
+
# processing
|
45
|
+
#
|
46
|
+
# validation_schema 'foo', Dry::Validation.Schama do
|
47
|
+
#
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# validation_schema Dry::Validation.Schema do
|
51
|
+
#
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# validation_schema 'foo', fail_fast: true, Dry::Validation.Schema do
|
55
|
+
#
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# validator
|
59
|
+
# name: to identify it in errors and as a key to register it with container
|
60
|
+
# fail_fast: when true runner will bail on first error
|
61
|
+
# pipe?: false
|
62
|
+
# code: validator schema to run
|
63
|
+
# call: run the validator schema
|
64
|
+
#
|
65
|
+
# validator-pipe
|
66
|
+
# name: to identify the pipe in errors and register it with container
|
67
|
+
# code: lambda to run
|
68
|
+
# call: run the lamda
|
69
|
+
module ValidatorDsl
|
70
|
+
|
71
|
+
def validators(*args)
|
72
|
+
@validators ||= []
|
73
|
+
return @validators if args.empty?
|
74
|
+
|
75
|
+
args.each do |arg|
|
76
|
+
@validators << load_validator(arg)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# When no name for a validator is given then the default name will
|
81
|
+
# be the name of the concrete handler class
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
def default_validator_name
|
85
|
+
self.to_s.split('::').last.underscore
|
86
|
+
end
|
87
|
+
|
88
|
+
# Converts a given block to a validator or load the validator from
|
89
|
+
# either global or feature validators
|
90
|
+
#
|
91
|
+
# @param key [String] name of the validator
|
92
|
+
# @param opts [Hash] options for creating a validator
|
93
|
+
# @option fail_fast [Bool] allows that validator to fail immediately
|
94
|
+
# @return [Nil]
|
95
|
+
def validator(key = nil, opts = {}, &block)
|
96
|
+
key = default_validator_name if key.nil?
|
97
|
+
validators << build_validator(key, opts, &block)
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
# load a validator with the given key from the app container.
|
102
|
+
#
|
103
|
+
# @note the key is encode and will be decoded first
|
104
|
+
# @see ValidatorDsl#convert_to_container_key for details
|
105
|
+
#
|
106
|
+
# @param key [String]
|
107
|
+
# @param opts [Hash]
|
108
|
+
# @return Appfuel::Validation::Validator
|
109
|
+
def load_validator(key, opts = {})
|
110
|
+
fail "validator must have a key" if key.nil?
|
111
|
+
|
112
|
+
container_key = convert_to_container_key(key)
|
113
|
+
container = Appfuel.app_container
|
114
|
+
unless container.key?(container_key)
|
115
|
+
fail "Could not locate validator with (#{container_key})"
|
116
|
+
end
|
117
|
+
|
118
|
+
container[container_key]
|
119
|
+
end
|
120
|
+
|
121
|
+
# return [Bool]
|
122
|
+
def validators?
|
123
|
+
!validators.empty?
|
124
|
+
end
|
125
|
+
|
126
|
+
# Used when resolving inputs to determine if we should apply any
|
127
|
+
# validation
|
128
|
+
#
|
129
|
+
# return [Bool]
|
130
|
+
def skip_validation?
|
131
|
+
@skip_validation == true
|
132
|
+
end
|
133
|
+
|
134
|
+
# Dsl method to allow a handler to tell the system not to validate
|
135
|
+
# anything and use the raw inputs
|
136
|
+
#
|
137
|
+
# return [Bool]
|
138
|
+
def skip_validation!
|
139
|
+
@skip_validation = true
|
140
|
+
end
|
141
|
+
|
142
|
+
# Validate all inputs using the list of validators that were assigned
|
143
|
+
# using the dsl methods.
|
144
|
+
#
|
145
|
+
# @param inputs [Hash]
|
146
|
+
# @return Appfuel::Response
|
147
|
+
def resolve_inputs(inputs = {})
|
148
|
+
return ok(inputs) if skip_validation?
|
149
|
+
return ok({}) unless validators?
|
150
|
+
|
151
|
+
response = nil
|
152
|
+
has_failed = false
|
153
|
+
validators.each do |validator|
|
154
|
+
if validator.pipe?
|
155
|
+
result = handle_validator_pipe(validator, inputs)
|
156
|
+
inputs = result unless result == false
|
157
|
+
next
|
158
|
+
end
|
159
|
+
|
160
|
+
result = validator.call(inputs)
|
161
|
+
if result.success? && !has_failed
|
162
|
+
response = handle_successful_inputs(result, response)
|
163
|
+
next
|
164
|
+
end
|
165
|
+
|
166
|
+
return error(result.errors(full: true)) if validator.fail_fast?
|
167
|
+
has_failed = true
|
168
|
+
response = handle_error_inputs(result, response)
|
169
|
+
end
|
170
|
+
|
171
|
+
fail "multi validators can not be only Procs" if response.nil?
|
172
|
+
|
173
|
+
response
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
# Decodes the given key into a dependency injection namespace that is
|
179
|
+
# used to find a validator or pipe in the app container. It decodes
|
180
|
+
# to a global or feature namespaces.
|
181
|
+
#
|
182
|
+
# @param key [String]
|
183
|
+
# #return [String]
|
184
|
+
def convert_to_container_key(key)
|
185
|
+
parts = key.to_s.split('.')
|
186
|
+
last = parts.last
|
187
|
+
first = parts.first
|
188
|
+
case first
|
189
|
+
when 'global'
|
190
|
+
"global.validators.#{last}"
|
191
|
+
when 'global-pipe'
|
192
|
+
"global.validator-pipes.#{last}"
|
193
|
+
when 'pipe'
|
194
|
+
"#{container_feature_key}.validator-pipes.#{last}"
|
195
|
+
else
|
196
|
+
"#{container_feature_key}.validators.#{first}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Create a validator for the handler or load it from the container
|
201
|
+
# depending on if a block is given
|
202
|
+
#
|
203
|
+
# @param key [String] key used to identify the item
|
204
|
+
# @param opts [Hash]
|
205
|
+
# @return [
|
206
|
+
# Appfuel::Validation::Validator,
|
207
|
+
# Appfuel::Validation::ValidatorPipe
|
208
|
+
# ]
|
209
|
+
def build_validator(key, opts = {}, &block)
|
210
|
+
return load_validator(key, opts) unless block_given?
|
211
|
+
|
212
|
+
Appfuel::Validation.build_validator(key, opts, &block)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Creates a response the first time otherwise it merges the results
|
216
|
+
# from the last validator into the response
|
217
|
+
#
|
218
|
+
# @param results [Hash] successful valid inputs
|
219
|
+
# @param response [Appfuel::Response]
|
220
|
+
def handle_successful_inputs(result, response)
|
221
|
+
if response.nil?
|
222
|
+
ok(result.output)
|
223
|
+
else
|
224
|
+
ok(response.ok.merge(result.output))
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Creates a response the first time otherwise it merges the error
|
229
|
+
# results from the last validator into the response
|
230
|
+
#
|
231
|
+
# @param results [Hash] successful valid inputs
|
232
|
+
# @param response [Appfuel::Response]
|
233
|
+
def handle_error_inputs(result, response)
|
234
|
+
if response.nil?
|
235
|
+
error(result.errors(full: true))
|
236
|
+
else
|
237
|
+
error(result.errors(full: true).merge(response.error_messages))
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Delegates call to the validator pipe
|
242
|
+
#
|
243
|
+
# @param pipe [Appfuel::Validation::ValidatorPipe]
|
244
|
+
# @param inputs [Hash]
|
245
|
+
# @return [Hash]
|
246
|
+
def handle_validator_pipe(pipe, inputs)
|
247
|
+
result = pipe.call(inputs, Dry::Container.new)
|
248
|
+
return false unless result
|
249
|
+
unless result.is_a?(Hash)
|
250
|
+
fail "multi validator proc must return a Hash"
|
251
|
+
end
|
252
|
+
result
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative 'initialize/initializer'
|
2
|
+
|
3
|
+
module Appfuel
|
4
|
+
module Initialize
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Dsl used to add an initializer into to the application container. This
|
8
|
+
# will add an initializer into the default app unless another name is
|
9
|
+
# given.
|
10
|
+
#
|
11
|
+
# @param name [String] name of the initializer
|
12
|
+
# @param envs [String, Symbol, Array] A env,list of envs this can run in
|
13
|
+
# @param app_name [String] name of app for this initializer
|
14
|
+
def define(namespace_key, name, envs = [], app_name = nil, &block)
|
15
|
+
initializers = Appfuel.resolve("#{namespace_key}.initializers", app_name)
|
16
|
+
initializers << Initializer.new(name, envs, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Populate configuration definition that is in the container and
|
20
|
+
# add its results to the container. It also adds the environment from
|
21
|
+
# the config to the container for easier access.
|
22
|
+
#
|
23
|
+
# @raises RuntimeError when :env is not in the config
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# @param container [Dry::Container]
|
27
|
+
# @param params [Hash]
|
28
|
+
# @option overrides [Hash] used to override config values
|
29
|
+
# @option env [ENV] used to collect environment variables
|
30
|
+
# @return [Dry::Container] that was passed in
|
31
|
+
def handle_configuration(container, params = {})
|
32
|
+
overrides = params[:overrides] || {}
|
33
|
+
env = params[:env] || ENV
|
34
|
+
definition = container['config_definition']
|
35
|
+
|
36
|
+
config = definition.populate(env: env, overrides: overrides)
|
37
|
+
env = config.fetch(:env) { fail "key (:env) is missing from config" }
|
38
|
+
|
39
|
+
container.register(:config, config)
|
40
|
+
container.register(:env, env)
|
41
|
+
|
42
|
+
container
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_repository_mapping(container, params = {})
|
46
|
+
initializer = container[:repository_initializer]
|
47
|
+
initializer.call(container)
|
48
|
+
end
|
49
|
+
|
50
|
+
# This will initialize the app by handling configuration and running
|
51
|
+
# all the initilizers, which will result in an app container that has
|
52
|
+
# registered the config, env, and anything else the initializers
|
53
|
+
# decide to add.
|
54
|
+
#
|
55
|
+
# @param params [Hash]
|
56
|
+
# @option app_name [String] name of the app to initialize, (optional)
|
57
|
+
# @return [Dry::Container]
|
58
|
+
def run(params = {})
|
59
|
+
app_name = params.fetch(:app_name) { Appfuel.default_app_name }
|
60
|
+
container = Appfuel.app_container(app_name)
|
61
|
+
handle_configuration(container, params)
|
62
|
+
handle_repository_mapping(container, params)
|
63
|
+
|
64
|
+
Appfuel.run_initializers('global', container, params[:exclude] || [])
|
65
|
+
|
66
|
+
container
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Appfuel
|
2
|
+
module Initialize
|
3
|
+
# The client application will declare a series of initializer blocks.
|
4
|
+
# Each of these blocks are represented as this class. This allows us
|
5
|
+
# to save the block to be later executed along with info about which
|
6
|
+
# environments this can run on
|
7
|
+
class Initializer
|
8
|
+
attr_reader :name, :envs, :code
|
9
|
+
|
10
|
+
# Ensure each environment is stored as a lowercased string, convert
|
11
|
+
# the name to a string as save the block to be executed later
|
12
|
+
#
|
13
|
+
# @raises ArgumentError, when env is not an Array
|
14
|
+
# @raises ArgumentError, when block is not given
|
15
|
+
#
|
16
|
+
# @param name [String, Symbol] name to identify this initializer
|
17
|
+
# @param env [String, Symbol, Array] env or list of envs to execute on
|
18
|
+
# @param blk [Proc] the code to be excuted
|
19
|
+
# @return [Initializer]
|
20
|
+
def initialize(name, env = [], &block)
|
21
|
+
@name = name.to_s
|
22
|
+
@envs = []
|
23
|
+
|
24
|
+
env = [env] if env.is_a?(String) || env.is_a?(Symbol)
|
25
|
+
env = [] if env.nil?
|
26
|
+
|
27
|
+
unless env.is_a?(Array)
|
28
|
+
fail ArgumentError, "environments must be a string, symbol or array"
|
29
|
+
end
|
30
|
+
env.each {|item| add_env(item) }
|
31
|
+
|
32
|
+
fail ArgumentError, "initializer requires a block" unless block_given?
|
33
|
+
@code = block
|
34
|
+
end
|
35
|
+
|
36
|
+
# Determines which env this is allowed to execute on. No enironment means
|
37
|
+
# it it is allow to execute on all
|
38
|
+
#
|
39
|
+
# @param env [String, Symbol]
|
40
|
+
# @return [Bool]
|
41
|
+
def env_allowed?(env)
|
42
|
+
return true if envs.empty?
|
43
|
+
|
44
|
+
envs.include?(env.to_s.downcase)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @raises RuntimeError, when env already exists
|
48
|
+
#
|
49
|
+
# @param name [String, Symbol] name of the environment
|
50
|
+
# @return [Array]
|
51
|
+
def add_env(name)
|
52
|
+
name = name.to_s.downcase
|
53
|
+
fail "env already exists" if envs.include?(name)
|
54
|
+
envs << name.to_s.downcase
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delegate to executing the stored code
|
58
|
+
#
|
59
|
+
# @param config [Hash]
|
60
|
+
# @param app_container [Dry::Container]
|
61
|
+
# @return nil
|
62
|
+
def call(config, container)
|
63
|
+
code.call(config, container)
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|