travis-api/lib/travis/features.rb
2016-08-14 20:35:11 -04:00

147 lines
3.7 KiB
Ruby

require 'redis'
require 'rollout'
require 'active_support/deprecation'
require 'active_support/core_ext/module'
module Travis
# Travis::Features contains methods to handle feature flags.
module Features
class << self
methods = (Rollout.public_instance_methods(false) - [:active?, "active?"]) << {:to => :rollout}
delegate(*methods)
end
def redis
Travis.redis
end
def rollout
@rollout ||= ::Rollout.new(redis)
end
# Returns whether a given feature is enabled either globally or for a given
# repository.
#
# By default, this will return false.
def active?(feature, repository)
feature_active?(feature) or
(rollout.active?(feature, repository.owner) or
repository_active?(feature, repository))
end
def activate_repository(feature, repository)
redis.sadd(repository_key(feature), repository_id(repository))
end
def deactivate_repository(feature, repository)
redis.srem(repository_key(feature), repository_id(repository))
end
# Return whether a given feature is enabled for a repository.
#
# By default, this will return false.
def repository_active?(feature, repository)
redis.sismember(repository_key(feature), repository_id(repository))
end
# Return whether a given feature is enabled for a user.
#
# By default, this will return false.
def user_active?(feature, user)
rollout.active?(feature, user)
end
def activate_all(feature)
redis.del(disabled_key(feature))
end
# Return whether a feature is enabled globally.
#
# By default, this will return false.
def feature_active?(feature)
enabled_for_all?(feature) and !feature_inactive?(feature)
end
# Return whether a feature has been disabled.
#
# This is similar to feature_deactivated?, but with the opposite default.
#
# By default this will return true (ie. disabled).
def feature_inactive?(feature)
redis.get(disabled_key(feature)) != "1"
end
# Return whether a feature has been disabled.
#
# This is similar to feature_inactive?, but with the opposite default.
#
# By default this will return false (ie not disabled).
def feature_deactivated?(feature)
redis.get(disabled_key(feature)) == '0'
end
def deactivate_all(feature)
redis.set(disabled_key(feature), 0)
end
# Return whether a feature has been enabled globally.
#
# By default this will return false.
def enabled_for_all?(feature)
redis.get(enabled_for_all_key(feature)) == '1'
end
def enable_for_all(feature)
redis.set(enabled_for_all_key(feature), 1)
end
def disable_for_all(feature)
redis.set(enabled_for_all_key(feature), 0)
end
def activate_owner(feature, owner)
redis.sadd(owner_key(feature, owner), owner.id)
end
def deactivate_owner(feature, owner)
redis.srem(owner_key(feature, owner), owner.id)
end
# Return whether a feature has been enabled for a user.
#
# By default, this return false.
def owner_active?(feature, owner)
redis.sismember(owner_key(feature, owner), owner.id)
end
extend self
private
def key(name)
"feature:#{name}"
end
def owner_key(feature, owner)
suffix = owner.class.table_name if owner
"#{key(feature)}:#{suffix}"
end
def repository_key(feature)
"#{key(feature)}:repositories"
end
def disabled_key(feature)
"#{key(feature)}:disabled"
end
def enabled_for_all_key(feature)
"#{key(feature)}:disabled"
end
def repository_id(repository)
repository.respond_to?(:id) ? repository.id : repository.to_i
end
end
end