servactory 1.2.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ef221cf056da7376cec0a04e0dd92ddba328f34163fe050d74e3f0158eb1e17
4
- data.tar.gz: 2bc1b62867fb2e6c09692bfd76c315bbf739202b445fc99e46511b6dd3437c6f
3
+ metadata.gz: d4ffa3b926585163837e461a8a1b129a81f951f88a8d715dd6e74297e0a37ddd
4
+ data.tar.gz: 1d1a3326828e282ad0f46bc76e2754fb44e0dbd5f2e00c452cd6e856866bcbbd
5
5
  SHA512:
6
- metadata.gz: 126ca96b81dcbea82334b216f9b911c33282aca4c66c26d511655339cd56184ce6fac7475420184f6fcd4681d34afe210f8ebffe18e0894c635c6bcbdc045754
7
- data.tar.gz: 22675c25495d5e2b3edfda926c5392985294c78c03e0e2d6f8930b8a8d5a7618dc94dd7cec413fba5b6ce234d23bbeea44c68cf58fc95d0e223c73c437721b43
6
+ metadata.gz: 07c4e1f255a4fabe953a3c1381229000b564b80fc0e4f1c08547fed23dcc9cb9b31ebab678d76f894ce55e5506120d412fab26bf214f433f00cf43d958b502d7
7
+ data.tar.gz: 85cadb2169b968a0e9cda6f9279d9be37b01acdc0f7f91ca2b7f8458e89a219213ad317b84002d1b7684bb695a73b4c5a3a6c092a4e3a61c05984e2ee027a164
data/README.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  A set of tools for building reliable services of any complexity.
4
4
 
5
+ [![Gem version](https://img.shields.io/gem/v/servactory?logo=rubygems&logoColor=fff)](https://rubygems.org/gems/servactory)
6
+
7
+ ## Contents
8
+
9
+ - [Requirements](https://github.com/afuno/servactory/edit/main/README.md#requirements)
10
+ - [Getting started](https://github.com/afuno/servactory/edit/main/README.md#getting-started)
11
+ - [Conventions](https://github.com/afuno/servactory/edit/main/README.md#conventions)
12
+ - [Installation](https://github.com/afuno/servactory/edit/main/README.md#installation)
13
+ - [Preparation](https://github.com/afuno/servactory/edit/main/README.md#preparation)
14
+ - [Usage](https://github.com/afuno/servactory/edit/main/README.md#usage)
15
+ - [Minimal example](https://github.com/afuno/servactory#minimal-example)
16
+ - [Input attributes](https://github.com/afuno/servactory#input-attributes)
17
+ - [Isolated usage](https://github.com/afuno/servactory#isolated-usage)
18
+ - [As an internal argument](https://github.com/afuno/servactory#isolated-usage)
19
+ - [Optional inputs](https://github.com/afuno/servactory#optional-inputs)
20
+ - [An array of specific values](https://github.com/afuno/servactory#an-array-of-specific-values)
21
+ - [Inclusion](https://github.com/afuno/servactory#inclusion)
22
+ - [Must](https://github.com/afuno/servactory#must)
23
+ - [Output attributes](https://github.com/afuno/servactory/edit/main/README.md#output-attributes)
24
+ - [Internal attributes](https://github.com/afuno/servactory/edit/main/README.md#internal-attributes)
25
+ - [Result](https://github.com/afuno/servactory/edit/main/README.md#result)
26
+
5
27
  ## Requirements
6
28
 
7
29
  - Ruby >= 2.7
@@ -70,7 +92,7 @@ end
70
92
  ### Minimal example
71
93
 
72
94
  ```ruby
73
- class SendService < ApplicationService::Base
95
+ class MinimalService < ApplicationService::Base
74
96
  stage { make :something }
75
97
 
76
98
  private
@@ -81,36 +103,158 @@ class SendService < ApplicationService::Base
81
103
  end
82
104
  ```
83
105
 
84
- ### Inputs
106
+ ### Input attributes
107
+
108
+ #### Isolated usage
109
+
110
+ With this approach, all input attributes are available only from `inputs`. This is default behaviour.
85
111
 
86
112
  ```ruby
87
- class SendService < ApplicationService::Base
113
+ class UsersService::Accept < ApplicationService::Base
88
114
  input :user, type: User
89
115
 
90
- stage { make :something }
116
+ stage { make :accept! }
91
117
 
92
118
  private
93
119
 
94
- def something
95
- # ...
120
+ def accept!
121
+ inputs.user.accept!
122
+ end
123
+ end
124
+ ```
125
+
126
+ #### As an internal argument
127
+
128
+ With this approach, all input attributes are available from `inputs` as well as directly from the context.
129
+
130
+ ```ruby
131
+ class UsersService::Accept < ApplicationService::Base
132
+ input :user, type: User, internal: true
133
+
134
+ stage { make :accept! }
135
+
136
+ private
137
+
138
+ def accept!
139
+ user.accept!
96
140
  end
97
141
  end
98
142
  ```
99
143
 
100
- ### Outputs
144
+ #### Optional inputs
145
+
146
+ By default, all inputs are required. To make an input optional, specify `false` in the `required` option.
147
+
148
+ ```ruby
149
+ class UsersService::Create < ApplicationService::Base
150
+ input :first_name, type: String, internal: true
151
+ input :middle_name, type: String, required: false
152
+ input :last_name, type: String, internal: true
153
+
154
+ # ...
155
+ end
156
+ ```
157
+
158
+ #### An array of specific values
159
+
160
+ ```ruby
161
+ class PymentsService::Send < ApplicationService::Base
162
+ input :invoice_numbers, type: String, array: true
163
+
164
+ # ...
165
+ end
166
+ ```
167
+
168
+ #### Inclusion
169
+
170
+ ```ruby
171
+ class EventService::Send < ApplicationService::Base
172
+ input :event_name, type: String, inclusion: %w[created rejected approved]
173
+
174
+ # ...
175
+ end
176
+ ```
177
+
178
+ #### Must
179
+
180
+ Sometimes there are cases that require the implementation of a specific input attribute check. In such cases `must` can help.
101
181
 
102
182
  ```ruby
103
- class SendService < ApplicationService::Base
183
+ class PymentsService::Send < ApplicationService::Base
184
+ input :invoice_numbers,
185
+ type: String,
186
+ array: true,
187
+ must: {
188
+ be_6_characters: {
189
+ is: ->(value:) { value.all? { |id| id.size == 6 } }
190
+ }
191
+ }
192
+
193
+ # ...
194
+ end
195
+ ```
196
+
197
+ ### Output attributes
198
+
199
+ ```ruby
200
+ class NotificationService::Create < ApplicationService::Base
104
201
  input :user, type: User
105
202
 
106
203
  output :notification, type: Notification
107
204
 
108
- stage { make :something }
205
+ stage { make :create_notification! }
109
206
 
110
207
  private
111
208
 
112
- def something
113
- self.notification = Notification.create!
209
+ def create_notification!
210
+ self.notification = Notification.create!(user: inputs.user)
211
+ end
212
+ end
213
+ ```
214
+
215
+ ### Internal attributes
216
+
217
+ ```ruby
218
+ class NotificationService::Create < ApplicationService::Base
219
+ input :user, type: User
220
+
221
+ internal :inviter, type: User
222
+
223
+ output :notification, type: Notification
224
+
225
+ stage do
226
+ make :assign_inviter
227
+ make :create_notification!
228
+ end
229
+
230
+ private
231
+
232
+ def assign_inviter
233
+ self.inviter = user.inviter
234
+ end
235
+
236
+ def create_notification!
237
+ self.notification = Notification.create!(user: inputs.user, inviter:)
114
238
  end
115
239
  end
116
240
  ```
241
+
242
+ ### Result
243
+
244
+ All services have the result of their work. For example, in case of success this call:
245
+
246
+ ```ruby
247
+ service_result = NotificationService::Create.call!(user: User.first)
248
+ ```
249
+
250
+ Will return this:
251
+
252
+ ```ruby
253
+ #<Servactory::Result:0x0000000112c00748 @notification=...>
254
+ ```
255
+
256
+ And then you can work with this result, for example, in this way:
257
+
258
+ ```ruby
259
+ Notification::SendJob.perform_later(service_result.notification.id)
260
+ ```
@@ -35,11 +35,16 @@ module Servactory
35
35
 
36
36
  attr_reader :context_store
37
37
 
38
- def assign_data_with(arguments)
39
- input_arguments_workbench.assign(context: context_store.context, arguments: arguments) # 1
40
- internal_arguments_workbench.assign(context: context_store.context) # 2
41
- output_arguments_workbench.assign(context: context_store.context) # 3
42
- stage_handyman&.assign(context: context_store.context) # 4
38
+ def assign_data_with(arguments) # rubocop:disable Metrics/AbcSize
39
+ input_arguments_workbench.assign(
40
+ context: context_store.context,
41
+ arguments: arguments,
42
+ collection_of_input_options: collection_of_input_options
43
+ )
44
+
45
+ internal_arguments_workbench.assign(context: context_store.context)
46
+ output_arguments_workbench.assign(context: context_store.context)
47
+ stage_handyman&.assign(context: context_store.context)
43
48
  end
44
49
 
45
50
  def prepare_data
@@ -5,7 +5,7 @@ module Servactory
5
5
  module Checks
6
6
  class Inclusion < Base
7
7
  DEFAULT_MESSAGE = lambda do |service_class_name:, input:|
8
- "[#{service_class_name}] Wrong value in `#{input.name}`, must be one of `#{input.inclusion}`"
8
+ "[#{service_class_name}] Wrong value in `#{input.name}`, must be one of `#{input.inclusion[:in]}`"
9
9
  end
10
10
 
11
11
  private_constant :DEFAULT_MESSAGE
@@ -31,7 +31,7 @@ module Servactory
31
31
  end
32
32
 
33
33
  def check
34
- return if @input.inclusion.include?(@value)
34
+ return if @input.inclusion[:in].include?(@value)
35
35
 
36
36
  add_error(
37
37
  DEFAULT_MESSAGE,
@@ -32,7 +32,7 @@ module Servactory
32
32
  @check_options = check_options
33
33
  end
34
34
 
35
- def check
35
+ def check # rubocop:disable Metrics/MethodLength
36
36
  @check_options.each do |code, options|
37
37
  message = call_or_fetch_message_from(code, options)
38
38
 
@@ -57,10 +57,12 @@ module Servactory
57
57
  return if check.call(value: @value)
58
58
 
59
59
  message.presence || DEFAULT_MESSAGE
60
- rescue StandardError => _e
60
+ rescue StandardError => e
61
61
  message_text =
62
62
  "[#{@context.class.name}] Syntax error inside `#{code}` of `#{@input.name}` input"
63
63
 
64
+ puts "#{message_text}: #{e}"
65
+
64
66
  add_error(
65
67
  message_text,
66
68
  service_class_name: @context.class.name,
@@ -6,7 +6,15 @@ module Servactory
6
6
  class Type < Base
7
7
  DEFAULT_MESSAGE = lambda do |service_class_name:, input:, expected_type:, given_type:|
8
8
  if input.array?
9
- "[#{service_class_name}] Wrong type in input array `#{input.name}`, expected `#{expected_type}`"
9
+ array_message = input.array[:message]
10
+
11
+ if array_message.is_a?(Proc)
12
+ array_message.call(input: input, expected_type: expected_type)
13
+ elsif array_message.is_a?(String) && array_message.present?
14
+ array_message
15
+ else
16
+ "[#{service_class_name}] Wrong type in input array `#{input.name}`, expected `#{expected_type}`"
17
+ end
10
18
  else
11
19
  "[#{service_class_name}] Wrong type of input `#{input.name}`, " \
12
20
  "expected `#{expected_type}`, " \
@@ -11,13 +11,21 @@ module Servactory
11
11
  private
12
12
 
13
13
  def input(name, **options)
14
- collection_of_input_arguments << InputArgument.new(name, **options)
14
+ collection_of_input_arguments << InputArgument.new(
15
+ name,
16
+ collection_of_options: collection_of_input_options,
17
+ **options
18
+ )
15
19
  end
16
20
 
17
21
  def collection_of_input_arguments
18
22
  @collection_of_input_arguments ||= Collection.new
19
23
  end
20
24
 
25
+ def collection_of_input_options
26
+ @collection_of_input_options ||= OptionsCollection.new
27
+ end
28
+
21
29
  def input_arguments_workbench
22
30
  @input_arguments_workbench ||= Workbench.work_with(collection_of_input_arguments)
23
31
  end
@@ -2,73 +2,187 @@
2
2
 
3
3
  module Servactory
4
4
  module InputArguments
5
- class InputArgument
5
+ class InputArgument # rubocop:disable Metrics/ClassLength
6
+ ARRAY_DEFAULT_VALUE = ->(is: false, message: nil) { { is: is, message: message } }
7
+
6
8
  attr_reader :name,
7
- :types,
8
- :inclusion,
9
- :must,
10
- :array,
11
- :required,
12
- :internal,
13
- :default
14
-
15
- def initialize(name, type:, **options)
9
+ :collection_of_options,
10
+ :types
11
+
12
+ def initialize(name, collection_of_options:, type:, **options)
16
13
  @name = name
14
+ @collection_of_options = collection_of_options
17
15
  @types = Array(type)
18
16
 
19
- @inclusion = options.fetch(:inclusion, nil)
20
- @must = options.fetch(:must, nil)
21
- @array = options.fetch(:array, false)
22
- @required = options.fetch(:required, true)
23
- @internal = options.fetch(:internal, false)
24
- @default = options.fetch(:default, nil)
17
+ add_basic_options_with(options)
18
+
19
+ @collection_of_options.each do |option|
20
+ self.class.attr_reader(:"#{option.name}")
21
+
22
+ instance_variable_set(:"@#{option.name}", option.value)
23
+ end
25
24
  end
26
25
 
27
- def options_for_checks
28
- {
29
- types: types,
30
- inclusion: inclusion,
31
- must: must,
32
- required: required,
33
- # internal: internal,
34
- default: default
35
- }
26
+ def add_basic_options_with(options)
27
+ # Check Class: Servactory::InputArguments::Checks::Required
28
+ add_required_option_with(options)
29
+
30
+ # Check Class: Servactory::InputArguments::Checks::Type
31
+ add_array_option_with(options)
32
+ add_default_option_with(options)
33
+
34
+ # Check Class: Servactory::InputArguments::Checks::Inclusion
35
+ add_inclusion_option_with(options)
36
+
37
+ # Check Class: Servactory::InputArguments::Checks::Must
38
+ add_must_option_with(options)
39
+
40
+ # Check Class: nil
41
+ add_internal_option_with(options)
36
42
  end
37
43
 
38
- def conflict_code
39
- return :required_vs_default if required? && default_value_present?
40
- return :array_vs_array if array? && types.include?(Array)
41
- return :array_vs_inclusion if array? && inclusion_present?
44
+ def add_required_option_with(options) # rubocop:disable Metrics/MethodLength
45
+ collection_of_options << Option.new(
46
+ name: :required,
47
+ input: self,
48
+ check_class: Servactory::InputArguments::Checks::Required,
49
+ define_input_methods: lambda do
50
+ <<-RUBY
51
+ def required?
52
+ Servactory::Utils.boolean?(required[:is])
53
+ end
42
54
 
43
- nil
55
+ def optional?
56
+ !required?
57
+ end
58
+ RUBY
59
+ end,
60
+ define_conflicts: lambda do
61
+ <<-RUBY
62
+ return :required_vs_default if required? && default_value_present?
63
+ RUBY
64
+ end,
65
+ need_for_checks: true,
66
+ value_key: :is,
67
+ value_fallback: true,
68
+ **options
69
+ )
44
70
  end
45
71
 
46
- def inclusion_present?
47
- inclusion.is_a?(Array) && inclusion.present?
72
+ def add_array_option_with(options) # rubocop:disable Metrics/MethodLength
73
+ collection_of_options << Option.new(
74
+ name: :array,
75
+ input: self,
76
+ check_class: Servactory::InputArguments::Checks::Type,
77
+ define_input_methods: lambda do
78
+ <<-RUBY
79
+ def array?
80
+ Servactory::Utils.boolean?(array[:is])
81
+ end
82
+ RUBY
83
+ end,
84
+ define_conflicts: lambda do
85
+ <<-RUBY
86
+ return :array_vs_array if array? && types.include?(Array)
87
+ return :array_vs_inclusion if array? && inclusion_present?
88
+ RUBY
89
+ end,
90
+ need_for_checks: false,
91
+ value_key: :is,
92
+ value_fallback: false,
93
+ **options
94
+ )
48
95
  end
49
96
 
50
- def must_present?
51
- must.present?
97
+ def add_default_option_with(options) # rubocop:disable Metrics/MethodLength
98
+ collection_of_options << Option.new(
99
+ name: :default,
100
+ input: self,
101
+ check_class: Servactory::InputArguments::Checks::Type,
102
+ define_input_methods: lambda do
103
+ <<-RUBY
104
+ def default_value_present?
105
+ !default.nil?
106
+ end
107
+ RUBY
108
+ end,
109
+ need_for_checks: true,
110
+ value_fallback: nil,
111
+ with_advanced_mode: false,
112
+ **options
113
+ )
52
114
  end
53
115
 
54
- def array?
55
- Servactory::Utils.boolean?(array)
116
+ def add_inclusion_option_with(options) # rubocop:disable Metrics/MethodLength
117
+ collection_of_options << Option.new(
118
+ name: :inclusion,
119
+ input: self,
120
+ check_class: Servactory::InputArguments::Checks::Inclusion,
121
+ define_input_methods: lambda do
122
+ <<-RUBY
123
+ def inclusion_present?
124
+ inclusion[:in].is_a?(Array) && inclusion[:in].present?
125
+ end
126
+ RUBY
127
+ end,
128
+ need_for_checks: true,
129
+ value_key: :in,
130
+ value_fallback: nil,
131
+ **options
132
+ )
56
133
  end
57
134
 
58
- def required?
59
- Servactory::Utils.boolean?(required)
135
+ def add_must_option_with(options) # rubocop:disable Metrics/MethodLength
136
+ collection_of_options << Option.new(
137
+ name: :must,
138
+ input: self,
139
+ check_class: Servactory::InputArguments::Checks::Must,
140
+ define_input_methods: lambda do
141
+ <<-RUBY
142
+ def must_present?
143
+ must.present?
144
+ end
145
+ RUBY
146
+ end,
147
+ need_for_checks: true,
148
+ value_key: :is,
149
+ value_fallback: nil,
150
+ with_advanced_mode: false,
151
+ **options
152
+ )
60
153
  end
61
154
 
62
- def optional?
63
- !required?
155
+ def add_internal_option_with(options) # rubocop:disable Metrics/MethodLength
156
+ collection_of_options << Option.new(
157
+ name: :internal,
158
+ input: self,
159
+ define_input_methods: lambda do
160
+ <<-RUBY
161
+ def internal?
162
+ Servactory::Utils.boolean?(internal[:is])
163
+ end
164
+ RUBY
165
+ end,
166
+ need_for_checks: false,
167
+ check_class: nil,
168
+ value_key: :is,
169
+ value_fallback: false,
170
+ **options
171
+ )
64
172
  end
65
173
 
66
- def internal?
67
- Servactory::Utils.boolean?(internal)
174
+ def options_for_checks
175
+ {
176
+ types: types
177
+ }.merge(
178
+ collection_of_options.options_for_checks
179
+ )
68
180
  end
69
181
 
70
- def default_value_present?
71
- !default.nil?
182
+ def conflict_code
183
+ instance_eval(collection_of_options.defined_conflicts)
184
+
185
+ nil
72
186
  end
73
187
 
74
188
  def with_conflicts?
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ class Option
6
+ DEFAULT_VALUE = ->(key:, value:, message: nil) { { key => value, message: message } }
7
+
8
+ private_constant :DEFAULT_VALUE
9
+
10
+ attr_reader :name,
11
+ :check_class,
12
+ :define_conflicts,
13
+ :need_for_checks,
14
+ :value_key,
15
+ :value
16
+
17
+ def initialize(
18
+ name:,
19
+ input:,
20
+ check_class:,
21
+ need_for_checks:,
22
+ value_fallback:,
23
+ value_key: nil,
24
+ define_input_methods: nil,
25
+ define_conflicts: nil,
26
+ with_advanced_mode: true,
27
+ **options
28
+ ) # do
29
+ @name = name.to_sym
30
+ @check_class = check_class
31
+ @define_conflicts = define_conflicts
32
+ @need_for_checks = need_for_checks
33
+ @value_key = value_key
34
+
35
+ @value = prepare_value_for(options, value_fallback: value_fallback, with_advanced_mode: with_advanced_mode)
36
+
37
+ input.instance_eval(define_input_methods.call) if define_input_methods.present?
38
+ end
39
+
40
+ def need_for_checks?
41
+ need_for_checks
42
+ end
43
+
44
+ private
45
+
46
+ def prepare_value_for(options, value_fallback:, with_advanced_mode:)
47
+ return options.fetch(@name, value_fallback) unless with_advanced_mode
48
+
49
+ prepare_advanced_for(
50
+ value: options.fetch(@name, DEFAULT_VALUE.call(key: value_key, value: value_fallback)),
51
+ value_fallback: value_fallback
52
+ )
53
+ end
54
+
55
+ def prepare_advanced_for(value:, value_fallback:)
56
+ if value.is_a?(Hash)
57
+ DEFAULT_VALUE.call(
58
+ key: value_key,
59
+ value: value.fetch(value_key, value_fallback),
60
+ message: value.fetch(:message, nil)
61
+ )
62
+ else
63
+ DEFAULT_VALUE.call(key: value_key, value: value)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module InputArguments
5
+ class OptionsCollection
6
+ # NOTE: http://words.steveklabnik.com/beware-subclassing-ruby-core-classes
7
+ extend Forwardable
8
+ def_delegators :@collection, :<<, :each, :select, :map
9
+
10
+ def initialize(*)
11
+ @collection = []
12
+ end
13
+
14
+ def check_classes
15
+ select { |option| option.check_class.present? }.map(&:check_class).uniq
16
+ end
17
+
18
+ def options_for_checks
19
+ select(&:need_for_checks?).to_h do |option|
20
+ value = if option.value.is_a?(Hash)
21
+ option.value.key?(:is) ? option.value.fetch(:is) : option.value
22
+ else
23
+ option.value
24
+ end
25
+
26
+ [option.name, value]
27
+ end
28
+ end
29
+
30
+ def defined_conflicts
31
+ map { |option| option.define_conflicts&.call }.reject(&:blank?).uniq.join
32
+ end
33
+ end
34
+ end
35
+ end
@@ -8,10 +8,11 @@ module Servactory
8
8
  new(...).check!
9
9
  end
10
10
 
11
- def initialize(context, incoming_arguments, collection_of_input_arguments)
11
+ def initialize(context, incoming_arguments, collection_of_input_arguments, collection_of_input_options)
12
12
  @context = context
13
13
  @incoming_arguments = incoming_arguments
14
14
  @collection_of_input_arguments = collection_of_input_arguments
15
+ @collection_of_input_options = collection_of_input_options
15
16
 
16
17
  @errors = []
17
18
  end
@@ -58,20 +59,15 @@ module Servactory
58
59
  ########################################################################
59
60
 
60
61
  def check_classes
61
- [
62
- Servactory::InputArguments::Checks::Required,
63
- Servactory::InputArguments::Checks::Type,
64
- Servactory::InputArguments::Checks::Inclusion,
65
- Servactory::InputArguments::Checks::Must
66
- ]
62
+ @collection_of_input_options.check_classes
67
63
  end
68
64
 
69
65
  ########################################################################
70
66
 
71
67
  def raise_errors
72
- return if @errors.empty?
68
+ return if (tmp_errors = @errors.reject(&:blank?).uniq).empty?
73
69
 
74
- raise Servactory.configuration.input_argument_error_class, @errors.first
70
+ raise Servactory.configuration.input_argument_error_class, tmp_errors.first
75
71
  end
76
72
  end
77
73
  end
@@ -11,9 +11,10 @@ module Servactory
11
11
  @collection_of_input_arguments = collection_of_input_arguments
12
12
  end
13
13
 
14
- def assign(context:, arguments:)
14
+ def assign(context:, arguments:, collection_of_input_options:)
15
15
  @context = context
16
16
  @incoming_arguments = arguments
17
+ @collection_of_input_options = collection_of_input_options
17
18
  end
18
19
 
19
20
  def find_unnecessary!
@@ -29,12 +30,14 @@ module Servactory
29
30
  end
30
31
 
31
32
  def check!
32
- Tools::Check.check!(context, @incoming_arguments, collection_of_input_arguments)
33
+ Tools::Check.check!(context, @incoming_arguments, collection_of_input_arguments, collection_of_input_options)
33
34
  end
34
35
 
35
36
  private
36
37
 
37
- attr_reader :context, :collection_of_input_arguments
38
+ attr_reader :context,
39
+ :collection_of_input_arguments,
40
+ :collection_of_input_options
38
41
  end
39
42
  end
40
43
  end
@@ -3,7 +3,7 @@
3
3
  module Servactory
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 2
6
+ MINOR = 4
7
7
  PATCH = 0
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH].join(".")
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.2.0
4
+ version: 1.4.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-05 00:00:00.000000000 Z
11
+ date: 2023-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -178,6 +178,8 @@ files:
178
178
  - lib/servactory/input_arguments/collection.rb
179
179
  - lib/servactory/input_arguments/dsl.rb
180
180
  - lib/servactory/input_arguments/input_argument.rb
181
+ - lib/servactory/input_arguments/option.rb
182
+ - lib/servactory/input_arguments/options_collection.rb
181
183
  - lib/servactory/input_arguments/tools/check.rb
182
184
  - lib/servactory/input_arguments/tools/find_unnecessary.rb
183
185
  - lib/servactory/input_arguments/tools/prepare.rb