sensu-redis 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1dd63d72bb8617b4a11636fc4f49f601fdc58f97
4
+ data.tar.gz: 1ecffe0185d61f8b98cdbb485c1d56d5d1da9e52
5
+ SHA512:
6
+ metadata.gz: b29df8a599bb52c350a4fd0aacdde00b1472ad58ef77782d02ba06878ab0b43dbec9ef2c0c514fcf9ec9b63a2c760f92f6de155a0bf9b8dfbdfe00d31bd5afeb
7
+ data.tar.gz: d6d503398789220f4433ffacd6cf18d20b5a5930bfd3bf0acee9743e5d6c31f169b8235198f2b92b5fd8c2805b45029cbca4c83aba9a319b2e70d91d7d2ae3ee
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sensu-redis.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # Sensu::Redis
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sensu/redis`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'sensu-redis'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install sensu-redis
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/sensu-redis.
36
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sensu/redis"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,43 @@
1
+ require "rubygems"
2
+ require "sensu/redis/parser"
3
+ require "sensu/redis/processor"
4
+ require "sensu/redis/commands"
5
+ require "sensu/redis/connection"
6
+ require "eventmachine"
7
+ require "uri"
8
+
9
+ module Sensu
10
+ module Redis
11
+ class Client < EM::Connection
12
+ include EM::Deferrable
13
+ include Parser
14
+ include Processor
15
+ include Commands
16
+ include Connection
17
+
18
+ class << self
19
+ def parse_url(url)
20
+ begin
21
+ uri = URI.parse(url)
22
+ {
23
+ :host => uri.host,
24
+ :port => uri.port,
25
+ :password => uri.password
26
+ }
27
+ rescue
28
+ raise ArgumentError, "invalid redis url"
29
+ end
30
+ end
31
+
32
+ def connect(options={})
33
+ if options.is_a?(String)
34
+ options = parse_url(options)
35
+ end
36
+ options[:host] ||= "127.0.0.1"
37
+ options[:port] = (options[:port] || 6379).to_i
38
+ EM.connect(options[:host], options[:port], self, options)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,93 @@
1
+ require "sensu/redis/constants"
2
+ require "sensu/redis/errors"
3
+
4
+ module Sensu
5
+ module Redis
6
+ # Sensu Module for requesting Redis commands, intended to be
7
+ # included by Sensu::Redis::Client.
8
+ #
9
+ # You can read about RESP @ http://redis.io/topics/protocol
10
+ module Commands
11
+ # Determine the byte size of a string.
12
+ #
13
+ # @param string [String]
14
+ # @return [Integer] string byte size.
15
+ def get_size(string)
16
+ string.respond_to?(:bytesize) ? string.bytesize : string.size
17
+ end
18
+
19
+ # Send a Redis command using RESP multi bulk. This method is
20
+ # called by the Redis command methods, which are created by
21
+ # `create_command_methods()`, it simply implements RESP and
22
+ # sends commands to Redis via EM connection `send_data()`.
23
+ def send_command(*arguments)
24
+ command = "*#{arguments.size}#{DELIM}"
25
+ arguments.each do |value|
26
+ value = value.to_s
27
+ command << "$#{get_size(value)}#{DELIM}#{value}#{DELIM}"
28
+ end
29
+ if @deferred_status
30
+ send_data(command)
31
+ else
32
+ callback { send_data(command) }
33
+ end
34
+ end
35
+
36
+ # Create Redis command methods. Command methods just wrap
37
+ # `send_command()` and enqueue a response callback. This method
38
+ # MUST be called in the connection object's `initialize()`.
39
+ def create_command_methods!
40
+ @response_callbacks ||= []
41
+ REDIS_COMMANDS.each do |command|
42
+ self.class.send(:define_method, command.to_sym) do |*arguments, &block|
43
+ send_command(command, *arguments)
44
+ @response_callbacks << [RESPONSE_PROCESSORS[command], block]
45
+ end
46
+ end
47
+ end
48
+
49
+ # Authenticate to Redis and select the correct DB, when
50
+ # applicable. The auth and select Redis commands must be the
51
+ # first commands (& callbacks) to run.
52
+ #
53
+ # @param password [String]
54
+ # @param db [Integer]
55
+ def auth_and_select_db(password=nil, db=nil)
56
+ callbacks = @callbacks || []
57
+ @callbacks = []
58
+ send_command(AUTH_COMMAND, password) if password
59
+ send_command(SELECT_COMMAND, db) if db
60
+ callbacks.each { |block| callback(&block) }
61
+ end
62
+
63
+ # Subscribe to a Redis PubSub channel.
64
+ #
65
+ # @param channel [String]
66
+ def subscribe(channel, &block)
67
+ @pubsub_callbacks ||= Hash.new([])
68
+ @pubsub_callbacks[channel] << block
69
+ send_command(SUBSCRIBE_COMMAND, channel, &block)
70
+ end
71
+
72
+ # Unsubscribe to one or more Redis PubSub channels. If a channel
73
+ # is provided, this method will unsubscribe from it. If a
74
+ # channel is not provided, this method will unsubscribe from all
75
+ # Redis PubSub channels.
76
+ #
77
+ # @param channel [String]
78
+ def unsubscribe(channel=nil, &block)
79
+ @pubsub_callbacks ||= Hash.new([])
80
+ arguments = [UNSUBSCRIBE_COMMAND]
81
+ if channel
82
+ @pubsub_callbacks[channel] = [block]
83
+ arguments << channel
84
+ else
85
+ @pubsub_callbacks.each_key do |key|
86
+ @pubsub_callbacks[key] = [block]
87
+ end
88
+ end
89
+ send_command(arguments)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,112 @@
1
+ require "sensu/redis/constants"
2
+ require "sensu/redis/errors"
3
+
4
+ module Sensu
5
+ module Redis
6
+ # Sensu Module connecting to Redis.
7
+ module Connection
8
+ def initialize(options={})
9
+ create_command_methods!
10
+ @host = options[:host]
11
+ @port = options[:port]
12
+ @db = (options[:db] || 0).to_i
13
+ @password = options[:password]
14
+ @auto_reconnect = options.fetch(:auto_reconnect, true)
15
+ @reconnect_on_error = options.fetch(:reconnect_on_error, true)
16
+ @error_callback = lambda do |error|
17
+ raise(error)
18
+ end
19
+ @reconnect_callbacks = {
20
+ :before => lambda{},
21
+ :after => lambda{}
22
+ }
23
+ end
24
+
25
+ # Set the on error callback.
26
+ def on_error(&block)
27
+ @error_callback = block
28
+ end
29
+
30
+ # Set the before reconnect callback.
31
+ def before_reconnect(&block)
32
+ @reconnect_callbacks[:before] = block
33
+ end
34
+
35
+ # Set the after reconnect callback.
36
+ def after_reconnect(&block)
37
+ @reconnect_callbacks[:after] = block
38
+ end
39
+
40
+ # Create an error and pass it to the error callback.
41
+ #
42
+ # @param klass [Class]
43
+ # @param message [String]
44
+ def error(klass, message)
45
+ redis_error = klass.new(message)
46
+ @error_callback.call(redis_error)
47
+ end
48
+
49
+ # Determine if connected to Redis.
50
+ def connected?
51
+ @connected || false
52
+ end
53
+
54
+ # Reconnect to Redis. The before reconnect callback is first
55
+ # call if not already reconnecting. This method uses a 1 second
56
+ # delay before attempting a reconnect.
57
+ def reconnect!
58
+ @reconnect_callbacks[:before].call unless @reconnecting
59
+ @reconnecting = true
60
+ EM.add_timer(1) do
61
+ reconnect(@host, @port)
62
+ end
63
+ end
64
+
65
+ # Close the Redis connection after writing the current
66
+ # command/data.
67
+ def close
68
+ @closing = true
69
+ close_connection_after_writing
70
+ end
71
+
72
+ # Called by EM when the connection closes, either intentionally
73
+ # or unexpectedly.
74
+ def unbind
75
+ @deferred_status = nil
76
+ @response_callbacks = []
77
+ @multibulk_count = false
78
+ if @closing
79
+ @reconnecting = false
80
+ elsif ((@connected || @reconnecting) && @auto_reconnect) || @reconnect_on_error
81
+ reconnect!
82
+ elsif @connected
83
+ error(ConnectionError, "connection closed")
84
+ else
85
+ error(ConnectionError, "unable to connect to redis server")
86
+ end
87
+ @connected = false
88
+ end
89
+
90
+ # Validate the connection, ensuring that the Redis release
91
+ # supports Sensu's required Redis commands. A connection error
92
+ # is thrown if Redis's version does not meet the requirement.
93
+ def validate_connection!
94
+ info do |redis_info|
95
+ if redis_info[:redis_version] < "1.3.14"
96
+ error(ConnectionError, "redis version must be >= 2.0 RC 1")
97
+ end
98
+ end
99
+ end
100
+
101
+ # Called by EM when the connection is established.
102
+ def connection_completed
103
+ @connected = true
104
+ auth_and_select_db(@password, @db)
105
+ validate_connection!
106
+ @reconnect_callbacks[:after].call if @reconnecting
107
+ @reconnecting = false
108
+ succeed
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,96 @@
1
+ module Sensu
2
+ module Redis
3
+ # RESP (REdis Serialization Protocol) response type characters and
4
+ # delimiter (http://redis.io/topics/protocol).
5
+ OK = "OK".freeze
6
+ MINUS = "-".freeze
7
+ PLUS = "+".freeze
8
+ COLON = ":".freeze
9
+ DOLLAR = "$".freeze
10
+ ASTERISK = "*".freeze
11
+ DELIM = "\r\n".freeze
12
+
13
+ # Redis response line parser incomplete data return value.
14
+ INCOMPLETE = "incomp".freeze
15
+
16
+ # Used to return empty array reponses.
17
+ EMPTY_ARRAY = [].freeze
18
+
19
+ # Redis response boolean values.
20
+ TRUE_VALUES = %w[1 OK].freeze
21
+
22
+ # Redis pubsub response type values.
23
+ PUBSUB_RESPONSES = %w[message unsubscribe].freeze
24
+
25
+ # Redis commands that are supported by this library.
26
+ REDIS_COMMANDS = [
27
+ "set",
28
+ "setnx",
29
+ "get",
30
+ "getset",
31
+ "del",
32
+ "info",
33
+ "sadd",
34
+ "smembers",
35
+ "sismembers",
36
+ "srem",
37
+ "scard",
38
+ "hset",
39
+ "hsetnx",
40
+ "hget",
41
+ "hgetall",
42
+ "hdel",
43
+ "hincrby",
44
+ "rpush",
45
+ "lpush",
46
+ "ltrim",
47
+ "lrange",
48
+ "exists",
49
+ "ttl",
50
+ "expire",
51
+ "flushdb",
52
+ "incr"
53
+ ].freeze
54
+
55
+ # Redis DB select command.
56
+ SELECT_COMMAND = "select".freeze
57
+
58
+ # Redis authentication command.
59
+ AUTH_COMMAND = "auth".freeze
60
+
61
+ # Redis PubSub subscribe command.
62
+ SUBSCRIBE_COMMAND = "subscribe".freeze
63
+
64
+ # Redis PubSub unsubscribe command.
65
+ UNSUBSCRIBE_COMMAND = "unsubscribe".freeze
66
+
67
+ # Boolean Redis response value processor.
68
+ BOOLEAN_PROCESSOR = lambda{|r| TRUE_VALUES.include?(r.to_s)}
69
+
70
+ # Redis response value processors.
71
+ RESPONSE_PROCESSORS = {
72
+ "exists" => BOOLEAN_PROCESSOR,
73
+ "sadd" => BOOLEAN_PROCESSOR,
74
+ "srem" => BOOLEAN_PROCESSOR,
75
+ "setnx" => BOOLEAN_PROCESSOR,
76
+ "del" => BOOLEAN_PROCESSOR,
77
+ "expire" => BOOLEAN_PROCESSOR,
78
+ "select" => BOOLEAN_PROCESSOR,
79
+ "hset" => BOOLEAN_PROCESSOR,
80
+ "hdel" => BOOLEAN_PROCESSOR,
81
+ "hsetnx" => BOOLEAN_PROCESSOR,
82
+ "hgetall" => lambda{|r| Hash[*r]},
83
+ "info" => lambda{|r|
84
+ info = {}
85
+ r.each_line do |line|
86
+ line.chomp!
87
+ unless line.empty?
88
+ k, v = line.split(":", 2)
89
+ info[k.to_sym] = v
90
+ end
91
+ end
92
+ info
93
+ }
94
+ }
95
+ end
96
+ end
@@ -0,0 +1,19 @@
1
+ module Sensu
2
+ module Redis
3
+ # Error class for Redis connection errors.
4
+ class ConnectionError < StandardError; end
5
+
6
+ # Error class for Redis protocol (RESP) errors.
7
+ class ProtocolError < StandardError; end
8
+
9
+ # Error class for Redis command errors.
10
+ class CommandError < StandardError
11
+ attr_accessor :code
12
+
13
+ def initialize(*args)
14
+ args[0] = "redis returned error code: #{args[0]}"
15
+ super
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,66 @@
1
+ require "sensu/redis/constants"
2
+ require "sensu/redis/errors"
3
+
4
+ module Sensu
5
+ module Redis
6
+ # Sensu Module for parsing RESP (REdis Serialization Protocol).
7
+ # You can read about RESP @ http://redis.io/topics/protocol
8
+ # This module calls methods provided by other Sensu Redis modules:
9
+ # Sensu::Redis::Processor.dispatch_error()
10
+ # Sensu::Redis::Processor.dispatch_response()
11
+ # Sensu::Redis::Processor.begin_multibulk()
12
+ # Sensu::Redis::Connection.error()
13
+ module Parser
14
+ # Parse a RESP line.
15
+ #
16
+ # @param line [String]
17
+ def parse_line(line)
18
+ # Trim off the response type and delimiter (\r\n).
19
+ response = line.slice(1..-3)
20
+ # First character indicates response type.
21
+ case line[0, 1]
22
+ when MINUS # Error, e.g. -ERR
23
+ dispatch_error(response)
24
+ when PLUS # String, e.g. +OK
25
+ dispatch_response(response)
26
+ when DOLLAR # Bulk string, e.g. $3\r\nfoo\r\n
27
+ response_size = Integer(response)
28
+ if response_size == -1 # No data, return nil.
29
+ dispatch_response(nil)
30
+ elsif @buffer.size >= response_size + 2 # Complete data.
31
+ dispatch_response(@buffer.slice!(0, response_size))
32
+ @buffer.slice!(0,2) # Discard delimeter (\r\n).
33
+ else # Incomplete, have data pushed back into buffer.
34
+ return INCOMPLETE
35
+ end
36
+ when COLON # Integer, e.g. :8
37
+ dispatch_response(Integer(response))
38
+ when ASTERISK # Array, e.g. *2\r\n$3\r\foo\r\n$3\r\nbar\r\n
39
+ multibulk_count = Integer(response)
40
+ if multibulk_count == -1 || multibulk_count == 0 # No data, return [].
41
+ dispatch_response(EMPTY_ARRAY)
42
+ else
43
+ begin_multibulk(multibulk_count) # Accumulate responses.
44
+ end
45
+ else
46
+ error(ProtocolError, "response type not recognized: #{line.strip}")
47
+ end
48
+ end
49
+
50
+ # EM connection receive data, parse incoming data using RESP
51
+ # (`parse_line()`).
52
+ #
53
+ # @param data [String]
54
+ def receive_data(data)
55
+ (@buffer ||= '') << data
56
+ while index = @buffer.index(DELIM)
57
+ line = @buffer.slice!(0, index+2)
58
+ if parse_line(line) == INCOMPLETE
59
+ @buffer[0...0] = line
60
+ break
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,79 @@
1
+ require "sensu/redis/constants"
2
+ require "sensu/redis/errors"
3
+
4
+ module Sensu
5
+ module Redis
6
+ # Sensu Module for processing Redis responses.
7
+ # This module calls methods provided by other Sensu Redis modules:
8
+ # Sensu::Redis::Connection.error()
9
+ module Processor
10
+ # Fetch the next Redis command response callback. Response
11
+ # callbacks may include an optional response processor block,
12
+ # i.e. "1" -> true.
13
+ #
14
+ # @return [Array] processor, callback.
15
+ def fetch_response_callback
16
+ @response_callbacks ||= []
17
+ @response_callbacks.shift
18
+ end
19
+
20
+ # Begin a multi bulk response array for an expected number of
21
+ # responses. Using this method causes `dispatch_response()` to
22
+ # wait until all of the expected responses have been added to
23
+ # the array, before the Redis command reponse callback is
24
+ # called.
25
+ #
26
+ # @param multibulk_count [Integer] number of expected responses.
27
+ def begin_multibulk(multibulk_count)
28
+ @multibulk_count = multibulk_count
29
+ @multibulk_values = []
30
+ end
31
+
32
+ # Dispatch a Redis error, dropping the associated Redis command
33
+ # response callback, and passing a Redis error object to the
34
+ # error callback (if set).
35
+ #
36
+ # @param code [String] Redis error code.
37
+ def dispatch_error(code)
38
+ fetch_response_callback
39
+ error(CommandError, code)
40
+ end
41
+
42
+ # Dispatch a response. If a multi bulk response has begun, this
43
+ # method will build the completed response array before the
44
+ # associated Redis command response callback is called. If one
45
+ # or more pubsub callbacks are defined, the approprate pubsub
46
+ # callbacks are called, provided with the pubsub response. Redis
47
+ # command response callbacks may have an optional processor
48
+ # block, responsible for producing a value with the correct
49
+ # type, e.g. "1" -> true (boolean).
50
+ #
51
+ # @param value [Object]
52
+ def dispatch_response(value)
53
+ if @multibulk_count
54
+ @multibulk_values << value
55
+ @multibulk_count -= 1
56
+ if @multibulk_count == 0
57
+ value = @multibulk_values
58
+ @multibulk_count = false
59
+ else
60
+ return
61
+ end
62
+ end
63
+ if @pubsub_callbacks && value.is_a?(Array)
64
+ if PUBSUB_RESPONSES.include?(value[0])
65
+ @pubsub_callbacks[value[1]].each do |block|
66
+ block.call(*value) if block
67
+ end
68
+ return
69
+ end
70
+ end
71
+ processor, block = fetch_response_callback
72
+ if block
73
+ value = processor.call(value) if processor
74
+ block.call(value)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "sensu-redis"
5
+ spec.version = "0.1.0"
6
+ spec.authors = ["Sean Porter"]
7
+ spec.email = ["portertech@gmail.com"]
8
+ spec.summary = "The Sensu Redis client library"
9
+ spec.description = "The Sensu Redis client library"
10
+ spec.homepage = "https://github.com/sensu/sensu-redis"
11
+ spec.license = "MIT"
12
+
13
+ spec.files = `git ls-files -z`.split("\x0")
14
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.add_dependency "eventmachine"
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "rake", "10.5.0"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "codeclimate-test-reporter" unless RUBY_VERSION < "1.9"
24
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sensu-redis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Porter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eventmachine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 10.5.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 10.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: codeclimate-test-reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: The Sensu Redis client library
84
+ email:
85
+ - portertech@gmail.com
86
+ executables:
87
+ - console
88
+ - setup
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - lib/sensu/redis.rb
100
+ - lib/sensu/redis/commands.rb
101
+ - lib/sensu/redis/connection.rb
102
+ - lib/sensu/redis/constants.rb
103
+ - lib/sensu/redis/errors.rb
104
+ - lib/sensu/redis/parser.rb
105
+ - lib/sensu/redis/processor.rb
106
+ - sensu-redis.gemspec
107
+ homepage: https://github.com/sensu/sensu-redis
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.4.5.1
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: The Sensu Redis client library
131
+ test_files: []