abstract_feature_branch 1.3.3 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +8 -10
- data/VERSION +1 -1
- data/abstract_feature_branch.gemspec +10 -8
- data/lib/abstract_feature_branch.rb +34 -1
- data/lib/ext/feature_branch.rb +9 -5
- data/lib/generators/templates/config/initializers/abstract_feature_branch.rb +3 -1
- metadata +28 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0241ac7ec58e588b7ad5705d3e2261d38d34b1cb8b7e354f1e356d36fbea4772
|
4
|
+
data.tar.gz: 25bb7d870cf117cae57df4d9510ba92dd01d6892f9088b33e5d6eb48d52a4eae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25e037089e15a21f1620f112c2ce9a5479c10633e2bccdd5760d680c3f490c6a5bdd8a9a981ae8e3f2119623ddc232d8ca67d8efac5260d7e0197bf50458c72d
|
7
|
+
data.tar.gz: 287cda44bd97f86a0dd031747af5be1af7b5c748cc9794aa3d776607dd3db28d25703c67fb6afba10f7b0b725dcbd7694e9f6d3a5995b433628a9b52d204c6a0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 1.4.0
|
4
|
+
|
5
|
+
- Avoid live loading of per-user features when `AbstractFeatureBranch.feature_store_live_fetching` is `false` to ensure better performance through caching.
|
6
|
+
|
3
7
|
## 1.3.3
|
4
8
|
|
5
9
|
- Redis network failure error handling for per-user feature enablement to default to `nil` value instead of crashing
|
data/README.md
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# Abstract Feature Branch 1.
|
1
|
+
# Abstract Feature Branch 1.4.0
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/abstract_feature_branch.png)](http://badge.fury.io/rb/abstract_feature_branch)
|
3
3
|
[![Build Status](https://api.travis-ci.org/AndyObtiva/abstract_feature_branch.png?branch=master)](https://travis-ci.org/AndyObtiva/abstract_feature_branch)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/AndyObtiva/abstract_feature_branch/badge.png?branch=master)](https://coveralls.io/r/AndyObtiva/abstract_feature_branch?branch=master)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/AndyObtiva/abstract_feature_branch.png)](https://codeclimate.com/github/AndyObtiva/abstract_feature_branch)
|
6
6
|
|
7
|
-
[`abstract_feature_branch`](https://rubygems.org/gems/abstract_feature_branch) is a Ruby gem that provides a variation on the [Branch by Abstraction Pattern](http://paulhammant.com/blog/branch_by_abstraction.html) by [Paul Hammant](https://paulhammant.com/) and the [Feature Toggles Pattern](https://martinfowler.com/bliki/FeatureToggle.html) by [Martin Fowler](https://martinfowler.com/).
|
8
|
-
|
9
|
-
It is a productivity and fault tolerance enhancing team practice.
|
7
|
+
[`abstract_feature_branch`](https://rubygems.org/gems/abstract_feature_branch) is a Ruby gem that provides a unique variation on the [Branch by Abstraction Pattern](http://paulhammant.com/blog/branch_by_abstraction.html) by [Paul Hammant](https://paulhammant.com/) and the [Feature Toggles Pattern](https://martinfowler.com/bliki/FeatureToggle.html) by [Martin Fowler](https://martinfowler.com/) to enhance team productivity and improve software fault tolerance.
|
10
8
|
|
11
9
|
It provides the ability to wrap blocks of code with an abstract feature branch name, and then
|
12
10
|
[specify in a configuration file](#instructions) which features to be switched on or off.
|
13
11
|
|
14
|
-
The goal is to build out upcoming features in the same source code repository branch (i.e.
|
12
|
+
The goal is to build out upcoming features in the same source code repository branch (i.e. [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) and [Trunk-Based Development](https://trunkbaseddevelopment.com)), regardless of whether all are
|
15
13
|
completed by the next release date or not, thus increasing team productivity by preventing integration delays.
|
16
14
|
Developers then disable in-progress features until they are ready to be switched on in production, yet enable them
|
17
15
|
locally and in staging environments for in-progress testing.
|
@@ -23,7 +21,7 @@ for a high risk feature.
|
|
23
21
|
[Bounded Contexts](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf) by allowing developers to configure
|
24
22
|
context-specific feature files if needed.
|
25
23
|
|
26
|
-
[`abstract_feature_branch`](https://rubygems.org/gems/abstract_feature_branch) is one of the simplest and most minimalistic "Feature Flags" Ruby gems out there as it enables you to get started very quickly by simply leveraging YAML files without having to set up a data store if you do not need it (albeit, you also have the option to use Redis as a very fast in-memory data store).
|
24
|
+
[`abstract_feature_branch`](https://rubygems.org/gems/abstract_feature_branch) is one of the simplest and most minimalistic "Feature Flags" Ruby gems out there as it enables you to get started very quickly by simply leveraging YAML files without having to set up a data store if you do not need it (albeit, you also have the option to use [Redis](https://redis.com) as a very fast in-memory data store).
|
27
25
|
|
28
26
|
|
29
27
|
|
@@ -40,8 +38,8 @@ Setup
|
|
40
38
|
### Rails Application Use
|
41
39
|
|
42
40
|
1. Configure Rubygem
|
43
|
-
- With `rails` between `~> 7.0` and `~> 2.0`: Add the following to Gemfile <pre>gem 'abstract_feature_branch', '~> 1.
|
44
|
-
- With `rails` `~> 2.0` only: Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '1.
|
41
|
+
- With `rails` between `~> 7.0` and `~> 2.0`: Add the following to Gemfile <pre>gem 'abstract_feature_branch', '~> 1.4.0'</pre>
|
42
|
+
- With `rails` `~> 2.0` only: Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '1.4.0'</pre>
|
45
43
|
2. Generate <code>config/initializers/abstract_feature_branch.rb</code>, <code>lib/tasks/abstract_feature_branch.rake</code>, <code>config/features.yml</code> and <code>config/features.local.yml</code> in your Rails app directory by running <pre>rails g abstract_feature_branch:install</pre>
|
46
44
|
3. [Optional] Generate <code>config/features/[context_path].yml</code> in your Rails app directory by running <pre>rails g abstract_feature_branch:context context_path</pre> (more details under [**instructions**](#instructions))
|
47
45
|
4. [Optional] Customize configuration in <code>config/initializers/abstract_feature_branch.rb</code> (can be useful for changing location of feature files in Rails application, configuring Redis with a Redis or ConnectionPool instance to use for overrides, and [per-user feature enablement](#per-user-feature-enablement), or troubleshooting a specific Rails environment feature configuration)
|
@@ -50,7 +48,7 @@ Setup
|
|
50
48
|
|
51
49
|
### Ruby Application General Use
|
52
50
|
|
53
|
-
1. <pre>gem install abstract_feature_branch -v 1.
|
51
|
+
1. <pre>gem install abstract_feature_branch -v 1.4.0</pre>
|
54
52
|
2. Add code <code>require 'abstract_feature_branch'</code>
|
55
53
|
3. Create <code>config/features.yml</code> under <code>AbstractFeatureBranch.application_root</code> and fill it with content similar to that of the sample <code>config/features.yml</code> mentioned under [**instructions**](#instructions).
|
56
54
|
4. [Optional] Create <code>config/features.local.yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under [**instructions**](#instructions))
|
@@ -61,7 +59,7 @@ Setup
|
|
61
59
|
9. [Optional] Add code <code>AbstractFeatureBranch.cacheable = {[environment] => [true/false]}</code> to indicate cacheability of loaded feature files for enhanced performance (it defaults to true for every environment other than development).
|
62
60
|
10. [Optional] Add code <code>AbstractFeatureBranch.load_application_features</code> to pre-load application features for improved first-use performance
|
63
61
|
11. [Optional] Add code <code>AbstractFeatureBranch.feature_store = Redis.new(options)</code> to configure Redis for overrides and/or [per-user feature enablement](#per-user-feature-enablement)
|
64
|
-
12. [Optional] Set <code>AbstractFeatureBranch.feature_store_live_fetching = true</code> to enable live fetching of features from store (e.g. Redis) to avoid need for app/server restart upon feature changes, with the trade-off of slightly more latency due to making calls to feature store over the network
|
62
|
+
12. [Optional] Set <code>AbstractFeatureBranch.feature_store_live_fetching = true</code> to enable live fetching of features from store (e.g. Redis) to avoid need for app/server restart upon feature changes, with the trade-off of slightly more latency due to making calls to feature store over the network (this affects per-user feature enablement too, pre-caching all user IDs for features on app/server restart when disabled)
|
65
63
|
|
66
64
|
Instructions
|
67
65
|
------------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: abstract_feature_branch 1.
|
5
|
+
# stub: abstract_feature_branch 1.4.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "abstract_feature_branch".freeze
|
9
|
-
s.version = "1.
|
9
|
+
s.version = "1.4.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "2023-
|
15
|
-
s.description = "abstract_feature_branch is a Ruby gem that provides a variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler
|
14
|
+
s.date = "2023-02-05"
|
15
|
+
s.description = "abstract_feature_branch is a Ruby gem that provides a unique variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler to enhance team productivity and improve software fault tolerance.\n\nIt provides the ability to wrap blocks of code with an abstract feature branch name, and then specify in a configuration file which features to be switched on or off.\n\nThe goal is to build out upcoming features in the same source code repository branch (i.e. Continuous Integration and Trunk-Based Development), regardless of whether all are completed by the next release date or not, thus increasing team productivity by preventing integration delays. Developers then disable in-progress features until they are ready to be switched on in production, yet enable them locally and in staging environments for in-progress testing.\n\nThis gives developers the added benefit of being able to switch a feature off after release should big problems arise for a high risk feature.\n\nabstract_feature_branch additionally supports Domain Driven Design's pattern of Bounded Contexts by allowing developers to configure context-specific feature files if needed.\n\nabstract_feature_branch is one of the simplest and most minimalistic \"Feature Flags\" Ruby gems out there as it enables you to get started very quickly by simply leveraging YAML files without having to set up a data store if you do not need it (albeit, you also have the option to use Redis as a very fast in-memory data store).\n".freeze
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"CHANGELOG.md",
|
18
18
|
"LICENSE.txt",
|
@@ -40,27 +40,29 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.homepage = "http://github.com/AndyObtiva/abstract_feature_branch".freeze
|
41
41
|
s.licenses = ["MIT".freeze]
|
42
42
|
s.post_install_message = "\nRails-only post-install instructions:\n\n1) Run the following command to generate the Rails initializer and basic feature files:\n\nrails g abstract_feature_branch:install\n\n2) Optionally, you may run this command to generate feature files per context:\n\nrails g abstract_feature_branch:context context_path\n \n3) Optionally, install Redis server with [Homebrew](https://brew.sh/) by running:\n\nbrew install redis\n\n4) Optionally, install redis client gem (required with Redis server) by adding the following line to Gemfile above abstract_feature_branch:\n\ngem 'redis', '~> 5.0.5'\n\nAfterwards, run:\n\nbundle\n\n5) Optionally, customize configuration in config/initializers/abstract_feature_branch.rb\n\n(can be useful for changing location of feature files in Rails application,\nconfiguring Redis with a Redis or ConnectionPool instance to use for overrides and per-user feature enablement,\nand/or troubleshooting specific Rails environment feature configurations)\n\n".freeze
|
43
|
-
s.rubygems_version = "3.
|
44
|
-
s.summary = "abstract_feature_branch is a Ruby gem that provides a variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler (aka Feature Flags).".freeze
|
43
|
+
s.rubygems_version = "3.3.6".freeze
|
44
|
+
s.summary = "abstract_feature_branch is a Ruby gem that provides a variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler (aka Feature Flags) to enable Continuous Integration and Trunk-Based Development.".freeze
|
45
45
|
|
46
46
|
if s.respond_to? :specification_version then
|
47
47
|
s.specification_version = 4
|
48
48
|
end
|
49
49
|
|
50
50
|
if s.respond_to? :add_runtime_dependency then
|
51
|
-
s.add_runtime_dependency(%q<deep_merge>.freeze, ["
|
51
|
+
s.add_runtime_dependency(%q<deep_merge>.freeze, [">= 1.0.0", "< 2.0.0"])
|
52
52
|
s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
53
53
|
s.add_development_dependency(%q<bundler>.freeze, [">= 2.1.4"])
|
54
54
|
s.add_development_dependency(%q<rspec>.freeze, ["= 2.14.1"])
|
55
55
|
s.add_development_dependency(%q<rdoc>.freeze, ["= 5.1.0"])
|
56
56
|
s.add_development_dependency(%q<psych>.freeze, ["= 3.3.4"])
|
57
|
+
s.add_development_dependency(%q<rake-tui>.freeze, ["~> 0.2"])
|
57
58
|
else
|
58
|
-
s.add_dependency(%q<deep_merge>.freeze, ["
|
59
|
+
s.add_dependency(%q<deep_merge>.freeze, [">= 1.0.0", "< 2.0.0"])
|
59
60
|
s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
|
60
61
|
s.add_dependency(%q<bundler>.freeze, [">= 2.1.4"])
|
61
62
|
s.add_dependency(%q<rspec>.freeze, ["= 2.14.1"])
|
62
63
|
s.add_dependency(%q<rdoc>.freeze, ["= 5.1.0"])
|
63
64
|
s.add_dependency(%q<psych>.freeze, ["= 3.3.4"])
|
65
|
+
s.add_dependency(%q<rake-tui>.freeze, ["~> 0.2"])
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
@@ -23,7 +23,8 @@ module AbstractFeatureBranch
|
|
23
23
|
|
24
24
|
class << self
|
25
25
|
extend Forwardable
|
26
|
-
def_delegators :configuration,
|
26
|
+
def_delegators :configuration, # delegating the following methods to configuration
|
27
|
+
:application_root, :application_root=, :initialize_application_root, :application_environment, :application_environment=, :initialize_application_environment,
|
27
28
|
:logger, :logger=, :initialize_logger, :cacheable, :cacheable=, :initialize_cacheable, :feature_store, :feature_store=, :user_features_storage, :user_features_storage=,
|
28
29
|
:feature_store_live_fetching, :feature_store_live_fetching=
|
29
30
|
|
@@ -84,6 +85,35 @@ module AbstractFeatureBranch
|
|
84
85
|
merge(environment_variable_overrides).
|
85
86
|
merge(redis_overrides)
|
86
87
|
end
|
88
|
+
|
89
|
+
def redis_per_user_features
|
90
|
+
@redis_per_user_features ||= load_redis_per_user_features
|
91
|
+
end
|
92
|
+
def load_redis_per_user_features
|
93
|
+
@redis_per_user_features = {}
|
94
|
+
return @redis_per_user_features if AbstractFeatureBranch.configuration.feature_store_live_fetching?
|
95
|
+
|
96
|
+
@environment_features.each do |environment, features|
|
97
|
+
features.each do |feature, value|
|
98
|
+
if value == 'per_user'
|
99
|
+
normalized_feature_name = feature.to_s.downcase
|
100
|
+
@redis_per_user_features[normalized_feature_name] ||= []
|
101
|
+
begin
|
102
|
+
per_user_feature_user_ids = AbstractFeatureBranch.
|
103
|
+
user_features_storage.
|
104
|
+
smembers("#{AbstractFeatureBranch::ENV_FEATURE_PREFIX}#{normalized_feature_name}")
|
105
|
+
@redis_per_user_features[normalized_feature_name] += per_user_feature_user_ids
|
106
|
+
rescue Exception => error
|
107
|
+
AbstractFeatureBranch.logger.error "AbstractFeatureBranch encountered an error in retrieving Per-User values for feature \"#{normalized_feature_name}\"! Defaulting to no values...\n\nError: #{error.full_message}\n\n"
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
@redis_per_user_features
|
115
|
+
end
|
116
|
+
|
87
117
|
def application_features
|
88
118
|
unload_application_features unless cacheable?
|
89
119
|
environment_features(application_environment)
|
@@ -94,6 +124,7 @@ module AbstractFeatureBranch
|
|
94
124
|
AbstractFeatureBranch.load_features
|
95
125
|
AbstractFeatureBranch.load_local_features
|
96
126
|
AbstractFeatureBranch.load_environment_features(application_environment)
|
127
|
+
AbstractFeatureBranch.load_redis_per_user_features
|
97
128
|
end
|
98
129
|
def unload_application_features
|
99
130
|
@redis_overrides = nil
|
@@ -101,7 +132,9 @@ module AbstractFeatureBranch
|
|
101
132
|
@features = nil
|
102
133
|
@local_features = nil
|
103
134
|
@environment_features = nil
|
135
|
+
@redis_per_user_features = nil
|
104
136
|
end
|
137
|
+
|
105
138
|
def cacheable?
|
106
139
|
value = downcase_keys(cacheable)[application_environment]
|
107
140
|
value = (application_environment != 'development') if value.nil?
|
data/lib/ext/feature_branch.rb
CHANGED
@@ -35,11 +35,15 @@ class Object
|
|
35
35
|
|
36
36
|
raise 'Abstract feature branch conflicts with another Ruby library having Object::feature_enabled_per_user_value' if Object.new.respond_to?(:feature_enabled_per_user_value, true)
|
37
37
|
def feature_enabled_per_user_value(normalized_feature_name, user_id)
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
if AbstractFeatureBranch.configuration.feature_store_live_fetching?
|
39
|
+
begin
|
40
|
+
AbstractFeatureBranch.user_features_storage.sismember("#{AbstractFeatureBranch::ENV_FEATURE_PREFIX}#{normalized_feature_name}", user_id)
|
41
|
+
rescue Exception => error
|
42
|
+
AbstractFeatureBranch.logger.error "AbstractFeatureBranch encountered an error in retrieving Per-User value for feature \"#{normalized_feature_name}\" and user_id #{user_id}! Defaulting to nil value...\n\nError: #{error.full_message}\n\n"
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
else
|
46
|
+
AbstractFeatureBranch.redis_per_user_features[normalized_feature_name]&.include?(user_id.to_s)
|
43
47
|
end
|
44
48
|
end
|
45
49
|
end
|
@@ -7,8 +7,10 @@
|
|
7
7
|
# The following example line works with Heroku Redis To Go while still operating on local Redis for local development
|
8
8
|
# AbstractFeatureBranch.feature_store = Redis.new(:url => ENV['REDISTOGO_URL'])
|
9
9
|
|
10
|
-
# Enable live fetching of feature configuration from storage system, to update features without app/server restart.
|
10
|
+
# Enable live fetching of feature configuration from storage system (Redis), to update features without app/server restart.
|
11
11
|
# false by default to only load features on app/server start for faster performance (requires restart on change)
|
12
|
+
# This also affects per-user feature loading from storage system (Redis), pre-caching user IDs for features on app/server
|
13
|
+
# restart when false, for better performance.
|
12
14
|
AbstractFeatureBranch.feature_store_live_fetching = false
|
13
15
|
|
14
16
|
# Application root where config/features.yml or config/features/ is found
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstract_feature_branch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deep_merge
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.0.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.0.0
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: 1.0.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.0.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: jeweler
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,14 +100,26 @@ dependencies:
|
|
94
100
|
- - '='
|
95
101
|
- !ruby/object:Gem::Version
|
96
102
|
version: 3.3.4
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rake-tui
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.2'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.2'
|
97
117
|
description: |
|
98
|
-
abstract_feature_branch is a Ruby gem that provides a variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler.
|
99
|
-
|
100
|
-
It is a productivity and fault tolerance enhancing team practice.
|
118
|
+
abstract_feature_branch is a Ruby gem that provides a unique variation on the Branch by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin Fowler to enhance team productivity and improve software fault tolerance.
|
101
119
|
|
102
120
|
It provides the ability to wrap blocks of code with an abstract feature branch name, and then specify in a configuration file which features to be switched on or off.
|
103
121
|
|
104
|
-
The goal is to build out upcoming features in the same source code repository branch (i.e.
|
122
|
+
The goal is to build out upcoming features in the same source code repository branch (i.e. Continuous Integration and Trunk-Based Development), regardless of whether all are completed by the next release date or not, thus increasing team productivity by preventing integration delays. Developers then disable in-progress features until they are ready to be switched on in production, yet enable them locally and in staging environments for in-progress testing.
|
105
123
|
|
106
124
|
This gives developers the added benefit of being able to switch a feature off after release should big problems arise for a high risk feature.
|
107
125
|
|
@@ -162,10 +180,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
180
|
- !ruby/object:Gem::Version
|
163
181
|
version: '0'
|
164
182
|
requirements: []
|
165
|
-
rubygems_version: 3.
|
183
|
+
rubygems_version: 3.3.6
|
166
184
|
signing_key:
|
167
185
|
specification_version: 4
|
168
186
|
summary: abstract_feature_branch is a Ruby gem that provides a variation on the Branch
|
169
187
|
by Abstraction Pattern by Paul Hammant and the Feature Toggles Pattern by Martin
|
170
|
-
Fowler (aka Feature Flags).
|
188
|
+
Fowler (aka Feature Flags) to enable Continuous Integration and Trunk-Based Development.
|
171
189
|
test_files: []
|