valkey-objects 0.2.0 → 0.2.2

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: 66451b3bbdc217925b068c50c8cdcd5cd392a6ddef99adbc7300c683c112d152
4
- data.tar.gz: eb06049f2987c87b8cb7fb188e15960fab83d2f7a820205b3ddd06df1ed11828
3
+ metadata.gz: 32d09321f670991b444f2c90843694b054596be914e071f76598019bf95302d1
4
+ data.tar.gz: b2cff91d109c421204ea924aa51eed2e1bd5a7d50ec7baced09926d6945485d0
5
5
  SHA512:
6
- metadata.gz: 78d4470e2aa1cc2b9763265c7a940f4f2da58798460fbce998e2aedd32cdcd6136accca257d83719328e59011b6da185c59f590863642d430488966b9a77cb9e
7
- data.tar.gz: ad6b0974b14ebd9bc022aa259a4a953556d5ec567d370a0335b279fc695f655713cba4d0499e8cb7d6bc15e610a5ba4918d8a81bdeca4ce8820bd0d65f8f6439
6
+ metadata.gz: b0b9306307f46e9ef2d4e495ddf08f6be8113f43a66568e679fa53a615cff36e8ad468657a126fb5cd302c50c0bb9c0aae0ee649b89cdb8f9f393747827b9eab
7
+ data.tar.gz: 2c5dc3f7a3d98860dc7cfac4b07c1778394669bac0349b8485a237322559262823adc8e6786f161b4b4cb1c996d4933402d99dfdda0b9f4823d237189d618eb3
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Valkey
4
4
  module Objects
5
- VERSION = "0.2.0"
5
+ VERSION = "0.2.2"
6
6
  end
7
7
  end
@@ -5,8 +5,14 @@ require_relative "objects/version"
5
5
  require 'redis-client'
6
6
  require 'json'
7
7
  require 'ruby-duration'
8
+ require 'amatch'
8
9
  require 'ap'
9
10
  module VK
11
+
12
+ @@XX = {}
13
+
14
+
15
+
10
16
  def self.included(x)
11
17
  x.extend VK
12
18
  end
@@ -16,6 +22,8 @@ module VK
16
22
  # Example:
17
23
  # class ExmpleObject
18
24
  # include VK
25
+ #
26
+ ## Add Object Containers by Value Type:
19
27
  # value :myValue
20
28
  # counter :myCounter
21
29
  # hashkey :myHashKey
@@ -23,51 +31,84 @@ module VK
23
31
  # set :mySet
24
32
  # queue :myQueue
25
33
  # place :myPlace
26
- # pipe :myPipe
27
34
  # toggle :myToggle
35
+ # ticker :myTicker
36
+ # entry :myEntry
37
+ #
38
+ ## Add an Object Container With an Implicit Expiration:
39
+ # value :myExpiringValue, ttl: (seconds to live without interaction)
40
+ #
28
41
  # def initialize k
29
42
  # @id = k
30
43
  # end
31
44
  # end
32
- #
33
- # Instantiation: @obj = ExampleObject.new('object id...')
45
+ ##
46
+ # Create the Object:
47
+ # @obj = ExampleObject.new('object id...')
48
+ ##
49
+ # For all object methods:
50
+ # @obj.myObjectContainer.expire(seconds)
51
+ # @obj.myObjectContainer.delete!
52
+ #
34
53
  xx = x.name.gsub("::", "-")
35
54
  ##
55
+ # Object Method Types:
56
+ ##
57
+ # A String Value
58
+ ##
36
59
  # value :myValue
37
- # @obj.myValue => A string
60
+ # @obj.myValue
61
+ # @obj.myValue.exist?
38
62
  # @obj.myValue.value = "my value"
39
63
  # @obj.myValue.value => "my value"
40
- define_method(:value) { |k| define_method(k.to_sym) { V.new(%[#{xx}:value:#{k}:#{@id}]) } };
64
+ define_method(:value) { |k, h={}| define_method(k.to_sym) { VALUE.new(%[#{xx}:value:#{k}:#{@id}], h) } };
65
+ ##
66
+ # A Number Value
41
67
  ##
42
- # counter :myCounter => A number
68
+ # counter :myCounter
43
69
  # @obj.myCounter
70
+ # @obj.myCounter.exist?
44
71
  # @obj.myCounter.value = number
45
- # @obj.myCounter.value => ...
72
+ # @obj.myCounter.value => number
46
73
  # @obj.myCounter.incr number
47
74
  # @obj.myCounter.decr number
48
75
  #
49
- define_method(:counter) { |k| define_method(k.to_sym) { C.new(%[#{xx}:counter:#{k}:#{@id}]); } };
76
+ define_method(:counter) { |k, h={}| define_method(k.to_sym) { COUNTER.new(%[#{xx}:counter:#{k}:#{@id}], h); } };
50
77
  ##
51
- #
52
- define_method(:timestamp) { |k| define_method(k.to_sym) { N.new(%[#{xx}:counter:#{k}:#{@id}]) } }
53
- ##
54
- # hashkey :myHashKey => The ubiquitous Ruby Hash in valkey/redis
78
+ # An Epoch Value
79
+ ##
80
+ # timestamp :myTimestamp
81
+ # @obj.myTimestamp
82
+ # @obj.myTimestamp.exist?
83
+ # @obj.myTimestamp.value!
84
+ # @obj.myTimestamp.value => epoch
85
+ # @obj.myTimestamp.ago => Seconds since epoch
86
+ # @obj.myTimestamp.to_time => Time object
87
+ define_method(:timestamp) { |k, h={}| define_method(k.to_sym) { TIMESTAMP.new(%[#{xx}:timestamp:#{k}:#{@id}], h) } }
88
+ ##
89
+ # A Hash Value
90
+ ##
91
+ # hashkey :myHashKey
55
92
  # @obj.myHashKey
56
93
  # @obj.myHashKey[:key] = value
57
- # @obj.myHashKey[:key] => ...
94
+ # @obj.myHashKey[:key] => "value"
58
95
  #
59
- define_method(:hashkey) { |k| define_method(k.to_sym) { H.new(%[#{xx}:hash:#{k}:#{@id}]); } };
60
- ##
61
- # sortedset :mySortedSet => A ranked collection of members
96
+ define_method(:hashkey) { |k, h={}| define_method(k.to_sym) { HASH.new(%[#{xx}:hashkey:#{k}:#{@id}], h); } };
97
+ ##
98
+ # A Sorted Set Value
99
+ ##
100
+ # sortedset :mySortedSet
62
101
  # @obj.mySortedSet
63
102
  # @obj.mySortedSet[:key] = value
64
103
  # @obj.mySortedSet[:key] => ...
65
104
  # @obj.mySortedSet.value { |key, i| ... }
66
105
  # @obj.mySortedSet.poke key, number
67
106
  #
68
- define_method(:sortedset) { |k| define_method(k.to_sym) { S.new(%[#{xx}:sortedset:#{k}:#{@id}]); } };
69
- ##
70
- # set :mySet => A collect of unique members
107
+ define_method(:sortedset) { |k, h={}| define_method(k.to_sym) { SORTEDSET.new(%[#{xx}:sortedset:#{k}:#{@id}], h); } };
108
+ ##
109
+ # A Collection of Values
110
+ ##
111
+ # set :mySet
71
112
  # @obj.mySet
72
113
  # @obj.mySet << "x"
73
114
  # @obj.myset.rm "x"
@@ -76,17 +117,21 @@ module VK
76
117
  # @obj.myset["pattern"]
77
118
  # @obj.mySet.value { |key, i| ... }
78
119
  #
79
- define_method(:set) { |k| define_method(k.to_sym) { G.new(%[#{xx}:set:#{k}:#{@id}]); } };
80
- ##
81
- # queue :myQueue => An array with push and pop utility
120
+ define_method(:set) { |k, h={}| define_method(k.to_sym) { SET.new(%[#{xx}:set:#{k}:#{@id}], h); } };
121
+ ##
122
+ # A List of Values
123
+ ##
124
+ # queue :myQueue
82
125
  # @obj.myQueue
83
126
  # @obj.myQueue << "x"
84
127
  # @obj.myQueue.front => "x" and pop
85
128
  # @obj.myQueue.value { |key, i| ... }
86
129
  #
87
- define_method(:queue) { |k| define_method(k.to_sym) { Q.new(%[#{xx}:queue:#{k}:#{@id}]); } };
88
- ##
89
- # place :myPlace => GPS Coordinates
130
+ define_method(:queue) { |k, h={}| define_method(k.to_sym) { QUEUE.new(%[#{xx}:queue:#{k}:#{@id}], h); } };
131
+ ##
132
+ # A Collection of Places
133
+ ##
134
+ # place :myPlace
90
135
  # @obj.myPlace
91
136
  # @obj.myPlace.add "key", longitude, latitude
92
137
  # @obj.myPlace["key"] => { longitude: xx, latitude: yy }
@@ -94,24 +139,45 @@ module VK
94
139
  # @obj.myPlace.radius longitude, latitude, distance
95
140
  # @obj.myPlace.value { |key, i| ... }
96
141
  #
97
- define_method(:place) { |k| define_method(k.to_sym) { P.new(%[#{xx}:place:#{k}:#{@id}]); } };
98
- ##
99
- # pipe :myPipe => Subscibe and handle, and publish.
100
- # @obj.myPipe
101
- # @obj.myPipe.on { |msg| ... }
102
- # @obj.myPipe << "input" => publish { input: "input" }
103
- # @obj.myPipe << ["input","input"] => publish { inputs: ["input", "input"] }
104
- # @obj.myPipe << {} => publish {}
105
- #
106
- define_method(:pipe) { |k| define_method(k.to_sym) { B.new(%[#{xx}:pipe:#{k}:#{@id}]); } };
107
- ##
108
- # toggle :myToggle => Boolean toggle.
142
+ define_method(:place) { |k, h={}| define_method(k.to_sym) { PLACE.new(%[#{xx}:place:#{k}:#{@id}], h); } };
143
+ ##
144
+ # A Boolean Value
145
+ ##
146
+ # toggle :myToggle
109
147
  # @obj.myToggle
110
- # @obj.value = bool
111
- # @obj.value => ...
112
- # @obj.value! => value = !value
148
+ # @obj.myToggle.exist?
149
+ # @obj.myToggle.value = bool
150
+ # @obj.myToggle.value => ...
151
+ # @obj.myToggle.value! => value = !value
113
152
  #
114
- define_method(:toggle) { |k| define_method(k.to_sym) { T.new(%[#{xx}:toggle:#{k}:#{@id}]); } };
153
+ define_method(:toggle) { |k, h={}| define_method(k.to_sym) { TOGGLE.new(%[#{xx}:toggle:#{k}:#{@id}], h); } };
154
+ ##
155
+ # A Sorted Hash of Values
156
+ ##
157
+ # ticker :myTicker
158
+ # @obj.myTicker
159
+ # @obj.myTicker[:key] = value
160
+ # @obj.myTicker[:key] => "value"
161
+ # @obj.myticker.value { |i,e| ... }
162
+ define_method(:ticker) { |k, h={}| define_method(k.to_sym) { SORTEDHASH.new(%[#{xx}:ticker:#{k}:#{@id}], h); } };
163
+ ##
164
+ # A List of Hashes
165
+ ##
166
+ # entry :myEntry
167
+ # @obj.myEntry
168
+ # @obj.myEntry << { key: 'value', ... }
169
+ # @obj.myEntry.value { |i,e| ... }
170
+ define_method(:entry) { |k, h={}| define_method(k.to_sym) { HASHLIST.new(%[#{xx}:entry:#{k}:#{@id}], h); } };
171
+ ##
172
+ # A list of Strings
173
+ ##
174
+ # vector :myVector
175
+ # @obj.myVector
176
+ # @obj.myVector << "An Entry of Text."
177
+ # @obj.myVector.value { |i,e| ... }
178
+ # @obj.myvector[0] = "An Entry of Text."
179
+ define_method(:vector) { |k, h={}| define_method(k.to_sym) { VECTOR.new(%[#{xx}:vector:#{k}:#{@id}], h); } };
180
+
115
181
  end
116
182
 
117
183
  def id
@@ -161,11 +227,15 @@ module VK
161
227
  def self.redis
162
228
  RedisClient.config(host: "127.0.0.1", port: 6379, db: 0).new_client
163
229
  end
164
-
230
+
165
231
  class O
166
232
  attr_reader :key
167
- def initialize k
233
+ def initialize k, h={}
168
234
  @key = k
235
+ @opts = h
236
+ if @opts.has_key?(:ttl)
237
+ expire @opts[:ttl]
238
+ end
169
239
  end
170
240
  def delete!
171
241
  VK.redis.call("DEL", key);
@@ -175,13 +245,19 @@ module VK
175
245
  end
176
246
  end
177
247
 
178
- class N < O
248
+ class TIMESTAMP < O
179
249
  def value
180
250
  VK.redis.call("GET", key).to_i;
251
+ if @opts.has_key?(:flush) == true
252
+ delete!
253
+ end
181
254
  end
182
255
  def value!
183
256
  VK.redis.call("SET", key, "#{VK.clock.to_i}");
184
257
  end
258
+ def exist?
259
+ VK.redis.call("GET", key) ? true : false
260
+ end
185
261
  def ago
186
262
  VK.clock.to_i - value;
187
263
  end
@@ -190,10 +266,16 @@ module VK
190
266
  end
191
267
  end
192
268
 
193
- class T < O
269
+ class TOGGLE < O
194
270
  def value
195
- VK.redis.call("GET", key) == 'true' ? true : false
271
+ VK.redis.call("GET", key) == 'true' ? true : false
272
+ if @opts.has_key?(:flush) == true
273
+ delete!
274
+ end
196
275
  end
276
+ def exist?
277
+ VK.redis.call("GET", key) ? true : false
278
+ end
197
279
  def value= x
198
280
  VK.redis.call("SET", key, "#{x.to_s}")
199
281
  end
@@ -206,42 +288,19 @@ module VK
206
288
  end
207
289
  end
208
290
 
209
- class B < O
210
- def on &b
211
- pubsub = VK.redis.pubsub
212
- pubsub.call("SUBSCRIBE", key)
213
- Process.detach( fork do
214
- loop do
215
- if m = pubsub.next_event(0)
216
- cn, ty, na, id = key.split(":")
217
- if m[0] == "message"
218
- b.call({ stub: na, object: cn.gsub("-", "::"), type: ty, id: id, event: m[0], data: JSON.parse(m[2]) })
219
- else
220
- ap({ stub: na, object: cn.gsub("-", "::"), type: ty, id: id, event: m[0], data: m[2] })
221
- end
222
- end
223
- end
224
- end
225
- );
226
- end
227
- def << x
228
- if x.class == String
229
- VK.redis.call("PUBLISH", key, JSON.generate({ input: x }))
230
- elsif x.class == Array
231
- VK.redis.call("PUBLISH", key, JSON.generate({ inputs: x }))
232
- elsif x.class == Hash
233
- VK.redis.call("PUBLISH", key, JSON.generate(x))
234
- end
235
- end
236
- end
237
-
238
- class V < O
291
+ class VALUE < O
239
292
  def value
240
293
  VK.redis.call("GET", key)
294
+ if @opts.has_key?(:flush) == true
295
+ delete!
296
+ end
241
297
  end
242
298
  def value= x
243
299
  VK.redis.call("SET", key, x)
244
300
  end
301
+ def exist?
302
+ VK.redis.call("GET", key) ? true : false
303
+ end
245
304
  def match r, &b
246
305
  m = Regexp.new(r).match(value)
247
306
  if block_given?
@@ -251,8 +310,54 @@ module VK
251
310
  end
252
311
  end
253
312
  end
313
+
314
+ class VECTOR < O
315
+ include Amatch
316
+ def value &b
317
+ a = []
318
+ VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i|
319
+ if block_given?
320
+ a << b.call(i, VK.redis.call("GET", e))
321
+ else
322
+ a << VK.redis.call("GET", e)
323
+ end
324
+ if @opts.has_key?(:flush) == true
325
+ VK.redis.call("DEL", e);
326
+ end
327
+ }
328
+ if @opts.has_key?(:flush) == true
329
+ delete!
330
+ end
331
+ return a
332
+ end
333
+ def [] k
334
+ VK.redis.call("GET", "#{@key}-#{k}");
335
+ end
336
+ def << i
337
+ kk = %[#{@key}-#{VK.redis.call("LLEN",@key)}]
338
+ VK.redis.call("SET", kk, i);
339
+ VK.redis.call("RPUSH", key, kk)
340
+ end
341
+ def nearest p
342
+ h = {}
343
+ value { |i,v|
344
+ h[i] = {
345
+ value: v,
346
+ levenshtein: p.levenshtein_similar(v),
347
+ damerau: p.damerau_levenshtein_similar(v),
348
+ hamming: p.hamming_similar(v),
349
+ distance: p.pair_distance_similar(v),
350
+ subsequence: p.longest_subsequence_similar(v),
351
+ substring: p.longest_substring_similar(v),
352
+ jaro: p.jaro_similar(v),
353
+ winkler: p.jarowinkler_similar(v)
354
+ }
355
+ }
356
+ return h
357
+ end
358
+ end
254
359
 
255
- class C < O
360
+ class COUNTER < O
256
361
  def incr n
257
362
  VK.redis.call("SET", key, value + n.to_f)
258
363
  end
@@ -261,27 +366,36 @@ module VK
261
366
  end
262
367
  def value
263
368
  VK.redis.call("GET", key).to_f
369
+ if @opts.has_key?(:flush) == true
370
+ delete!
371
+ end
264
372
  end
265
373
  def value= n
266
374
  VK.redis.call("SET", key, n.to_f)
267
375
  end
376
+ def exist?
377
+ VK.redis.call("GET", key) ? true : false
378
+ end
268
379
  end
269
380
 
270
- class H < O
381
+ class HASH < O
271
382
  def [] k
272
383
  VK.redis.call("HGET", key, k);
273
384
  end
274
385
  def []= k,v
275
- VK.redis.call("HMSET", key, k, v);
386
+ VK.redis.call("HSET", key, k, v);
276
387
  end
277
388
  def to_h
278
389
  VK.redis.call("HGETALL", key);
279
390
  end
280
391
  end
281
392
 
282
- class Q < O
393
+ class QUEUE < O
283
394
  def value &b
284
395
  VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i| b.call(i, e) }
396
+ if @opts.has_key?(:flush) == true
397
+ delete!
398
+ end
285
399
  end
286
400
  def length
287
401
  VK.redis.call("LLEN", key)
@@ -294,9 +408,12 @@ module VK
294
408
  end
295
409
  end
296
410
 
297
- class S < O
411
+ class SORTEDSET < O
298
412
  def value &b
299
413
  VK.redis.call("ZREVRANGE", key, 0, -1, 'WITHSCORES').each_with_index { |e, i| b.call(i, e) }
414
+ if @opts.has_key?(:flush) == true
415
+ delete!
416
+ end
300
417
  end
301
418
  def [] k
302
419
  VK.redis.call("ZSCORE", key, k).to_f;
@@ -309,9 +426,20 @@ module VK
309
426
  end
310
427
  end
311
428
 
312
- class G < O
429
+ class SET < O
313
430
  def value &b
314
- VK.redis.call("SMEMBERS", key).each_with_index { |e, i| b.call(i, e) }
431
+ a = Set.new
432
+ VK.redis.call("SMEMBERS", key).each_with_index { |e, i|
433
+ if block_given?
434
+ a << b.call(i, e)
435
+ else
436
+ a << e
437
+ end
438
+ }
439
+ if @opts.has_key?(:flush) == true
440
+ delete!
441
+ end
442
+ return aa
315
443
  end
316
444
  def include? k
317
445
  if VK.redis.call("SMISMEMBER", key, k)[0] == 0
@@ -342,9 +470,20 @@ module VK
342
470
  end
343
471
  end
344
472
 
345
- class P < O
473
+ class PLACE < O
346
474
  def value &b
347
- VK.redis.call("ZRANGE", key, 0, -1).each_with_index { |e, i| b.call(i, e) };
475
+ a = []
476
+ VK.redis.call("ZRANGE", key, 0, -1).each_with_index { |e, i|
477
+ if block_given?
478
+ a << b.call(i, e)
479
+ else
480
+ a << e
481
+ end
482
+ };
483
+ if @opts.has_key?(:flush) == true
484
+ delete!
485
+ end
486
+ return a
348
487
  end
349
488
  def add i, lon, lat
350
489
  VK.redis.call("GEOADD", key, lon, lat, i)
@@ -363,6 +502,68 @@ module VK
363
502
  end
364
503
  end
365
504
 
505
+ class SORTEDHASH < O
506
+ def value &b
507
+ VK.redis.call("ZREVRANGE", key, 0, -1, 'WITHSCORES').each_with_index { |e, i|
508
+ kx = %[#{@key}-#{e[0]}]
509
+ a = []
510
+ if block_given?
511
+ b.call(i, { key: e[0], value: VK.redis.call("GET", kx), score: e[1] } )
512
+ else
513
+ a << { key: e[0], value: VK.redis.call("GET", kx), score: e[1] }
514
+ end
515
+ if @opts.has_key?(:flush) == true
516
+ VK.redis.call("DEL", kx)
517
+ end
518
+ }
519
+ if @opts.has_key?(:flush) == true
520
+ delete!
521
+ end
522
+ return a
523
+ end
524
+ def [] k
525
+ kx = %[#{@key}-#{k}]
526
+ VK.redis.call("GET", kx)
527
+ end
528
+ def []= k, v
529
+ kx = %[#{@key}-#{k}]
530
+ VK.redis.call("SET", kx, v)
531
+ VK.redis.call("ZINCRBY", key, 1, k)
532
+ end
533
+ end
534
+
535
+ class HASHLIST < O
536
+ def value &b
537
+ a = []
538
+ VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i|
539
+ if block_given?
540
+ a << b.call(i, JSON.parse(VK.redis.call("GET", e)))
541
+ else
542
+ a << JSON.parse(VK.redis.call("GET", e))
543
+ end
544
+ if @opts.has_key?(:flush) == true
545
+ VK.redis.call("DEL", e)
546
+ end
547
+ }
548
+ if @opts.has_key?(:flush) == true
549
+ delete!
550
+ end
551
+ return a
552
+ end
553
+ def length
554
+ VK.redis.call("LLEN", key)
555
+ end
556
+ def [] k
557
+ hx = %[#{key}-#{k}]
558
+ JSON.parse(VK.redis.call("GET", hx));
559
+ end
560
+ def push h={}
561
+ hx = %[#{key}-#{length}]
562
+ VK.redis.call("SET", hx, JSON.generate(h));
563
+ VK.redis.call("RPUSH", key, hx)
564
+ end
565
+ end
566
+
366
567
  def self.flushdb!
367
568
  VK.redis.call("FLUSHDB")
368
569
  end
@@ -35,6 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_dependency "json"
36
36
  spec.add_dependency "ruby-duration"
37
37
  spec.add_dependency "pry"
38
+ spec.add_dependency "amatch"
38
39
  spec.add_dependency "awesome_print"
39
40
  # For more information and examples about making a new gem, check out our
40
41
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: valkey-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Olson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-12 00:00:00.000000000 Z
11
+ date: 2025-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: amatch
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: awesome_print
71
85
  requirement: !ruby/object:Gem::Requirement