servactory 1.2.0 → 1.4.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: 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