sbmt-kafka_consumer 2.8.0 → 3.0.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/Appraisals +2 -2
- data/CHANGELOG.md +8 -2
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/dip.yml +3 -3
- data/lib/sbmt/kafka_consumer/base_consumer.rb +12 -9
- data/lib/sbmt/kafka_consumer/client_configurer.rb +5 -4
- data/lib/sbmt/kafka_consumer/inbox_consumer.rb +19 -14
- data/lib/sbmt/kafka_consumer/routing/consumer_mapper/base.rb +17 -0
- data/lib/sbmt/kafka_consumer/routing/karafka_v1_consumer_mapper.rb +6 -1
- data/lib/sbmt/kafka_consumer/routing/karafka_v2_consumer_mapper.rb +10 -3
- data/lib/sbmt/kafka_consumer/testing/shared_contexts/with_sbmt_karafka_consumer.rb +14 -13
- data/lib/sbmt/kafka_consumer/version.rb +1 -1
- data/sbmt-kafka_consumer.gemspec +5 -5
- metadata +11 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7af7925acd4a61d131a66dd3cd290064ba11aac749ee64ca00841912bd038adc
|
4
|
+
data.tar.gz: 9cd1e1f789c6e4252adedf3dd3115f512c62240b75edadc38d1590e4a85b6000
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60dbd904786ddc419e9efbb0f02904c6035089a3b23fcb4035d41c85c8db303ae807138fa1e26c042688521c34a355f0314799e82addc73ef6308fc3fe6cad15
|
7
|
+
data.tar.gz: ca1d3af3c319695cbb33e11f9f66a384efb2c1884a387a233d5b197ae9ed5d3a3852c49662586a67ba15eb497ed325b92363cfe65ce8e086c6319b48dfb0569e
|
data/Appraisals
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
# See compatibility table at https://www.fastruby.io/blog/ruby/rails/versions/compatibility-table.html
|
4
4
|
|
5
5
|
versions_map = {
|
6
|
-
"6.0" => %w[2.7],
|
7
6
|
"6.1" => %w[2.7 3.0],
|
8
7
|
"7.0" => %w[3.1],
|
9
|
-
"7.1" => %w[3.2, 3.3]
|
8
|
+
"7.1" => %w[3.2, 3.3],
|
9
|
+
"7.2" => %w[3.3]
|
10
10
|
}
|
11
11
|
|
12
12
|
current_ruby_version = RUBY_VERSION.split(".").first(2).join(".")
|
data/CHANGELOG.md
CHANGED
@@ -13,11 +13,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
13
13
|
|
14
14
|
### Fixed
|
15
15
|
|
16
|
-
## [
|
16
|
+
## [3.0.0] - 2024-09-04
|
17
|
+
|
18
|
+
## BREAKING
|
19
|
+
|
20
|
+
- Drop support for Ruby 2.7
|
21
|
+
- Drop support for Rails 6.0
|
22
|
+
- Add support for Karafka 2.4
|
17
23
|
|
18
24
|
### Fixed
|
19
25
|
|
20
|
-
-
|
26
|
+
- Support consumer group mappers to support backward compatibility of consumer group naming
|
21
27
|
|
22
28
|
## [2.7.1] - 2024-08-01
|
23
29
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
[](https://badge.fury.io/rb/sbmt-kafka_consumer)
|
2
|
-
[](https://github.com/Kuper-Tech/sbmt-kafka_consumer/actions?query=branch%3Amaster)
|
3
3
|
|
4
4
|
# Sbmt-KafkaConsumer
|
5
5
|
|
6
|
-
This gem is used to consume Kafka messages. It is a wrapper over the [Karafka](https://github.com/karafka/karafka) gem, and is recommended for use as a transport with the [sbmt-outbox](https://github.com/
|
6
|
+
This gem is used to consume Kafka messages. It is a wrapper over the [Karafka](https://github.com/karafka/karafka) gem, and is recommended for use as a transport with the [sbmt-outbox](https://github.com/Kuper-Tech/sbmt-outbox) gem.
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -21,7 +21,7 @@ bundle install
|
|
21
21
|
|
22
22
|
## Demo
|
23
23
|
|
24
|
-
Learn how to use this gem and how it works with Ruby on Rails at here https://github.com/
|
24
|
+
Learn how to use this gem and how it works with Ruby on Rails at here https://github.com/Kuper-Tech/outbox-example-apps
|
25
25
|
|
26
26
|
## Auto configuration
|
27
27
|
|
@@ -47,7 +47,7 @@ rails g kafka_consumer:consumer MaybeNamespaced::Name
|
|
47
47
|
|
48
48
|
### Inbox consumer
|
49
49
|
|
50
|
-
To generate an Inbox consumer for use with gem [sbmt-outbox](https://github.com/
|
50
|
+
To generate an Inbox consumer for use with gem [sbmt-outbox](https://github.com/Kuper-Tech/sbmt-outbox), run the following command:
|
51
51
|
|
52
52
|
```shell
|
53
53
|
rails g kafka_consumer:inbox_consumer MaybeNamespaced::Name some-consumer-group some-topic
|
data/dip.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
version: '7'
|
2
2
|
|
3
3
|
environment:
|
4
|
-
RUBY_VERSION: '3.
|
4
|
+
RUBY_VERSION: '3.3'
|
5
5
|
|
6
6
|
compose:
|
7
7
|
files:
|
@@ -35,14 +35,14 @@ interaction:
|
|
35
35
|
subcommands:
|
36
36
|
all:
|
37
37
|
command: bundle exec appraisal rspec
|
38
|
-
rails-6.0:
|
39
|
-
command: bundle exec appraisal rails-6.0 rspec
|
40
38
|
rails-6.1:
|
41
39
|
command: bundle exec appraisal rails-6.1 rspec
|
42
40
|
rails-7.0:
|
43
41
|
command: bundle exec appraisal rails-7.0 rspec
|
44
42
|
rails-7.1:
|
45
43
|
command: bundle exec appraisal rails-7.1 rspec
|
44
|
+
rails-7.2:
|
45
|
+
command: bundle exec appraisal rails-7.2 rspec
|
46
46
|
|
47
47
|
rubocop:
|
48
48
|
description: Run Ruby linter
|
@@ -3,20 +3,15 @@
|
|
3
3
|
module Sbmt
|
4
4
|
module KafkaConsumer
|
5
5
|
class BaseConsumer < Karafka::BaseConsumer
|
6
|
-
|
7
|
-
|
6
|
+
def self.consumer_klass(skip_on_error: false, middlewares: [])
|
7
|
+
Class.new(self) do
|
8
|
+
const_set(:SKIP_ON_ERROR, skip_on_error)
|
9
|
+
const_set(:MIDDLEWARES, middlewares.map(&:constantize))
|
8
10
|
|
9
|
-
def self.consumer_klass(skip_on_error: nil, middlewares: nil)
|
10
|
-
klass = Class.new(self) do
|
11
11
|
def self.name
|
12
12
|
superclass.name
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
16
|
-
# defaults are set in class_attribute definition
|
17
|
-
klass.skip_on_error = skip_on_error if skip_on_error
|
18
|
-
klass.middlewares = middlewares.map(&:constantize) if middlewares
|
19
|
-
klass
|
20
15
|
end
|
21
16
|
|
22
17
|
def consume
|
@@ -117,6 +112,14 @@ module Sbmt
|
|
117
112
|
end
|
118
113
|
end
|
119
114
|
|
115
|
+
def skip_on_error
|
116
|
+
self.class::SKIP_ON_ERROR
|
117
|
+
end
|
118
|
+
|
119
|
+
def middlewares
|
120
|
+
self.class::MIDDLEWARES
|
121
|
+
end
|
122
|
+
|
120
123
|
# can be overridden in consumer to enable message logging
|
121
124
|
def log_payload?
|
122
125
|
false
|
@@ -6,10 +6,8 @@ class Sbmt::KafkaConsumer::ClientConfigurer
|
|
6
6
|
Karafka::App.setup do |karafka_config|
|
7
7
|
karafka_config.monitor = config.monitor_class.classify.constantize.new
|
8
8
|
karafka_config.logger = Sbmt::KafkaConsumer.logger
|
9
|
-
karafka_config.deserializer = config.deserializer_class.classify.constantize.new
|
10
9
|
|
11
10
|
karafka_config.client_id = config.client_id
|
12
|
-
karafka_config.consumer_mapper = config.consumer_mapper_class.classify.constantize.new
|
13
11
|
karafka_config.kafka = config.to_kafka_options
|
14
12
|
|
15
13
|
karafka_config.pause_timeout = config.pause_timeout * 1_000 if config.pause_timeout.present?
|
@@ -43,13 +41,16 @@ class Sbmt::KafkaConsumer::ClientConfigurer
|
|
43
41
|
|
44
42
|
raise "No configured consumer groups found, exiting" if target_consumer_groups.blank?
|
45
43
|
|
44
|
+
consumer_mapper = config.consumer_mapper_class.classify.constantize.new
|
45
|
+
|
46
46
|
# clear routes in case CLI runner tries to reconfigure them
|
47
47
|
# but railtie initializer had already executed and did the same
|
48
48
|
# otherwise we'll get duplicate routes error from sbmt-karafka internal config validation process
|
49
49
|
Karafka::App.routes.clear
|
50
50
|
Karafka::App.routes.draw do
|
51
51
|
target_consumer_groups.each do |cg|
|
52
|
-
|
52
|
+
group_id = consumer_mapper.call(cg.name)
|
53
|
+
consumer_group group_id do
|
53
54
|
cg.topics.each do |t|
|
54
55
|
topic t.name do
|
55
56
|
active t.active
|
@@ -66,7 +67,7 @@ class Sbmt::KafkaConsumer::ClientConfigurer
|
|
66
67
|
|
67
68
|
def self.routes
|
68
69
|
Karafka::App.routes.map do |cg|
|
69
|
-
topics = cg.topics.map { |t| {name: t.name, deserializer: t.
|
70
|
+
topics = cg.topics.map { |t| {name: t.name, deserializer: t.deserializers.payload} }
|
70
71
|
{group: cg.id, topics: topics}
|
71
72
|
end
|
72
73
|
end
|
@@ -6,20 +6,17 @@ module Sbmt
|
|
6
6
|
IDEMPOTENCY_HEADER_NAME = "Idempotency-Key"
|
7
7
|
DEFAULT_SOURCE = "KAFKA"
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def initialize
|
21
|
-
raise Sbmt::KafkaConsumer::Error, "inbox_item param is not set" if inbox_item_class.blank?
|
22
|
-
super
|
9
|
+
def self.consumer_klass(inbox_item:, event_name: nil, skip_on_error: false, name: nil, middlewares: [])
|
10
|
+
Class.new(self) do
|
11
|
+
const_set(:INBOX_ITEM_CLASS_NAME, inbox_item)
|
12
|
+
const_set(:EVENT_NAME, event_name)
|
13
|
+
const_set(:SKIP_ON_ERROR, skip_on_error)
|
14
|
+
const_set(:MIDDLEWARES, middlewares.map(&:constantize))
|
15
|
+
|
16
|
+
def self.name
|
17
|
+
superclass.name
|
18
|
+
end
|
19
|
+
end
|
23
20
|
end
|
24
21
|
|
25
22
|
def extra_message_attrs(_message)
|
@@ -104,6 +101,14 @@ module Sbmt
|
|
104
101
|
message.metadata.headers.fetch(IDEMPOTENCY_HEADER_NAME, nil).presence
|
105
102
|
end
|
106
103
|
|
104
|
+
def inbox_item_class
|
105
|
+
@inbox_item_class ||= self.class::INBOX_ITEM_CLASS_NAME.constantize
|
106
|
+
end
|
107
|
+
|
108
|
+
def event_name
|
109
|
+
@event_name ||= self.class::EVENT_NAME
|
110
|
+
end
|
111
|
+
|
107
112
|
def inbox_name
|
108
113
|
inbox_item_class.box_name
|
109
114
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sbmt
|
4
|
+
module KafkaConsumer
|
5
|
+
module Routing
|
6
|
+
module ConsumerMapper
|
7
|
+
class Base
|
8
|
+
# @param raw_consumer_group_name [String, Symbol] string or symbolized consumer group name
|
9
|
+
# @return [String] remapped final consumer group name
|
10
|
+
def call(raw_consumer_group_name)
|
11
|
+
raise "Implement #call in a subclass"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "consumer_mapper/base"
|
4
|
+
|
1
5
|
module Sbmt
|
2
6
|
module KafkaConsumer
|
3
7
|
module Routing
|
4
|
-
class KarafkaV1ConsumerMapper <
|
8
|
+
class KarafkaV1ConsumerMapper < ConsumerMapper::Base
|
9
|
+
# karafka v1 consumer group name mapper
|
5
10
|
def call(raw_consumer_group_name)
|
6
11
|
client_id = ActiveSupport::Inflector.underscore(Karafka::App.config.client_id).tr("/", "_")
|
7
12
|
"#{client_id}_#{raw_consumer_group_name}"
|
@@ -1,9 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "consumer_mapper/base"
|
4
|
+
|
1
5
|
module Sbmt
|
2
6
|
module KafkaConsumer
|
3
7
|
module Routing
|
4
|
-
#
|
5
|
-
|
6
|
-
|
8
|
+
# karafka v2 (before 2.4) consumer group name mapper
|
9
|
+
class KarafkaV2ConsumerMapper < ConsumerMapper::Base
|
10
|
+
def call(raw_consumer_group_name)
|
11
|
+
"#{Karafka::App.config.client_id}_#{raw_consumer_group_name}"
|
12
|
+
end
|
13
|
+
end
|
7
14
|
end
|
8
15
|
end
|
9
16
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
RSpec.shared_context "with sbmt karafka consumer" do
|
4
4
|
subject(:consume_with_sbmt_karafka) do
|
5
|
-
coordinator.increment
|
5
|
+
coordinator.increment(:consume)
|
6
6
|
consumer.on_consume
|
7
7
|
end
|
8
8
|
|
@@ -16,8 +16,9 @@ RSpec.shared_context "with sbmt karafka consumer" do
|
|
16
16
|
let(:kafka_client) { instance_double(Karafka::Connection::Client) }
|
17
17
|
let(:null_deserializer) { Sbmt::KafkaConsumer::Serialization::NullDeserializer.new }
|
18
18
|
|
19
|
-
let(:
|
20
|
-
|
19
|
+
let(:consumer) {
|
20
|
+
build_consumer(described_class.new)
|
21
|
+
}
|
21
22
|
|
22
23
|
before {
|
23
24
|
Sbmt::KafkaConsumer::ClientConfigurer.configure!
|
@@ -27,27 +28,27 @@ RSpec.shared_context "with sbmt karafka consumer" do
|
|
27
28
|
}
|
28
29
|
|
29
30
|
def publish_to_sbmt_karafka(raw_payload, opts = {})
|
30
|
-
message = Karafka::Messages::Message.new(raw_payload, Karafka::Messages::Metadata.new(
|
31
|
+
message = Karafka::Messages::Message.new(raw_payload, Karafka::Messages::Metadata.new(build_metadata_hash(opts)))
|
31
32
|
consumer.messages = consumer_messages([message])
|
32
33
|
end
|
33
34
|
|
34
35
|
def publish_to_sbmt_karafka_batch(raw_payloads, opts = {})
|
35
36
|
messages = raw_payloads.map do |p|
|
36
|
-
Karafka::Messages::Message.new(p, Karafka::Messages::Metadata.new(
|
37
|
+
Karafka::Messages::Message.new(p, Karafka::Messages::Metadata.new(build_metadata_hash(opts)))
|
37
38
|
end
|
38
39
|
consumer.messages = consumer_messages(messages)
|
39
40
|
end
|
40
41
|
|
41
42
|
# @return [Hash] message default options
|
42
|
-
def
|
43
|
+
def build_metadata_hash(opts)
|
43
44
|
{
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
offset: 0,
|
48
|
-
partition: 0,
|
49
|
-
received_at: Time.current,
|
50
|
-
topic: test_topic.name
|
45
|
+
deserializers: test_topic.deserializers(payload: opts[:deserializer] || null_deserializer),
|
46
|
+
raw_headers: opts[:headers] || {},
|
47
|
+
raw_key: opts[:key],
|
48
|
+
offset: opts[:offset] || 0,
|
49
|
+
partition: opts[:partition] || 0,
|
50
|
+
received_at: opts[:received_at] || Time.current,
|
51
|
+
topic: opts[:topic] || test_topic.name
|
51
52
|
}
|
52
53
|
end
|
53
54
|
|
data/sbmt-kafka_consumer.gemspec
CHANGED
@@ -6,12 +6,12 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "sbmt-kafka_consumer"
|
7
7
|
spec.license = "MIT"
|
8
8
|
spec.version = Sbmt::KafkaConsumer::VERSION
|
9
|
-
spec.authors = ["
|
9
|
+
spec.authors = ["Kuper Ruby-Platform Team"]
|
10
10
|
|
11
11
|
spec.summary = "Ruby gem for consuming Kafka messages"
|
12
12
|
spec.description = "This gem is used for consuming Kafka messages. It represents a wrapper over Karafka gem and is recommended for using as a transport with sbmt-outbox"
|
13
|
-
spec.homepage = "https://github.com/
|
14
|
-
spec.required_ruby_version = ">=
|
13
|
+
spec.homepage = "https://github.com/Kuper-Tech/sbmt-kafka_consumer"
|
14
|
+
spec.required_ruby_version = ">= 3.0.0"
|
15
15
|
|
16
16
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
17
|
|
@@ -31,9 +31,9 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
|
-
spec.add_dependency "rails", ">= 6.
|
34
|
+
spec.add_dependency "rails", ">= 6.1"
|
35
35
|
spec.add_dependency "zeitwerk", "~> 2.3"
|
36
|
-
spec.add_dependency "karafka", "~> 2.
|
36
|
+
spec.add_dependency "karafka", "~> 2.4"
|
37
37
|
spec.add_dependency "yabeda", ">= 0.11"
|
38
38
|
spec.add_dependency "anyway_config", ">= 2.4.0"
|
39
39
|
spec.add_dependency "thor"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sbmt-kafka_consumer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Kuper Ruby-Platform Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09-
|
11
|
+
date: 2024-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '6.
|
19
|
+
version: '6.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '6.
|
26
|
+
version: '6.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: zeitwerk
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,9 +43,6 @@ dependencies:
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2.2'
|
48
|
-
- - "<"
|
49
46
|
- !ruby/object:Gem::Version
|
50
47
|
version: '2.4'
|
51
48
|
type: :runtime
|
@@ -53,9 +50,6 @@ dependencies:
|
|
53
50
|
version_requirements: !ruby/object:Gem::Requirement
|
54
51
|
requirements:
|
55
52
|
- - "~>"
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: '2.2'
|
58
|
-
- - "<"
|
59
53
|
- !ruby/object:Gem::Version
|
60
54
|
version: '2.4'
|
61
55
|
- !ruby/object:Gem::Dependency
|
@@ -531,6 +525,7 @@ files:
|
|
531
525
|
- lib/sbmt/kafka_consumer/probes/host.rb
|
532
526
|
- lib/sbmt/kafka_consumer/probes/probe.rb
|
533
527
|
- lib/sbmt/kafka_consumer/railtie.rb
|
528
|
+
- lib/sbmt/kafka_consumer/routing/consumer_mapper/base.rb
|
534
529
|
- lib/sbmt/kafka_consumer/routing/karafka_v1_consumer_mapper.rb
|
535
530
|
- lib/sbmt/kafka_consumer/routing/karafka_v2_consumer_mapper.rb
|
536
531
|
- lib/sbmt/kafka_consumer/serialization/base_deserializer.rb
|
@@ -546,14 +541,14 @@ files:
|
|
546
541
|
- lib/sbmt/kafka_consumer/yabeda_configurer.rb
|
547
542
|
- rubocop/rspec.yml
|
548
543
|
- sbmt-kafka_consumer.gemspec
|
549
|
-
homepage: https://github.com/
|
544
|
+
homepage: https://github.com/Kuper-Tech/sbmt-kafka_consumer
|
550
545
|
licenses:
|
551
546
|
- MIT
|
552
547
|
metadata:
|
553
548
|
allowed_push_host: https://rubygems.org
|
554
|
-
homepage_uri: https://github.com/
|
555
|
-
source_code_uri: https://github.com/
|
556
|
-
changelog_uri: https://github.com/
|
549
|
+
homepage_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer
|
550
|
+
source_code_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer
|
551
|
+
changelog_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer/blob/master/CHANGELOG.md
|
557
552
|
rubygems_mfa_required: 'false'
|
558
553
|
post_install_message:
|
559
554
|
rdoc_options: []
|
@@ -563,7 +558,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
563
558
|
requirements:
|
564
559
|
- - ">="
|
565
560
|
- !ruby/object:Gem::Version
|
566
|
-
version:
|
561
|
+
version: 3.0.0
|
567
562
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
568
563
|
requirements:
|
569
564
|
- - ">="
|