dry-operation 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5b39cd9624408d00958a649070927f493af015cd79d64815edeae30e2b82993
4
- data.tar.gz: 9d12151f5a48051502dc88a7c7152819dd7a7baed354088c414f4e698e7ef28a
3
+ metadata.gz: cc1e7ef446a048939d8e419f77946db6f9ee7621ddad0fed3108fa03129426d9
4
+ data.tar.gz: e45c7a1c4dc5f3baf42897396c227f34481446a2e3721d9ed4fc5f6a8497b4d9
5
5
  SHA512:
6
- metadata.gz: c57e54507bcf2f601a2f172a125da654f788b5481aa8d4b60e3025129cc6c88c270853947998ebf997fdae4f52833f6a06288115be9c3bd1678a34f4bc52f86f
7
- data.tar.gz: 5baa6f1508f60b8bf64b3ea8409caec2fc58707e153373fbcecbd0dec6b2bcc8dc9e280d641d84501dbe52145c0be3237018fa99f05be958626aecdbf718081e
6
+ metadata.gz: 4b914c5124f131eb116ce48e919cc38c0cc00c5f70893ae9629c7eb72dd8e35dcd6e709bcf262019104310d4c0035da7e0097b8ee715bdd5585a57458dd6f315
7
+ data.tar.gz: 4a7d4c96fce72d09f18e4da94dc2db0e49fb1cf99b3acc4ca56f1fbb0e3d9baeed1a862ea0bdf282128afc1d81135175bdbeca469e2605337edbb04c38befd62
data/CHANGELOG.md ADDED
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ ### Changed
13
+
14
+ ### Deprecated
15
+
16
+ ### Removed
17
+
18
+ ### Fixed
19
+
20
+ ### Security
21
+
22
+ [Unreleased]: https://github.com/dry-rb/dry-operation/compare/v1.1.0...main
23
+
24
+ ## [1.1.0] - 2026-02-06
25
+
26
+ ### Changed
27
+
28
+ - In Rom extension, allow transaction options to be passed via `#transaction`. (@wuarmin in #37)
29
+ ```ruby
30
+ # Set options at extension time (used for all transactions within the class):
31
+ include Dry::Operation::Extensions::ROM[isolation: :serializable]
32
+
33
+ # Or per-transaction, in instance methods. These will be merged with the extension-level
34
+ # options.
35
+ transaction(savepoint: true) do
36
+ # This transaction will have options `isolation: :serializable, savepoint: true`
37
+ end
38
+ ```
39
+
40
+ [1.1.0]: https://github.com/dry-rb/dry-operation/compare/v1.0.1...v1.1.0
41
+
42
+ ## [1.0.1] - 2025-10-24
43
+
44
+ ### Changed
45
+
46
+ - Define `#transaction` method in extension modules themselves (which are included into the operation class), rather than directly on the operation class itself. This adheres to typical Ruby inheritance-based method lookup, and allows for overloads of `#transaction` to be defined directly in the operation class or mixed in via other modules. (@timriley in #33)
47
+
48
+ [1.0.1]: https://github.com/dry-rb/dry-operation/compare/v1.0.0...v1.0.1
49
+
50
+ ## 1.0.0 - 2024-11-02
51
+
52
+ ### Added
53
+
54
+ - Initial release. (@waiting-for-dev)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2024 dry-rb team
3
+ Copyright (c) 2015-2026 Hanakai team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,14 +1,17 @@
1
- [gem]: https://rubygems.org/gems/dry-operation
1
+ <!--- This file is synced from hanakai-rb/repo-sync -->
2
+
3
+ [rubygem]: https://rubygems.org/gems/dry-operation
2
4
  [actions]: https://github.com/dry-rb/dry-operation/actions
3
5
 
4
- # dry-operation [![Gem Version](https://badge.fury.io/rb/dry-operation.svg)][gem] [![Continuous Integration](https://github.com/dry-rb/dry-operation/actions/workflows/ci.yml/badge.svg)][actions]
6
+ # dry-operation [![Gem Version](https://badge.fury.io/rb/dry-operation.svg)][rubygem] [![CI Status](https://github.com/dry-rb/dry-operation/workflows/CI/badge.svg)][actions]
5
7
 
6
8
  ## Links
7
9
 
8
- * [User documentation](https://dry-rb.org/gems/dry-operation)
9
- * [API documentation](http://rubydoc.info/gems/dry-operation)
10
- * [Forum](https://discourse.dry-rb.org)
10
+ - [User documentation](https://dry-rb.org/gems/dry-operation)
11
+ - [API documentation](http://rubydoc.info/gems/dry-operation)
12
+ - [Forum](https://discourse.dry-rb.org)
11
13
 
12
14
  ## License
13
15
 
14
- See [`LICENSE`](LICENSE).
16
+ See `LICENSE` file.
17
+
@@ -1,31 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
4
+
3
5
  lib = File.expand_path("lib", __dir__)
4
- $LOAD_PATH.prepend(lib) unless $LOAD_PATH.include?(lib)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
7
  require "dry/operation/version"
6
8
 
7
9
  Gem::Specification.new do |spec|
8
- spec.name = "dry-operation"
9
- spec.version = Dry::Operation::VERSION
10
- spec.authors = ["dry-rb team"]
11
- spec.email = ["gems@dry-rb.org"]
12
- spec.homepage = "https://dry-rb.org/gems/dry-operation"
13
- spec.summary = "A domain specific language for composable business transaction workflows."
14
- spec.license = "MIT"
15
-
16
- spec.metadata = {
17
- "bug_tracker_uri" => "https://github.com/dry-rb/dry-operation/issues",
18
- "changelog_uri" => "https://github.com/dry-rb/dry-operation/blob/main/CHANGELOG.md",
19
- "documentation_uri" => "https://dry-rb.org/gems/dry-operation",
20
- "funding_uri" => "https://github.com/sponsors/hanami",
21
- "label" => "dry-operation",
22
- "source_code_uri" => "https://github.com/dry-rb/dry-operation"
23
- }
10
+ spec.name = "dry-operation"
11
+ spec.authors = ["Hanakai team"]
12
+ spec.email = ["info@hanakai.org"]
13
+ spec.license = "MIT"
14
+ spec.version = Dry::Operation::VERSION.dup
15
+
16
+ spec.summary = "A domain specific language for composable business transaction workflows."
17
+ spec.description = spec.summary
18
+ spec.homepage = "https://dry-rb.org/gems/dry-operation"
19
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-operation.gemspec", "lib/**/*"]
20
+ spec.bindir = "exe"
21
+ spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
25
+
26
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
27
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-operation/blob/main/CHANGELOG.md"
28
+ spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-operation"
29
+ spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-operation/issues"
30
+ spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
24
31
 
25
32
  spec.required_ruby_version = ">= 3.1.0"
26
- spec.add_dependency "zeitwerk", "~> 2.6"
27
- spec.add_dependency "dry-monads", "~> 1.6"
28
33
 
29
- spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
30
- spec.files = Dir["*.gemspec", "lib/**/*"]
34
+ spec.add_runtime_dependency "dry-monads", "~> 1.6"
35
+ spec.add_runtime_dependency "zeitwerk", "~> 2.6"
36
+ spec.add_development_dependency "bundler"
37
+ spec.add_development_dependency "rspec"
38
+ spec.add_development_dependency "yard"
31
39
  end
40
+
@@ -96,33 +96,34 @@ module Dry
96
96
  @options = options
97
97
  end
98
98
 
99
- def included(klass)
100
- class_exec(@connection, @options) do |default_connection, options|
101
- # @!method transaction(connection = ActiveRecord::Base, **options, &steps)
102
- # Wrap the given steps in an ActiveRecord transaction.
103
- #
104
- # If any of the steps returns a `Dry::Monads::Result::Failure`, the
105
- # transaction will be rolled back and `:halt` will be thrown with the
106
- # failure as its value.
107
- #
108
- # @param connection [#transaction] The class/object to use
109
- # @param options [Hash] Additional options for the ActiveRecord transaction
110
- # @yieldreturn [Object] the result of the block
111
- # @see Dry::Operation#steps
112
- # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#method-i-transaction
113
- klass.define_method(:transaction) do |connection = default_connection, **opts, &steps|
114
- intercepting_failure do
115
- result = nil
116
- connection.transaction(**options.merge(opts)) do
117
- intercepting_failure(->(failure) {
118
- result = failure
119
- raise ::ActiveRecord::Rollback
120
- }) do
121
- result = steps.()
122
- end
99
+ def included(_klass)
100
+ default_connection = @connection
101
+ default_options = @options
102
+
103
+ # @!method transaction(connection = ActiveRecord::Base, **options, &steps)
104
+ # Wrap the given steps in an ActiveRecord transaction.
105
+ #
106
+ # If any of the steps returns a `Dry::Monads::Result::Failure`, the
107
+ # transaction will be rolled back and `:halt` will be thrown with the
108
+ # failure as its value.
109
+ #
110
+ # @param connection [#transaction] The class/object to use
111
+ # @param options [Hash] Additional options for the ActiveRecord transaction
112
+ # @yieldreturn [Object] the result of the block
113
+ # @see Dry::Operation#steps
114
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#method-i-transaction
115
+ define_method(:transaction) do |connection = default_connection, **opts, &steps|
116
+ intercepting_failure do
117
+ result = nil
118
+ connection.transaction(**default_options.merge(opts)) do
119
+ intercepting_failure(->(failure) {
120
+ result = failure
121
+ raise ::ActiveRecord::Rollback
122
+ }) do
123
+ result = steps.()
123
124
  end
124
- result
125
125
  end
126
+ result
126
127
  end
127
128
  end
128
129
  end
@@ -9,15 +9,14 @@ end
9
9
  module Dry
10
10
  class Operation
11
11
  module Extensions
12
- # Add rom transaction support to operations
12
+ # Add Rom transaction support to operations.
13
13
  #
14
- # When this extension is included, you can use a `#transaction` method
15
- # to wrap the desired steps in a rom transaction. If any of the steps
16
- # returns a `Dry::Monads::Result::Failure`, the transaction will be rolled
17
- # back and, as usual, the rest of the flow will be skipped.
14
+ # When this extension is included, you can use a `#transaction` method to wrap the desired
15
+ # steps in a Rom transaction. If any of the steps returns a `Dry::Monads::Result::Failure`,
16
+ # the transaction will be rolled back and, as usual, the rest of the flow will be skipped.
18
17
  #
19
- # The extension expects the including class to give access to the rom
20
- # container via a `#rom` method.
18
+ # The extension expects the including class to give access to the Rom container via a `#rom`
19
+ # method.
21
20
  #
22
21
  # ```ruby
23
22
  # require "dry/operation/extensions/rom"
@@ -46,18 +45,27 @@ module Dry
46
45
  # end
47
46
  # ```
48
47
  #
49
- # By default, the `:default` gateway will be used. You can change this
50
- # when including the extension:
48
+ # By default, the `:default` gateway will be used and no additional
49
+ # options will be passed to the Rom transaction.
50
+ #
51
+ # You can change the default gateway and transaction options when
52
+ # including the extension:
51
53
  #
52
54
  # ```ruby
53
- # include Dry::Operation::Extensions::ROM[gateway: :my_gateway]
55
+ # include Dry::Operation::Extensions::ROM[
56
+ # gateway: :my_gateway,
57
+ # isolation: :serializable
58
+ # ]
54
59
  # ```
55
60
  #
56
- # Or you can change it at runtime:
61
+ # You can also override the gateway and/or transaction options at runtime:
57
62
  #
58
63
  # ```ruby
59
- # user = transaction(gateway: :my_gateway) do
60
- # # ...
64
+ # user = transaction(
65
+ # gateway: :my_gateway,
66
+ # isolation: :serializable
67
+ # ) do
68
+ # # ...
61
69
  # end
62
70
  # ```
63
71
  #
@@ -84,37 +92,39 @@ module Dry
84
92
  # Include the extension providing a custom gateway
85
93
  #
86
94
  # @param gateway [Symbol] the rom gateway to use
87
- def self.[](gateway: DEFAULT_GATEWAY)
88
- Builder.new(gateway: gateway)
95
+ def self.[](gateway: DEFAULT_GATEWAY, **options)
96
+ Builder.new(gateway: gateway, **options)
89
97
  end
90
98
 
91
99
  # @api private
92
100
  class Builder < Module
93
- def initialize(gateway:)
101
+ def initialize(gateway:, **options)
94
102
  super()
95
103
  @gateway = gateway
104
+ @options = options
96
105
  end
97
106
 
98
- def included(klass)
99
- class_exec(@gateway) do |default_gateway|
100
- klass.define_method(:transaction) do |gateway: default_gateway, &steps|
101
- raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:rom)
102
- When using the ROM extension, you need to define a #rom method \
103
- that returns the ROM container
104
- MSG
107
+ def included(_klass)
108
+ default_gateway = @gateway
109
+ default_options = @options
110
+
111
+ define_method(:transaction) do |gateway: default_gateway, **opts, &steps|
112
+ raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:rom)
113
+ When using the Rom extension, you need to define a #rom method \
114
+ that returns the Rom container
115
+ MSG
105
116
 
106
- intercepting_failure do
107
- result = nil
108
- rom.gateways[gateway].transaction do |t|
109
- intercepting_failure(->(failure) {
110
- result = failure
111
- t.rollback!
112
- }) do
113
- result = steps.()
114
- end
117
+ intercepting_failure do
118
+ result = nil
119
+ rom.gateways[gateway].transaction(**default_options.merge(opts)) do |t|
120
+ intercepting_failure(->(failure) {
121
+ result = failure
122
+ t.rollback!
123
+ }) do
124
+ result = steps.()
115
125
  end
116
- result
117
126
  end
127
+ result
118
128
  end
119
129
  end
120
130
  end
@@ -81,26 +81,26 @@ module Dry
81
81
  @options = options
82
82
  end
83
83
 
84
- def included(klass)
85
- class_exec(@options) do |default_options|
86
- klass.define_method(:transaction) do |**opts, &steps|
87
- raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:db)
88
- When using the Sequel extension, you need to define a #db method \
89
- that returns the Sequel database object
90
- MSG
84
+ def included(_klass)
85
+ default_options = @options
91
86
 
92
- intercepting_failure do
93
- result = nil
94
- db.transaction(**default_options.merge(opts)) do
95
- intercepting_failure(->(failure) {
96
- result = failure
97
- raise ::Sequel::Rollback
98
- }) do
99
- result = steps.()
100
- end
87
+ define_method(:transaction) do |**opts, &steps|
88
+ raise Dry::Operation::ExtensionError, <<~MSG unless respond_to?(:db)
89
+ When using the Sequel extension, you need to define a #db method \
90
+ that returns the Sequel database object
91
+ MSG
92
+
93
+ intercepting_failure do
94
+ result = nil
95
+ db.transaction(**default_options.merge(opts)) do
96
+ intercepting_failure(->(failure) {
97
+ result = failure
98
+ raise ::Sequel::Rollback
99
+ }) do
100
+ result = steps.()
101
101
  end
102
- result
103
102
  end
103
+ result
104
104
  end
105
105
  end
106
106
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  class Operation
5
- VERSION = "1.0.0"
5
+ VERSION = "1.1.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,52 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-operation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - dry-rb team
8
- autorequire:
9
- bindir: bin
7
+ - Hanakai team
8
+ bindir: exe
10
9
  cert_chain: []
11
- date: 2024-11-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: zeitwerk
13
+ name: dry-monads
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '2.6'
18
+ version: '1.6'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
- version: '2.6'
25
+ version: '1.6'
27
26
  - !ruby/object:Gem::Dependency
28
- name: dry-monads
27
+ name: zeitwerk
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - "~>"
32
31
  - !ruby/object:Gem::Version
33
- version: '1.6'
32
+ version: '2.6'
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - "~>"
39
38
  - !ruby/object:Gem::Version
40
- version: '1.6'
41
- description:
39
+ version: '2.6'
40
+ - !ruby/object:Gem::Dependency
41
+ name: bundler
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rspec
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: yard
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ description: A domain specific language for composable business transaction workflows.
42
83
  email:
43
- - gems@dry-rb.org
84
+ - info@hanakai.org
44
85
  executables: []
45
86
  extensions: []
46
87
  extra_rdoc_files:
47
- - README.md
88
+ - CHANGELOG.md
48
89
  - LICENSE
90
+ - README.md
49
91
  files:
92
+ - CHANGELOG.md
50
93
  - LICENSE
51
94
  - README.md
52
95
  - dry-operation.gemspec
@@ -63,13 +106,11 @@ homepage: https://dry-rb.org/gems/dry-operation
63
106
  licenses:
64
107
  - MIT
65
108
  metadata:
66
- bug_tracker_uri: https://github.com/dry-rb/dry-operation/issues
109
+ allowed_push_host: https://rubygems.org
67
110
  changelog_uri: https://github.com/dry-rb/dry-operation/blob/main/CHANGELOG.md
68
- documentation_uri: https://dry-rb.org/gems/dry-operation
69
- funding_uri: https://github.com/sponsors/hanami
70
- label: dry-operation
71
111
  source_code_uri: https://github.com/dry-rb/dry-operation
72
- post_install_message:
112
+ bug_tracker_uri: https://github.com/dry-rb/dry-operation/issues
113
+ funding_uri: https://github.com/sponsors/hanami
73
114
  rdoc_options: []
74
115
  require_paths:
75
116
  - lib
@@ -84,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
125
  - !ruby/object:Gem::Version
85
126
  version: '0'
86
127
  requirements: []
87
- rubygems_version: 3.5.22
88
- signing_key:
128
+ rubygems_version: 3.6.9
89
129
  specification_version: 4
90
130
  summary: A domain specific language for composable business transaction workflows.
91
131
  test_files: []