smart_container 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -8
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +46 -0
- data/lib/smart_core/container.rb +30 -0
- data/lib/smart_core/container/dependency_resolver.rb +9 -4
- data/lib/smart_core/container/dependency_resolver/route.rb +5 -8
- data/lib/smart_core/container/errors.rb +2 -1
- data/lib/smart_core/container/registry.rb +90 -3
- data/lib/smart_core/container/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb1bc1e5f80263730638b0b0387105364777f87e957b5f673c27c219f206273d
|
4
|
+
data.tar.gz: 0d1a505edb3b4456ab44ecfe52071b1cb5555f51680d3a48de68fb12bd11dcad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3959674748c1dcc2564bd6edc9ee0acdc3770b0bd260d50c7a1bba5906fee6725ff577e90a2b36b0a81910c423020431810b2a052f42c65826bfc8dcabe7dc22
|
7
|
+
data.tar.gz: f01f97eda299d91b22f730de1eba90e546f9f4de0362218bc0b8f86d8800acd6abf3d2214e223c0246f5c1d4b4742b71c7223ada409a3665765c088c88ab207e
|
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
---
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
|
+
os: linux
|
4
5
|
before_install:
|
5
6
|
- gem install bundler -v 2.1.2
|
6
7
|
script:
|
@@ -10,19 +11,11 @@ jobs:
|
|
10
11
|
fast_finish: true
|
11
12
|
include:
|
12
13
|
- rvm: 2.4.9
|
13
|
-
os: [linux, osx]
|
14
14
|
- rvm: 2.5.7
|
15
|
-
os: [linux, osx]
|
16
15
|
- rvm: 2.6.5
|
17
|
-
os: [linux, osx]
|
18
16
|
- rvm: 2.7.0
|
19
|
-
os: [linux, osx]
|
20
17
|
- rvm: ruby-head
|
21
|
-
os: [linux, osx]
|
22
18
|
- rvm: jruby-head
|
23
|
-
os: [linux, osx]
|
24
19
|
allow_failures:
|
25
20
|
- rvm: ruby-head
|
26
|
-
os: [linux, osx]
|
27
21
|
- rvm: jruby-head
|
28
|
-
os: [linux, osx]
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.4.0] - 2020-01-06
|
5
|
+
### Added
|
6
|
+
- `#keys(all_variants: false)` - return a list of dependency keys
|
7
|
+
(`all_variants: true` is mean "including namespace kaeys");
|
8
|
+
- `#each_dependency(yield_all: false) { |key, value| }` - iterate over conteiner's dependencies
|
9
|
+
(`yield_all: true` will include nested containers to iteration process);
|
10
|
+
### Fixed
|
11
|
+
- `SmartCore::Container::ResolvingError` class has incorrect message attribute name;
|
12
|
+
|
4
13
|
## [0.3.0] - 2020-01-05
|
5
14
|
### Changed
|
6
15
|
- Dependency resolving is not memoized by default (previously: totally memoized 😱);
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -24,6 +24,8 @@ require 'smart_core/container'
|
|
24
24
|
|
25
25
|
## Synopsis (demo)
|
26
26
|
|
27
|
+
- container class creation:
|
28
|
+
|
27
29
|
```ruby
|
28
30
|
class Container < SmartCore::Container
|
29
31
|
namespace(:database) do # support for namespaces
|
@@ -41,16 +43,60 @@ class Container < SmartCore::Container
|
|
41
43
|
# dependencies are not memoized by default (memoize: false)
|
42
44
|
register(:random) { rand(1000) }
|
43
45
|
end
|
46
|
+
```
|
44
47
|
|
48
|
+
- container instantiation and dependency resolving:
|
49
|
+
|
50
|
+
```ruby
|
45
51
|
container = Container.new # create container instance
|
52
|
+
```
|
46
53
|
|
54
|
+
```ruby
|
47
55
|
container['database.resolver'] # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
|
48
56
|
container['database.cache.redis'] # => #<RedisClient:0x00007f0f0f1d0158>
|
49
57
|
container['logger'] # => #<Logger:0x00007f5f0f2f0158>
|
50
58
|
|
59
|
+
container.resolve('logger') # #resolve(path) is an alias for #[](path)
|
60
|
+
|
51
61
|
# non-memoized dependency
|
52
62
|
container['random'] # => 352
|
53
63
|
container['random'] # => 57
|
64
|
+
|
65
|
+
# trying to resolve a namespace as dependency
|
66
|
+
container['database'] # => SmartCore::Container::ResolvingError
|
67
|
+
|
68
|
+
# but you can fetch any depenendency type (internal containers and values) via #fetch
|
69
|
+
container.fetch('database') # => SmartCore::Container (nested container)
|
70
|
+
container.fetch('database.resolver') # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
|
71
|
+
```
|
72
|
+
|
73
|
+
- container keys (dependency names):
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# get dependnecy keys (only dependencies)
|
77
|
+
container.keys
|
78
|
+
# => result:
|
79
|
+
[
|
80
|
+
'database.resolver',
|
81
|
+
'database.cache.memcached',
|
82
|
+
'database.cache.redis',
|
83
|
+
'logger',
|
84
|
+
'random'
|
85
|
+
]
|
86
|
+
```
|
87
|
+
```ruby
|
88
|
+
# get all keys (namespaces and dependencies)
|
89
|
+
container.keys(all_variants: true)
|
90
|
+
# => result:
|
91
|
+
[
|
92
|
+
'database', # namespace
|
93
|
+
'database.resolver',
|
94
|
+
'database.cache', # namespace
|
95
|
+
'database.cache.memcached',
|
96
|
+
'database.cache.redis',
|
97
|
+
'logger',
|
98
|
+
'random'
|
99
|
+
]
|
54
100
|
```
|
55
101
|
|
56
102
|
---
|
data/lib/smart_core/container.rb
CHANGED
@@ -20,6 +20,9 @@ module SmartCore
|
|
20
20
|
require_relative 'container/dependency_resolver'
|
21
21
|
require_relative 'container/mixin'
|
22
22
|
|
23
|
+
# @since 0.4.0
|
24
|
+
include ::Enumerable
|
25
|
+
|
23
26
|
# @since 0.1.0
|
24
27
|
include DefinitionDSL
|
25
28
|
|
@@ -102,6 +105,33 @@ module SmartCore
|
|
102
105
|
thread_safe { build_registry! }
|
103
106
|
end
|
104
107
|
|
108
|
+
# @option all_variants [Boolean]
|
109
|
+
# @return [Array<String>]
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
# @since 0.4.0
|
113
|
+
def keys(all_variants: SmartCore::Container::Registry::DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
114
|
+
thread_safe { registry.keys(all_variants: all_variants) }
|
115
|
+
end
|
116
|
+
|
117
|
+
# @option yield_all [Boolean]
|
118
|
+
# @param block [Block]
|
119
|
+
# @yield [dependency_name, dependency_value]
|
120
|
+
# @yield_param dependency_name [String]
|
121
|
+
# @yield_param dependency_value [Any, SmartCore::Container]
|
122
|
+
# @return [Enumerable]
|
123
|
+
#
|
124
|
+
# @api public
|
125
|
+
# @since 0.4.0
|
126
|
+
def each_dependency(
|
127
|
+
yield_all: SmartCore::Container::Registry::DEFAULT_ITERATION_YIELD_BEHAVIOUR,
|
128
|
+
&block
|
129
|
+
)
|
130
|
+
thread_safe { registry.each_dependency(yield_all: yield_all, &block) }
|
131
|
+
end
|
132
|
+
alias_method :each, :each_dependency
|
133
|
+
alias_method :each_pair, :each_dependency
|
134
|
+
|
105
135
|
# @option resolve_dependencies [Boolean]
|
106
136
|
# @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
|
107
137
|
#
|
@@ -5,6 +5,12 @@
|
|
5
5
|
module SmartCore::Container::DependencyResolver
|
6
6
|
require_relative 'dependency_resolver/route'
|
7
7
|
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.4.0
|
12
|
+
PATH_PART_SEPARATOR = '.'
|
13
|
+
|
8
14
|
class << self
|
9
15
|
# @param container [SmartCore::Container]
|
10
16
|
# @param dependency_path [String, Symbol]
|
@@ -84,10 +90,9 @@ module SmartCore::Container::DependencyResolver
|
|
84
90
|
# @api private
|
85
91
|
# @since 0.1.0
|
86
92
|
def process_resolving_error(dependency_path, error)
|
87
|
-
full_dependency_path = Route.build_path(
|
88
|
-
|
89
|
-
|
90
|
-
MESSAGE
|
93
|
+
full_dependency_path = Route.build_path(error.path_part)
|
94
|
+
message = "#{error.message} (incorrect path: \"#{full_dependency_path}\")"
|
95
|
+
raise(SmartCore::Container::ResolvingError.new(message, path_part: full_dependency_path))
|
91
96
|
end
|
92
97
|
end
|
93
98
|
end
|
@@ -2,18 +2,13 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
|
+
# @version 0.4.0
|
5
6
|
class SmartCore::Container::DependencyResolver::Route
|
6
7
|
require_relative 'route/cursor'
|
7
8
|
|
8
9
|
# @since 0.1.0
|
9
10
|
include Enumerable
|
10
11
|
|
11
|
-
# @return [String]
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
# @since 0.1.0
|
15
|
-
PATH_PART_SEPARATOR = '.'
|
16
|
-
|
17
12
|
class << self
|
18
13
|
# @param path [String, Symbol]
|
19
14
|
# @return [SmartCore::Container::DependencyResolver::Route]
|
@@ -28,8 +23,9 @@ class SmartCore::Container::DependencyResolver::Route
|
|
28
23
|
#
|
29
24
|
# @api private
|
30
25
|
# @since 0.1.0
|
26
|
+
# @version 0.4.0
|
31
27
|
def build_path(*path_parts)
|
32
|
-
path_parts.join(PATH_PART_SEPARATOR)
|
28
|
+
path_parts.join(SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR)
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
@@ -50,9 +46,10 @@ class SmartCore::Container::DependencyResolver::Route
|
|
50
46
|
#
|
51
47
|
# @api private
|
52
48
|
# @since 0.1.0
|
49
|
+
# @version 0.4.0
|
53
50
|
def initialize(path)
|
54
51
|
@path = path
|
55
|
-
@path_parts = path.split(PATH_PART_SEPARATOR).freeze
|
52
|
+
@path_parts = path.split(SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR).freeze
|
56
53
|
@size = @path_parts.size
|
57
54
|
end
|
58
55
|
|
@@ -13,6 +13,18 @@ class SmartCore::Container::Registry
|
|
13
13
|
# @since 0.3.0
|
14
14
|
DEFAULT_MEMOIZATION_BEHAVIOR = false
|
15
15
|
|
16
|
+
# @return [Boolean]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.4.0
|
20
|
+
DEFAULT_ITERATION_YIELD_BEHAVIOUR = false
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
# @since 0.4.0
|
26
|
+
DEFAULT_KEY_EXTRACTION_BEHAVIOUR = false
|
27
|
+
|
16
28
|
# @return [Hash<Symbol,SmartCore::Container::Entity>]
|
17
29
|
#
|
18
30
|
# @api private
|
@@ -84,6 +96,30 @@ class SmartCore::Container::Registry
|
|
84
96
|
thread_safe { enumerate(&block) }
|
85
97
|
end
|
86
98
|
|
99
|
+
# @param root_dependency_name [NilClass, String]
|
100
|
+
# @option yield_all [Boolean]
|
101
|
+
# @param block [Block]
|
102
|
+
# @return [Enumerable]
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
# @since 0.4.0
|
106
|
+
def each_dependency(
|
107
|
+
root_dependency_name = nil,
|
108
|
+
yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR,
|
109
|
+
&block
|
110
|
+
)
|
111
|
+
thread_safe { iterate(root_dependency_name, yield_all: yield_all, &block) }
|
112
|
+
end
|
113
|
+
|
114
|
+
# @option all_variants [Boolean]
|
115
|
+
# @return [Array<String>]
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
# @since 0.4.0
|
119
|
+
def keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
120
|
+
thread_safe { extract_keys(all_variants: all_variants) }
|
121
|
+
end
|
122
|
+
|
87
123
|
# @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
|
88
124
|
#
|
89
125
|
# @api private
|
@@ -158,9 +194,8 @@ class SmartCore::Container::Registry
|
|
158
194
|
dependency_name = indifferently_accessable_name(entity_path)
|
159
195
|
registry.fetch(dependency_name)
|
160
196
|
rescue KeyError
|
161
|
-
|
162
|
-
|
163
|
-
MESSAGE
|
197
|
+
error_message = "Entity with \"#{dependency_name}\" name does not exist"
|
198
|
+
raise(SmartCore::Container::ResolvingError.new(error_message, path_part: dependency_name))
|
164
199
|
end
|
165
200
|
|
166
201
|
# @param dependency_name [String, Symbol]
|
@@ -215,6 +250,58 @@ class SmartCore::Container::Registry
|
|
215
250
|
namespace_entity.tap { namespace_entity.append_definitions(dependencies_definition) }
|
216
251
|
end
|
217
252
|
|
253
|
+
# @param root_dependency_name [String, NilClass]
|
254
|
+
# @param block [Block]
|
255
|
+
# @option yield_all [Boolean]
|
256
|
+
# @yield [dependency_name, dependency]
|
257
|
+
# @yield_param dependency_name [String]
|
258
|
+
# @yield_param dependency [Any]
|
259
|
+
# @return [Enumerable]
|
260
|
+
#
|
261
|
+
# @api private
|
262
|
+
# @since 0.4.0
|
263
|
+
def iterate(root_dependency_name = nil, yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR, &block)
|
264
|
+
enumerator = Enumerator.new do |yielder|
|
265
|
+
registry.each_pair do |dependency_name, dependency|
|
266
|
+
final_dependency_name =
|
267
|
+
if root_dependency_name
|
268
|
+
"#{root_dependency_name}" \
|
269
|
+
"#{SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR}" \
|
270
|
+
"#{dependency_name}"
|
271
|
+
else
|
272
|
+
dependency_name
|
273
|
+
end
|
274
|
+
|
275
|
+
case dependency
|
276
|
+
when SmartCore::Container::Entities::Dependency
|
277
|
+
yielder.yield(final_dependency_name, dependency.reveal)
|
278
|
+
when SmartCore::Container::Entities::Namespace
|
279
|
+
yielder.yield(final_dependency_name, dependency.reveal) if yield_all
|
280
|
+
dependency.reveal.registry.each_dependency(
|
281
|
+
final_dependency_name,
|
282
|
+
yield_all: yield_all,
|
283
|
+
&block
|
284
|
+
)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
block_given? ? enumerator.each(&block) : enumerator.each
|
290
|
+
end
|
291
|
+
|
292
|
+
# @option all_variants [Boolean]
|
293
|
+
# @return [Array<String>]
|
294
|
+
#
|
295
|
+
# @api private
|
296
|
+
# @since 0.4.0
|
297
|
+
def extract_keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
298
|
+
Set.new.tap do |dependency_names|
|
299
|
+
iterate(yield_all: all_variants) do |dependency_name, _dependency|
|
300
|
+
dependency_names << dependency_name
|
301
|
+
end
|
302
|
+
end.to_a
|
303
|
+
end
|
304
|
+
|
218
305
|
# @param name [String, Symbol]
|
219
306
|
# @return [void]
|
220
307
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01-
|
11
|
+
date: 2020-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: smart_engine
|