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
endBoth 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
endIt'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)
endYou 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 featuresFlagship.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
endYou 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? }
endYou 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) }
endTo 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
endAnd 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
endIt'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
endAfter 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.