File: README.md

package info (click to toggle)
ruby-feature 1.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 184 kB
  • sloc: ruby: 760; sh: 20; makefile: 9
file content (203 lines) | stat: -rw-r--r-- 5,940 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
[![Gem Version](https://badge.fury.io/rb/feature.svg)](https://rubygems.org/gems/feature)
[![Travis-CI Build Status](https://travis-ci.org/mgsnova/feature.svg)](https://travis-ci.org/mgsnova/feature)
[![Coverage Status](http://img.shields.io/coveralls/mgsnova/feature/master.svg)](https://coveralls.io/r/mgsnova/feature)
[![Code Climate](https://codeclimate.com/github/mgsnova/feature.svg)](https://codeclimate.com/github/mgsnova/feature)
[![Inline docs](http://inch-ci.org/github/mgsnova/feature.svg)](http://inch-ci.org/github/mgsnova/feature)
[![Dependency Status](https://gemnasium.com/mgsnova/feature.svg)](https://gemnasium.com/mgsnova/feature)

# Feature

Feature is a battle-tested [feature toggle](http://martinfowler.com/bliki/FeatureToggle.html) library for ruby.

The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active features (symbols!). Unknown features are assumed inactive.

With this approach Feature is highly configurable and not bound to a specific kind of configuration.

**NOTE:** The current gem version works with Ruby 2+ and supports Ruby on Rails 4+.

**NOTE:** Ruby 1.9 is supported until version 1.2.0, Ruby 1.8 is supported until version 0.7.0.

**NOTE:** ActiveRecord / Rails 3 is supported until version 1.1.0.

## Installation

        gem install feature

## How to use

* Setup Feature
    * Create a repository (for more infos about configuration backends, see section below)
        ```ruby
        require 'feature'
        repo = Feature::Repository::SimpleRepository.new
        ```

    * Set repository to Feature
        ```ruby
        Feature.set_repository(repo)
        ```

* Use Feature in your production code
    ```ruby
    Feature.active?(:feature_name) # => true/false

    Feature.inactive?(:feature_name) # => true/false

    Feature.active_features # => [:list, :of, :features]

    Feature.with(:feature_name) do
      # code
    end

    Feature.without(:feature_name) do
      # code
    end

    # this returns value_true if :feature_name is active, otherwise value_false
    Feature.switch(:feature_name, value_true, value_false) 

    # switch may also take Procs that will be evaluated and it's result returned.
    Feature.switch(:feature_name, -> { code... }, -> { code... })
    ```

* Use Feature in your test code (for reliable testing of feature depending code)
    ```ruby
    require 'feature/testing'

    Feature.run_with_activated(:feature) do
      # your test code
    end

    # you also can give a list of features
    Feature.run_with_deactivated(:feature, :another_feature) do
      # your test code
    end
    ```

* Feature-toggle caching

    * By default, Feature will lazy-load the active features from the
      underlying repository the first time you try to check whether a
      feature is set or not. 

    * Subsequent calls to Feature will access the cached in-memory
      representation of the list of features. So changes to toggles in the 
      underlying repository would not be reflected in the application
      until you restart the application or manually call
        ```ruby
        Feature.refresh!
        ```

    * You can optionally pass in true as a second argument on
      set_repository, to force Feature to auto-refresh the feature list
      on every feature-toggle check you make.
        ```ruby
        Feature.set_repository(your_repository, true)
        ```

    * You can also optionally pass in a number as second argument on
      set_repository, to force Feature to refresh the feature list
      after X seconds. This will be done only on demand by a request.
        ```ruby
        Feature.set_repository(your_repository, 60)
        ```

## How to setup different backends

### SimpleRepository (in-memory)
```ruby
# File: Gemfile
gem 'feature'
```

```ruby
# setup code
require 'feature'

repo = Feature::Repository::SimpleRepository.new
repo.add_active_feature :be_nice

Feature.set_repository repo
```

### RedisRepository (features configured in redis server)
```ruby
# See here to learn how to configure redis: https://github.com/redis/redis-rb

# File: Gemfile
gem 'feature'
gem 'redis'
```

```ruby
# setup code (or Rails initializer: config/initializers/feature.rb)
require 'feature'

# "feature_toggles" will be the key name in redis
repo = Feature::Repository::RedisRepository.new("feature_toggles")
Feature.set_repository repo

# add/toggle features in Redis
Redis.current.hset("feature_toggles", "ActiveFeature", true)
Redis.current.hset("feature_toggles", "InActiveFeature", false)
```

### YamlRepository (features configured in static yml file)
```ruby
# File: Gemfile
gem 'feature'
```

```
# File: config/feature.yml
features:
    an_active_feature: true
    an_inactive_feature: false
```

```ruby
# setup code (or Rails initializer: config/initializers/feature.rb)
repo = Feature::Repository::YamlRepository.new("#{Rails.root}/config/feature.yml")
Feature.set_repository repo
```

You may also specify a Rails environment to use a new feature in development and test, but not production:
```
# File: config/feature.yml
test:
    features:
        a_new_feature: true
production:
    features:
        a_new_feature: false
```

```ruby
# File: config/initializers/feature.rb
repo = Feature::Repository::YamlRepository.new("#{Rails.root}/config/feature.yml", Rails.env)
Feature.set_repository repo
```

### ActiveRecordRepository (features configured in a database) using Rails

```ruby
# File: Gemfile
gem 'feature'
```

```
# Run generator and migrations
$ rails g feature:install
$ rake db:migrate
```

```ruby
# Add Features to table FeaturesToggle for example in
# File: db/schema.rb
FeatureToggle.create!(name: "ActiveFeature", active: true)
FeatureToggle.create!(name: "InActiveFeature", active: false)

# or in initializer
# File: config/initializers/feature.rb
repo.add_active_feature(:active_feature)
```