redis 5.1.0 → 5.4.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: ab20cee7f44b7d5f2736e1fbc7073cb950f52ceefc3dc1ff0edf9b4b778c7d8d
4
- data.tar.gz: 76b0b6169311906b2ee634f9314c74052a1612245d7e33220aab5cb2c617af8a
3
+ metadata.gz: 5d76a0d8a8a0361f991dc110219ffc77c12503148f9ece9586dd274321283265
4
+ data.tar.gz: fab1b1d4d3a5e22d2d952c98648a1412239f117a2c53bcbdf20ea7c43f456faa
5
5
  SHA512:
6
- metadata.gz: 220927cf03b0ad6ab0c7340d9b32ed073e379974d054eba12cf966ad65837eba00f114d1fdeb166780ead645befcc3ee9fb3a83aab8e8cb0b1661370f401f8cb
7
- data.tar.gz: 8f9476be4c7d4a3dd8dc1f29265b184932f67b49d524a0c79865dc95eee3ba165e9d24cb3f699ce287b886cc4f38b88574a5b33b1bab48f2fe9971597b7d2c5c
6
+ metadata.gz: 042f0aa785647bb0e6f73ff50722ba5dcf440e3f5e817c7eec030b876b7d34ca8be42a7a5a5a1767eba66b7424a8d2e74fe8e7b9e0362eedefe4fb58878cdb57
7
+ data.tar.gz: 5bc22d99f3a77929f35c02072be18d663ca127c77055afadd55455d3f571f61bbd70853d6fd4414e0e11f601c20d68872e8f097fce109341e5bda39f6aadb9fe
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Unreleased
2
2
 
3
+ # 5.4.1
4
+
5
+ - Properly handle NOSCRIPT errors.
6
+
7
+ # 5.4.0
8
+
9
+ - Fix `blmpop` method to actually use `BLMPOP`, it was mistakenly issuing `LMPOP` commands.
10
+ - `xadd` now accepts a `minid:` argument.
11
+ - `zrank` and `zrevrank` now accepts `with_score:` argument.
12
+ - `Redis#call` now accept a block, allowing to use `Redis` instances where `RedisClient` is expected.
13
+
14
+ # 5.3.0
15
+
16
+ - Fix the return type of `hgetall` when used inside a `multi` transaction which is itself inside a pipeline.
17
+
18
+ # 5.2.0
19
+
20
+ - Now require Ruby 2.6 because `redis-client` does.
21
+ - Eagerly close subscribed connection when using `subscribe_with_timeout`. See #1259.
22
+ - Add `exception` flag in `pipelined` allowing failed commands to be returned in the result array when set to `false`.
23
+
3
24
  # 5.1.0
4
25
 
5
26
  - `multi` now accept a `watch` keyword argument like `redis-client`. See #1236.
data/README.md CHANGED
@@ -34,7 +34,7 @@ You can also specify connection options as a [`redis://` URL][redis-url]:
34
34
  redis = Redis.new(url: "redis://:p4ssw0rd@10.0.1.1:6380/15")
35
35
  ```
36
36
 
37
- The client expects passwords with special chracters to be URL-encoded (i.e.
37
+ The client expects passwords with special characters to be URL-encoded (i.e.
38
38
  `CGI.escape(password)`).
39
39
 
40
40
  To connect to Redis listening on a Unix socket, try:
@@ -77,7 +77,7 @@ The client does not provide connection pooling. Each `Redis` instance
77
77
  has one and only one connection to the server, and use of this connection
78
78
  is protected by a mutex.
79
79
 
80
- As such it is heavilly recommended to use the [`connection_pool` gem](https://github.com/mperham/connection_pool), e.g.:
80
+ As such it is heavily recommended to use the [`connection_pool` gem](https://github.com/mperham/connection_pool), e.g.:
81
81
 
82
82
  ```ruby
83
83
  module MyApp
@@ -139,7 +139,7 @@ SENTINELS = [{ host: '127.0.0.1', port: 26380 },
139
139
  redis = Redis.new(name: 'mymaster', sentinels: SENTINELS, role: :master, password: 'mysecret')
140
140
  ```
141
141
 
142
- So you have to provide Sentinel credential and Redis explictly even they are the same
142
+ So you have to provide Sentinel credential and Redis explicitly even they are the same
143
143
 
144
144
  ```ruby
145
145
  # Use 'mysecret' to authenticate against the mymaster instance and sentinel
@@ -191,6 +191,28 @@ end
191
191
  # => ["OK"]
192
192
  ```
193
193
 
194
+ ### Exception management
195
+
196
+ The `exception` flag in the `#pipelined` is a feature that modifies the pipeline execution behavior. When set
197
+ to `false`, it doesn't raise an exception when a command error occurs. Instead, it allows the pipeline to execute all
198
+ commands, and any failed command will be available in the returned array. (Defaults to `true`)
199
+
200
+ ```ruby
201
+ results = redis.pipelined(exception: false) do |pipeline|
202
+ pipeline.set('key1', 'value1')
203
+ pipeline.lpush('key1', 'something') # This will fail
204
+ pipeline.set('key2', 'value2')
205
+ end
206
+ # results => ["OK", #<RedisClient::WrongTypeError: WRONGTYPE Operation against a key holding the wrong kind of value>, "OK"]
207
+
208
+ results.each do |result|
209
+ if result.is_a?(Redis::CommandError)
210
+ # Do something with the failed result
211
+ end
212
+ end
213
+ ```
214
+
215
+
194
216
  ### Executing commands atomically
195
217
 
196
218
  You can use `MULTI/EXEC` to run a number of commands in an atomic
@@ -251,6 +273,7 @@ See lib/redis/errors.rb for information about what exceptions are possible.
251
273
  ## Timeouts
252
274
 
253
275
  The client allows you to configure connect, read, and write timeouts.
276
+ Starting in version 5.0, the default for each is 1. Before that, it was 5.
254
277
  Passing a single `timeout` option will set all three values:
255
278
 
256
279
  ```ruby
@@ -383,7 +406,7 @@ gem "hiredis-client"
383
406
  ```
384
407
 
385
408
  If your application doesn't call `Bundler.require`, you may have
386
- to require it explictly:
409
+ to require it explicitly:
387
410
 
388
411
  ```ruby
389
412
  require "hiredis-client"
data/lib/redis/client.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'redis-client'
4
-
5
3
  class Redis
6
4
  class Client < ::RedisClient
7
5
  ERROR_MAPPING = {
@@ -17,6 +15,9 @@ class Redis
17
15
  RedisClient::ProtocolError => Redis::ProtocolError,
18
16
  RedisClient::OutOfMemoryError => Redis::OutOfMemoryError,
19
17
  }
18
+ if defined?(RedisClient::NoScriptError)
19
+ ERROR_MAPPING[RedisClient::NoScriptError] = Redis::NoScriptError
20
+ end
20
21
 
21
22
  class << self
22
23
  def config(**kwargs)
@@ -86,6 +87,12 @@ class Redis
86
87
  undef_method :call_once_v
87
88
  undef_method :blocking_call
88
89
 
90
+ def ensure_connected(retryable: true, &block)
91
+ super(retryable: retryable, &block)
92
+ rescue ::RedisClient::Error => error
93
+ Client.translate_error!(error)
94
+ end
95
+
89
96
  def call_v(command, &block)
90
97
  super(command, &block)
91
98
  rescue ::RedisClient::Error => error
@@ -105,7 +112,7 @@ class Redis
105
112
  Client.translate_error!(error)
106
113
  end
107
114
 
108
- def pipelined
115
+ def pipelined(exception: true)
109
116
  super
110
117
  rescue ::RedisClient::Error => error
111
118
  Client.translate_error!(error)
@@ -222,6 +222,8 @@ class Redis
222
222
  # - `:count => Integer`: return count keys at most per iteration
223
223
  #
224
224
  # @return [String, Array<[String, String]>] the next cursor and all found keys
225
+ #
226
+ # See the [Redis Server HSCAN documentation](https://redis.io/docs/latest/commands/hscan/) for further details
225
227
  def hscan(key, cursor, **options)
226
228
  _scan(:hscan, cursor, [key], **options) do |reply|
227
229
  [reply[0], reply[1].each_slice(2).to_a]
@@ -239,6 +241,8 @@ class Redis
239
241
  # - `:count => Integer`: return count keys at most per iteration
240
242
  #
241
243
  # @return [Enumerator] an enumerator for all found keys
244
+ #
245
+ # See the [Redis Server HSCAN documentation](https://redis.io/docs/latest/commands/hscan/) for further details
242
246
  def hscan_each(key, **options, &block)
243
247
  return to_enum(:hscan_each, key, **options) unless block_given?
244
248
 
@@ -22,6 +22,8 @@ class Redis
22
22
  # - `:type => String`: return keys only of the given type
23
23
  #
24
24
  # @return [String, Array<String>] the next cursor and all found keys
25
+ #
26
+ # See the [Redis Server SCAN documentation](https://redis.io/docs/latest/commands/scan/) for further details
25
27
  def scan(cursor, **options)
26
28
  _scan(:scan, cursor, [], **options)
27
29
  end
@@ -46,6 +48,8 @@ class Redis
46
48
  # - `:type => String`: return keys only of the given type
47
49
  #
48
50
  # @return [Enumerator] an enumerator for all found keys
51
+ #
52
+ # See the [Redis Server SCAN documentation](https://redis.io/docs/latest/commands/scan/) for further details
49
53
  def scan_each(**options, &block)
50
54
  return to_enum(:scan_each, **options) unless block_given?
51
55
 
@@ -282,6 +286,8 @@ class Redis
282
286
  #
283
287
  # @param [String] pattern
284
288
  # @return [Array<String>]
289
+ #
290
+ # See the [Redis Server KEYS documentation](https://redis.io/docs/latest/commands/keys/) for further details
285
291
  def keys(pattern = "*")
286
292
  send_command([:keys, pattern]) do |reply|
287
293
  if reply.is_a?(String)
@@ -205,7 +205,7 @@ class Redis
205
205
  def blmpop(timeout, *keys, modifier: "LEFT", count: nil)
206
206
  raise ArgumentError, "Pick either LEFT or RIGHT" unless modifier == "LEFT" || modifier == "RIGHT"
207
207
 
208
- args = [:lmpop, keys.size, *keys, modifier]
208
+ args = [:blmpop, timeout, keys.size, *keys, modifier]
209
209
  args << "COUNT" << Integer(count) if count
210
210
 
211
211
  send_blocking_command(args, timeout)
@@ -29,17 +29,23 @@ class Redis
29
29
  end
30
30
 
31
31
  # Listen for messages published to channels matching the given patterns.
32
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
33
+ # for further details
32
34
  def psubscribe(*channels, &block)
33
35
  _subscription(:psubscribe, 0, channels, block)
34
36
  end
35
37
 
36
38
  # Listen for messages published to channels matching the given patterns.
37
39
  # Throw a timeout error if there is no messages for a timeout period.
40
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
41
+ # for further details
38
42
  def psubscribe_with_timeout(timeout, *channels, &block)
39
43
  _subscription(:psubscribe_with_timeout, timeout, channels, block)
40
44
  end
41
45
 
42
46
  # Stop listening for messages posted to channels matching the given patterns.
47
+ # See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
48
+ # for further details
43
49
  def punsubscribe(*channels)
44
50
  _subscription(:punsubscribe, 0, channels, nil)
45
51
  end
@@ -184,6 +184,8 @@ class Redis
184
184
  # - `:count => Integer`: return count keys at most per iteration
185
185
  #
186
186
  # @return [String, Array<String>] the next cursor and all found members
187
+ #
188
+ # See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
187
189
  def sscan(key, cursor, **options)
188
190
  _scan(:sscan, cursor, [key], **options)
189
191
  end
@@ -199,6 +201,8 @@ class Redis
199
201
  # - `:count => Integer`: return count keys at most per iteration
200
202
  #
201
203
  # @return [Enumerator] an enumerator for all keys in the set
204
+ #
205
+ # See the [Redis Server SSCAN documentation](https://redis.io/docs/latest/commands/sscan/) for further details
202
206
  def sscan_each(key, **options, &block)
203
207
  return to_enum(:sscan_each, key, **options) unless block_given?
204
208
 
@@ -454,21 +454,55 @@ class Redis
454
454
 
455
455
  # Determine the index of a member in a sorted set.
456
456
  #
457
+ # @example Retrieve member rank
458
+ # redis.zrank("zset", "a")
459
+ # # => 3
460
+ # @example Retrieve member rank with their score
461
+ # redis.zrank("zset", "a", :with_score => true)
462
+ # # => [3, 32.0]
463
+ #
457
464
  # @param [String] key
458
465
  # @param [String] member
459
- # @return [Integer]
460
- def zrank(key, member)
461
- send_command([:zrank, key, member])
466
+ #
467
+ # @return [Integer, [Integer, Float]]
468
+ # - when `:with_score` is not specified, an Integer
469
+ # - when `:with_score` is specified, a `[rank, score]` pair
470
+ def zrank(key, member, withscore: false, with_score: withscore)
471
+ args = [:zrank, key, member]
472
+
473
+ if with_score
474
+ args << "WITHSCORE"
475
+ block = FloatifyPair
476
+ end
477
+
478
+ send_command(args, &block)
462
479
  end
463
480
 
464
481
  # Determine the index of a member in a sorted set, with scores ordered from
465
482
  # high to low.
466
483
  #
484
+ # @example Retrieve member rank
485
+ # redis.zrevrank("zset", "a")
486
+ # # => 3
487
+ # @example Retrieve member rank with their score
488
+ # redis.zrevrank("zset", "a", :with_score => true)
489
+ # # => [3, 32.0]
490
+ #
467
491
  # @param [String] key
468
492
  # @param [String] member
469
- # @return [Integer]
470
- def zrevrank(key, member)
471
- send_command([:zrevrank, key, member])
493
+ #
494
+ # @return [Integer, [Integer, Float]]
495
+ # - when `:with_score` is not specified, an Integer
496
+ # - when `:with_score` is specified, a `[rank, score]` pair
497
+ def zrevrank(key, member, withscore: false, with_score: withscore)
498
+ args = [:zrevrank, key, member]
499
+
500
+ if with_score
501
+ args << "WITHSCORE"
502
+ block = FloatifyPair
503
+ end
504
+
505
+ send_command(args, &block)
472
506
  end
473
507
 
474
508
  # Remove all members in a sorted set within the given indexes.
@@ -817,6 +851,8 @@ class Redis
817
851
  #
818
852
  # @return [String, Array<[String, Float]>] the next cursor and all found
819
853
  # members and scores
854
+ #
855
+ # See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
820
856
  def zscan(key, cursor, **options)
821
857
  _scan(:zscan, cursor, [key], **options) do |reply|
822
858
  [reply[0], FloatifyPairs.call(reply[1])]
@@ -834,6 +870,8 @@ class Redis
834
870
  # - `:count => Integer`: return count keys at most per iteration
835
871
  #
836
872
  # @return [Enumerator] an enumerator for all found scores and members
873
+ #
874
+ # See the [Redis Server ZSCAN documentation](https://redis.io/docs/latest/commands/zscan/) for further details
837
875
  def zscan_each(key, **options, &block)
838
876
  return to_enum(:zscan_each, key, **options) unless block_given?
839
877
 
@@ -41,18 +41,25 @@ class Redis
41
41
  # @param opts [Hash] several options for `XADD` command
42
42
  #
43
43
  # @option opts [String] :id the entry id, default value is `*`, it means auto generation
44
- # @option opts [Integer] :maxlen max length of entries
45
- # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen or not
44
+ # @option opts [Integer] :maxlen max length of entries to keep
45
+ # @option opts [Integer] :minid min id of entries to keep
46
+ # @option opts [Boolean] :approximate whether to add `~` modifier of maxlen/minid or not
46
47
  # @option opts [Boolean] :nomkstream whether to add NOMKSTREAM, default is not to add
47
48
  #
48
49
  # @return [String] the entry id
49
- def xadd(key, entry, approximate: nil, maxlen: nil, nomkstream: nil, id: '*')
50
+ def xadd(key, entry, approximate: nil, maxlen: nil, minid: nil, nomkstream: nil, id: '*')
50
51
  args = [:xadd, key]
51
52
  args << 'NOMKSTREAM' if nomkstream
52
53
  if maxlen
54
+ raise ArgumentError, "can't supply both maxlen and minid" if minid
55
+
53
56
  args << "MAXLEN"
54
57
  args << "~" if approximate
55
58
  args << maxlen
59
+ elsif minid
60
+ args << "MINID"
61
+ args << "~" if approximate
62
+ args << minid
56
63
  end
57
64
  args << id
58
65
  args.concat(entry.flatten)
@@ -83,12 +83,14 @@ class Redis
83
83
  end
84
84
  }
85
85
 
86
+ FloatifyPair = lambda { |(first, score)|
87
+ [first, Floatify.call(score)]
88
+ }
89
+
86
90
  FloatifyPairs = lambda { |value|
87
91
  return value unless value.respond_to?(:each_slice)
88
92
 
89
- value.each_slice(2).map do |member, score|
90
- [member, Floatify.call(score)]
91
- end
93
+ value.each_slice(2).map(&FloatifyPair)
92
94
  }
93
95
 
94
96
  HashifyInfo = lambda { |reply|
@@ -199,8 +201,8 @@ class Redis
199
201
  # hash, are up to consumers.
200
202
  #
201
203
  # Redis error replies are raised as Ruby exceptions.
202
- def call(*command)
203
- send_command(command)
204
+ def call(*command, &block)
205
+ send_command(command, &block)
204
206
  end
205
207
 
206
208
  # Interact with the sentinel command (masters, master, slaves, failover)
@@ -752,14 +752,14 @@ class Redis
752
752
  end
753
753
 
754
754
  # Determine the index of a member in a sorted set.
755
- def zrank(key, member)
756
- node_for(key).zrank(key, member)
755
+ def zrank(key, member, **options)
756
+ node_for(key).zrank(key, member, **options)
757
757
  end
758
758
 
759
759
  # Determine the index of a member in a sorted set, with scores ordered from
760
760
  # high to low.
761
- def zrevrank(key, member)
762
- node_for(key).zrevrank(key, member)
761
+ def zrevrank(key, member, **options)
762
+ node_for(key).zrevrank(key, member, **options)
763
763
  end
764
764
 
765
765
  # Remove all members in a sorted set within the given indexes.
@@ -948,12 +948,16 @@ class Redis
948
948
  end
949
949
 
950
950
  # Listen for messages published to channels matching the given patterns.
951
+ # See the [Redis Server PSUBSCRIBE documentation](https://redis.io/docs/latest/commands/psubscribe/)
952
+ # for further details
951
953
  def psubscribe(*channels, &block)
952
954
  raise NotImplementedError
953
955
  end
954
956
 
955
957
  # Stop listening for messages posted to channels matching the given
956
958
  # patterns.
959
+ # See the [Redis Server PUNSUBSCRIBE documentation](https://redis.io/docs/latest/commands/punsubscribe/)
960
+ # for further details
957
961
  def punsubscribe(*channels)
958
962
  raise NotImplementedError
959
963
  end
data/lib/redis/errors.rb CHANGED
@@ -29,6 +29,11 @@ class Redis
29
29
  class OutOfMemoryError < CommandError
30
30
  end
31
31
 
32
+ if defined?(RedisClient::NoScriptError)
33
+ class NoScriptError < CommandError
34
+ end
35
+ end
36
+
32
37
  # Base error for connection related errors.
33
38
  class BaseConnectionError < BaseError
34
39
  end
@@ -6,9 +6,10 @@ class Redis
6
6
  class PipelinedConnection
7
7
  attr_accessor :db
8
8
 
9
- def initialize(pipeline, futures = [])
9
+ def initialize(pipeline, futures = [], exception: true)
10
10
  @pipeline = pipeline
11
11
  @futures = futures
12
+ @exception = exception
12
13
  end
13
14
 
14
15
  include Commands
@@ -37,7 +38,7 @@ class Redis
37
38
  end
38
39
 
39
40
  def send_command(command, &block)
40
- future = Future.new(command, block)
41
+ future = Future.new(command, block, @exception)
41
42
  @pipeline.call_v(command) do |result|
42
43
  future._set(result)
43
44
  end
@@ -46,7 +47,7 @@ class Redis
46
47
  end
47
48
 
48
49
  def send_blocking_command(command, timeout, &block)
49
- future = Future.new(command, block)
50
+ future = Future.new(command, block, @exception)
50
51
  @pipeline.blocking_call_v(timeout, command) do |result|
51
52
  future._set(result)
52
53
  end
@@ -57,7 +58,7 @@ class Redis
57
58
 
58
59
  class MultiConnection < PipelinedConnection
59
60
  def multi
60
- raise Redis::Error, "Can't nest multi transaction"
61
+ raise Redis::BaseError, "Can't nest multi transaction"
61
62
  end
62
63
 
63
64
  private
@@ -79,10 +80,11 @@ class Redis
79
80
  class Future < BasicObject
80
81
  FutureNotReady = ::Redis::FutureNotReady.new
81
82
 
82
- def initialize(command, coerce)
83
+ def initialize(command, coerce, exception)
83
84
  @command = command
84
85
  @object = FutureNotReady
85
86
  @coerce = coerce
87
+ @exception = exception
86
88
  end
87
89
 
88
90
  def inspect
@@ -95,7 +97,7 @@ class Redis
95
97
  end
96
98
 
97
99
  def value
98
- ::Kernel.raise(@object) if @object.is_a?(::StandardError)
100
+ ::Kernel.raise(@object) if @exception && @object.is_a?(::StandardError)
99
101
  @object
100
102
  end
101
103
 
@@ -116,12 +118,14 @@ class Redis
116
118
  end
117
119
 
118
120
  def _set(replies)
119
- if replies
120
- @futures.each_with_index do |future, index|
121
+ @object = if replies
122
+ @futures.map.with_index do |future, index|
121
123
  future._set(replies[index])
124
+ future.value
122
125
  end
126
+ else
127
+ replies
123
128
  end
124
- @object = replies
125
129
  end
126
130
  end
127
131
  end
data/lib/redis/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Redis
4
- VERSION = '5.1.0'
4
+ VERSION = '5.4.1'
5
5
  end
data/lib/redis.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "redis-client"
4
+
3
5
  require "monitor"
4
6
  require "redis/errors"
5
7
  require "redis/commands"
@@ -99,10 +101,10 @@ class Redis
99
101
  @client
100
102
  end
101
103
 
102
- def pipelined
104
+ def pipelined(exception: true)
103
105
  synchronize do |client|
104
- client.pipelined do |raw_pipeline|
105
- yield PipelinedConnection.new(raw_pipeline)
106
+ client.pipelined(exception: exception) do |raw_pipeline|
107
+ yield PipelinedConnection.new(raw_pipeline, exception: exception)
106
108
  end
107
109
  end
108
110
  end
@@ -175,6 +177,7 @@ class Redis
175
177
  @subscription_client.send(method, *channels, &block)
176
178
  end
177
179
  ensure
180
+ @subscription_client&.close
178
181
  @subscription_client = nil
179
182
  end
180
183
  else
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -13,10 +13,9 @@ authors:
13
13
  - Michel Martens
14
14
  - Damian Janowski
15
15
  - Pieter Noordhuis
16
- autorequire:
17
16
  bindir: bin
18
17
  cert_chain: []
19
- date: 2024-02-09 00:00:00.000000000 Z
18
+ date: 2025-07-17 00:00:00.000000000 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: redis-client
@@ -24,14 +23,14 @@ dependencies:
24
23
  requirements:
25
24
  - - ">="
26
25
  - !ruby/object:Gem::Version
27
- version: 0.17.0
26
+ version: 0.22.0
28
27
  type: :runtime
29
28
  prerelease: false
30
29
  version_requirements: !ruby/object:Gem::Requirement
31
30
  requirements:
32
31
  - - ">="
33
32
  - !ruby/object:Gem::Version
34
- version: 0.17.0
33
+ version: 0.22.0
35
34
  description: |2
36
35
  A Ruby client that tries to match Redis' API one-to-one, while still
37
36
  providing an idiomatic interface.
@@ -75,10 +74,9 @@ licenses:
75
74
  metadata:
76
75
  bug_tracker_uri: https://github.com/redis/redis-rb/issues
77
76
  changelog_uri: https://github.com/redis/redis-rb/blob/master/CHANGELOG.md
78
- documentation_uri: https://www.rubydoc.info/gems/redis/5.1.0
77
+ documentation_uri: https://www.rubydoc.info/gems/redis/5.4.1
79
78
  homepage_uri: https://github.com/redis/redis-rb
80
- source_code_uri: https://github.com/redis/redis-rb/tree/v5.1.0
81
- post_install_message:
79
+ source_code_uri: https://github.com/redis/redis-rb/tree/v5.4.1
82
80
  rdoc_options: []
83
81
  require_paths:
84
82
  - lib
@@ -86,15 +84,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
84
  requirements:
87
85
  - - ">="
88
86
  - !ruby/object:Gem::Version
89
- version: 2.5.0
87
+ version: 2.6.0
90
88
  required_rubygems_version: !ruby/object:Gem::Requirement
91
89
  requirements:
92
90
  - - ">="
93
91
  - !ruby/object:Gem::Version
94
92
  version: '0'
95
93
  requirements: []
96
- rubygems_version: 3.3.7
97
- signing_key:
94
+ rubygems_version: 3.6.2
98
95
  specification_version: 4
99
96
  summary: A Ruby client library for Redis
100
97
  test_files: []