redis_feature_control 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gemspec
2
+ pkg
3
+ nbproject
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010 Ben VandenBos
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ redis_feature_control
2
+ =====================
3
+
4
+ Redis_feature_control is a module to mark features/services as enabled or disabled
5
+ so jobs can take appropriate action.
6
+
7
+
8
+ ### Why?
9
+
10
+ Sometimes you depend on services. Sometimes these services go down. Sometimes
11
+ you want to explicitly turn off services and have your app know the service is
12
+ turned off. That way your app can display a pretty message to a user
13
+ rather than trying a service and waiting for it to time out. Maybe your backend
14
+ job depends on a service. When it notices it's disabled, it can sleep or delay
15
+ that job to sometime in the future without having to test the service.
16
+
17
+
18
+
19
+ ### Usage
20
+
21
+ First configure it:
22
+
23
+ require 'rubygems'
24
+ require 'redis/feature_control'
25
+ Redis::FeatureControl.connection_string = "redis_server:6379"
26
+
27
+ Then add your features/services to it:
28
+
29
+ Redis::FeatureControl.features << :data_warehouse
30
+ Redis::FeatureControl.features << :cc_gateway
31
+ Redis::FeatureControl.features << :hulu
32
+
33
+ Then see if they are enabled and toggle them:
34
+
35
+ # on by default
36
+ Redis::FeatureControl.enabled?(:cc_gateway) # => true
37
+
38
+ # disabling...
39
+ Redis::FeatureControl.disable!(:cc_gateway)
40
+ Redis::FeatureControl.enabled?(:cc_gateway) # => false
41
+ Redis::FeatureControl.status(:cc_gateway) # => "disabled"
42
+
43
+ # enabling...
44
+ Redis::FeatureControl.enable!(:cc_gateway)
45
+ Redis::FeatureControl.enabled?(:cc_gateway) # => true
46
+ Redis::FeatureControl.disabled?(:cc_gateway) # => false
47
+ Redis::FeatureControl.status(:cc_gateway) # => "enabled"
48
+
49
+ ### Mocking for Test/Development
50
+
51
+ Since you don't always have redis available in development and test, sometimes
52
+ it's nice to just keep the state of features in memory. You can enable the mock
53
+ behavior like so:
54
+
55
+ Redis::FeatureControl.mock!
56
+
57
+ It will work exactly the same as when it's using redis, but it will only store
58
+ the states of features in memory.
59
+
60
+ To stop mocking:
61
+
62
+ Redis::FeatureControl.unmock!
63
+
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+
3
+ task :default => :test
4
+
5
+ desc "Run tests"
6
+ task :test do
7
+ Dir['test/*_test.rb'].each do |f|
8
+ require f
9
+ end
10
+ end
11
+
12
+ desc "Build a gem"
13
+ task :gem => [ :test, :gemspec, :build ]
14
+
15
+ begin
16
+ begin
17
+ require 'jeweler'
18
+ rescue LoadError
19
+ puts "Jeweler not available. Install it with: "
20
+ puts "gem install jeweler"
21
+ end
22
+
23
+ require 'redis/feature_control'
24
+
25
+ Jeweler::Tasks.new do |gemspec|
26
+ gemspec.name = "redis_feature_control"
27
+ gemspec.summary = "Feature enable/disable library on top of Redis"
28
+ gemspec.description = gemspec.summary
29
+ gemspec.email = "bvandenbos@gmail.com"
30
+ gemspec.homepage = "http://github.com/bvandenbos/redis_feature_control"
31
+ gemspec.authors = ["Ben VandenBos"]
32
+ gemspec.version = Redis::FeatureControl::Version
33
+
34
+ gemspec.add_dependency "redis", ">= 0.1.1"
35
+ gemspec.add_dependency "redis-namespace", ">= 0.2.0"
36
+ gemspec.add_development_dependency "jeweler"
37
+ gemspec.add_development_dependency "mocha"
38
+ end
39
+ end
40
+
41
+
42
+ desc "Push a new version to Gemcutter"
43
+ task :publish => [ :test, :gemspec, :build ] do
44
+ require 'redis/feature_control'
45
+ system "git tag v#{Redis::FeatureControl::Version}"
46
+ system "git push origin v#{Redis::FeatureControl::Version}"
47
+ system "git push origin master"
48
+ system "gem push pkg/redis_feature_control-#{Redis::FeatureControl::Version}.gem"
49
+ system "git clean -fd"
50
+ end
@@ -0,0 +1,141 @@
1
+ require 'rubygems'
2
+ require 'redis'
3
+ require 'redis/namespace'
4
+
5
+ #
6
+ # Redis::FeatureControl
7
+ #
8
+ # The point of this is to have a very simple way to turn pieces of the site on
9
+ # and off without having to load your entire Rails stack (models, etc).
10
+ #
11
+ # How it stores stuff in Redis:
12
+ # Features default on, so if the value in redis is nil, it's considered
13
+ # enabled. The value is "1" when explicitly turned on and "0" when off.
14
+ #
15
+ class Redis
16
+
17
+ module FeatureControl
18
+
19
+ Version = '0.0.1'
20
+
21
+ class Redis::FeatureControl::UnknownFeatureError < RuntimeError; end;
22
+
23
+ class << self
24
+
25
+ attr_accessor :features
26
+
27
+ def features
28
+ @features ||= []
29
+ end
30
+
31
+ def host
32
+ @host ||= 'localhost'
33
+ end
34
+
35
+ def port
36
+ @port ||= 6379
37
+ end
38
+
39
+ # Redis::FeatureControl
40
+ def connection_string=(value)
41
+ @host, @port = value.split(":", 2)
42
+ redis_connect!
43
+ end
44
+
45
+ # Connects to redis on the current host/port and sets the redis object
46
+ def redis_connect!
47
+ redis = Redis.new(:host => host, :port => port, :thread_safe => true)
48
+ @redis = Redis::Namespace.new(:feature_control, :redis => redis)
49
+ end
50
+
51
+ def redis
52
+ if @redis.nil?
53
+ begin
54
+ redis_connect!
55
+ rescue Errno::ECONNREFUSED
56
+ end
57
+ end
58
+ @redis
59
+ end
60
+
61
+ def disabled?(feature)
62
+ check_feature!(feature)
63
+ !enabled?(feature)
64
+ end
65
+
66
+ def enabled?(feature)
67
+ check_feature!(feature)
68
+ if mock?
69
+ mock_feature_hash[feature.to_s].nil? || true == mock_feature_hash[feature.to_s]
70
+ else
71
+ (redis.get(feature.to_s) || 1).to_i == 1
72
+ end
73
+ rescue Errno::ECONNREFUSED
74
+ true # default to enabled if we can't connect to redis
75
+ end
76
+
77
+ def enable!(feature)
78
+ check_feature!(feature)
79
+ if mock?
80
+ mock_feature_hash[feature.to_s] = true
81
+ else
82
+ redis.set(feature.to_s, 1)
83
+ end
84
+ rescue Errno::ECONNREFUSED
85
+ # Ignore
86
+ end
87
+
88
+ def disable!(feature)
89
+ check_feature!(feature)
90
+ if mock?
91
+ mock_feature_hash[feature.to_s] = false
92
+ else
93
+ redis.set(feature.to_s, 0)
94
+ end
95
+ rescue Errno::ECONNREFUSED
96
+ # Ignore
97
+ end
98
+
99
+ # value >=1 enable the feature
100
+ # value <1 disable the feature
101
+ def set_status(feature, value)
102
+ value = value.to_i
103
+ if value >= 1
104
+ enable!(feature)
105
+ else
106
+ disable!(feature)
107
+ end
108
+ end
109
+
110
+ # Returns a string for the state of the feature
111
+ def state(feature)
112
+ enabled?(feature) ? 'enabled' : 'disabled'
113
+ end
114
+
115
+ def check_feature!(feature)
116
+ raise Redis::FeatureControl::UnknownFeatureError unless features.include?(feature.to_sym)
117
+ end
118
+
119
+ # This redfines enabled/disabled to only use class variables instead of connecting
120
+ # to redis. This allows you to run tests w/out a connection to redis
121
+ def mock!
122
+ @mock = true
123
+ end
124
+
125
+ def unmock!
126
+ @mock = false
127
+ end
128
+
129
+ def mock?
130
+ @mock
131
+ end
132
+
133
+ def mock_feature_hash
134
+ @feature_hash ||= {}
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Redis::FeatureControlTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Redis::FeatureControl.connection_string = 'localhost:9736'
7
+ Redis::FeatureControl.unmock!
8
+ Redis::FeatureControl.features = [:enabled_feature]
9
+ Redis::FeatureControl.redis.flushall
10
+ end
11
+
12
+ def test_connection_string_works
13
+ Redis::FeatureControl.connection_string = "redis:1234"
14
+ assert_equal('redis', Redis::FeatureControl.host)
15
+ assert_equal('1234', Redis::FeatureControl.port)
16
+ end
17
+
18
+ def test_redis
19
+ assert(Redis::FeatureControl.redis.is_a?(Redis::Namespace))
20
+ end
21
+
22
+ def test_unknown_features_raise_errors
23
+ assert_raises(Redis::FeatureControl::UnknownFeatureError) do
24
+ Redis::FeatureControl.enabled?(:some_feature)
25
+ end
26
+ end
27
+
28
+ def test_enable_disable
29
+ Redis::FeatureControl.features << :cool_service # add a feature
30
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should be enabled by default
31
+ assert(!Redis::FeatureControl.disabled?(:cool_service)) # should be enabled by default
32
+
33
+ Redis::FeatureControl.enable!(:cool_service)
34
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
35
+
36
+ Redis::FeatureControl.disable!(:cool_service)
37
+ assert(!Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
38
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
39
+
40
+ Redis::FeatureControl.enable!(:cool_service)
41
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
42
+ end
43
+
44
+ def test_set_status
45
+
46
+ Redis::FeatureControl.features << :cool_service # add a feature
47
+
48
+ Redis::FeatureControl.set_status(:cool_service, 0.9) # <1
49
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
50
+
51
+ Redis::FeatureControl.set_status(:cool_service, 1.0)
52
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
53
+
54
+ Redis::FeatureControl.set_status(:cool_service, -1)
55
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
56
+
57
+ Redis::FeatureControl.set_status(:cool_service, -1.0)
58
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
59
+
60
+ Redis::FeatureControl.set_status(:cool_service, 42)
61
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
62
+
63
+ Redis::FeatureControl.set_status(:cool_service, -42)
64
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
65
+
66
+ end
67
+
68
+ def test_state_string
69
+ Redis::FeatureControl.features << :cool_service # add a feature
70
+
71
+ Redis::FeatureControl.enable!(:cool_service)
72
+ assert_equal('enabled', Redis::FeatureControl.state(:cool_service))
73
+
74
+ Redis::FeatureControl.disable!(:cool_service)
75
+ assert_equal('disabled', Redis::FeatureControl.state(:cool_service))
76
+ end
77
+
78
+ def test_check_feature
79
+ assert_raises(Redis::FeatureControl::UnknownFeatureError) do
80
+ Redis::FeatureControl.enabled?(:some_feature)
81
+ end
82
+
83
+ assert_nothing_raised do
84
+ Redis::FeatureControl.enabled?(:enabled_feature)
85
+ end
86
+ end
87
+
88
+ def test_mock
89
+
90
+ Redis::FeatureControl.mock!
91
+ assert(Redis::FeatureControl.mock?)
92
+
93
+ Redis::FeatureControl.unmock!
94
+ assert(!Redis::FeatureControl.mock?)
95
+ end
96
+
97
+ def test_mock_enable_disable
98
+ Redis::FeatureControl.mock!
99
+
100
+ Redis::FeatureControl.expects(:redis).never # It's mocked, so it shouldn't use redis
101
+
102
+ Redis::FeatureControl.features << :cool_service # add a feature
103
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should be enabled by default
104
+ assert(!Redis::FeatureControl.disabled?(:cool_service)) # should be enabled by default
105
+
106
+ Redis::FeatureControl.enable!(:cool_service)
107
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
108
+
109
+ Redis::FeatureControl.disable!(:cool_service)
110
+ assert(!Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
111
+ assert(Redis::FeatureControl.disabled?(:cool_service)) # should still be enabled
112
+
113
+ Redis::FeatureControl.enable!(:cool_service)
114
+ assert(Redis::FeatureControl.enabled?(:cool_service)) # should still be enabled
115
+ end
116
+
117
+ end
@@ -0,0 +1,132 @@
1
+ # Redis configuration file example
2
+
3
+ # By default Redis does not run as a daemon. Use 'yes' if you need it.
4
+ # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5
+ daemonize yes
6
+
7
+ # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8
+ # You can specify a custom pid file location here.
9
+ pidfile ./test/redis-test.pid
10
+
11
+ # Accept connections on the specified port, default is 6379
12
+ port 9736
13
+
14
+ # If you want you can bind a single interface, if the bind option is not
15
+ # specified all the interfaces will listen for connections.
16
+ #
17
+ # bind 127.0.0.1
18
+
19
+ # Close the connection after a client is idle for N seconds (0 to disable)
20
+ timeout 300
21
+
22
+ # Save the DB on disk:
23
+ #
24
+ # save <seconds> <changes>
25
+ #
26
+ # Will save the DB if both the given number of seconds and the given
27
+ # number of write operations against the DB occurred.
28
+ #
29
+ # In the example below the behaviour will be to save:
30
+ # after 900 sec (15 min) if at least 1 key changed
31
+ # after 300 sec (5 min) if at least 10 keys changed
32
+ # after 60 sec if at least 10000 keys changed
33
+ save 900 1
34
+ save 300 10
35
+ save 60 10000
36
+
37
+ # The filename where to dump the DB
38
+ dbfilename dump.rdb
39
+
40
+ # For default save/load DB in/from the working directory
41
+ # Note that you must specify a directory not a file name.
42
+ dir ./test/
43
+
44
+ # Set server verbosity to 'debug'
45
+ # it can be one of:
46
+ # debug (a lot of information, useful for development/testing)
47
+ # notice (moderately verbose, what you want in production probably)
48
+ # warning (only very important / critical messages are logged)
49
+ loglevel debug
50
+
51
+ # Specify the log file name. Also 'stdout' can be used to force
52
+ # the demon to log on the standard output. Note that if you use standard
53
+ # output for logging but daemonize, logs will be sent to /dev/null
54
+ logfile stdout
55
+
56
+ # Set the number of databases. The default database is DB 0, you can select
57
+ # a different one on a per-connection basis using SELECT <dbid> where
58
+ # dbid is a number between 0 and 'databases'-1
59
+ databases 16
60
+
61
+ ################################# REPLICATION #################################
62
+
63
+ # Master-Slave replication. Use slaveof to make a Redis instance a copy of
64
+ # another Redis server. Note that the configuration is local to the slave
65
+ # so for example it is possible to configure the slave to save the DB with a
66
+ # different interval, or to listen to another port, and so on.
67
+
68
+ # slaveof <masterip> <masterport>
69
+
70
+ ################################## SECURITY ###################################
71
+
72
+ # Require clients to issue AUTH <PASSWORD> before processing any other
73
+ # commands. This might be useful in environments in which you do not trust
74
+ # others with access to the host running redis-server.
75
+ #
76
+ # This should stay commented out for backward compatibility and because most
77
+ # people do not need auth (e.g. they run their own servers).
78
+
79
+ # requirepass foobared
80
+
81
+ ################################### LIMITS ####################################
82
+
83
+ # Set the max number of connected clients at the same time. By default there
84
+ # is no limit, and it's up to the number of file descriptors the Redis process
85
+ # is able to open. The special value '0' means no limts.
86
+ # Once the limit is reached Redis will close all the new connections sending
87
+ # an error 'max number of clients reached'.
88
+
89
+ # maxclients 128
90
+
91
+ # Don't use more memory than the specified amount of bytes.
92
+ # When the memory limit is reached Redis will try to remove keys with an
93
+ # EXPIRE set. It will try to start freeing keys that are going to expire
94
+ # in little time and preserve keys with a longer time to live.
95
+ # Redis will also try to remove objects from free lists if possible.
96
+ #
97
+ # If all this fails, Redis will start to reply with errors to commands
98
+ # that will use more memory, like SET, LPUSH, and so on, and will continue
99
+ # to reply to most read-only commands like GET.
100
+ #
101
+ # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
102
+ # 'state' server or cache, not as a real DB. When Redis is used as a real
103
+ # database the memory usage will grow over the weeks, it will be obvious if
104
+ # it is going to use too much memory in the long run, and you'll have the time
105
+ # to upgrade. With maxmemory after the limit is reached you'll start to get
106
+ # errors for write operations, and this may even lead to DB inconsistency.
107
+
108
+ # maxmemory <bytes>
109
+
110
+ ############################### ADVANCED CONFIG ###############################
111
+
112
+ # Glue small output buffers together in order to send small replies in a
113
+ # single TCP packet. Uses a bit more CPU but most of the times it is a win
114
+ # in terms of number of queries per second. Use 'yes' if unsure.
115
+ glueoutputbuf yes
116
+
117
+ # Use object sharing. Can save a lot of memory if you have many common
118
+ # string in your dataset, but performs lookups against the shared objects
119
+ # pool so it uses more CPU and can be a bit slower. Usually it's a good
120
+ # idea.
121
+ #
122
+ # When object sharing is enabled (shareobjects yes) you can use
123
+ # shareobjectspoolsize to control the size of the pool used in order to try
124
+ # object sharing. A bigger pool size will lead to better sharing capabilities.
125
+ # In general you want this value to be at least the double of the number of
126
+ # very common strings you have in your dataset.
127
+ #
128
+ # WARNING: object sharing is experimental, don't enable this feature
129
+ # in production before of Redis 1.0-stable. Still please try this feature in
130
+ # your development environment so that we can test it better.
131
+ shareobjects no
132
+ shareobjectspoolsize 1024
@@ -0,0 +1,40 @@
1
+ dir = File.dirname(File.expand_path(__FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'mocha'
6
+ require 'redis'
7
+ $LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
8
+ require 'redis/feature_control'
9
+
10
+ #
11
+ # make sure we can run redis
12
+ #
13
+
14
+ if !system("which redis-server")
15
+ puts '', "** can't find `redis-server` in your path"
16
+ puts "** try running `sudo rake install`"
17
+ abort ''
18
+ end
19
+
20
+
21
+ #
22
+ # start our own redis when the tests start,
23
+ # kill it when they end
24
+ #
25
+
26
+ at_exit do
27
+ next if $!
28
+
29
+ exit_code = Test::Unit::AutoRunner.run
30
+
31
+ pid = `ps -e -o pid,command | grep [r]edis-test`.split(" ")[0]
32
+ puts "Killing test redis server..."
33
+ `rm -f #{dir}/dump.rdb`
34
+ Process.kill("KILL", pid.to_i)
35
+ exit exit_code
36
+ end
37
+
38
+ puts "Starting redis for testing at localhost:9736..."
39
+ `redis-server #{dir}/redis-test.conf`
40
+ Redis::FeatureControl.connection_string = 'localhost:9736'
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis_feature_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben VandenBos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-10 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: redis
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: redis-namespace
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: jeweler
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: mocha
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description: Feature enable/disable library on top of Redis
56
+ email: bvandenbos@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - LICENSE
63
+ - README.md
64
+ files:
65
+ - .gitignore
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - lib/redis/feature_control.rb
70
+ - test/feature_control_test.rb
71
+ - test/redis-test.conf
72
+ - test/test_helper.rb
73
+ has_rdoc: true
74
+ homepage: http://github.com/bvandenbos/redis_feature_control
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options:
79
+ - --charset=UTF-8
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ version:
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: "0"
93
+ version:
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.3.5
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Feature enable/disable library on top of Redis
101
+ test_files:
102
+ - test/feature_control_test.rb
103
+ - test/test_helper.rb