convenient_service 0.18.0 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/lib/convenient_service/commands/is_service.rb +28 -0
  4. data/lib/convenient_service/commands/is_service_class.rb +30 -0
  5. data/lib/convenient_service/commands.rb +4 -0
  6. data/lib/convenient_service/common/plugins.rb +2 -3
  7. data/lib/convenient_service/core/concern/class_methods.rb +3 -0
  8. data/lib/convenient_service/core/entities/config/entities/concerns/entities/stack.rb +22 -0
  9. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/concern/instance_methods.rb +1 -1
  10. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middleware_creators/observable/entities/event.rb +13 -15
  11. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/commands/normalize_env.rb +55 -0
  12. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/commands.rb +1 -0
  13. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/chain/concern/instance_methods.rb +3 -3
  14. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/classic.rb +14 -0
  15. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/stack.rb +22 -0
  16. data/lib/convenient_service/dependencies/built_in.rb +0 -7
  17. data/lib/convenient_service/dependencies/extractions/ds.rb +45 -0
  18. data/lib/convenient_service/dependencies/only_queries.rb +29 -0
  19. data/lib/convenient_service/dependencies/queries/gems/active_model.rb +38 -0
  20. data/lib/convenient_service/dependencies/queries/gems/logger.rb +39 -0
  21. data/lib/convenient_service/dependencies/queries/gems/paint.rb +39 -0
  22. data/lib/convenient_service/dependencies/queries/gems/rspec.rb +60 -0
  23. data/lib/convenient_service/dependencies/queries/ruby.rb +103 -0
  24. data/lib/convenient_service/dependencies/queries/version/null_version.rb +87 -0
  25. data/lib/convenient_service/dependencies/queries/version.rb +87 -0
  26. data/lib/convenient_service/dependencies/queries.rb +536 -0
  27. data/lib/convenient_service/dependencies.rb +2 -438
  28. data/lib/convenient_service/feature/configs/standard.rb +0 -2
  29. data/lib/convenient_service/service/configs/amazing_print_inspect/aliases.rb +7 -0
  30. data/lib/convenient_service/service/configs/amazing_print_inspect.rb +61 -0
  31. data/lib/convenient_service/service/configs/awesome_print_inspect.rb +1 -1
  32. data/lib/convenient_service/service/configs/{minimal.rb → essential.rb} +2 -107
  33. data/lib/convenient_service/service/configs/standard/v1.rb +5 -10
  34. data/lib/convenient_service/service/configs/standard.rb +19 -31
  35. data/lib/convenient_service/service/configs.rb +1 -1
  36. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/expressions/and.rb +4 -1
  37. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/expressions/empty.rb +4 -4
  38. data/lib/convenient_service/service/plugins/can_have_connected_steps/entities/step_collection.rb +7 -0
  39. data/lib/convenient_service/service/plugins/can_have_fallbacks/concern.rb +18 -0
  40. data/lib/convenient_service/service/plugins/can_have_fallbacks/exceptions.rb +22 -4
  41. data/lib/convenient_service/service/plugins/can_have_fallbacks/middleware.rb +3 -3
  42. data/lib/convenient_service/service/plugins/can_have_rollbacks/middleware.rb +66 -0
  43. data/lib/convenient_service/service/plugins/can_have_rollbacks.rb +3 -0
  44. data/lib/convenient_service/service/plugins/can_have_sequential_steps/entities/step_collection.rb +7 -0
  45. data/lib/convenient_service/service/plugins/can_have_steps/commands/is_step.rb +34 -0
  46. data/lib/convenient_service/service/plugins/can_have_steps/commands.rb +1 -0
  47. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/concern/instance_methods.rb +22 -14
  48. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_method_step/can_be_executed/middleware.rb +1 -15
  49. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/exceptions.rb +53 -0
  50. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/middleware.rb +60 -15
  51. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks.rb +1 -0
  52. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_amazing_print_inspect/concern.rb +46 -0
  53. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_amazing_print_inspect.rb +3 -0
  54. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_awesome_print_inspect/concern.rb +3 -2
  55. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/has_result/middleware.rb +26 -1
  56. data/lib/convenient_service/service/plugins/can_have_steps.rb +41 -0
  57. data/lib/convenient_service/service/plugins/can_have_stubbed_results/commands/fetch_all_services_stubbed_results_cache.rb +2 -2
  58. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/exceptions.rb +53 -0
  59. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments/middleware.rb +108 -0
  60. data/lib/convenient_service/service/plugins/forbids_convenient_service_entities_as_constructor_arguments.rb +4 -0
  61. data/lib/convenient_service/service/plugins/has_amazing_print_inspect/concern.rb +39 -0
  62. data/lib/convenient_service/service/plugins/has_amazing_print_inspect.rb +3 -0
  63. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_from_exception/concern.rb +32 -0
  64. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_be_from_exception.rb +3 -0
  65. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/can_have_step/concern.rb +7 -0
  66. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_amazing_print_inspect/concern.rb +41 -0
  67. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_amazing_print_inspect.rb +3 -0
  68. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_awesome_print_inspect/concern.rb +2 -2
  69. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/concern/instance_methods.rb +0 -140
  70. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/code/plugins/has_amazing_print_inspect/concern.rb +46 -0
  71. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/code/plugins/has_amazing_print_inspect.rb +3 -0
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/plugins/has_amazing_print_inspect/concern.rb +46 -0
  73. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/plugins/has_amazing_print_inspect.rb +3 -0
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/message/plugins/has_amazing_print_inspect/concern.rb +46 -0
  75. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/message/plugins/has_amazing_print_inspect.rb +3 -0
  76. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/plugins/has_amazing_print_inspect/concern.rb +46 -0
  77. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/plugins/has_amazing_print_inspect.rb +3 -0
  78. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/concern/instance_methods.rb +161 -0
  79. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/concern.rb +27 -0
  80. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects/exceptions.rb +34 -0
  81. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/helps_to_learn_similarities_with_common_objects.rb +4 -0
  82. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins.rb +2 -0
  83. data/lib/convenient_service/service/plugins/has_mermaid_flowchart/concern.rb +6 -1
  84. data/lib/convenient_service/service/plugins/rescues_result_unhandled_exceptions/middleware.rb +1 -0
  85. data/lib/convenient_service/service/plugins.rb +3 -1
  86. data/lib/convenient_service/support/counter.rb +2 -0
  87. data/lib/convenient_service/support/middleware/stack_builder.rb +37 -0
  88. data/lib/convenient_service/support/thread_safe_counter.rb +1 -0
  89. data/lib/convenient_service/support.rb +0 -3
  90. data/lib/convenient_service/utils/object/get_own_method.rb +54 -0
  91. data/lib/convenient_service/utils/object/safe_send.rb +84 -0
  92. data/lib/convenient_service/utils/object.rb +24 -0
  93. data/lib/convenient_service/utils/string/enclose.rb +52 -0
  94. data/lib/convenient_service/utils/string.rb +5 -0
  95. data/lib/convenient_service/version.rb +1 -1
  96. data/lib/convenient_service.rb +62 -0
  97. metadata +149 -16
  98. data/lib/convenient_service/common/plugins/normalizes_env/middleware.rb +0 -31
  99. data/lib/convenient_service/common/plugins/normalizes_env.rb +0 -3
  100. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_have_fallbacks/result.rb +0 -3
  101. data/lib/convenient_service/services.rb +0 -4
  102. data/lib/convenient_service/support/gems/active_model.rb +0 -36
  103. data/lib/convenient_service/support/gems/logger.rb +0 -37
  104. data/lib/convenient_service/support/gems/paint.rb +0 -37
  105. data/lib/convenient_service/support/gems/rspec.rb +0 -58
  106. data/lib/convenient_service/support/ruby.rb +0 -53
  107. data/lib/convenient_service/support/version/null_version.rb +0 -85
  108. data/lib/convenient_service/support/version.rb +0 -75
  109. /data/lib/convenient_service/{support → dependencies/queries}/gems.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a908de0164e680bc5926c42eeeea9df2afdcddd065dcad74dcaf403aacfe22f5
4
- data.tar.gz: f10f0debfa96eeef7bf37ff35332606cd8a936833ab0f3ff98490bc0f8e6af37
3
+ metadata.gz: 1943fd64d61a41a18701985f5a7296b7cf3337ab0562c1912ee7765668dd6f3a
4
+ data.tar.gz: 02e2d46311210cd922b606848f36c82db136a7f2ca2013fba269c6c5eb3adc3a
5
5
  SHA512:
6
- metadata.gz: 4f172f536a57db46fd16a29ac859a59f32060c910db5ee568249be5a74328d001b152ad71cd81c35344085b41ea85f6e66f5dd8d9fdc414ed2fbe24433a3e002
7
- data.tar.gz: a64c8dda2bce2f27f1462f485c3b62268d06c48367d464486fd7a51c2fba01b0ba96da27c5d66a4f467b053b556631d395a25735833c7c448ad733e474b28540
6
+ metadata.gz: 74cded446d90f5b06675c5c19f7647792e195b47178504b14dbf650640186f33679e8bf8c17ad73e214ff5f1b38d233c7919c361f3f90c569435fc14e4c5d999
7
+ data.tar.gz: a7773a495b1805778221b006427562bd25acd7420c243aab192abaf0460d661d905259aed97a2c489ccd9e77bac349da1516f9dd8ec8d7b573115b5872229b92
data/README.md CHANGED
@@ -23,7 +23,7 @@
23
23
  [![Gem Version](https://badge.fury.io/rb/convenient_service.svg)](https://rubygems.org/gems/convenient_service) [![Gem Downloads](https://img.shields.io/gem/dt/convenient_service.svg)](https://rubygems.org/gems/convenient_service) ![visitors](https://visitor-badge.glitch.me/badge?page_id=marian13/convenient_service) ![GitHub repo size](https://img.shields.io/github/repo-size/marian13/convenient_service) [![GitHub Actions CI](https://github.com/marian13/convenient_service/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/marian13/convenient_service/actions/workflows/ci.yml) [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard) [![Coverage Status](https://coveralls.io/repos/github/marian13/convenient_service/badge.svg)](https://coveralls.io/github/marian13/convenient_service?branch=main) [![inline docs](http://inch-ci.org/github/marian13/convenient_service.svg?branch=main)](http://inch-ci.org/github/marian13/convenient_service) [![yard docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://marian13.github.io/convenient_service/)
24
24
  [![Convenient Service on stackoverflow](https://img.shields.io/badge/stackoverflow-community-orange.svg?logo=stackoverflow)](https://stackoverflow.com/tags/convenient-service)
25
25
  [![Patreon](https://img.shields.io/badge/patreon-donate-orange.svg)](https://www.patreon.com/user?u=31435716&fan_landing=true)
26
- [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
+ [![License: LGPL-3.0](https://img.shields.io/badge/license-LGPL--3.0-yellow.svg)](https://www.gnu.org/licenses/lgpl-3.0.html)
27
27
  <!-- badges:end -->
28
28
 
29
29
  <!-- logo:start -->
@@ -40,8 +40,7 @@ Yet another approach to revisit the service object pattern, but this time focusi
40
40
  <!-- warning:start -->
41
41
  ## ❗❗❗ WARNING ❗❗❗
42
42
 
43
- This library is under heavy development. Public API may be subject to change. The first major release is still to come. Use the current version at your own risk. Ruby 2.7+, JRuby 9.4+ (TruffleRuby support is planned as well). Thanks.
44
- <!-- features:end -->
43
+ This library is under heavy development. Most of the public API is polished, but it still may be subject to change. It has already been successfully used in production environments for more than a year, but the first major version is planned for the second quarter of 2025. Use the current version at your own risk. Ruby 2.7+, JRuby 9.4+ (TruffleRuby support is planned as well). Thanks.
45
44
  <!-- warning:end -->
46
45
 
47
46
  <!-- links:start -->
@@ -63,6 +62,8 @@ This library is under heavy development. Public API may be subject to change. Th
63
62
 
64
63
  - [Static Content](https://github.com/marian13/static_content/tree/main/convenient_service) repo.
65
64
 
65
+ - [Convenient Service Integration](https://github.com/marian13/convenient_service_integration) machinery.
66
+
66
67
  - Have a look at [Convenient Service Development Wiki](https://github.com/marian13/convenient_service/wiki) for the contribution tutorials.
67
68
 
68
69
  <!-- links:end -->
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Commands
5
+ class IsService < Support::Command
6
+ ##
7
+ # @!attribute [r] service
8
+ # @return [Object] Can be any type.
9
+ #
10
+ attr_reader :service
11
+
12
+ ##
13
+ # @param service [Object] Can be any type.
14
+ # @return [void]
15
+ #
16
+ def initialize(service:)
17
+ @service = service
18
+ end
19
+
20
+ ##
21
+ # @return [Boolean]
22
+ #
23
+ def call
24
+ Commands::IsServiceClass[service_class: service.class]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Commands
5
+ class IsServiceClass < Support::Command
6
+ ##
7
+ # @!attribute [r] service_class
8
+ # @return [Object] Can be any type.
9
+ #
10
+ attr_reader :service_class
11
+
12
+ ##
13
+ # @param service_class [Object] Can be any type.
14
+ # @return [void]
15
+ #
16
+ def initialize(service_class:)
17
+ @service_class = service_class
18
+ end
19
+
20
+ ##
21
+ # @return [Boolean]
22
+ #
23
+ def call
24
+ return unless service_class.instance_of?(::Class)
25
+
26
+ service_class.include?(Service::Configs::Essential)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commands/is_service_class"
4
+ require_relative "commands/is_service"
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  ##
4
- # NOTE: Order matters.
4
+ # @internal
5
+ # NOTE: Some plugins are order-dependent.
5
6
  #
6
- require_relative "plugins/normalizes_env"
7
-
8
7
  require_relative "plugins/caches_constructor_arguments"
9
8
  require_relative "plugins/caches_return_value"
10
9
  require_relative "plugins/can_be_copied"
@@ -117,6 +117,9 @@ module ConvenientService
117
117
  # - `lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb`
118
118
  # - https://gist.github.com/marian13/9c25041f835564e945d978839097d419
119
119
  #
120
+ # IMPORTANT: Psych has a monkey-patch `y` in IRB. That is why calling `Service.y` raise `private method called` instead of `undefined method`.
121
+ # - https://github.com/ruby/psych/blob/v5.1.2/lib/psych/y.rb#L5
122
+ #
120
123
  def method_missing(method, *args, **kwargs, &block)
121
124
  commit_config!(trigger: Constants::Triggers::CLASS_METHOD_MISSING)
122
125
 
@@ -48,6 +48,23 @@ module ConvenientService
48
48
  plain_stack.call(env)
49
49
  end
50
50
 
51
+ ##
52
+ # @param concern [ConvenientService::Support::Concern, Module]
53
+ # @param args [Array<Object>]
54
+ # @param block [Proc, nil]
55
+ # @return [ConvenientService::Core::Entities::Config::Entities::Concerns::Entities::Stack]
56
+ #
57
+ def unshift(concern, *args, &block)
58
+ plain_stack.unshift(cast(concern), *args, &block)
59
+
60
+ self
61
+ end
62
+
63
+ ##
64
+ # @return [ConvenientService::Core::Entities::Config::Entities::Concerns::Entities::Stack]
65
+ #
66
+ alias_method :prepend, :unshift
67
+
51
68
  ##
52
69
  # @param index_or_concern [Integer, ConvenientService::Support::Concern, Module]
53
70
  # @param concern [ConvenientService::Support::Concern, Module]
@@ -137,6 +154,11 @@ module ConvenientService
137
154
  self
138
155
  end
139
156
 
157
+ ##
158
+ # @return [ConvenientService::Core::Entities::Config::Entities::Concerns::Entities::Stack]
159
+ #
160
+ alias_method :remove, :delete
161
+
140
162
  ##
141
163
  # @param concern [ConvenientService::Support::Concern, Module]
142
164
  # @param args [Array<Object>]
@@ -78,7 +78,7 @@ module ConvenientService
78
78
  # # [Service::ClassMethodsMiddlewaresCallers, #<Class:Service>, ConvenientService::Core::ClassMethods, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
79
79
  #
80
80
  # ancestors_greater_than_methods_middlewares_callers # For the entity defined above.
81
- # # [#<Class:Service>, ConvenientService::Core::ClassMethods, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]# [Service::ClassMethodsMiddlewaresCallers, #<Class:Service>, ConvenientService::Core::ClassMethods, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
81
+ # # [#<Class:Service>, ConvenientService::Core::ClassMethods, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
82
82
  #
83
83
  # @note Returns empty array when `methods_middlewares_callers` are NOT prepended.
84
84
  # @note If you expect to receive not empty array, make sure the config is committed.
@@ -8,11 +8,16 @@ module ConvenientService
8
8
  class MethodMiddlewares
9
9
  module Entities
10
10
  module MiddlewareCreators
11
+ ##
12
+ # NOTE: `observer` is NOT a part of Ruby stdlib starting from Ruby 3.4. That is why a custom observer is implemented.
13
+ #
14
+ # @internal
15
+ # - https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html
16
+ # - https://github.com/ruby/observer
17
+ #
11
18
  class Observable < MiddlewareCreators::Base
12
19
  module Entities
13
20
  class Event
14
- include ::Observable
15
-
16
21
  ##
17
22
  # @!attribute [r] type
18
23
  # @return [Symbol]
@@ -41,7 +46,7 @@ module ConvenientService
41
46
  # @see https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html#method-i-add_observer
42
47
  #
43
48
  def add_observer(observer, func = default_handler_name)
44
- super
49
+ observers[observer] = func
45
50
  end
46
51
 
47
52
  ##
@@ -50,10 +55,8 @@ module ConvenientService
50
55
  # @see https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html#method-i-changed
51
56
  # @see https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html#method-i-notify_observers
52
57
  #
53
- def notify_observers(...)
54
- changed
55
-
56
- super
58
+ def notify_observers(*args, **kwargs, &block)
59
+ observers.each { |observer, method| observer.__send__(method, *args, **kwargs, &block) }
57
60
  end
58
61
 
59
62
  ##
@@ -64,7 +67,7 @@ module ConvenientService
64
67
  return unless other.instance_of?(self.class)
65
68
 
66
69
  return false if type != other.type
67
- return false if observer_peers != other.observer_peers
70
+ return false if observers != other.observers
68
71
 
69
72
  true
70
73
  end
@@ -74,13 +77,8 @@ module ConvenientService
74
77
  ##
75
78
  # @return [Hash]
76
79
  #
77
- # @see https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html#method-i-count_observers
78
- #
79
- # @internal
80
- # IMPORTANT: This method is using inherited private instance varaible. Ruby may change its name without any warning.
81
- #
82
- def observer_peers
83
- @observer_peers if defined? @observer_peers
80
+ def observers
81
+ @observers ||= {}
84
82
  end
85
83
  end
86
84
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Core
5
+ module Entities
6
+ class Config
7
+ module Entities
8
+ class MethodMiddlewares
9
+ module Entities
10
+ module Middlewares
11
+ class Chain < Middlewares::Base
12
+ module Commands
13
+ ##
14
+ # - Single splat `*` converts `nil` to empty array.
15
+ # - Double splat `**` raises on `nil`.
16
+ # - Umpersand `&` converts `nil` to `nil`.
17
+ #
18
+ # The following middleware converts `env[:kwargs]` to a hash.
19
+ # This way `__send__(:next, *env[:args], **env[:kwargs], &env[:block])` won't fail even if a user passes `nil` as `kwargs`.
20
+ #
21
+ # Check the following link for more details:
22
+ # - https://bugs.ruby-lang.org/issues/8507
23
+ #
24
+ class NormalizeEnv < Support::Command
25
+ ##
26
+ # @!attribute [r] env
27
+ # @return [Hash, nil]
28
+ #
29
+ attr_reader :env
30
+
31
+ ##
32
+ # @param env [Hash, nil]
33
+ # @return [void]
34
+ #
35
+ def initialize(env:)
36
+ @env = env.to_h
37
+ end
38
+
39
+ ##
40
+ # @return [Hash]
41
+ #
42
+ def call
43
+ env.merge(args: env[:args].to_a, kwargs: env[:kwargs].to_h, block: env[:block])
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "commands/create_observable_middleware"
4
+ require_relative "commands/normalize_env"
@@ -42,12 +42,12 @@ module ConvenientService
42
42
  # @return [Object] Can be any type.
43
43
  #
44
44
  def call(env)
45
- @__env__ = env
45
+ @__env__ = Commands::NormalizeEnv.call(env: env)
46
46
 
47
47
  ##
48
48
  # IMPORTANT: This is a library code. Do NOT do things like this in your application code.
49
49
  #
50
- chain.instance_variable_set(:@env, env)
50
+ chain.instance_variable_set(:@env, @__env__)
51
51
 
52
52
  ##
53
53
  # NOTE: `__send__` is used since `next` is ruby keyword.
@@ -55,7 +55,7 @@ module ConvenientService
55
55
  #
56
56
  # TODO: Enforce to always pass args, kwargs, block.
57
57
  #
58
- __send__(:next, *env[:args], **env[:kwargs], &env[:block])
58
+ __send__(:next, *@__env__[:args], **@__env__[:kwargs], &@__env__[:block])
59
59
  end
60
60
 
61
61
  ##
@@ -9,6 +9,20 @@ module ConvenientService
9
9
  module Entities
10
10
  module Middlewares
11
11
  ##
12
+ # Class `ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Classic` allows to define middlewares that interacts with `call` and `env` directly.
13
+ # For example `ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Chain::Commands::NormalizeEnv` was implemeted as middleware up to v0.18.
14
+ #
15
+ # class Middleware < MethodClassicMiddleware
16
+ # intended_for any_method, scope: any_scope, entity: any_entity
17
+ #
18
+ # def call(env = nil)
19
+ # env = env.to_h
20
+ # env = env.merge(args: env[:args].to_a, kwargs: env[:kwargs].to_h, block: env[:block])
21
+ #
22
+ # stack.call(env)
23
+ # end
24
+ # end
25
+ #
12
26
  # @abstract Subclass and override `#call`.
13
27
  #
14
28
  # @internal
@@ -49,6 +49,23 @@ module ConvenientService
49
49
  plain_stack.call(env)
50
50
  end
51
51
 
52
+ ##
53
+ # @param middleware [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
54
+ # @param args [Array<Object>]
55
+ # @param block [Proc, nil]
56
+ # @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Stack]
57
+ #
58
+ def unshift(middleware, *args, &block)
59
+ plain_stack.unshift(middleware, *args, &block)
60
+
61
+ self
62
+ end
63
+
64
+ ##
65
+ # @return [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Stack]
66
+ #
67
+ alias_method :prepend, :unshift
68
+
52
69
  ##
53
70
  # @param index_or_middleware [Integer, ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
54
71
  # @param middleware [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
@@ -140,6 +157,11 @@ module ConvenientService
140
157
  self
141
158
  end
142
159
 
160
+ ##
161
+ # @return [ConvenientService::Core::Entities::Config::Entities::Concerns::Entities::Stack]
162
+ #
163
+ alias_method :remove, :delete
164
+
143
165
  ##
144
166
  # @param middleware [ConvenientService::Core::Entities::Config::Entities::MethodMiddlewares::Entities::Middlewares::Base]
145
167
  # @param args [Array<Object>]
@@ -28,13 +28,6 @@ require "erb"
28
28
  #
29
29
  require "logger"
30
30
 
31
- ##
32
- # @internal
33
- # - https://ruby-doc.org/stdlib-2.7.0/libdoc/observer/rdoc/Observable.html
34
- # - https://github.com/ruby/observer
35
- #
36
- require "observer"
37
-
38
31
  ##
39
32
  # @internal
40
33
  # - https://ruby-doc.org/stdlib-2.7.0/libdoc/rubygems/rdoc/Gem/Version.html
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @api private
5
+ #
6
+ # Defines `ds` helper in order to have a quick way to find differences between strings like `git diff`.
7
+ #
8
+ # @param first_string [String]
9
+ # @param second_string [String]
10
+ # @return [nil]
11
+ #
12
+ # @note `ds' is a dev-only helper.
13
+ # @note `ds` is a short for `diff_strings`.
14
+ #
15
+ # @example
16
+ # first_string = <<~TEXT
17
+ # Step of `AnonymousClass(#14360)` is passed as constructor argument `kwargs[:baz]` to `AnonymousClass(#14360)`.
18
+ #
19
+ # It is an antipattern. It neglects the idea of steps.
20
+ #
21
+ # Please, try to reorganize `AnonymousClass(#14400)` service.
22
+ # TEXT
23
+ #
24
+ # second_string = <<~TEXT
25
+ # Step of `AnonymousClass(#14360)` is passed as constructor argument `kwargs[:baz]` to `AnonymousClass(#14400)`.
26
+ #
27
+ # It is an antipattern. It neglects the idea of steps.
28
+ #
29
+ # Please, try to reorganize `AnonymousClass(#14400)` service.
30
+ # TEXT
31
+ #
32
+ # ds(first_string, second_string)
33
+ # =>
34
+ # -Step of `AnonymousClass(#14360)` is passed as constructor argument `kwargs[:baz]` to `AnonymousClass(#14360)`.
35
+ # +Step of `AnonymousClass(#14360)` is passed as constructor argument `kwargs[:baz]` to `AnonymousClass(#14400)`.
36
+ #
37
+ # It is an antipattern. It neglects the idea of steps.
38
+ #
39
+ # Please, try to reorganize `AnonymousClass(#14400)` service.
40
+ #
41
+ def ds(first_string, second_string)
42
+ require "diffy"
43
+
44
+ puts ::Diffy::Diff.new(first_string, second_string).to_s(:color)
45
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @internal
5
+ # - https://ruby-doc.org/stdlib-2.7.0/libdoc/rubygems/rdoc/Gem/Version.html
6
+ # - https://github.com/rubygems/rubygems
7
+ # - https://github.com/rubygems/rubygems/blob/master/lib/rubygems/version.rb
8
+ #
9
+ require "rubygems"
10
+
11
+ ##
12
+ # This file load extracted dependencies.
13
+ #
14
+ # @internal
15
+ # https://github.com/marian13/convenient_service/wiki/Docs:-Dependencies
16
+ #
17
+ require_relative "queries"
18
+
19
+ ##
20
+ # `ConvenientService::Dependencies` can dynamically require plugins/extensions that have external dependencies.
21
+ #
22
+ # @internal
23
+ # https://github.com/marian13/convenient_service/wiki/Docs:-Dependencies
24
+ #
25
+ module ConvenientService
26
+ module Dependencies
27
+ extend Queries
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Dependencies
5
+ module Queries
6
+ module Gems
7
+ ##
8
+ # @api private
9
+ #
10
+ class ActiveModel
11
+ class << self
12
+ ##
13
+ # @return [Boolean]
14
+ #
15
+ # @internal
16
+ # `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
17
+ #
18
+ # rubocop:disable Style/TernaryParentheses
19
+ def loaded?
20
+ (defined? ::ActiveModel) ? true : false
21
+ end
22
+ # rubocop:enable Style/TernaryParentheses
23
+
24
+ ##
25
+ # @return [ConvenientService::Dependencies::Queries::Version]
26
+ #
27
+ # @internal
28
+ # https://github.com/rails/rails/blob/main/activemodel/lib/active_model/version.rb
29
+ #
30
+ def version
31
+ loaded? ? Version.new(::ActiveModel.version) : Version.null_version
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Dependencies
5
+ module Queries
6
+ module Gems
7
+ class Logger
8
+ class << self
9
+ ##
10
+ # @api private
11
+ #
12
+ # @return [Boolean]
13
+ #
14
+ # @internal
15
+ # `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
16
+ #
17
+ # rubocop:disable Style/TernaryParentheses
18
+ def loaded?
19
+ (defined? ::Logger) ? true : false
20
+ end
21
+ # rubocop:enable Style/TernaryParentheses
22
+
23
+ ##
24
+ # @api private
25
+ #
26
+ # @return [ConvenientService::Dependencies::Queries::Version]
27
+ #
28
+ # @internal
29
+ # - https://github.com/ruby/logger/blob/v1.5.3/lib/logger/version.rb
30
+ #
31
+ def version
32
+ loaded? ? Version.new(::Logger::VERSION) : Version.null_version
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Dependencies
5
+ module Queries
6
+ module Gems
7
+ class Paint
8
+ class << self
9
+ ##
10
+ # @api private
11
+ #
12
+ # @return [Boolean]
13
+ #
14
+ # @internal
15
+ # `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
16
+ #
17
+ # rubocop:disable Style/TernaryParentheses
18
+ def loaded?
19
+ (defined? ::Paint) ? true : false
20
+ end
21
+ # rubocop:enable Style/TernaryParentheses
22
+
23
+ ##
24
+ # @api private
25
+ #
26
+ # @return [ConvenientService::Dependencies::Queries::Version]
27
+ #
28
+ # @internal
29
+ # - https://github.com/janlelis/paint/blob/v2.2.1/lib/paint/version.rb
30
+ #
31
+ def version
32
+ loaded? ? Version.new(::Paint::VERSION) : Version.null_version
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Dependencies
5
+ module Queries
6
+ module Gems
7
+ ##
8
+ # @api private
9
+ #
10
+ class RSpec
11
+ class << self
12
+ ##
13
+ # @return [Boolean]
14
+ #
15
+ # @internal
16
+ # `Style/TernaryParentheses` is disabled since `defined?` has too low priority without parentheses.
17
+ #
18
+ # rubocop:disable Style/TernaryParentheses
19
+ def loaded?
20
+ (defined? ::RSpec) ? true : false
21
+ end
22
+ # rubocop:enable Style/TernaryParentheses
23
+
24
+ ##
25
+ # @return [ConvenientService::Dependencies::Queries::Version]
26
+ #
27
+ # @internal
28
+ # https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/version.rb
29
+ #
30
+ def version
31
+ loaded? ? Version.new(::RSpec::Core::Version::STRING) : Version.null_version
32
+ end
33
+
34
+ ##
35
+ # @return [RSpec::Core::Example, nil]
36
+ #
37
+ # @internal
38
+ # NOTE: Returns `nil` in environments where RSpec is NOT fully loaded, e.g: irb, rails console, etc.
39
+ #
40
+ # `::RSpec.current_example` docs:
41
+ # - https://www.rubydoc.info/github/rspec/rspec-core/RSpec.current_example
42
+ # - https://github.com/rspec/rspec-core/blob/v3.12.0/lib/rspec/core.rb#L122
43
+ # - https://relishapp.com/rspec/rspec-core/docs/metadata/current-example
44
+ #
45
+ def current_example
46
+ return unless loaded?
47
+
48
+ ##
49
+ # NOTE: This happens in Ruby-only projects where RSpec is loaded by `Bundler.require`, not by `bundle exec rspec`.
50
+ #
51
+ return unless ::RSpec.respond_to?(:current_example)
52
+
53
+ ::RSpec.current_example
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end