Sen-Zhang/simple_switch

View on GitHub
lib/tasks/simple_switch.rake

Summary

Maintainability
Test Coverage
namespace :simple_switch do

  # eg: bundle exec rake simple_switch:add_feature name='Foo' description='Foo feature'
  desc 'Add a feature'
  task :add_feature => :environment do
    check_strategy

    name            = ENV['name']
    description     = ENV['description']
    feature_manager = SimpleSwitch.feature_manager

    abort 'Feature name is required.' if name.blank?
    abort "Feature #{name} already exists." if feature_manager.has_feature?(name)

    feature_manager.add_feature(name: name, description: description)
    abort "Feature #{name} added."
  end

  # eg: bundle exec rake simple_switch:add_environment name='test'
  desc 'Add an environment'
  task :add_environment => :environment do
    check_strategy

    name            = ENV['name']
    feature_manager = SimpleSwitch.feature_manager

    abort 'Environment name is required.' if name.blank?
    abort "Environment #{name} already exists." if feature_manager.has_environment?(name)

    feature_manager.add_environment(name: name)
    abort "Environment #{name} added."
  end

  # eg: bundle exec rake simple_switch:add_feature_config feature='foo' environment='test' status=true
  desc 'Add feature configuration'
  task :add_feature_config => :environment do
    check_strategy

    feature     = ENV['feature']
    environment = ENV['environment']
    status      = ENV['status']

    feature_manager = SimpleSwitch.feature_manager

    abort 'Feature name is required.' if feature.blank?
    abort "Feature #{feature} does not exist, add this feature first." unless feature_manager.has_feature?(feature)
    abort 'Environment name is required.' if environment.blank?
    abort "Environment #{environment} does not exist, add this environment first." unless feature_manager.has_environment?(environment)

    feature_manager.add_state(feature: feature, environment: environment, status: status)

    abort 'Feature configuration added.'
  end

  # eg: bundle exec rake simple_switch:turn_on feature='foo' environment='test'
  desc 'Turn on feature for an environment'
  task :turn_on => :environment do
    toggle_feature_task(:on)
  end

  # eg: bundle exec rake simple_switch:turn_off feature='foo' environment='test'
  desc 'Turn off feature for an environment'
  task :turn_off => :environment do
    toggle_feature_task(:off)
  end

  private
  def check_strategy
    # TODO: Temporarily disable rake tasks for yml strategy
    abort "'yml' strategy does not support this task, please modify feature"\
          ' configuration yaml file instead.' if SimpleSwitch.feature_store != :database
  end

  def toggle_feature_task(status)
    check_strategy

    environment, feature, feature_manager = validate_args
    toggle_feature(feature, environment, feature_manager, status)
  end

  def validate_args
    feature     = ENV['feature']
    environment = ENV['environment']

    feature_manager = SimpleSwitch.feature_manager

    abort 'Feature name is required.' if feature.blank?
    abort "Feature #{feature} does not exist." unless feature_manager.has_feature?(feature)
    abort 'Environment name is required.' if environment.blank?
    abort "Environment #{environment} does not exist, add this environment first." unless feature_manager.has_environment?(environment)
    return environment, feature, feature_manager
  end

  def toggle_feature(feature, environment, feature_manager, status)
    success_msg   = "Feature '#{feature}' has been turned #{status} for environment '#{environment}'."
    error_msg     = "Feature '#{feature}' is not configured on environment '#{environment}'."
    toggle_method = status == :on ? :turn_on : :turn_off

    begin
      feature_manager.send(toggle_method, feature, environment)
      abort success_msg
    rescue
      abort error_msg
    end
  end
end