Ship/unship features using flags defined with declarative DSL.
Add this line to your application's Gemfile:
gem 'flagship'
And then execute:
$ bundle
Or install it yourself as:
$ gem install flagship
Flagship.define :app do
enable :stable_feature
enable :experimental_feature, if: ->(context) { context.current_user.staff? }
disable :deprecate_feature
end
Flagship.select_flagset(:app)
if Flagship.enabled?(:some_feature)
# Implement the feature here
end
if Flagship.disabled?(:some_feature)
# Run when :some_feature is not enabled
end
Both of below can be called as context.foo
from :if
block.
# Set a value
Flagship.set_context :foo, 'FOO'
# Set a lambda
Flagship.set_context :foo, ->(context) { 'FOO' }
Or you can set a method too.
Flagship.set_context :current_user, method(:current_user)
Using Flagship.with_context
method, you can override context variables temporarily.
class User
def enabled_features
Flagship.with_context current_user: self do
Flagship.features.enabled.map(&:key)
end
end
end
It's useful when you implement a method using Flagship
into some domain objects.
By using this, values specified in the argument is overridden and other values are inherited.
Flagship.define :common do
enable :stable_feature
end
Flagship.define :development, extend: :common do
enable :experimental_feature
end
Flagship.define :production, extend: :common do
disable :experimental_feature
end
if Rails.env.production?
Flagship.select_flagset(:production)
else
Flagship.select_flagset(:development)
end
You can override flags with ENV named FLAGSHIP_***
.
Assuming that there is a flag :foo
, you can override it with ENV FLAGSHIP_FOO=1
.
Flagship.features
# => Array of Flagship::Feature
Flagship.features.map(&:key)
# => Array key of all features
Flagship.features.enabled.map(&:key)
# => Array key of all enabled features
Flagship.define :blog do
enable :post
enable :comment, communication: true
enable :trackback, communication: true, tracking: true
end
Flagship.select_flagset(:blog)
Flagship.features.enabled.tagged(communication: true).map(&:key)
# => [:comment, :trackback]
Flagship.features.enabled.tagged(communication: true, tracking: true).map(&:key)
# => [:trackback]
Using with_tags
, you can set same tags to multiple features at once.
Flagship.define :blog do
enable :post
with_tags(communication: true) do
enable :comment
enable :trackback
end
end
You can call #enabled?
method inside of DSL.
Flagship.define :blog do
enable :comment, if: ->(context) { context.current_user.activated? }
enable :comment_deletion, if: ->(context) { enabled?(:comment) && context.current_user.moderator? }
end
You can define helpers as normal methods with def
. Methods can be used within blocks, procs, or as symbolic names for if statements to tidy up your code.
Flagship.define :blog do
def is_author(comment, user)
comment.author == user
end
def can_view_comment(context)
context.current_user.moderator?
end
enable :comment, if: :can_view_comment
enable :comment_deletion, if: ->(context) { is_author(context.comment, context.current_user) }
end
To share helpers, you can simply include them as modules.
module FlagHelpers
def is_author(context)
context.comment.author == context.current_user
end
end
Flagship.define :development do
include FlagHelpers
enable :delete, if: :is_author
end
Flagship.define :production do
include FlagHelpers
enable :delete, if: :is_author
end
And you can also extend helper methods from base flagset.
Flagship.define :base do
def is_author(context)
context.comment.author == context.current_user
end
end
Flagship.define :production do
enable :delete, if: :is_author
end
It's recommended to clear state of Flagship
before the suite and after the each tests.
You can do it by configuring like below:
RSpec.configure do |config|
config.before(:suite) do
Flagship.clear_context
Flagship.clear_current_flagset
end
config.after(:each) do
Flagship.clear_context
Flagship.clear_current_flagset
end
end
After checking out the repo, run bin/setup
to install dependencies. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/yuya-takeyama/flagship.
The gem is available as open source under the terms of the MIT License.