servactory 1.9.6 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/config/locales/en.yml +19 -4
  3. data/config/locales/ru.yml +21 -6
  4. data/lib/servactory/{methods/method.rb → actions/action.rb} +2 -2
  5. data/lib/servactory/{methods/aliases_for_make → actions/aliases}/collection.rb +2 -2
  6. data/lib/servactory/{methods/method_collection.rb → actions/collection.rb} +3 -3
  7. data/lib/servactory/{methods → actions}/dsl.rb +9 -9
  8. data/lib/servactory/{methods/shortcuts_for_make → actions/shortcuts}/collection.rb +2 -2
  9. data/lib/servactory/actions/stages/collection.rb +20 -0
  10. data/lib/servactory/actions/stages/stage.rb +30 -0
  11. data/lib/servactory/{methods → actions}/tools/runner.rb +1 -1
  12. data/lib/servactory/{methods → actions}/workspace.rb +4 -2
  13. data/lib/servactory/base.rb +1 -1
  14. data/lib/servactory/configuration/dsl.rb +4 -2
  15. data/lib/servactory/configuration/factory.rb +12 -4
  16. data/lib/servactory/configuration/setup.rb +24 -8
  17. data/lib/servactory/context/workspace/inputs.rb +43 -7
  18. data/lib/servactory/context/workspace/outputs.rb +1 -1
  19. data/lib/servactory/context/workspace.rb +0 -4
  20. data/lib/servactory/dsl.rb +18 -1
  21. data/lib/servactory/inputs/collection.rb +1 -1
  22. data/lib/servactory/inputs/dsl.rb +2 -0
  23. data/lib/servactory/inputs/input.rb +106 -88
  24. data/lib/servactory/inputs/tools/distributor.rb +24 -0
  25. data/lib/servactory/inputs/tools/rules.rb +3 -3
  26. data/lib/servactory/inputs/tools/{find_unnecessary.rb → unnecessary.rb} +4 -4
  27. data/lib/servactory/inputs/tools/validation.rb +5 -7
  28. data/lib/servactory/inputs/validations/base.rb +1 -1
  29. data/lib/servactory/inputs/validations/inclusion.rb +15 -10
  30. data/lib/servactory/inputs/validations/must.rb +26 -17
  31. data/lib/servactory/inputs/validations/required.rb +16 -11
  32. data/lib/servactory/inputs/validations/type.rb +19 -69
  33. data/lib/servactory/inputs/workspace.rb +6 -3
  34. data/lib/servactory/internals/dsl.rb +6 -1
  35. data/lib/servactory/internals/internal.rb +81 -14
  36. data/lib/servactory/internals/validations/base.rb +1 -1
  37. data/lib/servactory/internals/validations/type.rb +6 -43
  38. data/lib/servactory/maintenance/attributes/define_conflict.rb +15 -0
  39. data/lib/servactory/maintenance/attributes/define_method.rb +17 -0
  40. data/lib/servactory/maintenance/attributes/option.rb +121 -0
  41. data/lib/servactory/maintenance/attributes/option_helper.rb +17 -0
  42. data/lib/servactory/maintenance/attributes/option_helpers_collection.rb +20 -0
  43. data/lib/servactory/maintenance/attributes/options_collection.rb +48 -0
  44. data/lib/servactory/maintenance/collection_mode/class_names_collection.rb +16 -0
  45. data/lib/servactory/maintenance/hash_mode/class_names_collection.rb +16 -0
  46. data/lib/servactory/maintenance/validations/collection.rb +66 -0
  47. data/lib/servactory/maintenance/validations/object_schema.rb +116 -0
  48. data/lib/servactory/maintenance/validations/types.rb +181 -0
  49. data/lib/servactory/outputs/dsl.rb +6 -1
  50. data/lib/servactory/outputs/output.rb +79 -19
  51. data/lib/servactory/outputs/validations/base.rb +1 -1
  52. data/lib/servactory/outputs/validations/type.rb +6 -45
  53. data/lib/servactory/version.rb +5 -4
  54. data/lib/servactory.rb +1 -1
  55. metadata +56 -30
  56. data/lib/servactory/inputs/define_input_conflict.rb +0 -13
  57. data/lib/servactory/inputs/define_input_method.rb +0 -15
  58. data/lib/servactory/inputs/option.rb +0 -98
  59. data/lib/servactory/inputs/option_helper.rb +0 -15
  60. data/lib/servactory/inputs/option_helpers_collection.rb +0 -18
  61. data/lib/servactory/inputs/options_collection.rb +0 -46
  62. data/lib/servactory/methods/stage.rb +0 -28
  63. data/lib/servactory/methods/stage_collection.rb +0 -18
@@ -4,97 +4,47 @@ module Servactory
4
4
  module Inputs
5
5
  module Validations
6
6
  class Type < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, input:, expected_type:, given_type:|
8
- if input.array?
9
- array_message = input.array[:message]
7
+ def self.check(context:, input:, check_key:, **)
8
+ return unless should_be_checked_for?(input, check_key)
10
9
 
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
- I18n.t(
17
- "servactory.inputs.checks.type.default_error.for_array",
18
- service_class_name: service_class_name,
19
- input_name: input.name,
20
- expected_type: expected_type,
21
- given_type: given_type
22
- )
23
- end
24
- else
25
- I18n.t(
26
- "servactory.inputs.checks.type.default_error.default",
27
- service_class_name: service_class_name,
28
- input_name: input.name,
29
- expected_type: expected_type,
30
- given_type: given_type
31
- )
32
- end
33
- end
34
-
35
- private_constant :DEFAULT_MESSAGE
36
-
37
- def self.check(context:, input:, value:, check_key:, check_options:)
38
- return unless should_be_checked_for?(input, value, check_key)
39
-
40
- new(context: context, input: input, value: value, types: check_options).check
10
+ new(context: context, input: input).check
41
11
  end
42
12
 
43
- def self.should_be_checked_for?(input, value, check_key)
13
+ def self.should_be_checked_for?(input, check_key)
44
14
  check_key == :types && (
45
15
  input.required? || (
46
16
  input.optional? && !input.default.nil?
47
17
  ) || (
48
- input.optional? && !value.nil?
18
+ input.optional? && !input.value.nil?
49
19
  )
50
20
  )
51
21
  end
52
22
 
53
- ##########################################################################
54
-
55
- def initialize(context:, input:, value:, types:)
23
+ def initialize(context:, input:)
56
24
  super()
57
25
 
58
26
  @context = context
59
27
  @input = input
60
- @value = value
61
- @types = types
62
28
  end
63
29
 
64
- def check # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
65
- return if prepared_types.any? do |type|
66
- if @input.array?
67
- prepared_value.is_a?(::Array) &&
68
- prepared_value.respond_to?(:all?) && prepared_value.all?(type)
69
- else
70
- prepared_value.is_a?(type)
71
- end
72
- end
73
-
74
- add_error(
75
- DEFAULT_MESSAGE,
76
- service_class_name: @context.class.name,
77
- input: @input,
78
- expected_type: prepared_types.join(", "),
79
- given_type: prepared_value.class.name
30
+ def check
31
+ Servactory::Maintenance::Validations::Types.validate!(
32
+ context: @context,
33
+ attribute: @input,
34
+ types: @input.types,
35
+ value: prepared_value,
36
+ error_callback: ->(**args) { add_error(**args) }
80
37
  )
81
38
  end
82
39
 
83
- ########################################################################
84
-
85
- def prepared_types
86
- @prepared_types ||=
87
- @types.map do |type|
88
- if type.is_a?(String)
89
- Object.const_get(type)
90
- else
91
- type
92
- end
93
- end
94
- end
40
+ private
95
41
 
96
42
  def prepared_value
97
- @prepared_value ||= @input.optional? && !@input.default.nil? && @value.blank? ? @input.default : @value
43
+ @prepared_value ||= if @input.optional? && !@input.default.nil? && @input.value.blank?
44
+ @input.default
45
+ else
46
+ @input.value
47
+ end
98
48
  end
99
49
  end
100
50
  end
@@ -3,12 +3,15 @@
3
3
  module Servactory
4
4
  module Inputs
5
5
  module Workspace
6
+ private
7
+
6
8
  def call!(incoming_arguments:, collection_of_inputs:, **)
7
9
  super
8
10
 
9
- Tools::FindUnnecessary.validate!(self, incoming_arguments, collection_of_inputs)
10
- Tools::Rules.validate!(self, collection_of_inputs)
11
- Servactory::Inputs::Tools::Validation.validate!(self, incoming_arguments, collection_of_inputs)
11
+ Tools::Unnecessary.find!(self, incoming_arguments, collection_of_inputs)
12
+ Tools::Distributor.assign!(incoming_arguments, collection_of_inputs)
13
+ Tools::Rules.check!(self, collection_of_inputs)
14
+ Tools::Validation.validate!(self, collection_of_inputs)
12
15
  end
13
16
  end
14
17
  end
@@ -17,7 +17,12 @@ module Servactory
17
17
  private
18
18
 
19
19
  def internal(name, **options)
20
- collection_of_internals << Internal.new(name, **options)
20
+ collection_of_internals << Internal.new(
21
+ name,
22
+ collection_mode_class_names: config.collection_mode_class_names,
23
+ hash_mode_class_names: config.hash_mode_class_names,
24
+ **options
25
+ )
21
26
  end
22
27
 
23
28
  def collection_of_internals
@@ -4,29 +4,96 @@ module Servactory
4
4
  module Internals
5
5
  class Internal
6
6
  attr_reader :name,
7
- :types,
8
- :required
7
+ :collection_mode_class_names,
8
+ :hash_mode_class_names
9
9
 
10
- def initialize(name, type:, **_options)
10
+ def initialize(
11
+ name,
12
+ collection_mode_class_names:,
13
+ hash_mode_class_names:,
14
+ **options
15
+ )
11
16
  @name = name
12
- @types = Array(type)
17
+ @collection_mode_class_names = collection_mode_class_names
18
+ @hash_mode_class_names = hash_mode_class_names
13
19
 
14
- @required = options.fetch(:required, true)
20
+ add_basic_options_with(options)
15
21
  end
16
22
 
17
- def options_for_checks
18
- {
19
- types: types,
20
- required: required
21
- }
23
+ def method_missing(name, *args, &block)
24
+ option = collection_of_options.find_by(name: name)
25
+
26
+ return super if option.nil?
27
+
28
+ option.body
29
+ end
30
+
31
+ def respond_to_missing?(name, *)
32
+ collection_of_options.names.include?(name) || super
33
+ end
34
+
35
+ def add_basic_options_with(options)
36
+ # Check Class: Servactory::Internals::Validations::Type
37
+ add_types_option_with(options)
38
+ add_collection_option_with(options)
39
+ add_hash_option_with(options)
22
40
  end
23
41
 
24
- def required?
25
- required
42
+ def add_types_option_with(options)
43
+ collection_of_options << Servactory::Maintenance::Attributes::Option.new(
44
+ name: :types,
45
+ attribute: self,
46
+ validation_class: Servactory::Internals::Validations::Type,
47
+ original_value: Array(options.fetch(:type)),
48
+ need_for_checks: true,
49
+ body_fallback: nil,
50
+ with_advanced_mode: false
51
+ )
26
52
  end
27
53
 
28
- def optional?
29
- !required
54
+ def add_collection_option_with(options) # rubocop:disable Metrics/MethodLength
55
+ collection_of_options << Servactory::Maintenance::Attributes::Option.new(
56
+ name: :consists_of,
57
+ attribute: self,
58
+ validation_class: Servactory::Internals::Validations::Type,
59
+ define_methods: [
60
+ Servactory::Maintenance::Attributes::DefineMethod.new(
61
+ name: :collection_mode?,
62
+ content: ->(**) { collection_mode_class_names.include?(options.fetch(:type)) }
63
+ )
64
+ ],
65
+ need_for_checks: false,
66
+ body_key: :type,
67
+ body_value: String,
68
+ body_fallback: String,
69
+ **options
70
+ )
71
+ end
72
+
73
+ def add_hash_option_with(options) # rubocop:disable Metrics/MethodLength
74
+ collection_of_options << Servactory::Maintenance::Attributes::Option.new(
75
+ name: :schema,
76
+ attribute: self,
77
+ validation_class: Servactory::Inputs::Validations::Type,
78
+ define_methods: [
79
+ Servactory::Maintenance::Attributes::DefineMethod.new(
80
+ name: :hash_mode?,
81
+ content: ->(**) { hash_mode_class_names.include?(options.fetch(:type)) }
82
+ )
83
+ ],
84
+ need_for_checks: false,
85
+ body_key: :is,
86
+ body_fallback: {},
87
+ **options
88
+ )
89
+ end
90
+
91
+ def collection_of_options
92
+ @collection_of_options ||= Servactory::Maintenance::Attributes::OptionsCollection.new
93
+ end
94
+
95
+ def options_for_checks
96
+ collection_of_options.options_for_checks
30
97
  end
31
98
  end
32
99
  end
@@ -6,7 +6,7 @@ module Servactory
6
6
  class Base
7
7
  protected
8
8
 
9
- def raise_error_with(message, **attributes)
9
+ def raise_error_with(message:, **attributes)
10
10
  message = message.call(**attributes) if message.is_a?(Proc)
11
11
 
12
12
  raise @context.class.config.internal_error_class.new(message: message)
@@ -4,24 +4,10 @@ module Servactory
4
4
  module Internals
5
5
  module Validations
6
6
  class Type < Base
7
- DEFAULT_MESSAGE = lambda do |service_class_name:, internal:, expected_type:, given_type:|
8
- I18n.t(
9
- "servactory.internals.checks.type.default_error",
10
- service_class_name: service_class_name,
11
- internal_name: internal.name,
12
- expected_type: expected_type,
13
- given_type: given_type
14
- )
15
- end
16
-
17
- private_constant :DEFAULT_MESSAGE
18
-
19
7
  def self.validate!(...)
20
8
  new(...).validate!
21
9
  end
22
10
 
23
- ##########################################################################
24
-
25
11
  def initialize(context:, internal:, value:)
26
12
  super()
27
13
 
@@ -31,37 +17,14 @@ module Servactory
31
17
  end
32
18
 
33
19
  def validate!
34
- return unless should_be_checked?
35
-
36
- return if prepared_types.any? { |type| @value.is_a?(type) }
37
-
38
- raise_error_with(
39
- DEFAULT_MESSAGE,
40
- service_class_name: @context.class.name,
41
- internal: @internal,
42
- expected_type: prepared_types.join(", "),
43
- given_type: @value.class.name
20
+ Servactory::Maintenance::Validations::Types.validate!(
21
+ context: @context,
22
+ attribute: @internal,
23
+ types: @internal.types,
24
+ value: @value,
25
+ error_callback: ->(**args) { raise_error_with(**args) }
44
26
  )
45
27
  end
46
-
47
- private
48
-
49
- def should_be_checked?
50
- @internal.required? || (
51
- @internal.optional? && !@value.nil?
52
- )
53
- end
54
-
55
- def prepared_types
56
- @prepared_types ||=
57
- Array(@internal.types).map do |type|
58
- if type.is_a?(String)
59
- Object.const_get(type)
60
- else
61
- type
62
- end
63
- end
64
- end
65
28
  end
66
29
  end
67
30
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class DefineConflict
7
+ attr_reader :content
8
+
9
+ def initialize(content:)
10
+ @content = content
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class DefineMethod
7
+ attr_reader :name,
8
+ :content
9
+
10
+ def initialize(name:, content:)
11
+ @name = name.to_sym
12
+ @content = content
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class Option
7
+ DEFAULT_BODY = ->(key:, body:, message: nil) { { key => body, message: message } }
8
+
9
+ private_constant :DEFAULT_BODY
10
+
11
+ attr_reader :name,
12
+ :validation_class,
13
+ :define_methods,
14
+ :define_conflicts,
15
+ :need_for_checks,
16
+ :body
17
+
18
+ # rubocop:disable Metrics/MethodLength
19
+ def initialize(
20
+ name:,
21
+ attribute:,
22
+ validation_class:,
23
+ need_for_checks:,
24
+ body_fallback:,
25
+ original_value: nil,
26
+ body_key: nil,
27
+ body_value: true,
28
+ define_methods: nil,
29
+ define_conflicts: nil,
30
+ with_advanced_mode: true,
31
+ **options
32
+ ) # do
33
+ @name = name.to_sym
34
+ @validation_class = validation_class
35
+ @define_methods = define_methods
36
+ @define_conflicts = define_conflicts
37
+ @need_for_checks = need_for_checks
38
+
39
+ @body = prepare_value_for(
40
+ original_value: original_value,
41
+ options: options,
42
+ body_key: body_key,
43
+ body_value: body_value,
44
+ body_fallback: body_fallback,
45
+ with_advanced_mode: with_advanced_mode
46
+ )
47
+
48
+ prepare_methods_for(attribute)
49
+ end
50
+ # rubocop:enable Metrics/MethodLength
51
+
52
+ def need_for_checks?
53
+ need_for_checks
54
+ end
55
+
56
+ private
57
+
58
+ def prepare_value_for(
59
+ original_value:,
60
+ options:,
61
+ body_key:,
62
+ body_value:,
63
+ body_fallback:,
64
+ with_advanced_mode:
65
+ )
66
+ return original_value if original_value.present?
67
+
68
+ return options.fetch(@name, body_fallback) unless with_advanced_mode
69
+
70
+ prepare_advanced_for(
71
+ body: options.fetch(@name, DEFAULT_BODY.call(key: body_key, body: body_fallback)),
72
+ body_key: body_key,
73
+ body_value: body_value,
74
+ body_fallback: body_fallback
75
+ )
76
+ end
77
+
78
+ # rubocop:disable Metrics/MethodLength
79
+ def prepare_advanced_for(
80
+ body:,
81
+ body_key:,
82
+ body_value:,
83
+ body_fallback:
84
+ )
85
+ if body.is_a?(Hash)
86
+ if @name == :schema && body.fetch(body_key, nil).nil?
87
+ DEFAULT_BODY.call(key: body_key, body: body)
88
+ else
89
+ message = body.fetch(:message, nil)
90
+
91
+ DEFAULT_BODY.call(
92
+ key: body_key,
93
+ body: body.fetch(body_key, message.present? ? body_value : body_fallback),
94
+ message: message
95
+ )
96
+ end
97
+ else
98
+ DEFAULT_BODY.call(key: body_key, body: body)
99
+ end
100
+ end
101
+ # rubocop:enable Metrics/MethodLength
102
+
103
+ def prepare_methods_for(attribute)
104
+ attribute.instance_eval(define_methods_template) if define_methods_template.present?
105
+ end
106
+
107
+ def define_methods_template
108
+ return if @define_methods.blank?
109
+
110
+ @define_methods_template ||= @define_methods.map do |define_method|
111
+ <<-RUBY
112
+ def #{define_method.name}
113
+ #{define_method.content.call(option: @body)}
114
+ end
115
+ RUBY
116
+ end.join("\n")
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class OptionHelper
7
+ attr_reader :name,
8
+ :equivalent
9
+
10
+ def initialize(name:, equivalent:)
11
+ @name = name
12
+ @equivalent = equivalent
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class OptionHelpersCollection
7
+ extend Forwardable
8
+ def_delegators :@collection, :<<, :find, :merge
9
+
10
+ def initialize(collection)
11
+ @collection = collection
12
+ end
13
+
14
+ def find_by(name:)
15
+ find { |helper| helper.name == name }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Attributes
6
+ class OptionsCollection
7
+ extend Forwardable
8
+ def_delegators :@collection, :<<, :filter, :each, :map, :flat_map, :find
9
+
10
+ def initialize(*)
11
+ @collection = Set.new
12
+ end
13
+
14
+ def names
15
+ map(&:name)
16
+ end
17
+
18
+ def validation_classes
19
+ filter { |option| option.validation_class.present? }.map(&:validation_class).uniq
20
+ end
21
+
22
+ def options_for_checks
23
+ filter(&:need_for_checks?).to_h do |option|
24
+ option_body = if option.body.is_a?(Hash)
25
+ option.body.key?(:is) ? option.body.fetch(:is) : option.body
26
+ else
27
+ option.body
28
+ end
29
+
30
+ [option.name, option_body]
31
+ end
32
+ end
33
+
34
+ def defined_conflict_code
35
+ flat_map do |option|
36
+ option.define_conflicts&.map do |define_input_conflict|
37
+ define_input_conflict.content.call
38
+ end
39
+ end.reject(&:blank?).first
40
+ end
41
+
42
+ def find_by(name:)
43
+ find { |option| option.name == name }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module CollectionMode
6
+ class ClassNamesCollection
7
+ extend Forwardable
8
+ def_delegators :@collection, :include?
9
+
10
+ def initialize(collection)
11
+ @collection = collection
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module HashMode
6
+ class ClassNamesCollection
7
+ extend Forwardable
8
+ def_delegators :@collection, :include?
9
+
10
+ def initialize(collection)
11
+ @collection = collection
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Servactory
4
+ module Maintenance
5
+ module Validations
6
+ class Collection
7
+ attr_reader :errors
8
+
9
+ def self.validate(...)
10
+ new(...).validate
11
+ end
12
+
13
+ def initialize(value:, types:, type:)
14
+ @value = value
15
+ @types = types
16
+ @type = type
17
+
18
+ @errors = []
19
+ end
20
+
21
+ def validate
22
+ unless @value.is_a?(prepared_type)
23
+ add_error(
24
+ expected_type: prepared_type.name,
25
+ given_type: @value.class.name
26
+ )
27
+
28
+ return self
29
+ end
30
+
31
+ validate_value!
32
+
33
+ self
34
+ end
35
+
36
+ def valid?
37
+ @errors.empty?
38
+ end
39
+
40
+ private
41
+
42
+ def prepared_type
43
+ @prepared_type ||= @types.fetch(0, Array)
44
+ end
45
+
46
+ def validate_value!
47
+ @value.each do |value_item|
48
+ next if value_item.is_a?(@type)
49
+
50
+ add_error(
51
+ expected_type: @type,
52
+ given_type: value_item.class.name
53
+ )
54
+ end
55
+ end
56
+
57
+ def add_error(expected_type:, given_type:)
58
+ @errors << {
59
+ expected_type: expected_type,
60
+ given_type: given_type
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end