redis_counters 1.4.0 → 1.5.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
  SHA1:
3
- metadata.gz: 21ad3dea600e503c5c78e5f7b1c2c44df42b9c6c
4
- data.tar.gz: daa6aaaf6b4f4e9e4900d019c5bbbb9c0d675936
3
+ metadata.gz: a7e6d0cc5b4ca4ed565bb19a6d630460ca7f83a9
4
+ data.tar.gz: b7962325e5af14aa63f6231b9053cc8d5f020b66
5
5
  SHA512:
6
- metadata.gz: 4a59daf0d09208f4779758224ae19e03cc54dbea4623c4dac78a9aaf334a921513040c5cf60317f3f16528399b011b3faa8a759c2f21bdf02c8061a2593f9631
7
- data.tar.gz: 9afa7121c971ae69a1c5c2b868f42f871d6d28eef44394f7be8e52946b6e6fcfe8e7b35d831668debf33415b259ea7aad6bb14d494123d3522c9e8c7fdc0e022
6
+ metadata.gz: ea9edd7ea8fbc50f901de96b70cf51ea983c5e8bc07e0017bdddb844af3b4ec0f2105996b9dd200d7c0e5021955bc017af63e3240ec97af24ff824d3d6ea9f2b
7
+ data.tar.gz: 03a615b5e096b657e5e1982e3b568167b71b463d57d820e28062dc890b6af109e717de64ab3a7e64cffca2afbc5c0a5e14d27ebe03828772a8c4d721cff680c3
@@ -0,0 +1,22 @@
1
+ build:
2
+ test:
3
+ image: abakpress/dind-testing
4
+ pull: true
5
+ privileged: true
6
+ volumes:
7
+ - /home/data/drone/images:/images
8
+ - /home/data/drone/gems:/bundle
9
+ environment:
10
+ - COMPOSE_FILE_EXT=drone
11
+ - POSTGRES_IMAGE_TAG=9.3-latest
12
+ - SPHINX_IMAGE_TAG=2.2-latest
13
+ commands:
14
+ - wrapdocker docker -v
15
+
16
+ - fetch-images
17
+ --image abakpress/ruby-app:$RUBY_IMAGE_TAG
18
+ --image abakpress/postgres-db:$POSTGRES_IMAGE_TAG
19
+ --image abakpress/sphinx-index:$SPHINX_IMAGE_TAG
20
+
21
+ - dip provision
22
+ - dip rspec
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --tty
3
+ --format progress
4
+ --order random
5
+ --backtrace
data/Gemfile CHANGED
@@ -1,6 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'json', '< 2' if RUBY_VERSION < '2'
4
- gem 'activesupport', '< 5' if RUBY_VERSION < '2'
5
-
6
3
  gemspec
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # RedisCounters
2
2
 
3
- [![Dolly](http://dolly.railsc.ru/badges/abak-press/redis_counters/master)](http://dolly.railsc.ru/projects/36/builds/latest/?ref=master)
3
+ [![Build Status](https://drone.railsc.ru/api/badges/abak-press/redis_counters/status.svg)](https://drone.railsc.ru/abak-press/redis_counters)
4
4
  [![Code Climate](https://codeclimate.com/github/abak-press/redis_counters/badges/gpa.svg)](https://codeclimate.com/github/abak-press/redis_counters)
5
5
  [![Test Coverage](https://codeclimate.com/github/abak-press/redis_counters/badges/coverage.svg)](https://codeclimate.com/github/abak-press/redis_counters/coverage)
6
6
 
data/dip.yml ADDED
@@ -0,0 +1,41 @@
1
+ version: '1'
2
+
3
+ environment:
4
+ DOCKER_RUBY_VERSION: 2.2
5
+ RUBY_IMAGE_TAG: 2.2-latest
6
+ COMPOSE_FILE_EXT: development
7
+ RAILS_ENV: test
8
+
9
+ compose:
10
+ files:
11
+ - docker-compose.yml
12
+ - docker-compose.${COMPOSE_FILE_EXT}.yml
13
+
14
+ interaction:
15
+ sh:
16
+ service: app
17
+
18
+ irb:
19
+ service: app
20
+ command: irb
21
+
22
+ bundle:
23
+ service: app
24
+ command: bundle
25
+
26
+ rake:
27
+ service: app
28
+ command: bundle exec rake
29
+
30
+ rspec:
31
+ service: app
32
+ command: bundle exec rspec
33
+
34
+ clean:
35
+ service: app
36
+ command: rm -f Gemfile.lock gemfiles/*.gemfile.*
37
+
38
+ provision:
39
+ - docker volume create --name bundler_data
40
+ - dip clean
41
+ - dip bundle install
@@ -0,0 +1,13 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ volumes:
6
+ - .:/app
7
+ - ../:/localgems
8
+ - bundler-data:/bundle
9
+
10
+ volumes:
11
+ bundler-data:
12
+ external:
13
+ name: bundler_data
@@ -0,0 +1,7 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ volumes:
6
+ - .:/app
7
+ - /bundle:/bundle
@@ -0,0 +1,9 @@
1
+ version: '2'
2
+
3
+ services:
4
+ app:
5
+ image: abakpress/ruby-app:$RUBY_IMAGE_TAG
6
+ environment:
7
+ - BUNDLE_PATH=/bundle/$DOCKER_RUBY_VERSION
8
+ - BUNDLE_CONFIG=/app/.bundle/config
9
+ command: bash
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'redis_counters/version'
3
2
  require 'redis_counters/base_counter'
4
3
  require 'redis_counters/hash_counter'
@@ -12,10 +11,9 @@ require 'active_support'
12
11
  require 'active_support/core_ext'
13
12
 
14
13
  module RedisCounters
15
-
16
14
  def create_counter(redis, opts)
17
15
  BaseCounter.create(redis, opts)
18
16
  end
19
17
 
20
18
  module_function :create_counter
21
- end
19
+ end
@@ -1,11 +1,8 @@
1
- # coding: utf-8
2
1
  require 'forwardable'
3
2
  require 'active_support/core_ext/class/attribute'
4
3
 
5
4
  module RedisCounters
6
-
7
5
  # Базовый класс счетчика на основе Redis.
8
-
9
6
  class BaseCounter
10
7
  extend Forwardable
11
8
 
@@ -22,10 +19,13 @@ module RedisCounters
22
19
  # opts - Hash - хеш опций счетчика:
23
20
  # counter_name - Symbol/String - идентификатор счетчика.
24
21
  # key_delimiter - String - разделитель ключа (опционально).
25
- # value_delimiter - String - разделитель значений (опционально).
22
+ # value_delimiter - Array[String] или String, разделитель значений. Если это массив, то первый элемент будет
23
+ # считатся новым разделителем, а второй старым. Все данные будут записываться, используя
24
+ # новый. Старый будет использоваться только для старых данных. Так что если надо сменить
25
+ # делимитр у счётчика, например с ':' на '�', то сперва надо будет установить его на ['�',
26
+ # ':'], а после дампа старых данных в БД, на '�'.
26
27
  #
27
28
  # Returns RedisCounters::BaseCounter.
28
- #
29
29
  def self.create(redis, opts)
30
30
  counter_class = opts.fetch(:counter_class).to_s.constantize
31
31
  counter_class.new(redis, opts)
@@ -80,5 +80,4 @@ module RedisCounters
80
80
 
81
81
  def_delegator :redis, :multi, :transaction
82
82
  end
83
-
84
- end
83
+ end
@@ -191,4 +191,4 @@ module RedisCounters
191
191
  result
192
192
  end
193
193
  end
194
- end
194
+ end
@@ -1,11 +1,8 @@
1
- # coding: utf-8
2
1
  require 'redis_counters/base_counter'
3
2
  require 'redis_counters/clusterize_and_partitionize'
4
3
 
5
4
  module RedisCounters
6
-
7
5
  # Счетчик на основе redis-hash, с возможностью партиционирования и кластеризации значений.
8
-
9
6
  class HashCounter < BaseCounter
10
7
  include ClusterizeAndPartitionize
11
8
 
@@ -24,7 +21,11 @@ module RedisCounters
24
21
  group_params = [field_name]
25
22
  end
26
23
 
27
- group_params.join(value_delimiter)
24
+ if value_delimiter.is_a?(Array)
25
+ group_params.join(value_delimiter.first)
26
+ else
27
+ group_params.join(value_delimiter)
28
+ end
28
29
  end
29
30
 
30
31
  def field_name
@@ -43,12 +44,26 @@ module RedisCounters
43
44
  # cluster - Array - листовой кластер - массив параметров однозначно идентифицирующий кластер.
44
45
  # partition - Array - листовая партиция - массив параметров однозначно идентифицирующий партицию.
45
46
  #
46
- # Returns Array of WithIndifferentAccess.
47
- #
47
+ # Returns Array of HashWithIndifferentAccess.
48
48
  def partition_data(cluster, partition)
49
49
  keys = group_keys.dup.unshift(:value)
50
+
51
+ if delimiter_is_ary = value_delimiter.is_a?(Array)
52
+ new_delim, old_delim = value_delimiter
53
+ end
54
+
50
55
  redis.hgetall(key(partition, cluster)).inject(Array.new) do |result, (key, value)|
51
- values = key.split(value_delimiter, -1).unshift(format_value(value))
56
+ values = if delimiter_is_ary
57
+ if key.include?(new_delim)
58
+ key.split(new_delim, -1)
59
+ else
60
+ key.split(old_delim, -1)
61
+ end
62
+ else
63
+ key.split(value_delimiter, -1)
64
+ end
65
+
66
+ values = values.map(&:presence).unshift(format_value(value))
52
67
  values.delete_at(1) unless group_keys.present?
53
68
  result << Hash[keys.zip(values)].with_indifferent_access
54
69
  end
@@ -66,5 +81,4 @@ module RedisCounters
66
81
  @float_mode ||= options.fetch(:float_mode, false)
67
82
  end
68
83
  end
69
-
70
84
  end
@@ -1,3 +1,3 @@
1
1
  module RedisCounters
2
- VERSION = '1.4.0'
3
- end
2
+ VERSION = '1.5.0'.freeze
3
+ end
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ['lib']
18
18
 
19
- spec.add_dependency 'activesupport', '>= 3.0'
19
+ spec.add_dependency 'activesupport', '>= 3.0', '< 5'
20
20
 
21
21
  spec.add_development_dependency 'bundler'
22
22
  spec.add_development_dependency 'rake'
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'simplecov'
28
28
  spec.add_development_dependency 'cane', '>= 2.6.0'
29
29
  spec.add_development_dependency 'bundler-audit'
30
- spec.add_development_dependency 'apress-changelogger'
30
+ spec.add_development_dependency 'pry-byebug'
31
31
  end
@@ -257,7 +257,7 @@ describe RedisCounters::HashCounter do
257
257
  it { expect(counter.data(partitions).first[:param4]).to eq '1' }
258
258
  it { expect(counter.data(partitions).second[:value]).to eq 5 }
259
259
  it { expect(counter.data(partitions).second[:param3]).to eq '31' }
260
- it { expect(counter.data(partitions).second[:param4]).to eq '' }
260
+ it { expect(counter.data(partitions).second[:param4]).to eq nil }
261
261
  end
262
262
 
263
263
  context 'when group_keys given' do
@@ -446,6 +446,68 @@ describe RedisCounters::HashCounter do
446
446
  it { expect(counter.data.third[:value]).to eq 3 }
447
447
  end
448
448
 
449
+ context 'two delimiters' do
450
+ let(:options) do
451
+ {
452
+ counter_name: :test_counter,
453
+ group_keys: [:title, :url],
454
+ partition_keys: [:date],
455
+ key_delimiter: '&',
456
+ value_delimiter: %W(\uFFFD :)
457
+ }
458
+ end
459
+ let(:partition) { {title: 'Main', url: 'http://example.com', date: '2017-04-21'} }
460
+
461
+ before { counter.increment(partition) }
462
+
463
+ it 'uses the first (new) delimiter for writing' do
464
+ expect(counter.send(:field)).to eq('Main�http://example.com')
465
+ expect(counter.data).to eq([{'value' => 1, 'title' => 'Main', 'url' => 'http://example.com'}])
466
+ end
467
+ end
468
+
469
+ context 'new delimiter added when there is data separated by the old one' do
470
+ let(:options) do
471
+ {
472
+ counter_name: :test_counter,
473
+ group_keys: [:title, :url],
474
+ partition_keys: [:date],
475
+ key_delimiter: '&',
476
+ value_delimiter: %W(\uFFFD :)
477
+ }
478
+ end
479
+ let(:partition) { {title: 'Main', url: 'http://example.com', date: '2017-04-21'} }
480
+
481
+ before do
482
+ redis.hincrbyfloat('test_counter&2017-04-21', 'Main:/about', 1.0)
483
+ end
484
+
485
+ it 'understands the old delimiter' do
486
+ expect(counter.data).to eq([{'value' => 1, 'title' => 'Main', 'url' => '/about'}])
487
+ end
488
+ end
489
+
490
+ context 'new delimiter added and there is data separated by it but contains the old delimiter' do
491
+ let(:options) do
492
+ {
493
+ counter_name: :test_counter,
494
+ group_keys: [:title, :url],
495
+ partition_keys: [:date],
496
+ key_delimiter: '&',
497
+ value_delimiter: %W(\uFFFD :)
498
+ }
499
+ end
500
+ let(:partition) { {title: 'Main', url: 'http://example.com', date: '2017-04-21'} }
501
+
502
+ before do
503
+ redis.hincrbyfloat('test_counter&2017-04-21', 'Main�http://example.com', 1.0)
504
+ end
505
+
506
+ it 'uses the new delimiter' do
507
+ expect(counter.data).to eq([{'value' => 1, 'title' => 'Main', 'url' => 'http://example.com'}])
508
+ end
509
+ end
510
+
449
511
  context 'when check custom increment' do
450
512
  let(:options) { {
451
513
  :counter_name => :test_counter,
@@ -459,4 +521,4 @@ describe RedisCounters::HashCounter do
459
521
  it { expect(redis.hexists('test_counter', 'test_field')).to be_true }
460
522
  it { expect(redis.hget('test_counter', 'test_field').to_f).to be_within(0.001).of value*0.2.to_f }
461
523
  end
462
- end
524
+ end
@@ -1,13 +1,11 @@
1
- require 'rubygems'
2
1
  require 'bundler/setup'
3
2
  require 'rspec'
4
3
  require 'mock_redis'
5
4
  require 'timecop'
6
-
7
5
  require 'codeclimate-test-reporter'
8
- CodeClimate::TestReporter.start
9
-
10
6
  require 'simplecov'
7
+ require 'pry-byebug'
8
+
11
9
  SimpleCov.start('test_frameworks')
12
10
 
13
11
  require 'redis_counters'
@@ -18,7 +16,4 @@ Dir[File.join(support_dir, '**', '*.rb')].each { |f| require f }
18
16
 
19
17
  RSpec.configure do |config|
20
18
  config.backtrace_exclusion_patterns = [/lib\/rspec\/(core|expectations|matchers|mocks)/]
21
- config.color_enabled = true
22
- config.formatter = 'documentation'
23
- config.order = 'random'
24
- end
19
+ end
metadata CHANGED
@@ -1,169 +1,175 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_counters
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Napolskih
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-21 00:00:00.000000000 Z
11
+ date: 2017-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- version_requirements: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - '>='
17
- - !ruby/object:Gem::Version
18
- version: '3.0'
19
14
  name: activesupport
20
15
  requirement: !ruby/object:Gem::Requirement
21
16
  requirements:
22
- - - '>='
17
+ - - ">="
23
18
  - !ruby/object:Gem::Version
24
19
  version: '3.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
25
23
  type: :runtime
26
24
  prerelease: false
27
- - !ruby/object:Gem::Dependency
28
25
  version_requirements: !ruby/object:Gem::Requirement
29
26
  requirements:
30
- - - '>='
27
+ - - ">="
31
28
  - !ruby/object:Gem::Version
32
- version: '0'
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
33
+ - !ruby/object:Gem::Dependency
33
34
  name: bundler
34
35
  requirement: !ruby/object:Gem::Requirement
35
36
  requirements:
36
- - - '>='
37
+ - - ">="
37
38
  - !ruby/object:Gem::Version
38
39
  version: '0'
39
40
  type: :development
40
41
  prerelease: false
41
- - !ruby/object:Gem::Dependency
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - '>='
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
+ - !ruby/object:Gem::Dependency
47
48
  name: rake
48
49
  requirement: !ruby/object:Gem::Requirement
49
50
  requirements:
50
- - - '>='
51
+ - - ">="
51
52
  - !ruby/object:Gem::Version
52
53
  version: '0'
53
54
  type: :development
54
55
  prerelease: false
55
- - !ruby/object:Gem::Dependency
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ~>
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 2.14.0
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
61
62
  name: rspec
62
63
  requirement: !ruby/object:Gem::Requirement
63
64
  requirements:
64
- - - ~>
65
+ - - "~>"
65
66
  - !ruby/object:Gem::Version
66
67
  version: 2.14.0
67
68
  type: :development
68
69
  prerelease: false
69
- - !ruby/object:Gem::Dependency
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - '>='
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: '0'
74
+ version: 2.14.0
75
+ - !ruby/object:Gem::Dependency
75
76
  name: mock_redis
76
77
  requirement: !ruby/object:Gem::Requirement
77
78
  requirements:
78
- - - '>='
79
+ - - ">="
79
80
  - !ruby/object:Gem::Version
80
81
  version: '0'
81
82
  type: :development
82
83
  prerelease: false
83
- - !ruby/object:Gem::Dependency
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - '>='
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
89
90
  name: timecop
90
91
  requirement: !ruby/object:Gem::Requirement
91
92
  requirements:
92
- - - '>='
93
+ - - ">="
93
94
  - !ruby/object:Gem::Version
94
95
  version: '0'
95
96
  type: :development
96
97
  prerelease: false
97
- - !ruby/object:Gem::Dependency
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - '>='
100
+ - - ">="
101
101
  - !ruby/object:Gem::Version
102
- version: 0.4.1
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
103
104
  name: codeclimate-test-reporter
104
105
  requirement: !ruby/object:Gem::Requirement
105
106
  requirements:
106
- - - '>='
107
+ - - ">="
107
108
  - !ruby/object:Gem::Version
108
109
  version: 0.4.1
109
110
  type: :development
110
111
  prerelease: false
111
- - !ruby/object:Gem::Dependency
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - '>='
114
+ - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: 0.4.1
117
+ - !ruby/object:Gem::Dependency
117
118
  name: simplecov
118
119
  requirement: !ruby/object:Gem::Requirement
119
120
  requirements:
120
- - - '>='
121
+ - - ">="
121
122
  - !ruby/object:Gem::Version
122
123
  version: '0'
123
124
  type: :development
124
125
  prerelease: false
125
- - !ruby/object:Gem::Dependency
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
- - - '>='
128
+ - - ">="
129
129
  - !ruby/object:Gem::Version
130
- version: 2.6.0
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
131
132
  name: cane
132
133
  requirement: !ruby/object:Gem::Requirement
133
134
  requirements:
134
- - - '>='
135
+ - - ">="
135
136
  - !ruby/object:Gem::Version
136
137
  version: 2.6.0
137
138
  type: :development
138
139
  prerelease: false
139
- - !ruby/object:Gem::Dependency
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - '>='
142
+ - - ">="
143
143
  - !ruby/object:Gem::Version
144
- version: '0'
144
+ version: 2.6.0
145
+ - !ruby/object:Gem::Dependency
145
146
  name: bundler-audit
146
147
  requirement: !ruby/object:Gem::Requirement
147
148
  requirements:
148
- - - '>='
149
+ - - ">="
149
150
  - !ruby/object:Gem::Version
150
151
  version: '0'
151
152
  type: :development
152
153
  prerelease: false
153
- - !ruby/object:Gem::Dependency
154
154
  version_requirements: !ruby/object:Gem::Requirement
155
155
  requirements:
156
- - - '>='
156
+ - - ">="
157
157
  - !ruby/object:Gem::Version
158
158
  version: '0'
159
- name: apress-changelogger
159
+ - !ruby/object:Gem::Dependency
160
+ name: pry-byebug
160
161
  requirement: !ruby/object:Gem::Requirement
161
162
  requirements:
162
- - - '>='
163
+ - - ">="
163
164
  - !ruby/object:Gem::Version
164
165
  version: '0'
165
166
  type: :development
166
167
  prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
167
173
  description:
168
174
  email:
169
175
  - napolskih@gmail.com
@@ -171,12 +177,18 @@ executables: []
171
177
  extensions: []
172
178
  extra_rdoc_files: []
173
179
  files:
174
- - .gitignore
180
+ - ".drone.yml"
181
+ - ".gitignore"
182
+ - ".rspec"
175
183
  - CHANGELOG.md
176
184
  - Gemfile
177
185
  - Makefile
178
186
  - README.md
179
187
  - Rakefile
188
+ - dip.yml
189
+ - docker-compose.development.yml
190
+ - docker-compose.drone.yml
191
+ - docker-compose.yml
180
192
  - lib/redis_counters.rb
181
193
  - lib/redis_counters/base_counter.rb
182
194
  - lib/redis_counters/bucket.rb
@@ -215,12 +227,12 @@ require_paths:
215
227
  - lib
216
228
  required_ruby_version: !ruby/object:Gem::Requirement
217
229
  requirements:
218
- - - '>='
230
+ - - ">="
219
231
  - !ruby/object:Gem::Version
220
232
  version: '0'
221
233
  required_rubygems_version: !ruby/object:Gem::Requirement
222
234
  requirements:
223
- - - '>='
235
+ - - ">="
224
236
  - !ruby/object:Gem::Version
225
237
  version: '0'
226
238
  requirements: []