database_validations 1.2.0 → 2.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 +4 -4
- data/config/database.yml +17 -0
- data/config/database_config.rb +12 -0
- data/config/rubocop-default.yml +5 -0
- data/lib/database_validations/lib/adapters/mysql_adapter.rb +6 -5
- data/lib/database_validations/lib/adapters/postgresql_adapter.rb +7 -6
- data/lib/database_validations/lib/adapters/sqlite_adapter.rb +12 -5
- data/lib/database_validations/lib/checkers/db_uniqueness_validator.rb +2 -2
- data/lib/database_validations/lib/rescuer.rb +42 -5
- data/lib/database_validations/lib/validators/db_presence_validator.rb +3 -7
- data/lib/database_validations/rspec/uniqueness_validator_matcher.rb +1 -3
- data/lib/database_validations/version.rb +1 -1
- data/lib/rubocop/database_validations/plugin.rb +29 -0
- data/lib/rubocop/database_validations.rb +2 -0
- data/lib/rubocop-database_validations.rb +4 -0
- metadata +50 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb8e88ed5b20821f4c5ebd14e90ea1505689ea2d68619608b832c18ece68a50c
|
|
4
|
+
data.tar.gz: 4b658e6f4d179735bd6fc73002e9790ed18bb4134119a00403fe51bba3d4bba6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7053335a8acdf7dbf0f64a9c8e4bdfecaa6300a285158911af5d436f59265c05d36f118347c4e36b9016e6c4284ff54b0f680c30bbaba80ec4649ef2922da742
|
|
7
|
+
data.tar.gz: 4887ce0d4ab98df0498b7df3531bc8ecdc49c85b8af3bb22606f2bc1df3b3c9de871216abe9ef16ca9c1cb6c33b3382c7a2da63bf13464e0c852ff0e1e891b0c
|
data/config/database.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
postgresql:
|
|
2
|
+
adapter: postgresql
|
|
3
|
+
database: database_validations_test
|
|
4
|
+
host: <%= ENV['DB_HOST'] || '127.0.0.1' %>
|
|
5
|
+
username: <%= ENV['DB_USER'] || 'database_validations' %>
|
|
6
|
+
password: <%= ENV['DB_PASSWORD'] || 'database_validations' %>
|
|
7
|
+
|
|
8
|
+
mysql:
|
|
9
|
+
adapter: mysql2
|
|
10
|
+
database: database_validations_test
|
|
11
|
+
host: <%= ENV['DB_HOST'] || '127.0.0.1' %>
|
|
12
|
+
username: <%= ENV['DB_USER'] || 'root' %>
|
|
13
|
+
password: <%= ENV['DB_PASSWORD'] || 'database_validations' %>
|
|
14
|
+
|
|
15
|
+
sqlite:
|
|
16
|
+
adapter: sqlite3
|
|
17
|
+
database: ':memory:'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
module DatabaseConfig
|
|
5
|
+
def self.load(symbolize_keys: false)
|
|
6
|
+
yaml_path = File.expand_path('database.yml', __dir__)
|
|
7
|
+
yaml_content = ERB.new(File.read(yaml_path)).result
|
|
8
|
+
configs = YAML.safe_load(yaml_content)
|
|
9
|
+
configs = configs.transform_values { |v| v.transform_keys(&:to_sym) } if symbolize_keys
|
|
10
|
+
configs
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -4,14 +4,15 @@ module DatabaseValidations
|
|
|
4
4
|
ADAPTER = :mysql2
|
|
5
5
|
|
|
6
6
|
class << self
|
|
7
|
-
def unique_index_name(
|
|
8
|
-
|
|
7
|
+
def unique_index_name(error)
|
|
8
|
+
error.message[/key '([^']+)'/, 1]&.split('.')&.last
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def unique_error_columns(
|
|
11
|
+
def unique_error_columns(_error); end
|
|
12
12
|
|
|
13
|
-
def foreign_key_error_column(
|
|
14
|
-
|
|
13
|
+
def foreign_key_error_column(error)
|
|
14
|
+
column = error.message[/FOREIGN KEY \(`([^`]+)`\)/, 1]
|
|
15
|
+
column ? [column] : []
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -4,16 +4,17 @@ module DatabaseValidations
|
|
|
4
4
|
ADAPTER = :postgresql
|
|
5
5
|
|
|
6
6
|
class << self
|
|
7
|
-
def unique_index_name(
|
|
8
|
-
|
|
7
|
+
def unique_index_name(error)
|
|
8
|
+
error.message[/unique constraint "([^"]+)"/, 1]
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def unique_error_columns(
|
|
12
|
-
|
|
11
|
+
def unique_error_columns(error)
|
|
12
|
+
error.message[/Key \((.+)\)=/, 1].split(', ')
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def foreign_key_error_column(
|
|
16
|
-
|
|
15
|
+
def foreign_key_error_column(error)
|
|
16
|
+
column = error.message[/Key \(([^)]+)\)/, 1]
|
|
17
|
+
column ? [column] : []
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
end
|
|
@@ -4,14 +4,21 @@ module DatabaseValidations
|
|
|
4
4
|
ADAPTER = :sqlite3
|
|
5
5
|
|
|
6
6
|
class << self
|
|
7
|
-
def unique_index_name(
|
|
7
|
+
def unique_index_name(error)
|
|
8
|
+
error.message[/UNIQUE constraint failed: index '([^']+)'/, 1]
|
|
9
|
+
end
|
|
8
10
|
|
|
9
|
-
def unique_error_columns(
|
|
10
|
-
|
|
11
|
+
def unique_error_columns(error)
|
|
12
|
+
error.message.scan(/\w+\.([^,:]+)/).flatten
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
def foreign_key_error_column(
|
|
14
|
-
|
|
15
|
+
def foreign_key_error_column(error)
|
|
16
|
+
return [] unless error.respond_to?(:sql) && error.sql
|
|
17
|
+
|
|
18
|
+
columns_clause = error.sql[/\(([^)]+)\)\s*VALUES/i, 1]
|
|
19
|
+
return [] unless columns_clause
|
|
20
|
+
|
|
21
|
+
columns_clause.scan(/"([^"]+)"/).flatten
|
|
15
22
|
end
|
|
16
23
|
end
|
|
17
24
|
end
|
|
@@ -40,8 +40,8 @@ module DatabaseValidations
|
|
|
40
40
|
|
|
41
41
|
validator.attributes.map do |attribute|
|
|
42
42
|
columns = KeyGenerator.unify_columns(attribute, validator.options[:scope])
|
|
43
|
-
index = validator.index_name ? adapter.find_unique_index_by_name(validator.index_name.to_s) : adapter.find_unique_index(columns, validator.where) # rubocop:disable
|
|
44
|
-
raise Errors::IndexNotFound.new(columns, validator.where, validator.index_name, adapter.unique_indexes, adapter.table_name) unless index && valid_index?(columns, index) # rubocop:disable
|
|
43
|
+
index = validator.index_name ? adapter.find_unique_index_by_name(validator.index_name.to_s) : adapter.find_unique_index(columns, validator.where) # rubocop:disable Layout/LineLength
|
|
44
|
+
raise Errors::IndexNotFound.new(columns, validator.where, validator.index_name, adapter.unique_indexes, adapter.table_name) unless index && valid_index?(columns, index) # rubocop:disable Layout/LineLength
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -15,21 +15,58 @@ module DatabaseValidations
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def process(validate, instance, error, key_types)
|
|
18
|
+
keys = resolve_keys(instance, error, key_types)
|
|
19
|
+
attribute_validator = find_matching_validator(instance, keys)
|
|
20
|
+
return false unless attribute_validator
|
|
21
|
+
|
|
22
|
+
process_validator(validate, instance, attribute_validator)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resolve_keys(instance, error, key_types)
|
|
18
26
|
adapter = Adapters.factory(instance.class)
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
key_types.flat_map do |key_generator, error_processor|
|
|
29
|
+
result = adapter.public_send(error_processor, error)
|
|
30
|
+
|
|
31
|
+
# FK adapters return an array of candidate columns, each generating a
|
|
32
|
+
# separate key. Uniqueness adapters return columns that form a single
|
|
33
|
+
# composite key, passed together to the key generator.
|
|
34
|
+
if key_generator == :for_db_presence
|
|
35
|
+
Array(result).map { |column| KeyGenerator.public_send(key_generator, column) }
|
|
36
|
+
else
|
|
37
|
+
[KeyGenerator.public_send(key_generator, result)]
|
|
38
|
+
end
|
|
22
39
|
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def find_matching_validator(instance, keys)
|
|
43
|
+
first_match = nil
|
|
23
44
|
|
|
24
45
|
keys.each do |key|
|
|
25
46
|
attribute_validator = instance._db_validators[key]
|
|
26
|
-
|
|
27
47
|
next unless attribute_validator
|
|
28
48
|
|
|
29
|
-
|
|
49
|
+
first_match ||= attribute_validator
|
|
50
|
+
|
|
51
|
+
next if (keys.size > 1) && !foreign_key_invalid?(instance, attribute_validator)
|
|
52
|
+
|
|
53
|
+
return attribute_validator
|
|
30
54
|
end
|
|
31
55
|
|
|
32
|
-
|
|
56
|
+
# TOCTOU fallback: if disambiguate queries all passed (concurrent insert),
|
|
57
|
+
# use the first matching validator rather than leaving the error unhandled.
|
|
58
|
+
first_match
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def foreign_key_invalid?(instance, attribute_validator)
|
|
62
|
+
attribute = attribute_validator.attribute
|
|
63
|
+
reflection = instance.class._reflect_on_association(attribute)
|
|
64
|
+
return true unless reflection
|
|
65
|
+
|
|
66
|
+
fk_value = instance.read_attribute(reflection.foreign_key)
|
|
67
|
+
return true if fk_value.blank?
|
|
68
|
+
|
|
69
|
+
!reflection.klass.exists?(reflection.association_primary_key => fk_value)
|
|
33
70
|
end
|
|
34
71
|
|
|
35
72
|
def process_validator(validate, instance, attribute_validator)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module DatabaseValidations
|
|
2
2
|
class DbPresenceValidator < ActiveRecord::Validations::PresenceValidator
|
|
3
|
-
REFLECTION_MESSAGE =
|
|
3
|
+
REFLECTION_MESSAGE = :required
|
|
4
4
|
|
|
5
5
|
attr_reader :klass
|
|
6
6
|
|
|
@@ -53,15 +53,11 @@ module DatabaseValidations
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def db_belongs_to(name, scope = nil, **options)
|
|
56
|
-
|
|
57
|
-
options[:required] = false
|
|
58
|
-
else
|
|
59
|
-
options[:optional] = true
|
|
60
|
-
end
|
|
56
|
+
options[:optional] = true
|
|
61
57
|
|
|
62
58
|
belongs_to(name, scope, **options)
|
|
63
59
|
|
|
64
|
-
validates_with DatabaseValidations::DbPresenceValidator, _merge_attributes([name, message: DatabaseValidations::DbPresenceValidator::REFLECTION_MESSAGE]) # rubocop:disable
|
|
60
|
+
validates_with DatabaseValidations::DbPresenceValidator, _merge_attributes([name, { message: DatabaseValidations::DbPresenceValidator::REFLECTION_MESSAGE }]) # rubocop:disable Layout/LineLength
|
|
65
61
|
end
|
|
66
62
|
end
|
|
67
63
|
end
|
|
@@ -63,15 +63,13 @@ RSpec::Matchers.define :validate_db_uniqueness_of do |field| # rubocop:disable M
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
case_sensitive_default = ActiveRecord::VERSION::MAJOR >= 6 ? nil : true
|
|
67
|
-
|
|
68
66
|
@validators.include?(
|
|
69
67
|
field: field,
|
|
70
68
|
scope: Array.wrap(@scope),
|
|
71
69
|
where: @where,
|
|
72
70
|
message: @message,
|
|
73
71
|
index_name: @index_name,
|
|
74
|
-
case_sensitive: @case_sensitive.nil? ?
|
|
72
|
+
case_sensitive: @case_sensitive.nil? ? nil : @case_sensitive
|
|
75
73
|
)
|
|
76
74
|
end
|
|
77
75
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'lint_roller'
|
|
2
|
+
require 'database_validations/version'
|
|
3
|
+
|
|
4
|
+
module RuboCop
|
|
5
|
+
module DatabaseValidations
|
|
6
|
+
class Plugin < LintRoller::Plugin
|
|
7
|
+
def about
|
|
8
|
+
LintRoller::About.new(
|
|
9
|
+
name: 'rubocop-database_validations',
|
|
10
|
+
version: ::DatabaseValidations::VERSION,
|
|
11
|
+
homepage: 'https://github.com/toptal/database_validations',
|
|
12
|
+
description: 'RuboCop cops for database_validations gem.'
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def supported?(context)
|
|
17
|
+
context.engine == :rubocop
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def rules(_context)
|
|
21
|
+
LintRoller::Rules.new(
|
|
22
|
+
type: :path,
|
|
23
|
+
config_format: :rubocop,
|
|
24
|
+
value: File.join(__dir__, '..', '..', '..', 'config', 'rubocop-default.yml')
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: database_validations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Evgeniy Demin
|
|
@@ -15,56 +15,70 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 7.2.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
25
|
+
version: 7.2.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: lint_roller
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
26
40
|
- !ruby/object:Gem::Dependency
|
|
27
41
|
name: benchmark-ips
|
|
28
42
|
requirement: !ruby/object:Gem::Requirement
|
|
29
43
|
requirements:
|
|
30
|
-
- - "
|
|
44
|
+
- - ">="
|
|
31
45
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
46
|
+
version: '0'
|
|
33
47
|
type: :development
|
|
34
48
|
prerelease: false
|
|
35
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
50
|
requirements:
|
|
37
|
-
- - "
|
|
51
|
+
- - ">="
|
|
38
52
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
53
|
+
version: '0'
|
|
40
54
|
- !ruby/object:Gem::Dependency
|
|
41
55
|
name: bundler
|
|
42
56
|
requirement: !ruby/object:Gem::Requirement
|
|
43
57
|
requirements:
|
|
44
58
|
- - ">="
|
|
45
59
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
60
|
+
version: '0'
|
|
47
61
|
type: :development
|
|
48
62
|
prerelease: false
|
|
49
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
64
|
requirements:
|
|
51
65
|
- - ">="
|
|
52
66
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
67
|
+
version: '0'
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: db-query-matchers
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|
|
57
71
|
requirements:
|
|
58
72
|
- - ">="
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: '0
|
|
74
|
+
version: '0'
|
|
61
75
|
type: :development
|
|
62
76
|
prerelease: false
|
|
63
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
78
|
requirements:
|
|
65
79
|
- - ">="
|
|
66
80
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: '0
|
|
81
|
+
version: '0'
|
|
68
82
|
- !ruby/object:Gem::Dependency
|
|
69
83
|
name: mysql2
|
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -97,58 +111,58 @@ dependencies:
|
|
|
97
111
|
name: rake
|
|
98
112
|
requirement: !ruby/object:Gem::Requirement
|
|
99
113
|
requirements:
|
|
100
|
-
- - "
|
|
114
|
+
- - ">="
|
|
101
115
|
- !ruby/object:Gem::Version
|
|
102
|
-
version: '
|
|
116
|
+
version: '0'
|
|
103
117
|
type: :development
|
|
104
118
|
prerelease: false
|
|
105
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
120
|
requirements:
|
|
107
|
-
- - "
|
|
121
|
+
- - ">="
|
|
108
122
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '
|
|
123
|
+
version: '0'
|
|
110
124
|
- !ruby/object:Gem::Dependency
|
|
111
125
|
name: rspec
|
|
112
126
|
requirement: !ruby/object:Gem::Requirement
|
|
113
127
|
requirements:
|
|
114
|
-
- - "
|
|
128
|
+
- - ">="
|
|
115
129
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '
|
|
130
|
+
version: '0'
|
|
117
131
|
type: :development
|
|
118
132
|
prerelease: false
|
|
119
133
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
134
|
requirements:
|
|
121
|
-
- - "
|
|
135
|
+
- - ">="
|
|
122
136
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '
|
|
137
|
+
version: '0'
|
|
124
138
|
- !ruby/object:Gem::Dependency
|
|
125
139
|
name: rubocop
|
|
126
140
|
requirement: !ruby/object:Gem::Requirement
|
|
127
141
|
requirements:
|
|
128
|
-
- - "
|
|
142
|
+
- - ">="
|
|
129
143
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: '
|
|
144
|
+
version: '0'
|
|
131
145
|
type: :development
|
|
132
146
|
prerelease: false
|
|
133
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
134
148
|
requirements:
|
|
135
|
-
- - "
|
|
149
|
+
- - ">="
|
|
136
150
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: '
|
|
151
|
+
version: '0'
|
|
138
152
|
- !ruby/object:Gem::Dependency
|
|
139
153
|
name: rubocop-rspec
|
|
140
154
|
requirement: !ruby/object:Gem::Requirement
|
|
141
155
|
requirements:
|
|
142
|
-
- - "
|
|
156
|
+
- - ">="
|
|
143
157
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: '
|
|
158
|
+
version: '0'
|
|
145
159
|
type: :development
|
|
146
160
|
prerelease: false
|
|
147
161
|
version_requirements: !ruby/object:Gem::Requirement
|
|
148
162
|
requirements:
|
|
149
|
-
- - "
|
|
163
|
+
- - ">="
|
|
150
164
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '
|
|
165
|
+
version: '0'
|
|
152
166
|
- !ruby/object:Gem::Dependency
|
|
153
167
|
name: sqlite3
|
|
154
168
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -176,6 +190,9 @@ executables: []
|
|
|
176
190
|
extensions: []
|
|
177
191
|
extra_rdoc_files: []
|
|
178
192
|
files:
|
|
193
|
+
- config/database.yml
|
|
194
|
+
- config/database_config.rb
|
|
195
|
+
- config/rubocop-default.yml
|
|
179
196
|
- lib/database_validations.rb
|
|
180
197
|
- lib/database_validations/lib/adapters.rb
|
|
181
198
|
- lib/database_validations/lib/adapters/base_adapter.rb
|
|
@@ -203,10 +220,14 @@ files:
|
|
|
203
220
|
- lib/database_validations/rubocop/cops.rb
|
|
204
221
|
- lib/database_validations/tasks/database_validations.rake
|
|
205
222
|
- lib/database_validations/version.rb
|
|
223
|
+
- lib/rubocop-database_validations.rb
|
|
224
|
+
- lib/rubocop/database_validations.rb
|
|
225
|
+
- lib/rubocop/database_validations/plugin.rb
|
|
206
226
|
homepage: https://github.com/toptal/database_validations
|
|
207
227
|
licenses:
|
|
208
228
|
- MIT
|
|
209
|
-
metadata:
|
|
229
|
+
metadata:
|
|
230
|
+
default_lint_roller_plugin: RuboCop::DatabaseValidations::Plugin
|
|
210
231
|
rdoc_options: []
|
|
211
232
|
require_paths:
|
|
212
233
|
- lib
|
|
@@ -214,7 +235,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
214
235
|
requirements:
|
|
215
236
|
- - ">="
|
|
216
237
|
- !ruby/object:Gem::Version
|
|
217
|
-
version:
|
|
238
|
+
version: 3.2.0
|
|
218
239
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
240
|
requirements:
|
|
220
241
|
- - ">="
|