light-services 2.0.0.beta1 → 2.0.0.rc4

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: 9f6aea8958d622cea908db1b8697ab34919a55b8a90ae08dcd1308498e5963ec
4
- data.tar.gz: d4a1226609083ba01282c7d1bc273e75c394b2d39a2c17cca53792bc7eff74ab
3
+ metadata.gz: 0cb56d628d4f4fa27faee797fb1292542a4804441b51bbad04063629ad85bf1a
4
+ data.tar.gz: 30ceeeed2d98b8e78d7d1ebe8d3aaee614d6f320a7038931eae2bcceb5518a69
5
5
  SHA512:
6
- metadata.gz: e1dcc97d1d3cf6d48062a2dcb7061ecaccf602224dfbb68111c83a499614d221c17b3b1c0301ca448e58d27bcbd495d5303b5577fb1facdf16140ac591b40c1c
7
- data.tar.gz: 0d3d5f2282f56fbe07f786f54c098f9235a5f84906f70aaac1214da61c3fbef847c2af9754228c9b6eb9a682a40f2dd1bb1737755457e67a1a6bb5dc56816ffc
6
+ metadata.gz: '0987294172814178aeec11f380433a361e1e469806958e1c6e12dc7465b9a166af58506531ee99c8d39ec78a45a57968fbd67973b10c45ee792ac7796ca0a4bc'
7
+ data.tar.gz: 63b6d21e02e68e93487f177a0096b341f55398b05a2876100e2c729eee10c33b75284e1f5a433038e9e431c60bf4296c5c477544b19938994b575e0dff4aa8b4
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ # Common
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /_yardoc/
@@ -8,5 +9,12 @@
8
9
  /tmp/
9
10
  /.idea/
10
11
 
11
- # rspec failure tracking
12
+ # RSpec failure tracking
12
13
  .rspec_status
14
+
15
+ # Ignore IDE files
16
+ /.idea
17
+ *.iml
18
+
19
+ # Ignore gem files
20
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,85 +1,86 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- light-services (2.0.0.beta1)
4
+ light-services (2.0.0.rc3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- activemodel (6.0.3.2)
10
- activesupport (= 6.0.3.2)
11
- activerecord (6.0.3.2)
12
- activemodel (= 6.0.3.2)
13
- activesupport (= 6.0.3.2)
14
- activesupport (6.0.3.2)
9
+ activemodel (6.1.4)
10
+ activesupport (= 6.1.4)
11
+ activerecord (6.1.4)
12
+ activemodel (= 6.1.4)
13
+ activesupport (= 6.1.4)
14
+ activesupport (6.1.4)
15
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
- i18n (>= 0.7, < 2)
17
- minitest (~> 5.1)
18
- tzinfo (~> 1.1)
19
- zeitwerk (~> 2.2, >= 2.2.2)
20
- ast (2.4.1)
21
- codecov (0.1.17)
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ tzinfo (~> 2.0)
19
+ zeitwerk (~> 2.3)
20
+ ast (2.4.2)
21
+ codecov (0.1.21)
22
22
  json
23
23
  simplecov
24
- url
25
- concurrent-ruby (1.1.6)
26
- database_cleaner (1.8.5)
27
- database_cleaner-active_record (1.8.0)
24
+ concurrent-ruby (1.1.9)
25
+ database_cleaner (1.99.0)
26
+ database_cleaner-active_record (1.99.0)
28
27
  activerecord
29
- database_cleaner (~> 1.8.0)
30
- diff-lcs (1.4.2)
31
- docile (1.3.2)
32
- i18n (1.8.3)
28
+ database_cleaner (~> 1.99.0)
29
+ diff-lcs (1.4.4)
30
+ docile (1.4.0)
31
+ i18n (1.8.10)
33
32
  concurrent-ruby (~> 1.0)
34
- json (2.3.0)
35
- minitest (5.14.1)
36
- parallel (1.19.2)
37
- parser (2.7.1.4)
33
+ json (2.5.1)
34
+ minitest (5.14.4)
35
+ parallel (1.20.1)
36
+ parser (3.0.2.0)
38
37
  ast (~> 2.4.1)
39
38
  rainbow (3.0.0)
40
- rake (13.0.1)
41
- regexp_parser (1.7.1)
42
- rexml (3.2.4)
43
- rspec (3.9.0)
44
- rspec-core (~> 3.9.0)
45
- rspec-expectations (~> 3.9.0)
46
- rspec-mocks (~> 3.9.0)
47
- rspec-core (3.9.2)
48
- rspec-support (~> 3.9.3)
49
- rspec-expectations (3.9.2)
39
+ rake (13.0.6)
40
+ regexp_parser (2.1.1)
41
+ rexml (3.2.5)
42
+ rspec (3.10.0)
43
+ rspec-core (~> 3.10.0)
44
+ rspec-expectations (~> 3.10.0)
45
+ rspec-mocks (~> 3.10.0)
46
+ rspec-core (3.10.1)
47
+ rspec-support (~> 3.10.0)
48
+ rspec-expectations (3.10.1)
50
49
  diff-lcs (>= 1.2.0, < 2.0)
51
- rspec-support (~> 3.9.0)
52
- rspec-mocks (3.9.1)
50
+ rspec-support (~> 3.10.0)
51
+ rspec-mocks (3.10.2)
53
52
  diff-lcs (>= 1.2.0, < 2.0)
54
- rspec-support (~> 3.9.0)
55
- rspec-support (3.9.3)
56
- rubocop (0.86.0)
53
+ rspec-support (~> 3.10.0)
54
+ rspec-support (3.10.2)
55
+ rubocop (0.93.1)
57
56
  parallel (~> 1.10)
58
- parser (>= 2.7.0.1)
57
+ parser (>= 2.7.1.5)
59
58
  rainbow (>= 2.2.2, < 4.0)
60
- regexp_parser (>= 1.7)
59
+ regexp_parser (>= 1.8)
61
60
  rexml
62
- rubocop-ast (>= 0.0.3, < 1.0)
61
+ rubocop-ast (>= 0.6.0)
63
62
  ruby-progressbar (~> 1.7)
64
63
  unicode-display_width (>= 1.4.0, < 2.0)
65
- rubocop-ast (0.0.3)
66
- parser (>= 2.7.0.1)
67
- rubocop-performance (1.6.1)
68
- rubocop (>= 0.71.0)
69
- rubocop-rspec (1.40.0)
70
- rubocop (>= 0.68.1)
71
- ruby-progressbar (1.10.1)
72
- simplecov (0.18.5)
64
+ rubocop-ast (1.8.0)
65
+ parser (>= 3.0.1.1)
66
+ rubocop-performance (1.10.2)
67
+ rubocop (>= 0.90.0, < 2.0)
68
+ rubocop-ast (>= 0.4.0)
69
+ rubocop-rspec (1.44.1)
70
+ rubocop (~> 0.87)
71
+ rubocop-ast (>= 0.7.1)
72
+ ruby-progressbar (1.11.0)
73
+ simplecov (0.21.2)
73
74
  docile (~> 1.1)
74
75
  simplecov-html (~> 0.11)
75
- simplecov-html (0.12.2)
76
+ simplecov_json_formatter (~> 0.1)
77
+ simplecov-html (0.12.3)
78
+ simplecov_json_formatter (0.1.3)
76
79
  sqlite3 (1.4.2)
77
- thread_safe (0.3.6)
78
- tzinfo (1.2.7)
79
- thread_safe (~> 0.1)
80
+ tzinfo (2.0.4)
81
+ concurrent-ruby (~> 1.0)
80
82
  unicode-display_width (1.7.0)
81
- url (0.3.2)
82
- zeitwerk (2.3.1)
83
+ zeitwerk (2.4.2)
83
84
 
84
85
  PLATFORMS
85
86
  ruby
@@ -26,8 +26,14 @@ module Light
26
26
  mount_class_based_collection :outputs, item_class: Settings::Output, shortcut: :output
27
27
  mount_class_based_collection :arguments, item_class: Settings::Argument, shortcut: :arg, allow_redefine: true
28
28
 
29
+ # Arguments
30
+ # TODO: Rename internal arguments
31
+ arg :benchmark, default: false
32
+ arg :deepness, default: 0, context: true
33
+
29
34
  # Steps
30
35
  step :load_defaults_and_validate
36
+ step :log_header, if: :benchmark?
31
37
 
32
38
  # Getters
33
39
  attr_reader :outputs, :arguments, :errors, :warnings
@@ -39,6 +45,7 @@ module Light
39
45
  @outputs = Collection::Outputs.new(self)
40
46
  @arguments = Collection::Arguments.new(self, args)
41
47
 
48
+ @done = false
42
49
  @launched_steps = []
43
50
 
44
51
  initialize_errors
@@ -61,12 +68,27 @@ module Light
61
68
  @warnings.any?
62
69
  end
63
70
 
71
+ def done!
72
+ @done = true
73
+ end
74
+
75
+ def done?
76
+ @done
77
+ end
78
+
64
79
  def call
65
- run_steps
66
- run_steps_with_always
80
+ time = Benchmark.ms do
81
+ run_steps
82
+ run_steps_with_always
83
+
84
+ copy_warnings_to_parent_service
85
+ copy_errors_to_parent_service
86
+ end
87
+
88
+ return unless benchmark
67
89
 
68
- copy_warnings_to_parent_service
69
- copy_errors_to_parent_service
90
+ log "🟢 Finished #{self.class} in #{time}ms"
91
+ puts
70
92
  end
71
93
 
72
94
  class << self
@@ -83,6 +105,11 @@ module Light
83
105
  end
84
106
  end
85
107
 
108
+ # TODO: Add possibility to specify logger
109
+ def log(message)
110
+ puts "#{' ' * deepness}→ #{message}"
111
+ end
112
+
86
113
  private
87
114
 
88
115
  def initialize_errors
@@ -104,7 +131,7 @@ module Light
104
131
  def run_steps
105
132
  within_transaction do
106
133
  self.class.steps.each do |name, step|
107
- @launched_steps << name if step.run(self)
134
+ @launched_steps << name if step.run(self, benchmark: benchmark)
108
135
 
109
136
  break if @errors.break? || @warnings.break?
110
137
  end
@@ -146,6 +173,10 @@ module Light
146
173
  @arguments.validate!
147
174
  end
148
175
 
176
+ def log_header
177
+ log "🏎 Run service #{self.class}"
178
+ end
179
+
149
180
  def within_transaction
150
181
  if @config[:use_transactions] && defined?(ActiveRecord::Base)
151
182
  ActiveRecord::Base.transaction(requires_new: true) { yield }
@@ -22,10 +22,11 @@ module Light
22
22
  private
23
23
 
24
24
  def extend_arguments(args)
25
- return args unless @parent_service
26
-
27
25
  # TODO: Do we need `.dup` here?
28
- @parent_service.arguments.extend_with_context(args)
26
+ args = @parent_service.arguments.extend_with_context(args) if @parent_service
27
+ args[:deepness] += 1 if args[:deepness]
28
+
29
+ args
29
30
  end
30
31
  end
31
32
  end
@@ -28,6 +28,14 @@ module Light
28
28
  @storage[key]
29
29
  end
30
30
 
31
+ def [](key)
32
+ get(key)
33
+ end
34
+
35
+ def []=(key, value)
36
+ set(key, value)
37
+ end
38
+
31
39
  def load_defaults
32
40
  settings_collection.each do |name, settings|
33
41
  next if !settings.default_exists || key?(name)
@@ -10,18 +10,13 @@ module Light
10
10
  @messages = {}
11
11
  end
12
12
 
13
- def add(key, message, opts = {})
13
+ def add(key, message, opts = {}, last: nil)
14
14
  @messages[key] ||= []
15
-
16
- if message.is_a?(Array)
17
- @messages[key] += message
18
- else
19
- @messages[key] << message
20
- end
15
+ @messages[key] += [*message]
21
16
 
22
17
  raise!(key, message)
23
18
  break!(opts[:break])
24
- rollback!(opts[:rollback])
19
+ rollback!(opts[:rollback]) if last.nil? || last
25
20
  end
26
21
 
27
22
  def break?
@@ -32,8 +27,10 @@ module Light
32
27
  if defined?(ActiveRecord::Base) && entity.is_a?(ActiveRecord::Base)
33
28
  copy_from(entity.errors.messages, opts)
34
29
  elsif entity.respond_to?(:each)
35
- entity.each do |key, message|
36
- add(key, message, opts)
30
+ last_index = entity.size - 1
31
+
32
+ entity.each_with_index do |(key, message), index|
33
+ add(key, message, opts, last: index == last_index)
37
34
  end
38
35
  else
39
36
  # TODO: Update error
@@ -20,13 +20,26 @@ 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
23
27
  end
24
28
 
25
- def run(instance)
29
+ def run(instance, benchmark: false)
26
30
  return false unless run?(instance)
27
31
 
28
32
  if instance.respond_to?(name, true)
29
- instance.send(name)
33
+ if benchmark
34
+ time = Benchmark.ms do
35
+ instance.send(name)
36
+ end
37
+
38
+ instance.log "⏱️ Step #{name} took #{time}ms"
39
+ else
40
+ instance.send(name)
41
+ end
42
+
30
43
  true
31
44
  else
32
45
  raise Light::Services::NoStepError, "Cannot find step `#{name}` in service `#{@service_class}`"
@@ -36,6 +49,8 @@ module Light
36
49
  private
37
50
 
38
51
  def run?(instance)
52
+ return false if instance.done?
53
+
39
54
  if @if
40
55
  check_condition(@if, instance)
41
56
  elsif @unless
@@ -48,7 +63,7 @@ module Light
48
63
  def check_condition(condition, instance)
49
64
  case condition
50
65
  when Symbol
51
- instance.public_send(condition)
66
+ instance.send(condition)
52
67
  when Proc
53
68
  condition.call
54
69
  else
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Light
4
4
  module Services
5
- VERSION = "2.0.0.beta1"
5
+ VERSION = "2.0.0.rc4"
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.beta1
4
+ version: 2.0.0.rc4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Emelianenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-22 00:00:00.000000000 Z
11
+ date: 2021-08-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Powerful implementation of Service Object pattern for Ruby and Rails
14
14
  email:
@@ -20,12 +20,6 @@ files:
20
20
  - ".github/config/rubocop_linter_action.yml"
21
21
  - ".github/workflows/ci.yml"
22
22
  - ".gitignore"
23
- - ".idea/.gitignore"
24
- - ".idea/inspectionProfiles/Project_Default.xml"
25
- - ".idea/light-services.iml"
26
- - ".idea/misc.xml"
27
- - ".idea/modules.xml"
28
- - ".idea/vcs.xml"
29
23
  - ".rspec"
30
24
  - ".rubocop.yml"
31
25
  - CHANGELOG.md
data/.idea/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- # Default ignored files
2
- /shelf/
3
- /workspace.xml
4
- # Datasource local storage ignored files
5
- /dataSources/
6
- /dataSources.local.xml
7
- # Editor-based HTTP Client requests
8
- /httpRequests/
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
5
- </profile>
6
- </component>
@@ -1,53 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="ModuleRunConfigurationManager">
4
- <shared />
5
- </component>
6
- <component name="NewModuleRootManager">
7
- <content url="file://$MODULE_DIR$">
8
- <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
9
- <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
10
- <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
- </content>
12
- <orderEntry type="jdk" jdkName="rbenv: 2.7.1" jdkType="RUBY_SDK" />
13
- <orderEntry type="sourceFolder" forTests="false" />
14
- <orderEntry type="library" scope="PROVIDED" name="activemodel (v6.0.3.2, rbenv: 2.7.1) [gem]" level="application" />
15
- <orderEntry type="library" scope="PROVIDED" name="activerecord (v6.0.3.2, rbenv: 2.7.1) [gem]" level="application" />
16
- <orderEntry type="library" scope="PROVIDED" name="activesupport (v6.0.3.2, rbenv: 2.7.1) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.1, rbenv: 2.7.1) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, rbenv: 2.7.1) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="codecov (v0.1.17, rbenv: 2.7.1) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.6, rbenv: 2.7.1) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="database_cleaner (v1.8.5, rbenv: 2.7.1) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="database_cleaner-active_record (v1.8.0, rbenv: 2.7.1) [gem]" level="application" />
23
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.4.2, rbenv: 2.7.1) [gem]" level="application" />
24
- <orderEntry type="library" scope="PROVIDED" name="docile (v1.3.2, rbenv: 2.7.1) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="i18n (v1.8.3, rbenv: 2.7.1) [gem]" level="application" />
26
- <orderEntry type="library" scope="PROVIDED" name="json (v2.3.0, rbenv: 2.7.1) [gem]" level="application" />
27
- <orderEntry type="library" scope="PROVIDED" name="minitest (v5.14.1, rbenv: 2.7.1) [gem]" level="application" />
28
- <orderEntry type="library" scope="PROVIDED" name="parallel (v1.19.2, rbenv: 2.7.1) [gem]" level="application" />
29
- <orderEntry type="library" scope="PROVIDED" name="parser (v2.7.1.4, rbenv: 2.7.1) [gem]" level="application" />
30
- <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.0.0, rbenv: 2.7.1) [gem]" level="application" />
31
- <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.1, rbenv: 2.7.1) [gem]" level="application" />
32
- <orderEntry type="library" scope="PROVIDED" name="regexp_parser (v1.7.1, rbenv: 2.7.1) [gem]" level="application" />
33
- <orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.4, rbenv: 2.7.1) [gem]" level="application" />
34
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.9.0, rbenv: 2.7.1) [gem]" level="application" />
35
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.9.2, rbenv: 2.7.1) [gem]" level="application" />
36
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.9.2, rbenv: 2.7.1) [gem]" level="application" />
37
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.9.1, rbenv: 2.7.1) [gem]" level="application" />
38
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.9.3, rbenv: 2.7.1) [gem]" level="application" />
39
- <orderEntry type="library" scope="PROVIDED" name="rubocop (v0.86.0, rbenv: 2.7.1) [gem]" level="application" />
40
- <orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v0.0.3, rbenv: 2.7.1) [gem]" level="application" />
41
- <orderEntry type="library" scope="PROVIDED" name="rubocop-performance (v1.6.1, rbenv: 2.7.1) [gem]" level="application" />
42
- <orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v1.40.0, rbenv: 2.7.1) [gem]" level="application" />
43
- <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.10.1, rbenv: 2.7.1) [gem]" level="application" />
44
- <orderEntry type="library" scope="PROVIDED" name="simplecov (v0.18.5, rbenv: 2.7.1) [gem]" level="application" />
45
- <orderEntry type="library" scope="PROVIDED" name="simplecov-html (v0.12.2, rbenv: 2.7.1) [gem]" level="application" />
46
- <orderEntry type="library" scope="PROVIDED" name="sqlite3 (v1.4.2, rbenv: 2.7.1) [gem]" level="application" />
47
- <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.6, rbenv: 2.7.1) [gem]" level="application" />
48
- <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.7, rbenv: 2.7.1) [gem]" level="application" />
49
- <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v1.7.0, rbenv: 2.7.1) [gem]" level="application" />
50
- <orderEntry type="library" scope="PROVIDED" name="url (v0.3.2, rbenv: 2.7.1) [gem]" level="application" />
51
- <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.3.1, rbenv: 2.7.1) [gem]" level="application" />
52
- </component>
53
- </module>
data/.idea/misc.xml DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="JavaScriptSettings">
4
- <option name="languageLevel" value="ES6" />
5
- </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="ruby-2.6.3-p62" project-jdk-type="RUBY_SDK" />
7
- </project>
data/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/light-services.iml" filepath="$PROJECT_DIR$/.idea/light-services.iml" />
6
- </modules>
7
- </component>
8
- </project>
data/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>