abstract_feature_branch 0.8.0 → 0.9.0

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: 695366cdc70dc9883e9bcfcc498c384d8b52620c
4
- data.tar.gz: 9850c42b60dd40e604500acac757ea21598dd339
3
+ metadata.gz: c89fdfb59675ab1f3591c973daf0970ca1ad2c8f
4
+ data.tar.gz: 9fdb542f2134917987b0b45be6d2a6db9510b49a
5
5
  SHA512:
6
- metadata.gz: 918fdebd4a2ea0b5f600141910d816573721434bb3931dd7d0e881815adfec0f5c0da2c084e1e5cd1a667c812a9ca95457929ef16b1afa477202c40c7db5861b
7
- data.tar.gz: a1a7c5fceca419639dee473ee41d38ef9b0d9bb7f1aff55242d7fa4147e71ee950c860a8dac8172ce1c3a1e11b3c0c46f85894a4f36a9030410dae18368320af
6
+ metadata.gz: 13306a2b078d7fbc4938f7f4306bb0c8a0615ef1726a7b2bdbb306c5c16675a4e9d9956110982ffbeea2e1b4cc1e0e7e732a2073832b0e354561dd0240aff221
7
+ data.tar.gz: 408facf5b950144549f27faef351d36362f1a324a5f78faf8473574b7f0ed5331bff4c8ae70f4af2b8f096a174689547ea0ecc2162af098725d68ac46aab4fe2
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ repo_token: ylr6gphUkEVGf9nvY5Hfz48RHZnOf0Jjv
data/.travis.yml CHANGED
@@ -7,3 +7,22 @@ rvm:
7
7
  - jruby-18mode
8
8
  - jruby-19mode
9
9
  - rbx-2.1.1
10
+ gemfile:
11
+ - Gemfile
12
+ - ruby187.Gemfile
13
+ matrix:
14
+ include:
15
+ - rvm: 2.0.0
16
+ gemfile: Gemfile
17
+ - rvm: 1.9.3
18
+ gemfile: Gemfile
19
+ - rvm: 1.8.7
20
+ gemfile: ruby187.Gemfile
21
+ - rvm: ree
22
+ gemfile: ruby187.Gemfile
23
+ - rvm: jruby-18mode
24
+ gemfile: Gemfile
25
+ - rvm: jruby-19mode
26
+ gemfile: Gemfile
27
+ - rvm: rbx-2.1.1
28
+ gemfile: ruby187.Gemfile
data/README.md CHANGED
@@ -2,6 +2,7 @@ Abstract Feature Branch
2
2
  =======================
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
+ [![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
6
 
6
7
  abstract_feature_branch is a Rails gem that enables developers to easily branch by abstraction as per this pattern:
7
8
  http://paulhammant.com/blog/branch_by_abstraction.html
@@ -35,15 +36,15 @@ Setup
35
36
  ### Rails Application Use
36
37
 
37
38
  1. Configure Rubygem
38
- - Rails (~> 4.0.0 or ~> 3.0): Add the following to Gemfile <pre>gem 'abstract_feature_branch', '0.8.0'</pre>
39
- - Rails (~> 2.0): Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '0.8.0'</pre>
39
+ - Rails (~> 4.0.0 or ~> 3.0): Add the following to Gemfile <pre>gem 'abstract_feature_branch', '0.9.0'</pre>
40
+ - Rails (~> 2.0): Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '0.9.0'</pre>
40
41
  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>
41
42
  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))
42
43
  4. (Optional and rarely needed) Customize configuration in <code>config/initializers/abstract_feature_branch.rb</code> (can be useful for changing location of feature files in Rails application or troubleshooting a specific Rails environment feature configuration)
43
44
 
44
45
  ### Ruby Application General Use
45
46
 
46
- 1. <pre>gem install abstract_feature_branch -v 0.8.0</pre>
47
+ 1. <pre>gem install abstract_feature_branch -v 0.9.0</pre>
47
48
  2. Add code <code>require 'abstract_feature_branch'</code>
48
49
  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).
49
50
  4. (Optional) Create <code>config/features.local.yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under [**instructions**](#instructions))
@@ -358,6 +359,7 @@ For Rails application use, the rake task is generated under <code>lib/tasks/abst
358
359
 
359
360
  For Ruby application general use, here is the content of the rake task:
360
361
 
362
+ > require 'abstract_feature_branch'
361
363
  > namespace :abstract_feature_branch do
362
364
  >
363
365
  > desc "Beautify YAML of specified feature file via file_path argument or all feature files when no argument specified (config/features.yml, config/features.local.yml, and config/features/**/*.yml) by sorting features by name and eliminating extra empty lines"
@@ -378,6 +380,9 @@ task changes.
378
380
  Release Notes
379
381
  -------------
380
382
 
383
+ Version 0.9.0:
384
+ - Added support for runtime read of feature files in development to ease local testing (trading off performance)
385
+
381
386
  Version 0.8.0:
382
387
  - Added rake task for beautifying feature files, sorting feature names within environment sections and eliminating extra empty lines. Added support for externalized logger.
383
388
 
@@ -428,7 +433,6 @@ Version 0.2.0:
428
433
  Upcoming
429
434
  --------
430
435
 
431
- - Support runtime read of features yml in development for easy testing purposes (trading off performance)
432
436
  - Support configuring per environment whether features yml is read at runtime or not (given performance trade-off)
433
437
 
434
438
  Contributing to abstract_feature_branch
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.9.0
@@ -5,17 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "abstract_feature_branch"
8
- s.version = "0.8.0"
8
+ s.version = "0.9.0"
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 = "2013-11-25"
12
+ s.date = "2013-11-26"
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",
16
16
  "README.md"
17
17
  ]
18
18
  s.files = [
19
+ ".coveralls.yml",
19
20
  ".travis.yml",
20
21
  "LICENSE.txt",
21
22
  "README.md",
@@ -37,9 +38,11 @@ Gem::Specification.new do |s|
37
38
  "lib/generators/templates/config/features.yml",
38
39
  "lib/generators/templates/config/initializers/abstract_feature_branch.rb",
39
40
  "lib/generators/templates/lib/tasks/abstract_feature_branch.rake",
41
+ "ruby187.Gemfile",
40
42
  "spec/abstract_feature_branch/file_beautifier_spec.rb",
41
43
  "spec/ext/feature_branch__feature_branch_spec.rb",
42
44
  "spec/ext/feature_branch__feature_enabled_spec.rb",
45
+ "spec/fixtures/application_development_config/config/features.reference.yml",
43
46
  "spec/fixtures/application_no_config/no_config",
44
47
  "spec/fixtures/application_rails_config/config/features.local.yml",
45
48
  "spec/fixtures/application_rails_config/config/features.yml",
@@ -69,16 +72,13 @@ Gem::Specification.new do |s|
69
72
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
70
73
  s.add_runtime_dependency(%q<deep_merge>, ["= 1.0.0"])
71
74
  s.add_development_dependency(%q<jeweler>, ["= 1.8.8"])
72
- s.add_development_dependency(%q<rspec>, ["= 2.14.1"])
73
75
  else
74
76
  s.add_dependency(%q<deep_merge>, ["= 1.0.0"])
75
77
  s.add_dependency(%q<jeweler>, ["= 1.8.8"])
76
- s.add_dependency(%q<rspec>, ["= 2.14.1"])
77
78
  end
78
79
  else
79
80
  s.add_dependency(%q<deep_merge>, ["= 1.0.0"])
80
81
  s.add_dependency(%q<jeweler>, ["= 1.8.8"])
81
- s.add_dependency(%q<rspec>, ["= 2.14.1"])
82
82
  end
83
83
  end
84
84
 
@@ -82,6 +82,7 @@ module AbstractFeatureBranch
82
82
  @environment_features[environment] = features[environment].merge(local_features[environment]).merge(environment_variable_overrides)
83
83
  end
84
84
  def self.application_features
85
+ unload_application_features unless cacheable?
85
86
  environment_features(application_environment)
86
87
  end
87
88
  def self.load_application_features
@@ -90,6 +91,15 @@ module AbstractFeatureBranch
90
91
  AbstractFeatureBranch.load_local_features
91
92
  AbstractFeatureBranch.load_environment_features(application_environment)
92
93
  end
94
+ def self.unload_application_features
95
+ @environment_variable_overrides = nil
96
+ @features = nil
97
+ @local_features = nil
98
+ @environment_features = nil
99
+ end
100
+ def self.cacheable?
101
+ application_environment != 'development'
102
+ end
93
103
 
94
104
  private
95
105
 
data/ruby187.Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'deep_merge', '1.0.0', :require => false #avoid loading into memory to use deep_merge only if Rails is unavailable
4
+
5
+ group :development do
6
+ gem 'jeweler', '1.8.8'
7
+ end
8
+
9
+ group :test do
10
+ gem 'rspec', '2.14.1'
11
+ end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  describe 'feature_branch object extensions' do
4
4
  before do
5
5
  @app_env_backup = AbstractFeatureBranch.application_environment
6
+ @app_root_backup = AbstractFeatureBranch.application_root
6
7
  AbstractFeatureBranch.logger.warn 'Environment variable ABSTRACT_FEATURE_BRANCH_FEATURE1 already set, potentially conflicting with another test' if ENV.keys.include?('ABSTRACT_FEATURE_BRANCH_FEATURE1')
7
8
  AbstractFeatureBranch.logger.warn 'Environment variable Abstract_Feature_Branch_Feature2 already set, potentially conflicting with another test' if ENV.keys.include?('Abstract_Feature_Branch_Feature2')
8
9
  AbstractFeatureBranch.logger.warn 'Environment variable abstract_feature_branch_feature3 already set, potentially conflicting with another test' if ENV.keys.include?('abstract_feature_branch_feature3')
@@ -11,9 +12,9 @@ describe 'feature_branch object extensions' do
11
12
  ENV.delete('ABSTRACT_FEATURE_BRANCH_FEATURE1')
12
13
  ENV.delete('Abstract_Feature_Branch_Feature2')
13
14
  ENV.delete('abstract_feature_branch_feature3')
14
- AbstractFeatureBranch.initialize_application_root
15
- AbstractFeatureBranch.load_application_features
15
+ AbstractFeatureBranch.application_root = @app_root_backup
16
16
  AbstractFeatureBranch.application_environment = @app_env_backup
17
+ AbstractFeatureBranch.unload_application_features
17
18
  end
18
19
  describe '#feature_branch' do
19
20
  context 'class level behavior (case-insensitive string or symbol feature names)' do
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  describe 'feature_branch object extensions' do
4
4
  before do
5
5
  @app_env_backup = AbstractFeatureBranch.application_environment
6
+ @app_root_backup = AbstractFeatureBranch.application_root
6
7
  AbstractFeatureBranch.logger.warn 'Environment variable ABSTRACT_FEATURE_BRANCH_FEATURE1 already set, potentially conflicting with another test' if ENV.keys.include?('ABSTRACT_FEATURE_BRANCH_FEATURE1')
7
8
  AbstractFeatureBranch.logger.warn 'Environment variable Abstract_Feature_Branch_Feature2 already set, potentially conflicting with another test' if ENV.keys.include?('Abstract_Feature_Branch_Feature2')
8
9
  AbstractFeatureBranch.logger.warn 'Environment variable abstract_feature_branch_feature3 already set, potentially conflicting with another test' if ENV.keys.include?('abstract_feature_branch_feature3')
@@ -11,9 +12,9 @@ describe 'feature_branch object extensions' do
11
12
  ENV.delete('ABSTRACT_FEATURE_BRANCH_FEATURE1')
12
13
  ENV.delete('Abstract_Feature_Branch_Feature2')
13
14
  ENV.delete('abstract_feature_branch_feature3')
14
- AbstractFeatureBranch.initialize_application_root
15
- AbstractFeatureBranch.load_application_features
15
+ AbstractFeatureBranch.application_root = @app_root_backup
16
16
  AbstractFeatureBranch.application_environment = @app_env_backup
17
+ AbstractFeatureBranch.unload_application_features
17
18
  end
18
19
  describe '#feature_enabled?' do
19
20
  it 'determines whether a feature is enabled or not in features configuration (case-insensitive string or symbol feature names)' do
@@ -38,7 +39,7 @@ describe 'feature_branch object extensions' do
38
39
  feature_enabled?(:feature4).should == false
39
40
  feature_enabled?(:feature5).should == true
40
41
  end
41
- it 'no local configuration in production environment' do
42
+ it 'has no local configuration for production environment' do
42
43
  AbstractFeatureBranch.application_environment = 'production'
43
44
  feature_enabled?(:feature4).should == true
44
45
  feature_enabled?(:feature5).should be_nil
@@ -64,6 +65,86 @@ describe 'feature_branch object extensions' do
64
65
  feature_enabled?(:feature4a).should be_nil
65
66
  feature_enabled?(:feature5).should be_nil
66
67
  end
68
+
69
+ context 'cacheability' do
70
+ before do
71
+ @development_application_root = File.expand_path(File.join(__FILE__, '..', '..', 'fixtures', 'application_development_config'))
72
+ @feature_file_reference_path = File.join(@development_application_root, 'config', 'features.reference.yml')
73
+ @feature_file_path = File.join(@development_application_root, 'config', 'features.yml')
74
+ FileUtils.cp(@feature_file_reference_path, @feature_file_path)
75
+ AbstractFeatureBranch.application_root = @development_application_root
76
+ end
77
+ after do
78
+ FileUtils.rm(@feature_file_path)
79
+ end
80
+ it 'refreshes features at runtime in development (without forcing load of application features again)' do
81
+ AbstractFeatureBranch.application_environment = 'development'
82
+ feature_enabled?(:feature1).should == false
83
+ feature_enabled?(:feature2).should == true
84
+ File.open(@feature_file_path, 'w+') do |file|
85
+ file << <<-CONTENT
86
+ defaults: &defaults
87
+
88
+ development:
89
+ <<: *defaults
90
+ FEATURE1: true
91
+ Feature2: false
92
+
93
+ test:
94
+ <<: *defaults
95
+ FEATURE1: true
96
+ Feature2: false
97
+
98
+ staging:
99
+ <<: *defaults
100
+ FEATURE1: true
101
+ Feature2: false
102
+
103
+ production:
104
+ <<: *defaults
105
+ FEATURE1: true
106
+ Feature2: false
107
+ CONTENT
108
+ end
109
+ feature_enabled?(:feature1).should == true
110
+ feature_enabled?(:feature2).should == false
111
+ end
112
+ %w(test staging production).each do |environment|
113
+ it "does not refresh features at runtime in #{environment} (without forcing load of application features again)" do
114
+ AbstractFeatureBranch.application_environment = environment
115
+ AbstractFeatureBranch.load_application_features
116
+ feature_enabled?(:feature1).should == false
117
+ feature_enabled?(:feature2).should == true
118
+ File.open(@feature_file_path, 'w+') do |file|
119
+ file << <<-CONTENT
120
+ defaults: &defaults
121
+
122
+ development:
123
+ <<: *defaults
124
+ FEATURE1: true
125
+ Feature2: false
126
+
127
+ test:
128
+ <<: *defaults
129
+ FEATURE1: true
130
+ Feature2: false
131
+
132
+ staging:
133
+ <<: *defaults
134
+ FEATURE1: true
135
+ Feature2: false
136
+
137
+ production:
138
+ <<: *defaults
139
+ FEATURE1: true
140
+ Feature2: false
141
+ CONTENT
142
+ end
143
+ feature_enabled?(:feature1).should == false
144
+ feature_enabled?(:feature2).should == true
145
+ end
146
+ end
147
+ end
67
148
  end
68
149
  describe 'self#feature_enabled?' do
69
150
  after do
@@ -0,0 +1,21 @@
1
+ defaults: &defaults
2
+
3
+ development:
4
+ <<: *defaults
5
+ FEATURE1: false
6
+ Feature2: true
7
+
8
+ test:
9
+ <<: *defaults
10
+ FEATURE1: false
11
+ Feature2: true
12
+
13
+ staging:
14
+ <<: *defaults
15
+ FEATURE1: false
16
+ Feature2: true
17
+
18
+ production:
19
+ <<: *defaults
20
+ FEATURE1: false
21
+ Feature2: true
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: 0.8.0
4
+ version: 0.9.0
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: 2013-11-25 00:00:00.000000000 Z
11
+ date: 2013-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: deep_merge
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.8.8
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '='
46
- - !ruby/object:Gem::Version
47
- version: 2.14.1
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '='
53
- - !ruby/object:Gem::Version
54
- version: 2.14.1
55
41
  description: |
56
42
  abstract_feature_branch is a Rails gem that enables developers to easily branch by abstraction as per this pattern:
57
43
  http://paulhammant.com/blog/branch_by_abstraction.html
@@ -80,6 +66,7 @@ extra_rdoc_files:
80
66
  - LICENSE.txt
81
67
  - README.md
82
68
  files:
69
+ - .coveralls.yml
83
70
  - .travis.yml
84
71
  - LICENSE.txt
85
72
  - README.md
@@ -101,9 +88,11 @@ files:
101
88
  - lib/generators/templates/config/features.yml
102
89
  - lib/generators/templates/config/initializers/abstract_feature_branch.rb
103
90
  - lib/generators/templates/lib/tasks/abstract_feature_branch.rake
91
+ - ruby187.Gemfile
104
92
  - spec/abstract_feature_branch/file_beautifier_spec.rb
105
93
  - spec/ext/feature_branch__feature_branch_spec.rb
106
94
  - spec/ext/feature_branch__feature_enabled_spec.rb
95
+ - spec/fixtures/application_development_config/config/features.reference.yml
107
96
  - spec/fixtures/application_no_config/no_config
108
97
  - spec/fixtures/application_rails_config/config/features.local.yml
109
98
  - spec/fixtures/application_rails_config/config/features.yml