smart_core 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +5 -8
  5. data/CHANGELOG.md +5 -0
  6. data/README.md +14 -4
  7. data/lib/smart_core.rb +2 -2
  8. data/lib/smart_core/container.rb +49 -56
  9. data/lib/smart_core/container/arbitary_lock.rb +22 -0
  10. data/lib/smart_core/container/definition_dsl.rb +105 -55
  11. data/lib/smart_core/container/{command_set.rb → definition_dsl/command_set.rb} +20 -26
  12. data/lib/smart_core/container/definition_dsl/commands.rb +12 -0
  13. data/lib/smart_core/container/{commands → definition_dsl/commands}/base.rb +3 -3
  14. data/lib/smart_core/container/definition_dsl/commands/definition/compose.rb +46 -0
  15. data/lib/smart_core/container/definition_dsl/commands/definition/namespace.rb +51 -0
  16. data/lib/smart_core/container/{commands → definition_dsl/commands/definition}/register.rb +13 -25
  17. data/lib/smart_core/container/definition_dsl/commands/instantiation/compose.rb +50 -0
  18. data/lib/smart_core/container/definition_dsl/commands/instantiation/freeze_state.rb +24 -0
  19. data/lib/smart_core/container/dependency_compatability.rb +3 -3
  20. data/lib/smart_core/container/dependency_compatability/definition.rb +42 -0
  21. data/lib/smart_core/container/dependency_compatability/general.rb +61 -0
  22. data/lib/smart_core/container/dependency_compatability/registry.rb +28 -29
  23. data/lib/smart_core/container/dependency_resolver.rb +9 -4
  24. data/lib/smart_core/container/entities.rb +11 -0
  25. data/lib/smart_core/container/{entity.rb → entities/base.rb} +7 -7
  26. data/lib/smart_core/container/entities/dependency.rb +38 -0
  27. data/lib/smart_core/container/entities/dependency_builder.rb +50 -0
  28. data/lib/smart_core/container/entities/namespace.rb +73 -0
  29. data/lib/smart_core/container/entities/namespace_builder.rb +41 -0
  30. data/lib/smart_core/container/errors.rb +43 -0
  31. data/lib/smart_core/container/key_guard.rb +5 -5
  32. data/lib/smart_core/container/mixin.rb +20 -16
  33. data/lib/smart_core/container/registry.rb +224 -201
  34. data/lib/smart_core/container/registry_builder.rb +38 -5
  35. data/lib/smart_core/{exceptions.rb → errors.rb} +0 -0
  36. data/lib/smart_core/operation.rb +3 -1
  37. data/lib/smart_core/operation/{custom.rb → callback.rb} +7 -7
  38. data/lib/smart_core/operation/result.rb +1 -1
  39. data/lib/smart_core/operation/result_interface.rb +3 -3
  40. data/lib/smart_core/version.rb +1 -1
  41. data/smart_core.gemspec +6 -5
  42. metadata +28 -38
  43. data/lib/smart_core/container/command_definer.rb +0 -117
  44. data/lib/smart_core/container/commands.rb +0 -9
  45. data/lib/smart_core/container/commands/namespace.rb +0 -53
  46. data/lib/smart_core/container/dependency.rb +0 -44
  47. data/lib/smart_core/container/dependency_builder.rb +0 -48
  48. data/lib/smart_core/container/dependency_compatability/abstract.rb +0 -59
  49. data/lib/smart_core/container/dependency_compatability/command_set.rb +0 -35
  50. data/lib/smart_core/container/exceptions.rb +0 -31
  51. data/lib/smart_core/container/memoized_dependency.rb +0 -28
  52. data/lib/smart_core/container/namespace.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7867022eeaee9e4538e85a8daa448b0906cae19bf54bdeb1d527699de3934d3
4
- data.tar.gz: ba755bf600dfd06a1cf82f318dc48a5e6ed1955e703073757ca35ecba711d803
3
+ metadata.gz: 19dd6183688e0576100f7178ad66764ca76d1461c459eaeb239815c1b75a2d30
4
+ data.tar.gz: 34419b8bac8cc0e409c823282320fadf14f562225a5c4dd62545c4270b298919
5
5
  SHA512:
6
- metadata.gz: 745b23e80f8eaa5799cc538ee470f6fcd8bea122fe421b1baf719655f33c0fba4b838f5a985f5a3180247aa5e1b0f07e7e16266c1b0ac0ac22ce975fc336db06
7
- data.tar.gz: 70de948e0cc48516091af87cf194ed2564544c3d2586aaee5d7c97daaee96eee593a1426102461c36d76bd1add72ceb4bd1557b2746084ede695beccefdaef71
6
+ metadata.gz: '06718cef684bec320e3fa67d83e9486df6c991571fcabe6fad48a2a7063f554499e46a7c231bc37edb8dcb2325daf9004ae293f3e736e85f73a6eb6c791d7a74'
7
+ data.tar.gz: d13ec368c4bed72a132f1de1963c322383e8ad7d5168c3da188a13b649f7ec1cc27da080cc917b0c5c30c344436847229dd7bf92b429d6cd499dc77557274070
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
+ --format documentation
1
2
  --color
2
- --format progress
3
3
  --require spec_helper
@@ -5,7 +5,7 @@ inherit_gem:
5
5
 
6
6
  AllCops:
7
7
  UseCache: true
8
- TargetRubyVersion: 2.6.3
8
+ TargetRubyVersion: 2.6.5
9
9
  Include:
10
10
  - bin/console
11
11
  - lib/**/*.rb
@@ -1,20 +1,17 @@
1
1
  language: ruby
2
2
  sudo: false
3
- before_install: gem install bundler
4
3
  cache: bundler
4
+ before_install: gem install bundler
5
+ script: bundle exec rspec
5
6
  matrix:
6
7
  fast_finish: true
7
8
  include:
8
9
  - rvm: 2.3.8
9
- - rvm: 2.4.7
10
- - rvm: 2.5.6
11
- - rvm: 2.6.4
10
+ - rvm: 2.4.9
11
+ - rvm: 2.5.7
12
+ - rvm: 2.6.5
12
13
  - rvm: ruby-head
13
14
  - rvm: jruby-head
14
15
  allow_failures:
15
16
  - rvm: ruby-head
16
17
  - rvm: jruby-head
17
- script: bundle exec rspec
18
- notifications:
19
- slack:
20
- secure: CUM3xnSJvn/y6Z+epQrO5uSk1EUuP4S+ugcS+48nlWD6eEzhYZwcBAK9tvD6kYGOPzoWyKSbW6Is1kzSunNr6f8ICc8HtrVHzoHE8UCzwZ7FpjgD0JgMgC4+xLLBO6lV0Hc7dNh4KLAhy4Zvbr09DPjcG8UW9/QgUdn+wBf9LHMgA+2SpBPEzMwz6pMbWW/+kkoCz2KU877kEfuFFGfvoOEFWTxUUhuCYi5a1SmTjm9A7CFTEWNkX8yHJwdgVgONjvm9lnhTeV0DvMeEOhk8Kx/hzQ2OGIicXZXWyZFkzNzpQm5xE12Hs4rY7mGPbo3bsYRDH9Ys6yf4fpNf0oZ/1agzl/gnDzacA2wL2b+eq1uZblE/fdwrNp+GIH0R+Ec2rsVKM7kh71sA6Xp1pzFb2DnHj5O4QFaPMsLyIZqD0BkVt4pNfwi4ZUB56sWkYeRQGm8x2Beh02IyFfxI65lY5kZrW6GjXx5eFeOHcmzQzeADWLSBf4iw01G/A/QqwZzlZ3fm0fRJi8BKDh3Jj0IrGndE9Bl+E7uOClKKngTPxOVLOLo/vY5mfI8M94f99kr0J45XkoAdc0SQfi3hDa/tHaakI5GJsmByjgOQwV7OU/2wzJoXAg/RPYjsYcwnTgzm9bLXPhQzfM8rUS5vLTOWIW+N0QKmWml7eWVtiedcwXA=
@@ -1,6 +1,11 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.7.0] - 2019-11-10
5
+ ### Changed
6
+ - `SmartCore::Operation::Custom` result type is renamed to `SmartCore::Operation::Callback`;
7
+ - Full reimplementation of `SmartCore::Container`;
8
+
4
9
  ## [0.6.0] - 2019-09-18
5
10
  ### Added
6
11
  - New result type: `SmartCore::Operation::Custom` with custom logic provided as a proc;
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SmartCore · [![Gem Version](https://badge.fury.io/rb/smart_core.svg)](https://badge.fury.io/rb/smart_core) [![Build Status](https://travis-ci.org/0exp/smart_core.svg?branch=master)](https://travis-ci.org/0exp/smart_core) [![Coverage Status](https://coveralls.io/repos/github/0exp/smart_core/badge.svg?branch=master)](https://coveralls.io/github/0exp/smart_core?branch=master)
1
+ # SmartCore · [![Gem Version](https://badge.fury.io/rb/smart_core.svg)](https://badge.fury.io/rb/smart_core) [![Build Status](https://travis-ci.org/0exp/smart_core.svg?branch=master)](https://travis-ci.org/0exp/smart_core)
2
2
 
3
3
  In active development (**Coming Soon**: Powerful documentaion :))
4
4
  > Meetup Slides: [link](docs/SmartCore.pdf)
@@ -26,10 +26,20 @@ require 'smart_core'
26
26
  #### Completed abstractions:
27
27
 
28
28
  - Service Object (Operation, Functional Object);
29
+ - IoC Container (Dependency Container);
29
30
  - Initializer (DSL);
30
31
  - Validator (Validation Layer);
31
- - Dependency Container;
32
- - (Soon) Schema;
32
+
33
+ ---
34
+
35
+ #### Roadmap
36
+
37
+ - Value Object (`SmartCore::ValueObject` (`DTO`) (truely immutable and comparable objects 😈));
38
+ - Schema Structure Validator (`SmartCore::Schema`);
39
+ - Saga (`SmartCore::Saga`);
40
+ - External Type System (`SmartCore::Types`);
41
+ - Step-like execution behavior for `SmartCore::Operation` (`.step`);
42
+ - Automatic result instantiation and handling for `SmartCore::Operation`;
33
43
 
34
44
  ---
35
45
 
@@ -37,7 +47,7 @@ require 'smart_core'
37
47
 
38
48
  - Fork it ( https://github.com/0exp/smart_core/fork )
39
49
  - Create your feature branch (`git checkout -b feature/my-new-feature`)
40
- - Commit your changes (`git commit -am 'Add some feature'`)
50
+ - Commit your changes (`git commit -am '[feature_context] Add some feature'`)
41
51
  - Push to the branch (`git push origin feature/my-new-feature`)
42
52
  - Create new Pull Request
43
53
 
@@ -4,9 +4,9 @@
4
4
  # @since 0.1.0
5
5
  module SmartCore
6
6
  require_relative 'smart_core/version'
7
- require_relative 'smart_core/exceptions'
8
- require_relative 'smart_core/initializer'
7
+ require_relative 'smart_core/errors'
9
8
  require_relative 'smart_core/container'
9
+ require_relative 'smart_core/initializer'
10
10
  require_relative 'smart_core/injector'
11
11
  require_relative 'smart_core/validator'
12
12
  require_relative 'smart_core/operation'
@@ -1,123 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.5.0
4
+ # @since 0.1.0
5
5
  class SmartCore::Container
6
- require_relative 'container/exceptions'
7
- require_relative 'container/commands'
8
- require_relative 'container/command_set'
6
+ require_relative 'container/errors'
7
+ require_relative 'container/arbitary_lock'
9
8
  require_relative 'container/key_guard'
10
- require_relative 'container/entity'
11
- require_relative 'container/dependency'
12
- require_relative 'container/memoized_dependency'
13
- require_relative 'container/namespace'
14
- require_relative 'container/dependency_builder'
9
+ require_relative 'container/entities'
10
+ require_relative 'container/definition_dsl'
11
+ require_relative 'container/dependency_compatability'
15
12
  require_relative 'container/registry'
16
13
  require_relative 'container/registry_builder'
17
- require_relative 'container/dependency_compatability'
18
14
  require_relative 'container/dependency_resolver'
19
- require_relative 'container/definition_dsl'
20
15
  require_relative 'container/mixin'
21
16
 
22
- # TODO: container composition
23
- # TODO: #merge / #merge!
24
-
25
- # @since 0.5.0
17
+ # @since 0.1.0
26
18
  include DefinitionDSL
27
19
 
28
20
  # @return [void]
29
21
  #
30
22
  # @api public
31
- # @since 0.5.0
23
+ # @since 0.1.0
32
24
  def initialize
33
- build_registry
34
- @access_lock = Mutex.new
25
+ build_registry!
26
+ @access_lock = ArbitaryLock.new
35
27
  end
36
28
 
37
29
  # @param dependency_name [String, Symbol]
38
- # @param options [Hash<Symbol,Any>]
39
30
  # @param dependency_definition [Block]
40
31
  # @return [void]
41
32
  #
42
- # @todo option list
43
- #
44
33
  # @api public
45
- # @since 0.5.0
46
- def register(dependency_name, **options, &dependency_definition)
47
- thread_safe do
48
- registry.register(dependency_name, **options, &dependency_definition)
49
- end
34
+ # @sicne 0.1.0
35
+ def register(dependency_name, &dependency_definition)
36
+ thread_safe { registry.register_dependency(dependency_name, &dependency_definition) }
50
37
  end
51
38
 
39
+ # @param namespace_name [String, Symbol]
40
+ # @param dependencies_definition [Block]
52
41
  # @return [void]
53
42
  #
54
43
  # @api public
55
- # @since 0.5.0
56
- def freeze
57
- thread_safe { registry.freeze }
44
+ # @since 0.1.0
45
+ def namespace(namespace_name, &dependencies_definition)
46
+ thread_safe { registry.register_namespace(namespace_name, &dependencies_definition) }
58
47
  end
59
48
 
60
- # @return [Boolean]
49
+ # @param dependency_path [String, Symbol]
50
+ # @return [Any]
61
51
  #
62
52
  # @api public
63
- # @since 0.5.0
64
- def frozen?
65
- thread_safe { registry.frozen? }
53
+ # @since 0.1.0
54
+ def resolve(dependency_path)
55
+ thread_safe { DependencyResolver.resolve(registry, dependency_path) }
66
56
  end
67
57
 
68
- # @param namespace_name [String, Symbol]
69
- # @param dependency_definitions [Block]
70
58
  # @return [void]
71
59
  #
72
60
  # @api public
73
- # @since 0.5.0
74
- def namespace(namespace_name, &dependency_definitions)
75
- thread_safe do
76
- registry.namespace(namespace_name, &dependency_definitions)
77
- end
61
+ # @since 0.1.0
62
+ def freeze!
63
+ thread_safe { registry.freeze! }
78
64
  end
79
65
 
80
- # @param dependency_path [String, Symbol]
81
- # @return [Any]
66
+ # @return [Boolean]
82
67
  #
83
68
  # @api public
84
- # @since 0.5.0
85
- def resolve(dependency_path)
86
- thread_safe do
87
- DependencyResolver.resolve(registry, dependency_path)
88
- end
69
+ # @since 0.1.0
70
+ def frozen?
71
+ thread_safe { registry.frozen? }
89
72
  end
90
73
 
91
74
  # @return [void]
92
75
  #
93
76
  # @api public
94
- # @since 0.5.0
77
+ # @since 0.1.0
95
78
  def reload!
96
- thread_safe { build_registry }
79
+ thread_safe { build_registry! }
80
+ end
81
+
82
+ # @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
83
+ #
84
+ # @api public
85
+ # @since 0.1.0
86
+ def hash_tree(resolve_dependencies: false)
87
+ thread_safe { registry.hash_tree(resolve_dependencies: resolve_dependencies) }
97
88
  end
89
+ alias_method :to_h, :hash_tree
90
+ alias_method :to_hash, :hash_tree
98
91
 
99
92
  private
100
93
 
101
94
  # @return [SmartCore::Container::Registry]
102
95
  #
103
96
  # @api private
104
- # @since 0.5.0
97
+ # @since 0.1.0
105
98
  attr_reader :registry
106
99
 
107
100
  # @return [void]
108
101
  #
109
102
  # @api private
110
- # @since 0.5.0
111
- def build_registry
112
- @registry = RegistryBuilder.build(self.class.__commands__)
103
+ # @since 0.1.0
104
+ def build_registry!
105
+ @registry = RegistryBuilder.build(self)
113
106
  end
114
107
 
115
- # @param block [Proc]
108
+ # @param block [Block]
116
109
  # @return [Any]
117
110
  #
118
111
  # @api private
119
- # @since 0.5.0
112
+ # @since 0.1.0
120
113
  def thread_safe(&block)
121
- @access_lock.synchronize(&block)
114
+ @access_lock.thread_safe(&block)
122
115
  end
123
116
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.7.0
5
+ class SmartCore::Container::ArbitaryLock
6
+ # @return [void]
7
+ #
8
+ # @api private
9
+ # @since 0.7.0
10
+ def initialize
11
+ @lock = Mutex.new
12
+ end
13
+
14
+ # @param block [Proc]
15
+ # @return [Any]
16
+ #
17
+ # @api private
18
+ # @since 0.7.0
19
+ def thread_safe(&block)
20
+ @lock.owned? ? yield : @lock.synchronize(&block)
21
+ end
22
+ end
@@ -1,66 +1,116 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @api private
4
- # @since 0.5.0
5
- module SmartCore::Container::DefinitionDSL
6
- class << self
7
- # @param base_klass [Class<SmartCore::Container>]
8
- # @return [void]
9
- #
10
- # @api private
11
- # @since 0.5.0
12
- def included(base_klass)
13
- base_klass.instance_variable_set(:@__commands__, SmartCore::Container::CommandSet.new)
14
- base_klass.singleton_class.send(:attr_reader, :__commands__)
15
- base_klass.extend(ClassMethods)
16
- base_klass.singleton_class.prepend(ClassInheritance)
3
+ class SmartCore::Container
4
+ # @api private
5
+ # @since 0.7.0
6
+ module DefinitionDSL
7
+ require_relative 'definition_dsl/commands'
8
+ require_relative 'definition_dsl/command_set'
9
+
10
+ class << self
11
+ # @param base_klass [Class<SmartCore::Container>]
12
+ # @return [void]
13
+ #
14
+ # @api private
15
+ # @since 0.7.0
16
+ def included(base_klass)
17
+ base_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
18
+ base_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
19
+ base_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
20
+ base_klass.singleton_class.send(:attr_reader, :__container_definition_commands__)
21
+ base_klass.singleton_class.send(:attr_reader, :__container_instantiation_commands__)
22
+ base_klass.extend(ClassMethods)
23
+ base_klass.singleton_class.prepend(ClassInheritance)
24
+ end
17
25
  end
18
- end
19
26
 
20
- # @api private
21
- # @since 0.5.0
22
- module ClassInheritance
23
- # @param child_klass [Class<SmartCore::Container>]
24
- # @return [void]
25
- #
26
27
  # @api private
27
- # @since 0.5.0
28
- def inherited(child_klass)
29
- child_klass.instance_variable_set(:@__commands__, SmartCore::Container::CommandSet.new)
30
- child_klass.__commands__.concat(__commands__)
31
- child_klass.singleton_class.prepend(ClassInheritance)
32
- super
33
- end
34
- end
28
+ # @since 0.7.0
29
+ module ClassInheritance
30
+ # @param child_klass [Class<SmartCore::Container>]
31
+ # @return [void]
32
+ #
33
+ # @api private
34
+ # @since 0.7.0
35
+ def inherited(child_klass)
36
+ child_klass.instance_variable_set(:@__container_definition_commands__, CommandSet.new)
37
+ child_klass.instance_variable_set(:@__container_instantiation_commands__, CommandSet.new)
38
+ child_klass.instance_variable_set(:@__container_definition_lock__, ArbitaryLock.new)
35
39
 
36
- # @api private
37
- # @since 0.5.0
38
- module ClassMethods
39
- # @param namespace_name [String, Symbol]
40
- # @param dependency_definitions [Block]
41
- # @return [void]
42
- #
43
- # @api public
44
- # @since 0.5.0
45
- def namespace(namespace_name, &dependency_definitions)
46
- __commands__ << SmartCore::Container::Commands::Namespace.new(
47
- namespace_name, dependency_definitions
48
- )
40
+ child_klass.__container_definition_commands__.concat(
41
+ __container_definition_commands__
42
+ )
43
+
44
+ child_klass.__container_instantiation_commands__.concat(
45
+ __container_instantiation_commands__
46
+ )
47
+
48
+ child_klass.singleton_class.prepend(ClassInheritance)
49
+ super
50
+ end
49
51
  end
50
52
 
51
- # @param dependency_name [String, Symbol]
52
- # @param options [Hash<Symbol,Any>]
53
- # @param dependency_definition [Proc]
54
- # @return [void]
55
- #
56
- # @todo option list
57
- #
58
- # @api public
59
- # @since 0.5.0
60
- def register(dependency_name, **options, &dependency_definition)
61
- __commands__ << SmartCore::Container::Commands::Register.new(
62
- dependency_name, dependency_definition, **options
63
- )
53
+ # @api private
54
+ # @since 0.7.0
55
+ module ClassMethods
56
+ # @param namespace_name [String, Symbol]
57
+ # @param dependencies_definition [Block]
58
+ # @return [void]
59
+ #
60
+ # @api public
61
+ # @since 0.7.0
62
+ def namespace(namespace_name, &dependencies_definition)
63
+ @__container_definition_lock__.thread_safe do
64
+ DependencyCompatability::Definition.prevent_dependency_overlap!(self, namespace_name)
65
+
66
+ __container_definition_commands__ << Commands::Definition::Namespace.new(
67
+ namespace_name, dependencies_definition
68
+ )
69
+ end
70
+ end
71
+
72
+ # @param dependency_name [String, Symbol]
73
+ # @param dependency_definition [Block]
74
+ # @return [void]
75
+ #
76
+ # @api public
77
+ # @since 0.7.0
78
+ def register(dependency_name, &dependency_definition)
79
+ @__container_definition_lock__.thread_safe do
80
+ DependencyCompatability::Definition.prevent_namespace_overlap!(self, dependency_name)
81
+
82
+ __container_definition_commands__ << Commands::Definition::Register.new(
83
+ dependency_name, dependency_definition
84
+ )
85
+ end
86
+ end
87
+
88
+ # @param container_klass [Class<SmartCore::Container>]
89
+ # @return [void]
90
+ #
91
+ # @api public
92
+ # @since 0.7.0
93
+ def compose(container_klass)
94
+ @__container_definition_lock__.thread_safe do
95
+ __container_definition_commands__ << Commands::Definition::Compose.new(
96
+ container_klass
97
+ )
98
+
99
+ __container_instantiation_commands__ << Commands::Instantiation::Compose.new(
100
+ container_klass
101
+ )
102
+ end
103
+ end
104
+
105
+ # @return [void]
106
+ #
107
+ # @api public
108
+ # @since 0.7.0
109
+ def freeze_state!
110
+ @__container_definition_lock__.thread_safe do
111
+ __container_instantiation_commands__ << Commands::Instantiation::FreezeState.new
112
+ end
113
+ end
64
114
  end
65
115
  end
66
116
  end