light-services 2.0.0.rc3 → 2.0.0.rc7

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: 38e4a0f496e63ba78279cf3f1f1b671e838eb1509f4c59f4ee9694c831d64c13
4
- data.tar.gz: 8019b013bcef53aa1e9be21818dcb0ab21095d4f1db539b6c891967dc22afabd
3
+ metadata.gz: 56f8e05e0898a95e0012bd2bedf572743cbc6869b560b4a7c53aaf826a148851
4
+ data.tar.gz: 31349929949615aa616c6c5b58737c4248cf199df340cfa52672b446ef7dd0b3
5
5
  SHA512:
6
- metadata.gz: b7f9f99835b0151b1f98016ad4af7767b17e49c3d65a1e991fe8522055a17f58301c183706bc30e2cebc40bd94990d21da70f66f01b17e104b2ed08c56a8a27e
7
- data.tar.gz: e2d2b02ca50631518a02329d4b439f253e59ce648cdb4e37448b7a43209a6d2379272c083516862e0dbe38e8999e6419f2d9ece538f0d8a4a15e73e292211dba
6
+ metadata.gz: b9fb14ebb26407e8eda911e54bd3bc40cf57977ddda0b7626d2712624e446b9c55e1727a43308771bc85792be3df9701da3441db7127e40bf77a35acb89bf4db
7
+ data.tar.gz: 48fade5a78989a8a71c07c055f92d666585367a1140dc26b2799162738efa072815d8511e6c1d7c68d20c6163393ae9acdc7868720462d972b67810c6335158d
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- light-services (2.0.0.rc2)
4
+ light-services (2.0.0.rc7)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "light/services/message"
3
4
  require "light/services/messages"
4
5
  require "light/services/base_with_context"
5
6
 
@@ -27,14 +28,10 @@ module Light
27
28
  mount_class_based_collection :arguments, item_class: Settings::Argument, shortcut: :arg, allow_redefine: true
28
29
 
29
30
  # Arguments
30
- # TODO: Rename internal arguments
31
+ arg :verbose, default: false
31
32
  arg :benchmark, default: false
32
33
  arg :deepness, default: 0, context: true
33
34
 
34
- # Steps
35
- step :load_defaults_and_validate
36
- step :log_header, if: :benchmark?
37
-
38
35
  # Getters
39
36
  attr_reader :outputs, :arguments, :errors, :warnings
40
37
 
@@ -77,6 +74,9 @@ module Light
77
74
  end
78
75
 
79
76
  def call
77
+ load_defaults_and_validate
78
+ log_header if benchmark? || verbose?
79
+
80
80
  time = Benchmark.ms do
81
81
  run_steps
82
82
  run_steps_with_always
@@ -92,9 +92,12 @@ module Light
92
92
  end
93
93
 
94
94
  class << self
95
- # TODO: Create `run!`
96
- def run(args = {})
97
- new(args).tap(&:call)
95
+ def run(args = {}, config = {})
96
+ new(args, config).tap(&:call)
97
+ end
98
+
99
+ def run!(args = {})
100
+ run(args, raise_on_error: true)
98
101
  end
99
102
 
100
103
  def with(service_or_config = {}, config = {})
@@ -14,11 +14,15 @@ module Light
14
14
  raise Light::Services::ArgTypeError, "#{parent_service.class} - must be a subclass of Light::Services::Base"
15
15
  end
16
16
 
17
- # TODO: Create `run!`
18
17
  def run(args = {})
19
18
  @service_class.new(extend_arguments(args), @config, @parent_service).tap(&:call)
20
19
  end
21
20
 
21
+ def run!(args = {})
22
+ @config[:raise_on_error] = true
23
+ run(args)
24
+ end
25
+
22
26
  private
23
27
 
24
28
  def extend_arguments(args)
@@ -63,14 +63,12 @@ module Light
63
63
 
64
64
  def validate_name!(klass, name)
65
65
  if !@allow_redefine && all(klass).key?(name)
66
- # TODO: Update error class
67
66
  raise Light::Services::Error, "#{@item_class} with name `#{name}` already exists in service #{klass}"
68
67
  end
69
68
  end
70
69
 
71
70
  def validate_opts!(klass, name, opts)
72
71
  if opts[:before] && opts[:after]
73
- # TODO: Update error class
74
72
  raise Light::Services::Error, "You cannot specify `before` and `after` " \
75
73
  "for #{@item_class} `#{name}` in service #{klass} at the same time"
76
74
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This class stores errors and warnings
4
+ module Light
5
+ module Services
6
+ class Message
7
+ # Getters
8
+ attr_reader :key, :text
9
+
10
+ def initialize(key, text, opts = {})
11
+ @key = key
12
+ @text = text
13
+ @opts = opts
14
+ end
15
+
16
+ def break?
17
+ @opts[:break]
18
+ end
19
+
20
+ def rollback?
21
+ @opts[:rollback]
22
+ end
23
+
24
+ def to_s
25
+ text
26
+ end
27
+ end
28
+ end
29
+ end
@@ -10,13 +10,21 @@ module Light
10
10
  @messages = {}
11
11
  end
12
12
 
13
- def add(key, message, opts = {})
14
- @messages[key] ||= []
15
- @messages[key] += [*message]
13
+ def add(key, text, opts = {})
14
+ raise Light::Services::Error, "Error text can't be blank" if !text || text.blank?
16
15
 
17
- raise!(key, message)
18
- break!(opts[:break])
19
- rollback!(opts[:rollback])
16
+ message = nil
17
+
18
+ [*text].each do |text|
19
+ message = text.is_a?(Message) ? text : Message.new(key, text, opts)
20
+
21
+ @messages[key] ||= []
22
+ @messages[key] << message
23
+ end
24
+
25
+ raise!(message)
26
+ break!(opts.key?(:break) ? opts[:break] : message.break?)
27
+ rollback!(opts.key?(:rollback) ? opts[:rollback] : message.rollback?) if !opts.key?(:last) || opts[:last]
20
28
  end
21
29
 
22
30
  def break?
@@ -26,45 +34,40 @@ module Light
26
34
  def copy_from(entity, opts = {})
27
35
  if defined?(ActiveRecord::Base) && entity.is_a?(ActiveRecord::Base)
28
36
  copy_from(entity.errors.messages, opts)
37
+ elsif entity.is_a?(Light::Services::Base)
38
+ copy_from(entity.errors, opts)
29
39
  elsif entity.respond_to?(:each)
30
- entity.each do |key, message|
31
- add(key, message, opts)
40
+ last_index = entity.size - 1
41
+
42
+ entity.each_with_index do |(key, message), index|
43
+ add(key, message, opts.merge(last: index == last_index))
32
44
  end
33
45
  else
34
- # TODO: Update error
35
- raise Light::Services::Error
46
+ raise Light::Services::Error, "Don't know how to import errors from #{entity}"
36
47
  end
37
48
  end
38
49
 
39
50
  def copy_to(entity)
40
- if defined?(ActiveRecord::Base) && entity.is_a?(ActiveRecord::Base)
41
- each do |key, message|
42
- entity.errors.add(key, message)
51
+ if defined?(ActiveRecord::Base) && entity.is_a?(ActiveRecord::Base) || entity.is_a?(Light::Services::Base)
52
+ each do |key, messages|
53
+ messages.each do |message|
54
+ entity.errors.add(key, message.to_s)
55
+ end
43
56
  end
44
57
  elsif entity.is_a?(Hash)
45
- each do |key, message|
58
+ each do |key, messages|
46
59
  entity[key] ||= []
47
- entity[key] << message
60
+ entity[key] += messages.map(&:to_s)
48
61
  end
49
62
  else
50
- # TODO: Update error
51
- raise Light::Services::Error
63
+ raise Light::Services::Error, "Don't know how to export errors to #{entity}"
52
64
  end
53
65
 
54
66
  entity
55
67
  end
56
68
 
57
- def errors_to_record(record)
58
- if !defined?(ActiveRecord::Base) || !record.is_a?(ActiveRecord::Base)
59
- # TODO: Update error
60
- raise Light::Services::Error
61
- end
62
-
63
- errors.each do |key, message|
64
- record.errors.add(key, message)
65
- end
66
-
67
- record
69
+ def to_h
70
+ @messages.to_h.map { |key, value| [key, value.map(&:to_s)] }.to_h
68
71
  end
69
72
 
70
73
  def method_missing(method, *args, &block)
@@ -87,10 +90,10 @@ module Light
87
90
  @break = true
88
91
  end
89
92
 
90
- def raise!(key, message)
93
+ def raise!(message)
91
94
  return unless @config[:raise_on_add]
92
95
 
93
- raise Light::Services::Error, "#{key.to_s.capitalize} #{message}"
96
+ raise Light::Services::Error, "#{message.key.to_s.capitalize} #{message}"
94
97
  end
95
98
 
96
99
  def rollback!(rollback)
@@ -6,7 +6,7 @@ module Light
6
6
  module Settings
7
7
  class Argument
8
8
  # Getters
9
- attr_reader :name, :default_exists, :default, :context, :optional
9
+ attr_reader :name, :default_exists, :default, :context, :optional, :arg_types_cache
10
10
 
11
11
  def initialize(name, service_class, opts = {})
12
12
  @name = name
@@ -18,6 +18,8 @@ module Light
18
18
  @default = opts.delete(:default)
19
19
  @optional = opts.delete(:optional)
20
20
 
21
+ @arg_types_cache = {}
22
+
21
23
  define_methods
22
24
  end
23
25
 
@@ -25,6 +27,8 @@ module Light
25
27
  return if !@type || [*@type].any? do |type|
26
28
  if type == :boolean
27
29
  value.is_a?(TrueClass) || value.is_a?(FalseClass)
30
+ elsif type.is_a?(Symbol)
31
+ arg_type(value) == type
28
32
  else
29
33
  value.is_a?(type)
30
34
  end
@@ -36,6 +40,19 @@ module Light
36
40
 
37
41
  private
38
42
 
43
+ def arg_type(value)
44
+ klass = value.class
45
+
46
+ @arg_types_cache[klass] ||= klass
47
+ .name
48
+ .gsub(/::/, '/')
49
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
50
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
51
+ .tr("-", "_")
52
+ .downcase
53
+ .to_sym
54
+ end
55
+
39
56
  def define_methods
40
57
  name = @name
41
58
 
@@ -20,10 +20,6 @@ module Light
20
20
  raise Light::Services::TwoConditions, "#{service_class} `if` and `unless` cannot be specified " \
21
21
  "for the step `#{name}` at the same time"
22
22
  end
23
-
24
- if @always && (@if || @unless)
25
- raise Light::Services::Error, "#{service_class} `always` cannot be combined with `if` and `unless`"
26
- end
27
23
  end
28
24
 
29
25
  def run(instance, benchmark: false)
@@ -65,7 +61,7 @@ module Light
65
61
  when Symbol
66
62
  instance.send(condition)
67
63
  when Proc
68
- condition.call
64
+ instance.instance_exec(&condition)
69
65
  else
70
66
  raise Light::Services::Error, "#{@service_class} condition should be a Symbol or Proc " \
71
67
  "for the step `#{@name}` (currently: #{condition.class})"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Light
4
4
  module Services
5
- VERSION = "2.0.0.rc3"
5
+ VERSION = "2.0.0.rc7"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: light-services
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc3
4
+ version: 2.0.0.rc7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Emelianenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-25 00:00:00.000000000 Z
11
+ date: 2022-03-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Powerful implementation of Service Object pattern for Ruby and Rails
14
14
  email:
@@ -41,6 +41,7 @@ files:
41
41
  - lib/light/services/collection/outputs.rb
42
42
  - lib/light/services/config.rb
43
43
  - lib/light/services/exceptions.rb
44
+ - lib/light/services/message.rb
44
45
  - lib/light/services/messages.rb
45
46
  - lib/light/services/settings/argument.rb
46
47
  - lib/light/services/settings/output.rb
@@ -70,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  - !ruby/object:Gem::Version
71
72
  version: 1.3.1
72
73
  requirements: []
73
- rubygems_version: 3.1.2
74
+ rubygems_version: 3.1.6
74
75
  signing_key:
75
76
  specification_version: 4
76
77
  summary: Powerful implementation of Service Object pattern for Ruby and Rails