smart_container 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|