business_flow 0.20.0 → 0.21.1

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: 629b01be7c90cd6bd0d11524bda269fc640863487e2a45a59d739497938d0ac9
4
- data.tar.gz: 7e3b3799817d2e8d451da79b266ebb9329f6db311c707ae1608471813f5ecb9f
3
+ metadata.gz: 58b3100df6d7fe1c1a09846cec4cd3df8692e7c8ab6a1a5f59387bddd116adf9
4
+ data.tar.gz: cc3a48bc0b5cb9932b921ebabfab8ceaf5ce64b292f7eed5e2c48e58f37912c7
5
5
  SHA512:
6
- metadata.gz: 1b9affb629f4994fe84655c081d429ef056e221c59739d926ee87205d2febb7ab314beda318f0f7f94b38f215ddcd3588b4f813be38918d43496ad6ce0fa066c
7
- data.tar.gz: 2fa9f60dd2d93f674ccf0473ebeb44ac8545d3a2f34cf2a815111a8bc934311bb0b07a205d6d5bd3ef7b84830859c2daa3e4bc07c7ad9819650127050e1c8124
6
+ metadata.gz: a50eaa3074e7369e57ff20f715f77c332fbea9dc2f2904fb8cbe84e8aafcc20f0b7dc1f7c3d9681642b7b3b6db8106d8ab6bad6367368e93a81145db6a7f6381
7
+ data.tar.gz: 4ce3770b14b51f01b77e0bbe57d990fe0ea6156539a5154afe99a99436cd07b0ff9787b7da1a4d5757adff719d0bcbe7842f72f996c9b9578ee5eb0453c7143c
data/.circleci/config.yml CHANGED
@@ -1,24 +1,11 @@
1
1
  version: 2.1
2
2
 
3
- setup: true
4
-
5
3
  orbs:
6
4
  ruby: circleci/ruby@2.5.3
7
5
 
8
- executors:
9
- docker: # Docker using the Base Convenience Image
10
- docker:
11
- - image: cimg/base:stable
12
- # linux: # a Linux VM running Ubuntu 20.04
13
- # machine:
14
- # image: ubuntu-2004:202107-02
15
- # macos: # macos executor running Xcode
16
- # macos:
17
- # xcode: 14.2.0
18
-
19
6
  references:
20
7
  RUBY_IMAGE: &RUBY_IMAGE
21
- cimg/ruby:3.3.7
8
+ cimg/ruby:3.3.9
22
9
  RUBY_DEPS: &RUBY_DEPS
23
10
  include-branch-in-cache-key: false
24
11
  clean-bundle: true
@@ -57,19 +44,22 @@ jobs:
57
44
  - run: bundle exec reek
58
45
  rspec:
59
46
  parameters:
60
- os:
61
- type: executor
62
47
  ruby-version:
63
48
  type: string
64
- executor: << parameters.os >>
49
+ docker:
50
+ - image: cimg/ruby:<< parameters.ruby-version >>
65
51
  steps:
66
52
  - checkout
67
- - run: 'rm .ruby-*'
68
- - ruby/install:
69
- version: << parameters.ruby-version >>
70
- - run: bundle
71
- - run: appraisal install
72
- - run: appraisal rspec --format p
53
+ - restore_cache:
54
+ key: v3-business_flow-<< parameters.ruby-version >>-{{ checksum "Gemfile.lock" }}-{{ checksum "Appraisals" }}
55
+ - run: bundle config set --local path 'vendor/bundle'
56
+ - run: bundle install
57
+ - run: bundle exec appraisal install --path 'vendor/bundle'
58
+ - save_cache:
59
+ key: v3-business_flow-<< parameters.ruby-version >>-{{ checksum "Gemfile.lock" }}-{{ checksum "Appraisals" }}
60
+ paths:
61
+ - ~/project/vendor/bundle
62
+ - run: bundle exec appraisal rspec --format p
73
63
 
74
64
  workflows:
75
65
  full:
@@ -84,12 +74,8 @@ workflows:
84
74
  - rspec:
85
75
  matrix:
86
76
  parameters:
87
- os:
88
- - docker
89
- # - linux
90
- # - macos # Disabled because macOS testing isn't worth sorting out why GPG isn't present.
91
77
  ruby-version:
92
- - "3.1.7"
93
- - "3.2.8"
94
- - "3.3.8"
95
- - "3.4.3"
78
+ - "3.1.6"
79
+ - "3.2.9"
80
+ - "3.3.9"
81
+ - "3.4.6"
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-3.1.6
1
+ ruby-3.3.9
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ ## 0.21.1
2
+
3
+ ENHANCEMENTS:
4
+
5
+ * Added #failure_exception= to flow classes for setting an exception causing a failure. Setting an exception also fails the flow execution.
6
+ * Added #exception to flow result classes for reading the exception causing a failure.
7
+ * Set #exception as the cause: on FlowFailedException.
8
+ * ClusterLock now propogates Zookeeper errors through failure_exception and the case on its LockFailure exception.
9
+
10
+ ## 0.21.0
11
+
12
+ BUG FIXES:
13
+
14
+ * Resolved issue that could result in ClusterLock continuing to hold lock in the event of a Zookeeper error during the unlock process.
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
- f.match(%r{^(test|spec|features)/})
18
+ f.match(%r{^(test|spec|features|gemfiles)/|(Appraisals|Gemfile)})
19
19
  end
20
20
  spec.bindir = 'exe'
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -3,6 +3,35 @@
3
3
  module BusinessFlow
4
4
  # Mixin for business flow to acquire and retain a cluster lock.
5
5
  module ClusterLock
6
+ # Error raised when there is an internal issue with acquiring a lock.
7
+ class LockFailure < StandardError
8
+ attr_reader :error_type
9
+
10
+ def initialize(error_type, message)
11
+ @error_type = error_type
12
+ super(message)
13
+ end
14
+
15
+ def add_to(flow)
16
+ errors = flow.errors
17
+ unless errors.key?(:cluster_lock)
18
+ BusinessFlow.add_error(errors, :cluster_lock, error_type, message)
19
+ end
20
+ flow.failure_exception = self
21
+ flow
22
+ end
23
+ end
24
+
25
+ # Holder for information about the lock
26
+ class LockInfo
27
+ attr_reader :lock_name, :zookeeper_servers
28
+
29
+ def initialize(lock_name, zookeeper_servers)
30
+ @lock_name = lock_name
31
+ @zookeeper_servers = zookeeper_servers
32
+ end
33
+ end
34
+
6
35
  def self.included(klass)
7
36
  klass.extend(ClassMethods)
8
37
  end
@@ -51,34 +80,6 @@ module BusinessFlow
51
80
 
52
81
  # DSL Methods
53
82
  module ClassMethods # rubocop:disable Metrics/ModuleLength
54
- # Error raised when there is an internal issue with acquiring a lock.
55
- class LockFailure < StandardError
56
- attr_reader :error_type
57
-
58
- def initialize(error_type, message)
59
- @error_type = error_type
60
- super(message)
61
- end
62
-
63
- def add_to(flow)
64
- errors = flow.errors
65
- unless errors.key?(:cluster_lock)
66
- BusinessFlow.add_error(errors, :cluster_lock, error_type, message)
67
- end
68
- flow
69
- end
70
- end
71
-
72
- # Holder for information about the lock
73
- class LockInfo
74
- attr_reader :lock_name, :zookeeper_servers
75
-
76
- def initialize(lock_name, zookeeper_servers)
77
- @lock_name = lock_name
78
- @zookeeper_servers = zookeeper_servers
79
- end
80
- end
81
-
82
83
  def with_cluster_lock(lock_name = nil, opts = {}, &blk)
83
84
  if lock_name.is_a?(String)
84
85
  @lock_name = Step.new(Callable.new(proc { lock_name }), {})
@@ -186,11 +187,10 @@ module BusinessFlow
186
187
  end
187
188
 
188
189
  def self.cleanup(lock, zk_connection)
189
- begin
190
- lock&.unlock
191
- rescue ZK::Exceptions::OperationTimeOut
192
- # Just let the connection close handle this.
193
- end
190
+ lock&.unlock
191
+ rescue ZK::Exceptions::OperationTimeOut
192
+ # Just let the connection close handle this.
193
+ ensure
194
194
  zk_connection&.close!
195
195
  end
196
196
 
@@ -217,7 +217,7 @@ module BusinessFlow
217
217
  rescue ZK::Exceptions::LockAssertionFailedError, ZK::Exceptions::OperationTimeOut => e
218
218
  # This would occur if we asserted a cluster lock while executing the flow.
219
219
  # This will have set an error on the flow, so we can carry on.
220
- raise LockFailure.new(exception_to_error_type(e), e.message)
220
+ raise LockFailure.new(exception_to_error_type(e), e.message), cause: e
221
221
  ensure
222
222
  cleanup(lock, zk_connection)
223
223
  end
@@ -128,7 +128,7 @@ module BusinessFlow
128
128
 
129
129
  def call!(*args)
130
130
  flow = call(*args)
131
- raise FlowFailedException, flow if flow.errors?
131
+ raise FlowFailedException, flow, cause: flow.exception if flow.errors?
132
132
 
133
133
  flow
134
134
  end
@@ -154,7 +154,8 @@ module BusinessFlow
154
154
  # We use instance_variable_get here instead of making it part of
155
155
  # from_flow to ensure that we do not create the errors object unless
156
156
  # we need it.
157
- result = const_get(:Result).new(flow.instance_variable_get(:@errors))
157
+ result = const_get(:Result).new(flow.instance_variable_get(:@errors),
158
+ flow.send(:failure_exception))
158
159
  result.from_flow(flow) if @result_copy
159
160
  result
160
161
  end
@@ -205,8 +206,11 @@ module BusinessFlow
205
206
 
206
207
  RESULT_DEF = %(
207
208
  class Result
208
- def initialize(errors)
209
+ attr_reader :exception
210
+
211
+ def initialize(errors, exception)
209
212
  @errors = errors
213
+ @exception = exception
210
214
  end
211
215
 
212
216
  def errors
@@ -216,7 +220,7 @@ module BusinessFlow
216
220
  def errors?
217
221
  # We're explicitly using the instance variable here so that if no
218
222
  # errors have been created, we don't initialize the error object.
219
- !!@errors && @errors.present?
223
+ (!!@errors && @errors.present?) || !exception.nil?
220
224
  end
221
225
 
222
226
  def valid?(_context = nil)
@@ -263,6 +267,9 @@ module BusinessFlow
263
267
  attr_reader :parameter_object
264
268
  private :parameter_object
265
269
 
270
+ attr_accessor :failure_exception
271
+ private :failure_exception
272
+
266
273
  def call
267
274
  return if invalid?
268
275
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BusinessFlow
4
- VERSION = '0.20.0'
4
+ VERSION = '0.21.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: business_flow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Scarborough
@@ -63,30 +63,13 @@ files:
63
63
  - ".ruby-gemset"
64
64
  - ".ruby-version"
65
65
  - ".travis.yml"
66
- - Appraisals
67
- - Gemfile
68
- - Gemfile.lock
66
+ - CHANGELOG.md
69
67
  - LICENSE.txt
70
68
  - README.md
71
69
  - Rakefile
72
70
  - bin/console
73
71
  - bin/setup
74
72
  - business_flow.gemspec
75
- - gemfiles/.bundle/config
76
- - gemfiles/activemodel_4.2.gemfile
77
- - gemfiles/activemodel_4.2.gemfile.lock
78
- - gemfiles/activemodel_5.2.gemfile
79
- - gemfiles/activemodel_5.2.gemfile.lock
80
- - gemfiles/activemodel_6.1.gemfile
81
- - gemfiles/activemodel_6.1.gemfile.lock
82
- - gemfiles/activemodel_7.0.gemfile
83
- - gemfiles/activemodel_7.0.gemfile.lock
84
- - gemfiles/activemodel_7.1.gemfile
85
- - gemfiles/activemodel_7.1.gemfile.lock
86
- - gemfiles/activemodel_7.2.gemfile
87
- - gemfiles/activemodel_7.2.gemfile.lock
88
- - gemfiles/activemodel_8.0.gemfile
89
- - gemfiles/activemodel_8.0.gemfile.lock
90
73
  - lib/business_flow.rb
91
74
  - lib/business_flow/base.rb
92
75
  - lib/business_flow/cacheable.rb
@@ -122,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
105
  - !ruby/object:Gem::Version
123
106
  version: '0'
124
107
  requirements: []
125
- rubygems_version: 3.6.9
108
+ rubygems_version: 3.7.2
126
109
  specification_version: 4
127
110
  summary: General purpose management of service object flows
128
111
  test_files: []
data/Appraisals DELETED
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if RUBY_ENGINE == 'ruby' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4.0')
4
- appraise 'activemodel-4.2' do
5
- source 'https://teak_io_199:6YKvtYgoo5R8_zxD@gems.railslts.com' do
6
- gem 'activemodel', '~> 4.2.11'
7
- gem 'activesupport', '~> 4.2.11'
8
- end
9
- end
10
-
11
- appraise 'activemodel-5.2' do
12
- source 'https://teak_io_199:6YKvtYgoo5R8_zxD@gems.railslts.com' do
13
- gem 'activemodel', '~> 5.2.8'
14
- gem 'activesupport', '~> 5.2.8'
15
- end
16
- end
17
- end
18
-
19
- appraise 'activemodel-6.1' do
20
- source 'https://teak_io_199:6YKvtYgoo5R8_zxD@gems.railslts.com' do
21
- gem 'activemodel', '~> 6.1.7'
22
- gem 'activesupport', '~> 6.1.7'
23
- end
24
- end
25
-
26
- if RUBY_ENGINE == 'ruby' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4.0')
27
- appraise 'activemodel-7.0' do
28
- gem 'activemodel', '~> 7.0.8'
29
- gem 'activesupport', '~> 7.0.8'
30
- end
31
- end
32
-
33
- appraise 'activemodel-7.1' do
34
- gem 'activemodel', '~> 7.1.3'
35
- gem 'activesupport', '~> 7.1.3'
36
- end
37
-
38
- appraise 'activemodel-7.2' do
39
- gem 'activemodel', '~> 7.2.1'
40
- gem 'activesupport', '~> 7.2.1'
41
- end
42
-
43
- if RUBY_ENGINE == 'ruby' && Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0')
44
- appraise 'activemodel-8.0' do
45
- gem 'activemodel', '~> 8.0.0'
46
- gem 'activesupport', '~> 8.0.0'
47
- end
48
- end
data/Gemfile DELETED
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in business_flow.gemspec
8
- gemspec
9
-
10
- gem 'pry', '~> 0.15.2'
11
- gem 'rake', '~> 13.0'
12
- gem 'reek', '~> 6.1'
13
- gem 'retryable', '~> 3.0.4'
14
- gem 'rspec', '~> 3.0'
15
- gem 'rubocop', '~> 1.59'
16
- gem 'rubocop-factory_bot', '~> 2.27'
17
- gem 'rubocop-rspec', '~> 3.0'
18
- gem 'rubocop-rspec_rails', '~> 2.31'
19
- gem 'rubocop-rake', '~> 0.7.0'
20
- gem 'simplecov', '~> 0.22.0'
21
- gem 'timecop', '~> 0.9.1'
22
-
23
- gem 'ruby3-backward-compatibility'
24
-
25
- gem 'appraisal', '~> 2.5.0'
data/Gemfile.lock DELETED
@@ -1,175 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- business_flow (0.20.0)
5
- activemodel (>= 4.2, < 8.1)
6
- activesupport (>= 4.2, < 8.1)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- activemodel (7.1.5.1)
12
- activesupport (= 7.1.5.1)
13
- activesupport (7.1.5.1)
14
- base64
15
- benchmark (>= 0.3)
16
- bigdecimal
17
- concurrent-ruby (~> 1.0, >= 1.0.2)
18
- connection_pool (>= 2.2.5)
19
- drb
20
- i18n (>= 1.6, < 2)
21
- logger (>= 1.4.2)
22
- minitest (>= 5.1)
23
- mutex_m
24
- securerandom (>= 0.3)
25
- tzinfo (~> 2.0)
26
- appraisal (2.5.0)
27
- bundler
28
- rake
29
- thor (>= 0.14.0)
30
- ast (2.4.3)
31
- base64 (0.3.0)
32
- benchmark (0.4.1)
33
- bigdecimal (3.2.2)
34
- coderay (1.1.3)
35
- concurrent-ruby (1.3.5)
36
- connection_pool (2.5.3)
37
- diff-lcs (1.6.2)
38
- docile (1.4.1)
39
- drb (2.2.3)
40
- dry-configurable (1.3.0)
41
- dry-core (~> 1.1)
42
- zeitwerk (~> 2.6)
43
- dry-core (1.1.0)
44
- concurrent-ruby (~> 1.0)
45
- logger
46
- zeitwerk (~> 2.6)
47
- dry-inflector (1.2.0)
48
- dry-initializer (3.2.0)
49
- dry-logic (1.6.0)
50
- bigdecimal
51
- concurrent-ruby (~> 1.0)
52
- dry-core (~> 1.1)
53
- zeitwerk (~> 2.6)
54
- dry-schema (1.14.1)
55
- concurrent-ruby (~> 1.0)
56
- dry-configurable (~> 1.0, >= 1.0.1)
57
- dry-core (~> 1.1)
58
- dry-initializer (~> 3.2)
59
- dry-logic (~> 1.5)
60
- dry-types (~> 1.8)
61
- zeitwerk (~> 2.6)
62
- dry-types (1.8.3)
63
- bigdecimal (~> 3.0)
64
- concurrent-ruby (~> 1.0)
65
- dry-core (~> 1.0)
66
- dry-inflector (~> 1.0)
67
- dry-logic (~> 1.4)
68
- zeitwerk (~> 2.6)
69
- i18n (1.14.7)
70
- concurrent-ruby (~> 1.0)
71
- json (2.12.2)
72
- language_server-protocol (3.17.0.5)
73
- lint_roller (1.1.0)
74
- logger (1.7.0)
75
- method_source (1.1.0)
76
- minitest (5.25.5)
77
- mutex_m (0.3.0)
78
- parallel (1.27.0)
79
- parser (3.3.8.0)
80
- ast (~> 2.4.1)
81
- racc
82
- prism (1.4.0)
83
- pry (0.15.2)
84
- coderay (~> 1.1)
85
- method_source (~> 1.0)
86
- racc (1.8.1)
87
- rainbow (3.1.1)
88
- rake (13.3.0)
89
- reek (6.5.0)
90
- dry-schema (~> 1.13)
91
- logger (~> 1.6)
92
- parser (~> 3.3.0)
93
- rainbow (>= 2.0, < 4.0)
94
- rexml (~> 3.1)
95
- regexp_parser (2.10.0)
96
- retryable (3.0.5)
97
- rexml (3.4.1)
98
- rspec (3.13.1)
99
- rspec-core (~> 3.13.0)
100
- rspec-expectations (~> 3.13.0)
101
- rspec-mocks (~> 3.13.0)
102
- rspec-core (3.13.5)
103
- rspec-support (~> 3.13.0)
104
- rspec-expectations (3.13.5)
105
- diff-lcs (>= 1.2.0, < 2.0)
106
- rspec-support (~> 3.13.0)
107
- rspec-mocks (3.13.5)
108
- diff-lcs (>= 1.2.0, < 2.0)
109
- rspec-support (~> 3.13.0)
110
- rspec-support (3.13.4)
111
- rubocop (1.78.0)
112
- json (~> 2.3)
113
- language_server-protocol (~> 3.17.0.2)
114
- lint_roller (~> 1.1.0)
115
- parallel (~> 1.10)
116
- parser (>= 3.3.0.2)
117
- rainbow (>= 2.2.2, < 4.0)
118
- regexp_parser (>= 2.9.3, < 3.0)
119
- rubocop-ast (>= 1.45.1, < 2.0)
120
- ruby-progressbar (~> 1.7)
121
- unicode-display_width (>= 2.4.0, < 4.0)
122
- rubocop-ast (1.45.1)
123
- parser (>= 3.3.7.2)
124
- prism (~> 1.4)
125
- rubocop-factory_bot (2.27.1)
126
- lint_roller (~> 1.1)
127
- rubocop (~> 1.72, >= 1.72.1)
128
- rubocop-rake (0.7.1)
129
- lint_roller (~> 1.1)
130
- rubocop (>= 1.72.1)
131
- rubocop-rspec (3.6.0)
132
- lint_roller (~> 1.1)
133
- rubocop (~> 1.72, >= 1.72.1)
134
- rubocop-rspec_rails (2.31.0)
135
- lint_roller (~> 1.1)
136
- rubocop (~> 1.72, >= 1.72.1)
137
- rubocop-rspec (~> 3.5)
138
- ruby-progressbar (1.13.0)
139
- ruby3-backward-compatibility (1.5.0)
140
- securerandom (0.3.2)
141
- simplecov (0.22.0)
142
- docile (~> 1.1)
143
- simplecov-html (~> 0.11)
144
- simplecov_json_formatter (~> 0.1)
145
- simplecov-html (0.13.1)
146
- simplecov_json_formatter (0.1.4)
147
- thor (1.3.2)
148
- timecop (0.9.10)
149
- tzinfo (2.0.6)
150
- concurrent-ruby (~> 1.0)
151
- unicode-display_width (2.6.0)
152
- zeitwerk (2.6.18)
153
-
154
- PLATFORMS
155
- ruby
156
-
157
- DEPENDENCIES
158
- appraisal (~> 2.5.0)
159
- business_flow!
160
- pry (~> 0.15.2)
161
- rake (~> 13.0)
162
- reek (~> 6.1)
163
- retryable (~> 3.0.4)
164
- rspec (~> 3.0)
165
- rubocop (~> 1.59)
166
- rubocop-factory_bot (~> 2.27)
167
- rubocop-rake (~> 0.7.0)
168
- rubocop-rspec (~> 3.0)
169
- rubocop-rspec_rails (~> 2.31)
170
- ruby3-backward-compatibility
171
- simplecov (~> 0.22.0)
172
- timecop (~> 0.9.1)
173
-
174
- BUNDLED WITH
175
- 2.6.9
@@ -1,2 +0,0 @@
1
- ---
2
- BUNDLE_RETRY: "1"
@@ -1,24 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "pry", "~> 0.15.2"
6
- gem "rake", "~> 13.0"
7
- gem "reek", "~> 6.1.0"
8
- gem "retryable", "~> 3.0.4"
9
- gem "rspec", "~> 3.0"
10
- gem "rubocop", "~> 1.59"
11
- gem "rubocop-factory_bot", "~> 2.24"
12
- gem "rubocop-rspec", "~> 2.29"
13
- gem "rubocop-rspec_rails", "~> 2.28"
14
- gem "simplecov", "~> 0.22.0"
15
- gem "timecop", "~> 0.9.1"
16
- gem "appraisal", "~> 2.5.0"
17
- gem "ruby3-backward-compatibility"
18
-
19
- source 'https://teak_io_199:6YKvtYgoo5R8_zxD@gems.railslts.com' do
20
- gem "activemodel", "~> 4.2.11"
21
- gem "activesupport", "~> 4.2.11"
22
- end
23
-
24
- gemspec path: "../"