Purpose
Featury is designed to group and manage multiple features within a project.
It provides the flexibility to utilize any pre-existing solution or create your own.
It's easily adjustable to align with the unique needs and objectives of your project.
Quick Start
Installation
gem "featury"
Usage
Basic class for your features
For instance, assume that you are utilizing Flipper for managing features.
In such scenario, the base class could potentially be structured as follows:
class ApplicationFeature < Featury::Base
action :enabled? do |features:, **options|
features.all? { |feature| Flipper.enabled?(feature, *options.values) }
end
action :disabled? do |features:, **options|
features.any? { |feature| !Flipper.enabled?(feature, *options.values) }
end
action :enable do |features:, **options|
features.all? { |feature| Flipper.enable(feature, *options.values) }
end
action :disable do |features:, **options|
features.all? { |feature| Flipper.disable(feature, *options.values) }
end
end
Features of your project
class UserFeature::Onboarding < ApplicationFeature
resource :user, type: User
condition ->(resources:) { resources.user.onboarding_awaiting? }
prefix :user_onboarding
features :passage
groups BillingFeature,
PaymentSystemFeature
end
class BillingFeature < ApplicationFeature
prefix :billing
features :api,
:webhooks
end
class PaymentSystemFeature < ApplicationFeature
prefix :payment_system
features :api,
:webhooks
end
The resource
method provides an indication of how the transmitted information ought to be processed.
Besides the options provided by Servactory, additional ones are available for stipulating the processing mode of the transmitted data.
If a resource needs to be conveyed as a feature flag option, utilize the option
parameter:
resource :user, type: User, option: true
To transfer a resource to a nested group, utilize the nested
option:
resource :user, type: User, nested: true
Working with the features of your project
Each of these actions will be applied to every feature flag.
Subsequently, the outcome of these actions will be contingent upon the combined results of all feature flags.
UserFeature::Onboarding.enabled?(user:)
UserFeature::Onboarding.disabled?(user:)
UserFeature::Onboarding.enable(user:)
UserFeature::Onboarding.disable(user:)
You can also utilize the with
method to pass necessary arguments.
feature = UserFeature::Onboarding.with(user:)
feature.enabled?
feature.disabled?
feature.enable
feature.disable
If a feature flag is deactivated, possibly via automation processes,
the primary feature class subsequently responds with false
when
queried about its enablement status.
In the preceding example, there might be a scenario where the payment system is
undergoing technical maintenance and therefore is temporarily shut down.
Consequently, the onboarding process for new users will be halted until further notice.
Contributing
This project is intended to be a safe, welcoming space for collaboration.
Contributors are expected to adhere to the Contributor Covenant code of conduct.
We recommend reading the contributing guide as well.
License
Featury is available as open source under the terms of the MIT License.