abstract_feature_branch 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4bd986e2f793fa698d09ec8c8da54e65c8453c8
4
- data.tar.gz: bff3c99598c72578ec0ff0c35658f2dff8c2b759
3
+ metadata.gz: 171dc3b05d9257bd90a08f4675cb4be9649e0c1e
4
+ data.tar.gz: caa97d72c5866c47023ce82bba130b747e526936
5
5
  SHA512:
6
- metadata.gz: 246a4b2c80ef846b32858f8ecf76675dc8b99c1b9fe1f0dec1a24bf0e046a72c305be87b2a5a09959589209b5d937284b1968676079009c6f4884bf93b1e5814
7
- data.tar.gz: 1a373850678a326fe82729093ae6274b6a4519e3ea579fd5fda1c933a42e170ded9474e51872ff8e9ed770b29e22c57690e3b1bffff9d30e78b9c21348320ae7
6
+ metadata.gz: 92bc2cf8e35055a73a2e44a276b89cd5d3a27b2e499ed176243f836046392bb2f38109aa50b38a75b6c8ab254dc7695796ee0fb5b89d5e8ea652dc29ffc76edb
7
+ data.tar.gz: b63edde1fb4b6beeece611e173dc002a56ff00a577d10003d769b1f21945a9b9e924663b87dfdefe673b3093c741e4ce6becc65e9f7d5af85b6b32efee1de76f
data/README.md CHANGED
@@ -3,6 +3,13 @@ Abstract Feature Branch
3
3
  [![Gem Version](https://badge.fury.io/rb/abstract_feature_branch.png)](http://badge.fury.io/rb/abstract_feature_branch)
4
4
  [![Build Status](https://api.travis-ci.org/AndyObtiva/abstract_feature_branch.png?branch=master)](https://travis-ci.org/AndyObtiva/abstract_feature_branch)
5
5
  [![Coverage Status](https://coveralls.io/repos/AndyObtiva/abstract_feature_branch/badge.png?branch=master)](https://coveralls.io/r/AndyObtiva/abstract_feature_branch?branch=master)
6
+ [![Code Climate](https://codeclimate.com/github/AndyObtiva/abstract_feature_branch.png)](https://codeclimate.com/github/AndyObtiva/abstract_feature_branch)
7
+
8
+ **As Featured In**
9
+
10
+ [![Factor 75](https://dzd6ppgm28vds.cloudfront.net/assets/logo-b190de0b423855600e216d490fc160ad.png)](https://www.factor75.com)..[![Character Business Card](https://characterbusinesscard.s3.amazonaws.com/assets/Character-Business-Card-Logo-Desktop-44eb97b18b0a100488ba9c322343b91a.png)](https://www.characterbusinesscard.com)..[![Early Shares](http://early-shares-assets-production.s3.amazonaws.com/assets/logo2x-67fadfc8bb942ba92cca60c464010f1f.png)](https://www.earlyshares.com)
11
+
12
+
6
13
 
7
14
  abstract_feature_branch is a Rails gem that enables developers to easily branch by abstraction as per this pattern:
8
15
  http://paulhammant.com/blog/branch_by_abstraction.html
@@ -37,15 +44,15 @@ Setup
37
44
  ### Rails Application Use
38
45
 
39
46
  1. Configure Rubygem
40
- - Rails (~> 4.0.0 or ~> 3.0): Add the following to Gemfile <pre>gem 'abstract_feature_branch', '1.1.1'</pre>
41
- - Rails (~> 2.0): Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '1.1.1'</pre>
47
+ - Rails (~> 4.0.0 or ~> 3.0): Add the following to Gemfile <pre>gem 'abstract_feature_branch', '1.2.2'</pre>
48
+ - Rails (~> 2.0): Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '1.2.2'</pre>
42
49
  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>
43
50
  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))
44
51
  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 for per-user feature enablement, or troubleshooting a specific Rails environment feature configuration)
45
52
 
46
53
  ### Ruby Application General Use
47
54
 
48
- 1. <pre>gem install abstract_feature_branch -v 1.1.1</pre>
55
+ 1. <pre>gem install abstract_feature_branch -v 1.2.2</pre>
49
56
  2. Add code <code>require 'abstract_feature_branch'</code>
50
57
  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).
51
58
  4. (Optional) Create <code>config/features.local.yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under [**instructions**](#instructions))
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.1
1
+ 1.2.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "abstract_feature_branch"
8
- s.version = "1.2.1"
8
+ s.version = "1.2.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Annas \"Andy\" Maleh"]
12
- s.date = "2014-01-23"
12
+ s.date = "2014-02-23"
13
13
  s.description = "abstract_feature_branch is a Rails gem that enables developers to easily branch by abstraction as per this pattern:\nhttp://paulhammant.com/blog/branch_by_abstraction.html\n\nIt is a productivity and fault tolerance enhancing team practice that has been utilized by professional software development\nteams at large corporations, such as Sears and Groupon.\n\nIt provides the ability to wrap blocks of code with an abstract feature branch name, and then\nspecify 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, regardless of whether all are\ncompleted by the next release date or not, thus increasing team productivity by preventing integration delays.\nDevelopers then disable in-progress features until they are ready to be switched on in production, yet enable them\nlocally 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\nfor a high risk feature.\n\nabstract_feature_branch additionally supports DDD's pattern of\nBounded Contexts by allowing developers to configure\ncontext-specific feature files if needed.\n"
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE.txt",
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "config/features/public.local.yml",
31
31
  "config/features/public.yml",
32
32
  "lib/abstract_feature_branch.rb",
33
+ "lib/abstract_feature_branch/configuration.rb",
33
34
  "lib/abstract_feature_branch/file_beautifier.rb",
34
35
  "lib/ext/feature_branch.rb",
35
36
  "lib/generators/abstract_feature_branch/context_generator.rb",
@@ -12,61 +12,19 @@ end
12
12
  require 'logger' unless defined?(Rails) && Rails.logger
13
13
  require 'deep_merge' unless {}.respond_to?(:deep_merge!)
14
14
 
15
+ require File.join(File.dirname(__FILE__), 'abstract_feature_branch', 'configuration')
16
+
15
17
  module AbstractFeatureBranch
16
18
  ENV_FEATURE_PREFIX = "abstract_feature_branch_"
17
19
 
18
20
  class << self
19
- def application_root
20
- @application_root ||= initialize_application_root
21
- end
22
- def application_root=(path)
23
- @application_root = path
24
- end
25
- def initialize_application_root
26
- self.application_root = defined?(Rails) ? Rails.root : '.'
27
- end
28
- def application_environment
29
- @application_environment ||= initialize_application_environment
30
- end
31
- def application_environment=(environment)
32
- @application_environment = environment
33
- end
34
- def initialize_application_environment
35
- self.application_environment = defined?(Rails) ? Rails.env.to_s : ENV['APP_ENV'] || 'development'
36
- end
37
- def logger
38
- @logger ||= initialize_logger
39
- end
40
- def logger=(logger)
41
- @logger = logger
42
- end
43
- def initialize_logger
44
- self.logger = defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
45
- end
46
- def cacheable
47
- @cacheable ||= initialize_cacheable
48
- end
49
- def cacheable=(cacheable)
50
- @cacheable = cacheable
51
- end
52
- def initialize_cacheable
53
- self.cacheable = {
54
- :development => false,
55
- :test => true,
56
- :staging => true,
57
- :production => true
58
- }
59
- end
60
- def user_features_storage
61
- @user_features_storage ||= initialize_user_features_storage
62
- end
63
- def user_features_storage=(user_features_storage)
64
- @user_features_storage = user_features_storage
65
- end
66
- def initialize_user_features_storage
67
- require 'redis'
68
- self.user_features_storage = Redis.new
21
+ extend Forwardable
22
+ def_delegators :configuration, :application_root, :application_root=, :initialize_application_root, :application_environment, :application_environment=, :initialize_application_environment, :logger, :logger=, :initialize_logger, :cacheable, :cacheable=, :initialize_cacheable, :user_features_storage, :user_features_storage=, :initialize_user_features_storage
23
+
24
+ def configuration
25
+ @configuration ||= Configuration.new
69
26
  end
27
+
70
28
  def environment_variable_overrides
71
29
  @environment_variable_overrides ||= load_environment_variable_overrides
72
30
  end
@@ -78,24 +36,14 @@ module AbstractFeatureBranch
78
36
  end
79
37
  def load_local_features
80
38
  @local_features = {}
81
- Dir.glob(File.join(application_root, 'config', 'features', '**', '*.local.yml')).each do |feature_configuration_file|
82
- @local_features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(feature_configuration_file)))
83
- end
84
- main_local_features_file = File.join(application_root, 'config', 'features.local.yml')
85
- @local_features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(main_local_features_file))) if File.exists?(main_local_features_file)
86
- @local_features
39
+ load_specific_features(@local_features, '.local.yml')
87
40
  end
88
41
  def features
89
42
  @features ||= load_features
90
43
  end
91
44
  def load_features
92
45
  @features = {}
93
- Dir.glob(File.join(application_root, 'config', 'features', '**', '*.yml')).each do |feature_configuration_file|
94
- @features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(feature_configuration_file)))
95
- end
96
- main_features_file = File.join(application_root, 'config', 'features.yml')
97
- @features.deep_merge!(downcase_feature_hash_keys(YAML.load_file(main_features_file))) if File.exists?(main_features_file)
98
- @features
46
+ load_specific_features(@features, '.yml')
99
47
  end
100
48
  # performance optimization via caching of feature values resolved through environment variable overrides and local features
101
49
  def environment_features(environment)
@@ -141,6 +89,15 @@ module AbstractFeatureBranch
141
89
 
142
90
  private
143
91
 
92
+ def load_specific_features(features_hash, extension)
93
+ Dir.glob(File.join(application_root, 'config', 'features', '**', "*#{extension}")).each do |feature_configuration_file|
94
+ features_hash.deep_merge!(downcase_feature_hash_keys(YAML.load_file(feature_configuration_file)))
95
+ end
96
+ main_local_features_file = File.join(application_root, 'config', "features#{extension}")
97
+ features_hash.deep_merge!(downcase_feature_hash_keys(YAML.load_file(main_local_features_file))) if File.exists?(main_local_features_file)
98
+ features_hash
99
+ end
100
+
144
101
  def featureize_keys(hash)
145
102
  Hash[hash.map {|k, v| [k.sub(ENV_FEATURE_PREFIX, ''), v]}]
146
103
  end
@@ -0,0 +1,55 @@
1
+ module AbstractFeatureBranch
2
+ class Configuration
3
+ def application_root
4
+ @application_root ||= initialize_application_root
5
+ end
6
+ def application_root=(path)
7
+ @application_root = path
8
+ end
9
+ def initialize_application_root
10
+ self.application_root = defined?(Rails) ? Rails.root : '.'
11
+ end
12
+ def application_environment
13
+ @application_environment ||= initialize_application_environment
14
+ end
15
+ def application_environment=(environment)
16
+ @application_environment = environment
17
+ end
18
+ def initialize_application_environment
19
+ self.application_environment = defined?(Rails) ? Rails.env.to_s : ENV['APP_ENV'] || 'development'
20
+ end
21
+ def logger
22
+ @logger ||= initialize_logger
23
+ end
24
+ def logger=(logger)
25
+ @logger = logger
26
+ end
27
+ def initialize_logger
28
+ self.logger = defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
29
+ end
30
+ def cacheable
31
+ @cacheable ||= initialize_cacheable
32
+ end
33
+ def cacheable=(cacheable)
34
+ @cacheable = cacheable
35
+ end
36
+ def initialize_cacheable
37
+ self.cacheable = {
38
+ :development => false,
39
+ :test => true,
40
+ :staging => true,
41
+ :production => true
42
+ }
43
+ end
44
+ def user_features_storage
45
+ @user_features_storage ||= initialize_user_features_storage
46
+ end
47
+ def user_features_storage=(user_features_storage)
48
+ @user_features_storage = user_features_storage
49
+ end
50
+ def initialize_user_features_storage
51
+ require 'redis'
52
+ self.user_features_storage = Redis.new
53
+ end
54
+ end
55
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abstract_feature_branch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Annas "Andy" Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-23 00:00:00.000000000 Z
11
+ date: 2014-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -94,6 +94,7 @@ files:
94
94
  - config/features/public.local.yml
95
95
  - config/features/public.yml
96
96
  - lib/abstract_feature_branch.rb
97
+ - lib/abstract_feature_branch/configuration.rb
97
98
  - lib/abstract_feature_branch/file_beautifier.rb
98
99
  - lib/ext/feature_branch.rb
99
100
  - lib/generators/abstract_feature_branch/context_generator.rb