opera 0.3.5 → 0.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 +4 -4
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/specs.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile +4 -4
- data/Gemfile.lock +38 -35
- data/README.md +21 -115
- data/lib/opera/operation/instructions/executors/operation.rb +0 -1
- data/lib/opera/operation/instructions/executors/operations.rb +0 -3
- data/lib/opera/operation/instructions/executors/step.rb +0 -4
- data/lib/opera/operation/instructions/executors/validate.rb +8 -11
- data/lib/opera/operation/result.rb +11 -18
- data/lib/opera/version.rb +1 -1
- data/opera.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b16c9b85d248e5ca4edbdec7d247d4ac4dfa1d65db6aab6099af3bc4dc790250
|
4
|
+
data.tar.gz: edccc8b266eb67a2a3ffe2065637d2232a46f885c131d13cb682b52862564913
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b942136109cdb2963ae694e5bf97e99871f537e8ef5c04b6e76c050257dd15ddfa30744117dadd316cba1492895c3c999dee21b81be2ae153933b8df3092fe4
|
7
|
+
data.tar.gz: 79986a10962b8a3e9843c55deb7c18b9576fcd64d3b9ae44ca4ccfb4cf39508a5643a2e008015853f04a75f206e75c96c553ecb6b10d4dad008c5b104db4652d
|
@@ -2,14 +2,14 @@ name: Release
|
|
2
2
|
|
3
3
|
on:
|
4
4
|
push:
|
5
|
-
branches: [
|
5
|
+
branches: [master]
|
6
6
|
|
7
7
|
jobs:
|
8
8
|
test:
|
9
9
|
runs-on: ubuntu-latest
|
10
10
|
strategy:
|
11
11
|
matrix:
|
12
|
-
ruby-version: [
|
12
|
+
ruby-version: ['3.1', '3.2', '3.4', 'jruby-9.4.12.1']
|
13
13
|
|
14
14
|
steps:
|
15
15
|
- uses: actions/checkout@v4
|
data/.github/workflows/specs.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -3,11 +3,11 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in opera.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem 'rake', '~>
|
7
|
-
gem 'rspec', '~> 3.
|
6
|
+
gem 'rake', '~> 13.2'
|
7
|
+
gem 'rspec', '~> 3.13'
|
8
8
|
|
9
9
|
group :test, :development do
|
10
10
|
gem 'dry-validation'
|
11
|
-
gem 'pry
|
12
|
-
gem 'pry-
|
11
|
+
gem 'pry'
|
12
|
+
gem 'pry-byebug', require: false, platforms: :ruby
|
13
13
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,70 +1,73 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
opera (0.
|
4
|
+
opera (0.4.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
bigdecimal (3.1.
|
10
|
-
byebug (
|
9
|
+
bigdecimal (3.1.9)
|
10
|
+
byebug (12.0.0)
|
11
11
|
coderay (1.1.3)
|
12
|
-
concurrent-ruby (1.3.
|
13
|
-
diff-lcs (1.
|
14
|
-
dry-configurable (1.
|
15
|
-
dry-core (~> 1.
|
12
|
+
concurrent-ruby (1.3.5)
|
13
|
+
diff-lcs (1.6.2)
|
14
|
+
dry-configurable (1.3.0)
|
15
|
+
dry-core (~> 1.1)
|
16
16
|
zeitwerk (~> 2.6)
|
17
|
-
dry-core (1.0
|
17
|
+
dry-core (1.1.0)
|
18
18
|
concurrent-ruby (~> 1.0)
|
19
|
+
logger
|
19
20
|
zeitwerk (~> 2.6)
|
20
|
-
dry-inflector (1.
|
21
|
-
dry-initializer (3.
|
22
|
-
dry-logic (1.
|
21
|
+
dry-inflector (1.2.0)
|
22
|
+
dry-initializer (3.2.0)
|
23
|
+
dry-logic (1.6.0)
|
24
|
+
bigdecimal
|
23
25
|
concurrent-ruby (~> 1.0)
|
24
|
-
dry-core (~> 1.
|
26
|
+
dry-core (~> 1.1)
|
25
27
|
zeitwerk (~> 2.6)
|
26
|
-
dry-schema (1.
|
28
|
+
dry-schema (1.14.1)
|
27
29
|
concurrent-ruby (~> 1.0)
|
28
30
|
dry-configurable (~> 1.0, >= 1.0.1)
|
29
|
-
dry-core (~> 1.
|
30
|
-
dry-initializer (~> 3.
|
31
|
-
dry-logic (
|
32
|
-
dry-types (
|
31
|
+
dry-core (~> 1.1)
|
32
|
+
dry-initializer (~> 3.2)
|
33
|
+
dry-logic (~> 1.5)
|
34
|
+
dry-types (~> 1.8)
|
33
35
|
zeitwerk (~> 2.6)
|
34
|
-
dry-types (1.
|
36
|
+
dry-types (1.8.2)
|
35
37
|
bigdecimal (~> 3.0)
|
36
38
|
concurrent-ruby (~> 1.0)
|
37
39
|
dry-core (~> 1.0)
|
38
40
|
dry-inflector (~> 1.0)
|
39
41
|
dry-logic (~> 1.4)
|
40
42
|
zeitwerk (~> 2.6)
|
41
|
-
dry-validation (1.
|
43
|
+
dry-validation (1.11.1)
|
42
44
|
concurrent-ruby (~> 1.0)
|
43
|
-
dry-core (~> 1.
|
44
|
-
dry-initializer (~> 3.
|
45
|
-
dry-schema (
|
45
|
+
dry-core (~> 1.1)
|
46
|
+
dry-initializer (~> 3.2)
|
47
|
+
dry-schema (~> 1.14)
|
46
48
|
zeitwerk (~> 2.6)
|
49
|
+
logger (1.7.0)
|
47
50
|
method_source (1.1.0)
|
48
|
-
pry (0.
|
51
|
+
pry (0.15.2)
|
49
52
|
coderay (~> 1.1)
|
50
53
|
method_source (~> 1.0)
|
51
|
-
pry-byebug (3.
|
52
|
-
byebug (~>
|
53
|
-
pry (>= 0.13, < 0.
|
54
|
-
rake (
|
54
|
+
pry-byebug (3.11.0)
|
55
|
+
byebug (~> 12.0)
|
56
|
+
pry (>= 0.13, < 0.16)
|
57
|
+
rake (13.2.1)
|
55
58
|
rspec (3.13.0)
|
56
59
|
rspec-core (~> 3.13.0)
|
57
60
|
rspec-expectations (~> 3.13.0)
|
58
61
|
rspec-mocks (~> 3.13.0)
|
59
|
-
rspec-core (3.13.
|
62
|
+
rspec-core (3.13.3)
|
60
63
|
rspec-support (~> 3.13.0)
|
61
|
-
rspec-expectations (3.13.
|
64
|
+
rspec-expectations (3.13.4)
|
62
65
|
diff-lcs (>= 1.2.0, < 2.0)
|
63
66
|
rspec-support (~> 3.13.0)
|
64
|
-
rspec-mocks (3.13.
|
67
|
+
rspec-mocks (3.13.4)
|
65
68
|
diff-lcs (>= 1.2.0, < 2.0)
|
66
69
|
rspec-support (~> 3.13.0)
|
67
|
-
rspec-support (3.13.
|
70
|
+
rspec-support (3.13.3)
|
68
71
|
zeitwerk (2.6.18)
|
69
72
|
|
70
73
|
PLATFORMS
|
@@ -73,10 +76,10 @@ PLATFORMS
|
|
73
76
|
DEPENDENCIES
|
74
77
|
dry-validation
|
75
78
|
opera!
|
79
|
+
pry
|
76
80
|
pry-byebug
|
77
|
-
|
78
|
-
|
79
|
-
rspec (~> 3.0)
|
81
|
+
rake (~> 13.2)
|
82
|
+
rspec (~> 3.13)
|
80
83
|
|
81
84
|
BUNDLED WITH
|
82
|
-
2.
|
85
|
+
2.3.3
|
data/README.md
CHANGED
@@ -31,7 +31,7 @@ Note. If you are using Ruby 2.x please use Opera 0.2.x
|
|
31
31
|
## Configuration
|
32
32
|
|
33
33
|
Opera is built to be used with or without Rails.
|
34
|
-
Simply
|
34
|
+
Simply initialize the configuration and choose a custom logger and which library to use for implementing transactions.
|
35
35
|
|
36
36
|
```ruby
|
37
37
|
Opera::Operation::Config.configure do |config|
|
@@ -136,28 +136,6 @@ class A < Opera::Operation::Base
|
|
136
136
|
end
|
137
137
|
```
|
138
138
|
|
139
|
-
### Debugging
|
140
|
-
|
141
|
-
When you want to easily debug exceptions you can add this
|
142
|
-
to your dummy.rb:
|
143
|
-
|
144
|
-
```
|
145
|
-
Rails.application.configure do
|
146
|
-
config.x.reporter = Logger.new(STDERR)
|
147
|
-
end
|
148
|
-
```
|
149
|
-
|
150
|
-
This should display exceptions captured inside operations.
|
151
|
-
|
152
|
-
You can also do it in Opera::Operation configuration block:
|
153
|
-
|
154
|
-
```
|
155
|
-
Opera::Operation::Config.configure do |config|
|
156
|
-
config.transaction_class = ActiveRecord::Base
|
157
|
-
config.reporter = Logger.new(STDERR)
|
158
|
-
end
|
159
|
-
```
|
160
|
-
|
161
139
|
### Content
|
162
140
|
[Basic operation](#user-content-basic-operation)
|
163
141
|
|
@@ -165,8 +143,6 @@ end
|
|
165
143
|
|
166
144
|
[Example operation with old validations](#user-content-example-operation-with-old-validations)
|
167
145
|
|
168
|
-
[Example with step that raises exception](#user-content-example-with-step-that-raises-exception)
|
169
|
-
|
170
146
|
[Failing transaction](#user-content-failing-transaction)
|
171
147
|
|
172
148
|
[Passing transaction](#user-content-passing-transaction)
|
@@ -195,7 +171,7 @@ class Profile::Create < Opera::Operation::Base
|
|
195
171
|
attr_accessor :profile
|
196
172
|
end
|
197
173
|
# DEPRECATED
|
198
|
-
# dependencies_reader :current_account, :mailer
|
174
|
+
# dependencies_reader :current_account, :mailer
|
199
175
|
dependencies do
|
200
176
|
attr_reader :current_account, :mailer
|
201
177
|
end
|
@@ -237,7 +213,7 @@ Profile::Create.call(params: {
|
|
237
213
|
current_account: Account.find(1)
|
238
214
|
})
|
239
215
|
|
240
|
-
#<Opera::Operation::Result:0x0000561636dced60 @errors={}, @
|
216
|
+
#<Opera::Operation::Result:0x0000561636dced60 @errors={}, @information={}, @executions=[:profile_schema, :create, :send_email, :output], @output={:model=>#<Profile id: 30, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-14 16:04:08", updated_at: "2020-08-14 16:04:08", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
241
217
|
```
|
242
218
|
|
243
219
|
#### Call with INVALID parameters - missing first_name
|
@@ -250,7 +226,7 @@ Profile::Create.call(params: {
|
|
250
226
|
current_account: Account.find(1)
|
251
227
|
})
|
252
228
|
|
253
|
-
#<Opera::Operation::Result:0x0000562d3f635390 @errors={:first_name=>["is missing"]}, @
|
229
|
+
#<Opera::Operation::Result:0x0000562d3f635390 @errors={:first_name=>["is missing"]}, @information={}, @executions=[:profile_schema]>
|
254
230
|
```
|
255
231
|
|
256
232
|
#### Call with MISSING dependencies
|
@@ -263,7 +239,7 @@ Profile::Create.call(params: {
|
|
263
239
|
current_account: Account.find(1)
|
264
240
|
})
|
265
241
|
|
266
|
-
#<Opera::Operation::Result:0x007f87ba2c8f00 @errors={}, @
|
242
|
+
#<Opera::Operation::Result:0x007f87ba2c8f00 @errors={}, @information={}, @executions=[:profile_schema, :create, :send_email, :output], @output={:model=>#<Profile id: 33, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2019-01-03 12:04:25", updated_at: "2019-01-03 12:04:25", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
267
243
|
```
|
268
244
|
|
269
245
|
### Example with sanitizing parameters
|
@@ -322,7 +298,7 @@ Profile::Create.call(params: {
|
|
322
298
|
})
|
323
299
|
|
324
300
|
# NOTE: Last name is missing in output model
|
325
|
-
#<Opera::Operation::Result:0x000055e36a1fab78 @errors={}, @
|
301
|
+
#<Opera::Operation::Result:0x000055e36a1fab78 @errors={}, @information={}, @executions=[:profile_schema, :create, :send_email, :output], @output={:model=>#<Profile id: 44, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: nil, created_at: "2020-08-17 11:07:08", updated_at: "2020-08-17 11:07:08", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
326
302
|
```
|
327
303
|
|
328
304
|
### Example operation with old validations
|
@@ -393,7 +369,7 @@ Profile::Create.call(params: {
|
|
393
369
|
current_account: Account.find(1)
|
394
370
|
})
|
395
371
|
|
396
|
-
#<Opera::Operation::Result:0x0000560ebc9e7a98 @errors={}, @
|
372
|
+
#<Opera::Operation::Result:0x0000560ebc9e7a98 @errors={}, @information={}, @executions=[:profile_schema, :build_record, :old_validation, :create, :send_email, :output], @output={:model=>#<Profile id: 41, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-14 19:15:12", updated_at: "2020-08-14 19:15:12", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
397
373
|
```
|
398
374
|
|
399
375
|
#### Call with INVALID parameters
|
@@ -406,74 +382,7 @@ Profile::Create.call(params: {
|
|
406
382
|
current_account: Account.find(1)
|
407
383
|
})
|
408
384
|
|
409
|
-
#<Opera::Operation::Result:0x0000560ef76ba588 @errors={:last_name=>["can't be blank"]}, @
|
410
|
-
```
|
411
|
-
|
412
|
-
### Example with step that raises exception
|
413
|
-
|
414
|
-
```ruby
|
415
|
-
class Profile::Create < Opera::Operation::Base
|
416
|
-
# DEPRECATED
|
417
|
-
# context_accessor :profile
|
418
|
-
context do
|
419
|
-
attr_accessor :profile
|
420
|
-
end
|
421
|
-
# DEPRECATED
|
422
|
-
# dependencies_reader :current_account, :mailer
|
423
|
-
dependencies do
|
424
|
-
attr_reader :current_account, :mailer
|
425
|
-
end
|
426
|
-
|
427
|
-
validate :profile_schema
|
428
|
-
|
429
|
-
step :build_record
|
430
|
-
step :exception
|
431
|
-
step :create
|
432
|
-
step :send_email
|
433
|
-
step :output
|
434
|
-
|
435
|
-
def profile_schema
|
436
|
-
Dry::Validation.Schema do
|
437
|
-
required(:first_name).filled
|
438
|
-
end.call(params)
|
439
|
-
end
|
440
|
-
|
441
|
-
def build_record
|
442
|
-
self.profile = current_account.profiles.build(params)
|
443
|
-
self.profile.force_name_validation = true
|
444
|
-
end
|
445
|
-
|
446
|
-
def exception
|
447
|
-
raise StandardError, 'Example'
|
448
|
-
end
|
449
|
-
|
450
|
-
def create
|
451
|
-
self.profile = profile.save
|
452
|
-
end
|
453
|
-
|
454
|
-
def send_email
|
455
|
-
return true unless mailer
|
456
|
-
|
457
|
-
mailer.send_mail(profile: profile)
|
458
|
-
end
|
459
|
-
|
460
|
-
def output
|
461
|
-
result.output(model: profile)
|
462
|
-
end
|
463
|
-
end
|
464
|
-
```
|
465
|
-
|
466
|
-
##### Call with step throwing exception
|
467
|
-
|
468
|
-
```ruby
|
469
|
-
result = Profile::Create.call(params: {
|
470
|
-
first_name: :foo,
|
471
|
-
last_name: :bar
|
472
|
-
}, dependencies: {
|
473
|
-
current_account: Account.find(1)
|
474
|
-
})
|
475
|
-
|
476
|
-
#<Opera::Operation::Result:0x0000562ad0f897c8 @errors={}, @exceptions={"Profile::Create#exception"=>["Example"]}, @information={}, @executions=[:profile_schema, :build_record, :exception]>
|
385
|
+
#<Opera::Operation::Result:0x0000560ef76ba588 @errors={:last_name=>["can't be blank"]}, @information={:missing_validations=>"Please check dry validations"}, @executions=[:build_record, :old_validation]>
|
477
386
|
```
|
478
387
|
|
479
388
|
### Example with step that finishes execution
|
@@ -536,7 +445,7 @@ result = Profile::Create.call(params: {
|
|
536
445
|
current_account: Account.find(1)
|
537
446
|
})
|
538
447
|
|
539
|
-
#<Opera::Operation::Result:0x007fc2c59a8460 @errors={}, @
|
448
|
+
#<Opera::Operation::Result:0x007fc2c59a8460 @errors={}, @information={}, @executions=[:profile_schema, :build_record, :create]>
|
540
449
|
```
|
541
450
|
|
542
451
|
### Failing transaction
|
@@ -609,7 +518,7 @@ D, [2020-08-14T16:13:30.946466 #2504] DEBUG -- : Account Load (0.5ms) SELECT
|
|
609
518
|
D, [2020-08-14T16:13:30.960254 #2504] DEBUG -- : (0.2ms) BEGIN
|
610
519
|
D, [2020-08-14T16:13:30.983981 #2504] DEBUG -- : SQL (0.7ms) INSERT INTO "profiles" ("first_name", "last_name", "created_at", "updated_at", "account_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["first_name", "foo"], ["last_name", "bar"], ["created_at", "2020-08-14 16:13:30.982289"], ["updated_at", "2020-08-14 16:13:30.982289"], ["account_id", 1]]
|
611
520
|
D, [2020-08-14T16:13:30.986233 #2504] DEBUG -- : (0.2ms) ROLLBACK
|
612
|
-
|
521
|
+
D, [2020-08-14T16:13:30.988231 #2504] DEBUG -- : unknown attribute 'example_attr' for Profile. (ActiveModel::UnknownAttributeError)
|
613
522
|
```
|
614
523
|
|
615
524
|
### Passing transaction
|
@@ -682,7 +591,7 @@ D, [2020-08-17T12:10:44.856964 #2741] DEBUG -- : (0.2ms) BEGIN
|
|
682
591
|
D, [2020-08-17T12:10:44.881332 #2741] DEBUG -- : SQL (0.7ms) INSERT INTO "profiles" ("first_name", "last_name", "created_at", "updated_at", "account_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["first_name", "foo"], ["last_name", "bar"], ["created_at", "2020-08-17 12:10:44.879684"], ["updated_at", "2020-08-17 12:10:44.879684"], ["account_id", 1]]
|
683
592
|
D, [2020-08-17T12:10:44.886168 #2741] DEBUG -- : SQL (0.6ms) UPDATE "profiles" SET "updated_at" = $1 WHERE "profiles"."id" = $2 [["updated_at", "2020-08-16 12:10:44.883164"], ["id", 47]]
|
684
593
|
D, [2020-08-17T12:10:44.898132 #2741] DEBUG -- : (10.3ms) COMMIT
|
685
|
-
#<Opera::Operation::Result:0x0000556528f29058 @errors={}, @
|
594
|
+
#<Opera::Operation::Result:0x0000556528f29058 @errors={}, @information={}, @executions=[:profile_schema, :create, :update, :send_email, :output], @output={:model=>#<Profile id: 47, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-17 12:10:44", updated_at: "2020-08-16 12:10:44", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
686
595
|
```
|
687
596
|
|
688
597
|
### Benchmark
|
@@ -747,7 +656,7 @@ Profile::Create.call(params: {
|
|
747
656
|
}, dependencies: {
|
748
657
|
current_account: Account.find(1)
|
749
658
|
})
|
750
|
-
#<Opera::Operation::Result:0x007ff414a01238 @errors={}, @
|
659
|
+
#<Opera::Operation::Result:0x007ff414a01238 @errors={}, @information={fast_section: {:real=>0.300013706088066e-05, :total=>0.0}, slow_section: {:real=>1.800013706088066e-05, :total=>0.0}}, @executions=[:profile_schema, :create, :update, :send_email, :output], @output={:model=>#<Profile id: 30, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-19 10:46:00", updated_at: "2020-08-18 10:46:00", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
751
660
|
```
|
752
661
|
|
753
662
|
### Success
|
@@ -817,7 +726,7 @@ Profile::Create.call(params: {
|
|
817
726
|
}, dependencies: {
|
818
727
|
current_account: Account.find(1)
|
819
728
|
})
|
820
|
-
#<Opera::Operation::Result:0x007fd0248e5638 @errors={"mailer"=>["Missing dependency"]}, @
|
729
|
+
#<Opera::Operation::Result:0x007fd0248e5638 @errors={"mailer"=>["Missing dependency"]}, @information={}, @executions=[:profile_schema, :populate, :create, :update, :send_email, :output], @output={:model=>#<Profile id: 40, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2019-01-03 12:21:35", updated_at: "2019-01-02 12:21:35", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
821
730
|
```
|
822
731
|
|
823
732
|
### Finish If
|
@@ -886,7 +795,7 @@ Profile::Create.call(params: {
|
|
886
795
|
create_only: true,
|
887
796
|
current_account: Account.find(1)
|
888
797
|
})
|
889
|
-
#<Opera::Operation::Result:0x007fd0248e5638 @errors={}, @
|
798
|
+
#<Opera::Operation::Result:0x007fd0248e5638 @errors={}, @information={}, @executions=[:profile_schema, :create, :profile_create_only], @output={}>
|
890
799
|
```
|
891
800
|
|
892
801
|
### Inner Operation
|
@@ -938,7 +847,7 @@ Profile::Create.call(params: {
|
|
938
847
|
}, dependencies: {
|
939
848
|
current_account: Account.find(1)
|
940
849
|
})
|
941
|
-
#<Opera::Operation::Result:0x007f99b25f0f20 @errors={}, @
|
850
|
+
#<Opera::Operation::Result:0x007f99b25f0f20 @errors={}, @information={}, @executions=[:profile_schema, :find, :create, :output], @output={:model=>{:id=>1, :user_id=>1, :linkedin_uid=>nil, ...}}>
|
942
851
|
```
|
943
852
|
|
944
853
|
### Inner Operations
|
@@ -976,7 +885,7 @@ end
|
|
976
885
|
```ruby
|
977
886
|
Profile::CreateMultiple.call(params: { number: 3 })
|
978
887
|
|
979
|
-
#<Opera::Operation::Result:0x0000564189f38c90 @errors={}, @
|
888
|
+
#<Opera::Operation::Result:0x0000564189f38c90 @errors={}, @information={}, @executions=[{:create_multiple=>[[:validate, :create], [:validate, :create], [:validate, :create], [:validate, :create]]}, :output], @output=[{:model=>"Profile 1"}, {:model=>"Profile 7"}, {:model=>"Profile 69"}, {:model=>"Profile 92"}]>
|
980
889
|
```
|
981
890
|
|
982
891
|
## Opera::Operation::Result - Instance Methods
|
@@ -989,15 +898,13 @@ Opera::Operation::Result.new(output: 'success')
|
|
989
898
|
```
|
990
899
|
|
991
900
|
>
|
992
|
-
- success? - [true, false] - Return true if no errors
|
993
|
-
- failure? - [true, false] - Return true if any error
|
901
|
+
- success? - [true, false] - Return true if no errors
|
902
|
+
- failure? - [true, false] - Return true if any error
|
994
903
|
- output - [Anything] - Return Anything
|
995
904
|
- output=(Anything) - Sets content of operation output
|
996
905
|
- output! - Return Anything if Success, raise exception if Failure
|
997
906
|
- add_error(key, value) - Adds new error message
|
998
907
|
- add_errors(Hash) - Adds multiple error messages
|
999
|
-
- add_exception(method, message, classname: nil) - Adds new exception
|
1000
|
-
- add_exceptions(Hash) - Adds multiple exceptions
|
1001
908
|
- add_information(Hash) - Adss new information - Useful informations for developers
|
1002
909
|
|
1003
910
|
## Opera::Operation::Base - Instance Methods
|
@@ -1135,16 +1042,15 @@ end
|
|
1135
1042
|
- step(Symbol) - single instruction
|
1136
1043
|
- return [Truthly] - continue operation execution
|
1137
1044
|
- return [False] - stops operation execution
|
1138
|
-
- raise Exception - exception gets captured and stops operation execution
|
1139
1045
|
- operation(Symbol) - single instruction - requires to return Opera::Operation::Result object
|
1140
|
-
- return [Opera::Operation::Result] - stops operation STEPS execution if
|
1046
|
+
- return [Opera::Operation::Result] - stops operation STEPS execution if failure
|
1141
1047
|
- validate(Symbol) - single dry-validations - requires to return Dry::Validation::Result object
|
1142
1048
|
- return [Dry::Validation::Result] - stops operation STEPS execution if any error but continue with other validations
|
1143
1049
|
- transaction(*Symbols) - list of instructions to be wrapped in transaction
|
1144
1050
|
- return [Truthly] - continue operation execution
|
1145
|
-
- return [False
|
1051
|
+
- return [False] - stops operation execution and breaks transaction/do rollback
|
1146
1052
|
- call(params: Hash, dependencies: Hash?)
|
1147
|
-
- return [Opera::Operation::Result]
|
1053
|
+
- return [Opera::Operation::Result]
|
1148
1054
|
|
1149
1055
|
## Development
|
1150
1056
|
|
@@ -12,8 +12,6 @@ module Opera
|
|
12
12
|
instruction[:kind] = :step
|
13
13
|
operations_results = super
|
14
14
|
|
15
|
-
return if result.exceptions.any?
|
16
|
-
|
17
15
|
case operations_results
|
18
16
|
when Array
|
19
17
|
operations_results.each do |operation_result|
|
@@ -38,7 +36,6 @@ module Opera
|
|
38
36
|
def add_failures(failures)
|
39
37
|
failures.each do |failure|
|
40
38
|
result.add_errors(failure.errors)
|
41
|
-
result.add_exceptions(failure.exceptions)
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
@@ -12,10 +12,6 @@ module Opera
|
|
12
12
|
operation.result.add_execution(method) unless production_mode?
|
13
13
|
operation.send(method)
|
14
14
|
end
|
15
|
-
rescue StandardError => exception
|
16
|
-
reporter&.error(exception)
|
17
|
-
operation.result.add_exception(method, "#{exception.message}, for #{operation.inspect}", classname: operation.class.name)
|
18
|
-
operation.result
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
@@ -13,23 +13,20 @@ module Opera
|
|
13
13
|
|
14
14
|
def evaluate_instruction(instruction)
|
15
15
|
instruction[:kind] = :step
|
16
|
-
|
16
|
+
validation_result = super
|
17
17
|
|
18
|
-
case
|
18
|
+
case validation_result
|
19
19
|
when Opera::Operation::Result
|
20
|
-
add_instruction_output(instruction,
|
20
|
+
add_instruction_output(instruction, validation_result.output)
|
21
21
|
|
22
|
-
unless
|
23
|
-
result.add_errors(dry_result.errors)
|
24
|
-
result.add_exceptions(dry_result.exceptions)
|
25
|
-
end
|
22
|
+
result.add_errors(validation_result.errors) unless validation_result.success?
|
26
23
|
when Dry::Validation::Result
|
27
|
-
add_instruction_output(instruction,
|
24
|
+
add_instruction_output(instruction, validation_result.to_h)
|
28
25
|
|
29
|
-
result.add_errors(
|
26
|
+
result.add_errors(validation_result.errors) unless validation_result.success?
|
30
27
|
else
|
31
|
-
|
32
|
-
|
28
|
+
raise TypeError, "#{validation_result.class} is not a valid result for 'validate' step. " \
|
29
|
+
"Please check output of '#{instruction[:method]}' step in #{operation.class.name}"
|
33
30
|
end
|
34
31
|
end
|
35
32
|
end
|
@@ -3,10 +3,16 @@
|
|
3
3
|
module Opera
|
4
4
|
module Operation
|
5
5
|
class Result
|
6
|
-
class OutputError < StandardError
|
6
|
+
class OutputError < StandardError
|
7
|
+
attr_reader :errors
|
8
|
+
|
9
|
+
def initialize(msg, errors = {})
|
10
|
+
@errors = errors
|
11
|
+
super(msg)
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
attr_reader :errors, # Acumulator of errors in validation + steps
|
9
|
-
:exceptions, # Acumulator of exceptions in steps
|
10
16
|
:information, # Temporal object to store related information
|
11
17
|
:executions # Stacktrace or Pipe of the methods evaludated
|
12
18
|
|
@@ -14,14 +20,13 @@ module Opera
|
|
14
20
|
|
15
21
|
def initialize(output: nil, errors: {})
|
16
22
|
@errors = errors
|
17
|
-
@exceptions = {}
|
18
23
|
@information = {}
|
19
24
|
@executions = []
|
20
25
|
@output = output
|
21
26
|
end
|
22
27
|
|
23
28
|
def failure?
|
24
|
-
errors.any?
|
29
|
+
errors.any?
|
25
30
|
end
|
26
31
|
|
27
32
|
def success?
|
@@ -29,11 +34,11 @@ module Opera
|
|
29
34
|
end
|
30
35
|
|
31
36
|
def failures
|
32
|
-
errors
|
37
|
+
errors
|
33
38
|
end
|
34
39
|
|
35
40
|
def output!
|
36
|
-
raise OutputError
|
41
|
+
raise OutputError.new('Cannot retrieve output from a Failure.', errors) if failure?
|
37
42
|
|
38
43
|
output
|
39
44
|
end
|
@@ -60,18 +65,6 @@ module Opera
|
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
63
|
-
def add_exception(method, message, classname: nil)
|
64
|
-
key = [classname, Array(method).first].compact.join('#')
|
65
|
-
|
66
|
-
@exceptions[key] = message unless @exceptions.key?(key)
|
67
|
-
end
|
68
|
-
|
69
|
-
def add_exceptions(exceptions)
|
70
|
-
exceptions.each_pair do |key, value|
|
71
|
-
add_exception(key, value)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
68
|
def add_information(hash)
|
76
69
|
@information.merge!(hash)
|
77
70
|
end
|
data/lib/opera/version.rb
CHANGED
data/opera.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.summary = 'Use simple DSL language to keep your Operations clean and maintainable'
|
10
10
|
spec.homepage = 'https://github.com/Profinda/opera'
|
11
11
|
spec.license = 'MIT'
|
12
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 3.
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 3.1.0')
|
13
13
|
|
14
14
|
spec.metadata['homepage_uri'] = spec.homepage
|
15
15
|
spec.metadata['source_code_uri'] = spec.homepage
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ProFinda Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-validation
|
@@ -110,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
110
|
requirements:
|
111
111
|
- - ">="
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version: 3.
|
113
|
+
version: 3.1.0
|
114
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
116
|
- - ">="
|