GithubHelp home page GithubHelp logo

ruby_flipper's Introduction

Ruby Flipper

Travis-CI

Ruby Flipper makes it easy to define features and switch them on and off. It's configuration DSL provides a very flexible but still not too verbose syntax to fulfil your flipping needs.

Usage

To use ruby flipper, you have to load a feature definition file somewhere:

RubyFlipper.load(File.expand_path '../features.rb', __FILE__)

This configuration can be reset by calling:

RubyFlipper.reset

Feature Definitions

The file loaded by ruby flipper is written in ruby flipper's simple DSL. The most basic feature definition is just a feature with a name. Without any further conditions, the feature is active by default.

feature :always_on_feature

You can specify conditions that are used to determine whether a feature is active or not in three different ways:

feature :conditional_feature_with_parameter, false
feature :conditional_feature_with_condition_opt, :condition #> false
feature :conditional_feature_with_conditions_opt, :conditions #> false

In the examples above, the features are statically disabled. You can use three different types of conditions.

Static Conditions

A static condition is a boolean that is evaluated when the feature definitions are loaded. This can be used to statically activate/deactivate features or make features dependent on variables that don't change during runtime.

feature :development_feature, Rails.env.development?
```ruby

This defines a feature that is only active in Rails' development mode.

### Reference Conditions

A reference condition is a symbol that references another feature. This can be used to make a feature dependent on another feature or extract complex condition definitions and reuse them for several features.

```ruby
feature :dependent_feature, :development_feature

This defines a feature that is only active when the feature :development_feature is active.

Dynamic Conditions

A dynamic condition is a proc (or anything that responds to :call) that will be evaluated each time the state of a feature is checked. This can be used to activate/deactivate features dynamically depending on variables that change during runtime.

feature :admin_feature, condition #> lambda { User.current.is_admin? }

This defines a feature that is only active when the current user is an admin (the user specific stuff must be implemented somewhere else).

Dynamic conditions can also be given to the feature method as a block:

feature :admin_feature do
  User.current.is_admin?
end

Within such a proc, you can also check whether another feature is active or not to phrase complex condition dependencies:

feature :shy_feature do
  active?(:development_feature) && (active?(:admin_feature) || Time.now.hour < 8)
end

This defines a feature that is only active when the feature :development_feature is active and either the feature :admin_feature is active or it is between midnight and 8:00 in the morning (however that might be useful).

Combined Conditions

A combined condition is an array of other conditions. Any type of condition can be combined in an array. All conditions have to be met for a feature to be active.

feature :combined_feature, [:development_feature, lambda { User.current.name == 'patti' }]

This defines a feature that is only enabled when the feature :development_feature is enbled and the current user is 'patti'.

More

For more examples, see spec/fixtures/features.rb and spec/ruby_flipper_spec.rb (section 'integration specs using spec/fixtures/features.rb' which is an end-to-end integration test).

Condition Definitions

If you have a lot of dependent features with shared conditions you can clean up your definition file by explicitly defining conditions that aren't used as features but just as conditions real features depend on.

condition :development, Rails.env.development?
condition :admin do
  User.current.is_admin?
end
feature :user_administration, :development, :admin
feature :new_feature, :development

Of course, you can nest this as deep as you like (features depending on conditions depending on conditions depending on features depending on conditions...), although this might lead to completely incomprehensible rulesets.

The condition method is just an alias to the feature method, so internally, it makes absolutely no difference which method you use. Using both methods just helps you structuring your feature definitions and makes the feature definition file easier to understand.

Usage

Finally, there are two ways to check whether a feature is active or not within your code. You can just give it a block that will only be evaluated when the feature is active:

feature_active?(:hidden_feature) do
  # do something for that feature
end

or if you need the state of a feature as a boolean value or want to do something when a feature is not active:

if feature_active?(:hidden_feature)
  # do something for that feature
else
  # do something else
end

Its also possible to pass arbitary arguments to feature_active? like so:

if feature_active?(:hidden_feature, "secret_sauce")
  ...
end

Those parameters will be passed to the block defining the condition.

This method is defined on Object, so it is available anywhere you might ever need it.

Describing Features

Last and least, you can describe your features, for example when you use ticket numbers or anything other cryptic for your feature names. The description isn't used anywhere yet, but it might make your code more readable.

feature :feature_452, :development, :description #> 'Feature 452: An end user can change his data on his profile page.'

You could also just use comments for that, but giving this to ruby flipper in code enables you to evaluate your features and print lists containing the description.

RubyFlipper::Feature.all.each do |feature|
  puts "#{feature.name}: #{feature.description}"
end

Contributors:

  • Thanks to Ryan Ahearn for implementing dynamic parameters to feature_active?

License

ruby_flipper is released under the MIT License.

ruby_flipper's People

Contributors

thomasjachmann avatar thenoseman avatar mrcasals avatar

Stargazers

Josh Lee avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.