servactory 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 995ff46dfe5e3620a05d0bbe4b21f515de2b63e593f971e1ec906721cd4bfb6d
4
- data.tar.gz: 9df30c884f28760025da0a9f1e68ccb12a42e5cea702602c086fd0b31212da62
3
+ metadata.gz: 417ec054ab2d314d3a54167a81ee92408cc3f631fea88220d85d06838dcb86db
4
+ data.tar.gz: 4e49086ca53660fd8e7e7cddce9734092703278f6da7f3880b43922ae053fe49
5
5
  SHA512:
6
- metadata.gz: 6bf7a7a0b667c3dce0926747b36fa85dc7cb6452e54cf7a51367918f8530cd09996a0d21e5d19d0fc06bc91cdfa3c00f2f0a464b9816738b9ea935b88c0d997b
7
- data.tar.gz: 8b29bf3059b7420492c63321737eca8b9f79deea94ce52dfb5dd203c70f0a8fecbbeb29b55e2eb73a687220f85cbb71a5bd85664cd5b45a404e2cbe7ed168a42
6
+ metadata.gz: b511278027c0384d1643b46b3b88a48e17f1f2b5685824f06190f98c07f5e4398a5494b9da8c2c75250ed14c1f3b3123b2c917bb00fa0a9159b5ccecc1fc2117
7
+ data.tar.gz: '0865a04061268ae4e582a499728b4b881d41d398cf322c9a91f10d24f14588904b1c65dca2f81750bd5bd912ac04384344216d73aed6f5699499c50531a884f6'
data/README.md CHANGED
@@ -26,7 +26,7 @@ A set of tools for building reliable services of any complexity.
26
26
  - [Must](#must)
27
27
  - [Output attributes](#output-attributes)
28
28
  - [Internal attributes](#internal-attributes)
29
- - [Stage](#stage)
29
+ - [Make](#make)
30
30
  - [Failures](#failures)
31
31
  - [I18n](#i18n)
32
32
  - [Testing](#testing)
@@ -102,7 +102,7 @@ end
102
102
 
103
103
  ```ruby
104
104
  class MinimalService < ApplicationService::Base
105
- stage { make :call }
105
+ make :call
106
106
 
107
107
  private
108
108
 
@@ -164,8 +164,8 @@ With this approach, all input attributes are available only from `inputs`. This
164
164
  ```ruby
165
165
  class UsersService::Accept < ApplicationService::Base
166
166
  input :user, type: User
167
-
168
- stage { make :accept! }
167
+
168
+ make :accept!
169
169
 
170
170
  private
171
171
 
@@ -182,8 +182,8 @@ With this approach, all input attributes are available from `inputs` as well as
182
182
  ```ruby
183
183
  class UsersService::Accept < ApplicationService::Base
184
184
  input :user, type: User, internal: true
185
-
186
- stage { make :accept! }
185
+
186
+ make :accept!
187
187
 
188
188
  private
189
189
 
@@ -217,7 +217,7 @@ class NotificationService::Create < ApplicationService::Base
217
217
 
218
218
  output :notification, type: Notification
219
219
 
220
- stage { make :create_notification! }
220
+ make :create_notification!
221
221
 
222
222
  private
223
223
 
@@ -273,8 +273,8 @@ class NotificationService::Create < ApplicationService::Base
273
273
  input :user, type: User
274
274
 
275
275
  output :notification, type: Notification
276
-
277
- stage { make :create_notification! }
276
+
277
+ make :create_notification!
278
278
 
279
279
  private
280
280
 
@@ -293,11 +293,9 @@ class NotificationService::Create < ApplicationService::Base
293
293
  internal :inviter, type: User
294
294
 
295
295
  output :notification, type: Notification
296
-
297
- stage do
298
- make :assign_inviter
299
- make :create_notification!
300
- end
296
+
297
+ make :assign_inviter
298
+ make :create_notification!
301
299
 
302
300
  private
303
301
 
@@ -311,14 +309,12 @@ class NotificationService::Create < ApplicationService::Base
311
309
  end
312
310
  ```
313
311
 
314
- ### Stage
315
-
316
- A "stage" is a single action or group of actions that needs to be "make".
312
+ ### Make
317
313
 
318
314
  #### Minimal example
319
315
 
320
316
  ```ruby
321
- stage { make :something }
317
+ make :something
322
318
 
323
319
  def something
324
320
  # ...
@@ -328,26 +324,19 @@ end
328
324
  #### Condition
329
325
 
330
326
  ```ruby
331
- stage { make :something, if: -> { Settings.something.enabled } }
327
+ make :something, if: -> { Settings.something.enabled }
332
328
 
333
329
  def something
334
330
  # ...
335
331
  end
336
332
  ```
337
333
 
338
- #### Groups
339
-
340
- The functionality of stage groups will be expanded in future releases.
334
+ #### Several
341
335
 
342
336
  ```ruby
343
- stage do
344
- make :assign_api_model
345
- make :perform_api_request
346
- end
347
-
348
- stage do
349
- make :process_result
350
- end
337
+ make :assign_api_model
338
+ make :perform_api_request
339
+ make :process_result
351
340
 
352
341
  def assign_api_model
353
342
  self.api_model = APIModel.new
@@ -362,14 +351,18 @@ def process_result
362
351
  end
363
352
  ```
364
353
 
354
+ #### Inheritance
355
+
356
+ Service inheritance is also supported.
357
+
365
358
  ### Failures
366
359
 
367
- The methods that are used in the stages may fail. In order to more informatively provide information about this outside the service, the following methods were prepared.
360
+ The methods that are used in `make` may fail. In order to more informatively provide information about this outside the service, the following methods were prepared.
368
361
 
369
362
  #### Fail
370
363
 
371
364
  ```ruby
372
- stage { make :check! }
365
+ make :check!
373
366
 
374
367
  def check!
375
368
  return if inputs.invoice_number.start_with?("AA")
@@ -381,7 +374,7 @@ end
381
374
  #### Fail for input
382
375
 
383
376
  ```ruby
384
- stage { make :check! }
377
+ make :check!
385
378
 
386
379
  def check!
387
380
  return if inputs.invoice_number.start_with?("AA")
@@ -7,7 +7,7 @@ module Servactory
7
7
  include InputArguments::DSL
8
8
  include InternalArguments::DSL
9
9
  include OutputArguments::DSL
10
- include Stage::DSL
10
+ include MakeMethods::DSL
11
11
 
12
12
  private_class_method :new
13
13
  end
@@ -18,7 +18,7 @@ module Servactory
18
18
 
19
19
  input_arguments_workbench.check!
20
20
 
21
- stage_handyman.run_methods!
21
+ make_methods_workbench.run!
22
22
 
23
23
  context_store.context.raise_first_fail
24
24
 
@@ -43,7 +43,7 @@ module Servactory
43
43
 
44
44
  input_arguments_workbench.check!
45
45
 
46
- stage_handyman.run_methods!
46
+ make_methods_workbench.run!
47
47
 
48
48
  Servactory::Result.prepare_for(
49
49
  context: context_store.context,
@@ -55,7 +55,7 @@ module Servactory
55
55
 
56
56
  attr_reader :context_store
57
57
 
58
- def assign_data_with(arguments) # rubocop:disable Metrics/AbcSize
58
+ def assign_data_with(arguments)
59
59
  input_arguments_workbench.assign(
60
60
  context: context_store.context,
61
61
  arguments: arguments,
@@ -64,7 +64,7 @@ module Servactory
64
64
 
65
65
  internal_arguments_workbench.assign(context: context_store.context)
66
66
  output_arguments_workbench.assign(context: context_store.context)
67
- stage_handyman&.assign(context: context_store.context)
67
+ make_methods_workbench.assign(context: context_store.context)
68
68
  end
69
69
 
70
70
  def prepare_data
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ class Engine < Rails::Engine
5
+ isolate_namespace Servactory
6
+ end
7
+ end
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map
8
+ def_delegators :@collection, :<<, :each, :map, :merge
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -8,6 +8,12 @@ module Servactory
8
8
  end
9
9
 
10
10
  module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_input_arguments).merge(collection_of_input_arguments)
15
+ end
16
+
11
17
  private
12
18
 
13
19
  def input(name, **options)
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map
8
+ def_delegators :@collection, :<<, :each, :map, :merge
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -8,6 +8,12 @@ module Servactory
8
8
  end
9
9
 
10
10
  module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_internal_arguments).merge(collection_of_internal_arguments)
15
+ end
16
+
11
17
  private
12
18
 
13
19
  def internal(name, **options)
@@ -21,7 +21,8 @@ module Servactory
21
21
 
22
22
  private
23
23
 
24
- attr_reader :context, :collection_of_internal_arguments
24
+ attr_reader :context,
25
+ :collection_of_internal_arguments
25
26
  end
26
27
  end
27
28
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module Stage
5
- class Methods
4
+ module MakeMethods
5
+ class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@methods, :<<, :each
8
+ def_delegators :@collection, :<<, :each, :merge
9
9
 
10
10
  def initialize(*)
11
- @methods = Set.new
11
+ @collection = Set.new
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module MakeMethods
5
+ module DSL
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_make_methods).merge(collection_of_make_methods)
15
+ end
16
+
17
+ private
18
+
19
+ def make(name, **options)
20
+ collection_of_make_methods << MakeMethod.new(name, **options)
21
+ end
22
+
23
+ def collection_of_make_methods
24
+ @collection_of_make_methods ||= Collection.new
25
+ end
26
+
27
+ def make_methods_workbench
28
+ @make_methods_workbench ||= Workbench.work_with(collection_of_make_methods)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,21 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Servactory
4
- module Stage
5
- class Method
6
- attr_reader :name, :condition
4
+ module MakeMethods
5
+ class MakeMethod
6
+ attr_reader :name,
7
+ :condition
7
8
 
8
9
  def initialize(name, **options)
9
10
  @name = name
10
11
 
11
12
  @condition = options.fetch(:if, nil)
12
13
  end
13
-
14
- # def options
15
- # {
16
- # condition:
17
- # }
18
- # end
19
14
  end
20
15
  end
21
16
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module MakeMethods
5
+ class Workbench
6
+ def self.work_with(...)
7
+ new(...)
8
+ end
9
+
10
+ def initialize(collection_of_make_methods)
11
+ @collection_of_make_methods = collection_of_make_methods
12
+ end
13
+
14
+ def assign(context:)
15
+ @context = context
16
+ end
17
+
18
+ def run!
19
+ collection_of_make_methods.each do |make_method|
20
+ next if unnecessary_for?(make_method)
21
+
22
+ context.send(make_method.name)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :context,
29
+ :collection_of_make_methods
30
+
31
+ def unnecessary_for?(make_method)
32
+ condition = make_method.condition
33
+
34
+ return false if condition.blank?
35
+ return !Servactory::Utils.boolean?(condition) unless condition.is_a?(Proc)
36
+
37
+ !condition.call(context)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -5,7 +5,7 @@ module Servactory
5
5
  class Collection
6
6
  # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
7
  extend Forwardable
8
- def_delegators :@collection, :<<, :each, :map
8
+ def_delegators :@collection, :<<, :each, :map, :merge
9
9
 
10
10
  def initialize(*)
11
11
  @collection = Set.new
@@ -8,6 +8,12 @@ module Servactory
8
8
  end
9
9
 
10
10
  module ClassMethods
11
+ def inherited(child)
12
+ super
13
+
14
+ child.send(:collection_of_output_arguments).merge(collection_of_output_arguments)
15
+ end
16
+
11
17
  private
12
18
 
13
19
  def output(name, **options)
@@ -3,8 +3,8 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 4
7
- PATCH = 6
6
+ MINOR = 5
7
+ PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
10
10
  end
data/lib/servactory.rb CHANGED
@@ -5,7 +5,6 @@ require "zeitwerk"
5
5
  require "active_support/core_ext/string"
6
6
 
7
7
  # require "servactory/support/loader"
8
- # require "servactory/engine"
9
8
 
10
9
  loader = Zeitwerk::Loader.for_gem
11
10
  loader.inflector.inflect(
@@ -29,6 +28,8 @@ module Servactory
29
28
  end
30
29
  end
31
30
 
31
+ require "servactory/engine" if defined?(Rails::Engine)
32
+
32
33
  # require_relative "servactory/exceptions"
33
34
 
34
35
  # require_relative "servactory/base"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servactory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.6
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton Sokolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-16 00:00:00.000000000 Z
11
+ date: 2023-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -186,6 +186,7 @@ files:
186
186
  - lib/servactory/context/workspace.rb
187
187
  - lib/servactory/context/workspace/error.rb
188
188
  - lib/servactory/context/workspace/errors.rb
189
+ - lib/servactory/engine.rb
189
190
  - lib/servactory/errors/base.rb
190
191
  - lib/servactory/errors/failure.rb
191
192
  - lib/servactory/errors/input_argument_error.rb
@@ -218,6 +219,10 @@ files:
218
219
  - lib/servactory/internal_arguments/internal_argument.rb
219
220
  - lib/servactory/internal_arguments/tools/prepare.rb
220
221
  - lib/servactory/internal_arguments/workbench.rb
222
+ - lib/servactory/make_methods/collection.rb
223
+ - lib/servactory/make_methods/dsl.rb
224
+ - lib/servactory/make_methods/make_method.rb
225
+ - lib/servactory/make_methods/workbench.rb
221
226
  - lib/servactory/output_arguments/checks/base.rb
222
227
  - lib/servactory/output_arguments/checks/type.rb
223
228
  - lib/servactory/output_arguments/collection.rb
@@ -227,11 +232,6 @@ files:
227
232
  - lib/servactory/output_arguments/tools/prepare.rb
228
233
  - lib/servactory/output_arguments/workbench.rb
229
234
  - lib/servactory/result.rb
230
- - lib/servactory/stage/dsl.rb
231
- - lib/servactory/stage/factory.rb
232
- - lib/servactory/stage/handyman.rb
233
- - lib/servactory/stage/method.rb
234
- - lib/servactory/stage/methods.rb
235
235
  - lib/servactory/utils.rb
236
236
  - lib/servactory/version.rb
237
237
  homepage: https://github.com/afuno/servactory
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Stage
5
- module DSL
6
- def self.included(base)
7
- base.extend(ClassMethods)
8
- end
9
-
10
- module ClassMethods
11
- private
12
-
13
- attr_reader :stage_handyman
14
-
15
- def stage(&block)
16
- @stage_factory ||= Factory.new
17
-
18
- @stage_factory.instance_eval(&block)
19
-
20
- @stage_handyman = Handyman.work_in(@stage_factory)
21
-
22
- # @stage_factory
23
-
24
- nil
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Stage
5
- class Factory
6
- def make(name, **options)
7
- methods << Method.new(name, **options)
8
- end
9
-
10
- def methods
11
- @methods ||= Methods.new
12
- end
13
- end
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Servactory
4
- module Stage
5
- class Handyman
6
- def self.work_in(...)
7
- new(...)
8
- end
9
-
10
- def initialize(factory)
11
- @factory = factory
12
- end
13
-
14
- def assign(context:)
15
- @context = context
16
- end
17
-
18
- def methods
19
- factory.methods
20
- end
21
-
22
- def run_methods!
23
- methods.each do |method|
24
- next if method.condition && !method.condition.call(context)
25
-
26
- context.send(method.name)
27
- end
28
- end
29
-
30
- private
31
-
32
- attr_reader :factory, :context
33
- end
34
- end
35
- end