abstract_feature_branch 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +138 -37
- data/VERSION +1 -1
- data/abstract_feature_branch.gemspec +26 -11
- data/config/features/admin.local.yml +2 -1
- data/config/features/admin.yml +2 -1
- data/config/features/internal/wiki.local.yml +2 -1
- data/config/features/internal/wiki.yml +2 -1
- data/config/features/public.local.yml +2 -1
- data/config/features/public.yml +2 -1
- data/lib/abstract_feature_branch.rb +14 -3
- data/lib/abstract_feature_branch/file_beautifier.rb +63 -0
- data/lib/generators/abstract_feature_branch/install_generator.rb +1 -0
- data/lib/generators/templates/config/features.local.yml +1 -0
- data/lib/generators/templates/config/initializers/abstract_feature_branch.rb +3 -0
- data/lib/generators/templates/lib/tasks/abstract_feature_branch.rake +9 -0
- data/spec/abstract_feature_branch/file_beautifier_spec.rb +384 -0
- data/spec/ext/feature_branch__feature_branch_spec.rb +145 -0
- data/spec/ext/feature_branch__feature_enabled_spec.rb +84 -0
- data/spec/{application_no_config → fixtures/application_no_config}/no_config +0 -0
- data/spec/{application_rails_config → fixtures/application_rails_config}/config/features.local.yml +1 -0
- data/spec/{application_rails_config → fixtures/application_rails_config}/config/features.yml +0 -0
- data/spec/fixtures/application_ugly_config_reference/config/another_application_configuration.yml +31 -0
- data/spec/fixtures/application_ugly_config_reference/config/database.yml +17 -0
- data/spec/fixtures/application_ugly_config_reference/config/features.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features.yml +49 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/admin.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/admin.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/empty.local.yml +0 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/feature_empty_config.local.yml +13 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/including_comments.local.yml +52 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/public.local.yml +44 -0
- data/spec/fixtures/application_ugly_config_reference/config/features/public.yml +44 -0
- metadata +46 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 695366cdc70dc9883e9bcfcc498c384d8b52620c
|
4
|
+
data.tar.gz: 9850c42b60dd40e604500acac757ea21598dd339
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 918fdebd4a2ea0b5f600141910d816573721434bb3931dd7d0e881815adfec0f5c0da2c084e1e5cd1a667c812a9ca95457929ef16b1afa477202c40c7db5861b
|
7
|
+
data.tar.gz: a1a7c5fceca419639dee473ee41d38ef9b0d9bb7f1aff55242d7fa4147e71ee950c860a8dac8172ce1c3a1e11b3c0c46f85894a4f36a9030410dae18368320af
|
data/README.md
CHANGED
@@ -7,10 +7,10 @@ abstract_feature_branch is a Rails gem that enables developers to easily branch
|
|
7
7
|
http://paulhammant.com/blog/branch_by_abstraction.html
|
8
8
|
|
9
9
|
It is a productivity and fault tolerance enhancing team practice that has been utilized by professional software development
|
10
|
-
teams at large corporations, such as Sears and Groupon.
|
10
|
+
teams at large corporations, such as [Sears](http://www.sears.com) and [Groupon](http://www.groupon.com).
|
11
11
|
|
12
|
-
It
|
13
|
-
specify which features to be switched on or off
|
12
|
+
It provides the ability to wrap blocks of code with an abstract feature branch name, and then
|
13
|
+
specify in a configuration file which features to be switched on or off.
|
14
14
|
|
15
15
|
The goal is to build out upcoming features in the same source code repository branch, regardless of whether all are
|
16
16
|
completed by the next release date or not, thus increasing team productivity by preventing integration delays.
|
@@ -21,7 +21,7 @@ This gives developers the added benefit of being able to switch a feature off af
|
|
21
21
|
for a high risk feature.
|
22
22
|
|
23
23
|
abstract_feature_branch additionally supports [DDD](http://www.domaindrivendesign.org)'s pattern of
|
24
|
-
[
|
24
|
+
[Bounded Contexts](http://dddcommunity.org/uncategorized/bounded-context/) by allowing developers to configure
|
25
25
|
context-specific feature files if needed.
|
26
26
|
|
27
27
|
Requirements
|
@@ -32,25 +32,26 @@ Requirements
|
|
32
32
|
Setup
|
33
33
|
-----
|
34
34
|
|
35
|
-
### Rails Application
|
35
|
+
### Rails Application Use
|
36
36
|
|
37
37
|
1. Configure Rubygem
|
38
|
-
- Rails (~> 4.0.0 or ~> 3.0): Add the following to Gemfile <pre>gem 'abstract_feature_branch', '0.
|
39
|
-
- Rails (~> 2.0): Add the following to config/environment.rb <pre>config.gem 'abstract_feature_branch', :version => '0.
|
40
|
-
2. Generate <code>config/initializers/abstract_feature_branch.rb</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
|
-
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**)
|
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>
|
40
|
+
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
|
+
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
42
|
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
43
|
|
44
|
-
### Ruby Application
|
44
|
+
### Ruby Application General Use
|
45
45
|
|
46
|
-
1. <pre>gem install abstract_feature_branch -v 0.
|
46
|
+
1. <pre>gem install abstract_feature_branch -v 0.8.0</pre>
|
47
47
|
2. Add code <code>require 'abstract_feature_branch'</code>
|
48
|
-
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
|
49
|
-
4. (Optional) Create <code>config/features.local.yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under **instructions**)
|
50
|
-
5. (Optional) Create <code>config/features/[context_path].yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under **instructions**)
|
48
|
+
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
|
+
4. (Optional) Create <code>config/features.local.yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under [**instructions**](#instructions))
|
50
|
+
5. (Optional) Create <code>config/features/[context_path].yml</code> under <code>AbstractFeatureBranch.application_root</code> (more details under [**instructions**](#instructions))
|
51
51
|
6. (Optional) Add code <code>AbstractFeatureBranch.application_root = "[your_application_path]"</code> to configure the location of feature files (it defaults to <code>'.'</code>)
|
52
52
|
7. (Optional) Add code <code>AbstractFeatureBranch.application_environment = "[your_application_environment]"</code> (it defaults to <code>'development'</code>). Alternatively, you can set <code>ENV['APP_ENV']</code> before the <code>require</code> statement or an an external environment variable.
|
53
|
-
8. (Optional) Add code <code>AbstractFeatureBranch.
|
53
|
+
8. (Optional) Add code <code>AbstractFeatureBranch.logger = "[your_application_logger]"</code> (it defaults to a new instance of Ruby <code>Logger</code>. Must use a logger with <code>info</code> and <code>warn</code> methods).
|
54
|
+
9. (Optional) Add code <code>AbstractFeatureBranch.load_application_features</code> to pre-load application features for improved first-use performance
|
54
55
|
|
55
56
|
Instructions
|
56
57
|
------------
|
@@ -128,20 +129,6 @@ Note that <code>feature_branch</code> executes the false branch if the feature i
|
|
128
129
|
|
129
130
|
Note that <code>feature_enabled?</code> returns false if the feature is disabled and nil if the feature is non-existent (practically the same effect, but nil can sometimes be useful to detect if a feature is referenced).
|
130
131
|
|
131
|
-
Initializer
|
132
|
-
-----------
|
133
|
-
|
134
|
-
Here is the content of the generated initializer (<code>config/initializers/abstract_feature_branch.rb</code>), which contains instructions on how to customize:
|
135
|
-
|
136
|
-
> # Application root where config/features.yml or config/features/ is found
|
137
|
-
> AbstractFeatureBranch.application_root = Rails.root
|
138
|
-
>
|
139
|
-
> # Application environment (e.g. "development", "staging" or "production")
|
140
|
-
> AbstractFeatureBranch.application_environment = Rails.env.to_s
|
141
|
-
>
|
142
|
-
> # Pre-loads application features to improve performance of first web-page hit
|
143
|
-
> AbstractFeatureBranch.load_application_features
|
144
|
-
|
145
132
|
Recommendations
|
146
133
|
---------------
|
147
134
|
|
@@ -199,11 +186,11 @@ simply switching off the URL route to them. Example:
|
|
199
186
|
> }
|
200
187
|
|
201
188
|
- Once a feature has been released and switched on in production, and it has worked well for a while (e.g. for two consecutive releases),
|
202
|
-
it is recommended that its feature branching code is plucked out of the codebase to simplify and improve
|
189
|
+
it is **strongly recommended** that its feature branching code is plucked out of the codebase to simplify and improve
|
203
190
|
future maintainability given that it is no longer needed at that point.
|
204
191
|
|
205
|
-
-
|
206
|
-
utilizing the context generator mentioned above: <pre>rails g abstract_feature_branch:context context_path</pre>
|
192
|
+
- Once <code>config/features.yml</code> grows too big (e.g. 20+ features), it is **strongly recommended* to split it into
|
193
|
+
multiple context-specific feature files by utilizing the context generator mentioned above: <pre>rails g abstract_feature_branch:context context_path</pre>
|
207
194
|
|
208
195
|
- When working on a new feature locally that the developer does not want others on the team to see yet, the feature
|
209
196
|
can be enabled in <code>config/features.local.yml</code> only as it is git ignored, and disabled in <code>config/features.yml</code>
|
@@ -262,11 +249,12 @@ Gotcha with abstract feature branching in CSS and JS files:
|
|
262
249
|
|
263
250
|
If you've used abstract feature branching in CSS or JS files via ERB, setting environment variable overrides won't
|
264
251
|
affect them as you need asset recompilation in addition to it, which can only be triggered by changing a CSS or JS
|
265
|
-
file and redeploying on Heroku (
|
252
|
+
file and redeploying on Heroku (even if it's just a minor change to force it). In any case, environment variable
|
266
253
|
overrides have been recommended above as an emergency or temporary measure. If there is a need to rely on environment
|
267
|
-
variable overrides to alter the style or JavaScript behavior of a page back and forth without a redeploy, one solution
|
268
|
-
is to do additional abstract feature branching in HTML templates (e.g. ERB or HAML
|
269
|
-
CSS classes or invoke different JavaScript methods per branch
|
254
|
+
variable overrides to alter the style or JavaScript behavior of a page back and forth without a redeploy, **one solution**
|
255
|
+
is to do additional abstract feature branching in HTML templates (e.g. ERB or [HAML](http://haml.info) to
|
256
|
+
link to different stylesheets and JS files, use different CSS classes, or invoke different JavaScript methods per branch
|
257
|
+
of HTML for example.
|
270
258
|
|
271
259
|
Feature Configuration Load Order
|
272
260
|
--------------------------------
|
@@ -280,9 +268,119 @@ the former if overlap in features occurs:
|
|
280
268
|
4. Main local feature file override: <code>config/features.local.yml</code>
|
281
269
|
5. Environment variable overrides
|
282
270
|
|
271
|
+
Rails Initializer
|
272
|
+
-----------------
|
273
|
+
|
274
|
+
Here is the content of the generated initializer (<code>config/initializers/abstract_feature_branch.rb</code>), which contains instructions on how to customize via [dependency injection](http://en.wikipedia.org/wiki/Dependency_injection):
|
275
|
+
|
276
|
+
> # Application root where config/features.yml or config/features/ is found
|
277
|
+
> AbstractFeatureBranch.application_root = Rails.root
|
278
|
+
>
|
279
|
+
> # Application environment (e.g. "development", "staging" or "production")
|
280
|
+
> AbstractFeatureBranch.application_environment = Rails.env.to_s
|
281
|
+
>
|
282
|
+
> # Abstract Feature Branch logger
|
283
|
+
> AbstractFeatureBranch.logger = Rails.logger
|
284
|
+
>
|
285
|
+
> # Pre-loads application features to improve performance of first web-page hit
|
286
|
+
> AbstractFeatureBranch.load_application_features
|
287
|
+
|
288
|
+
Rake Task
|
289
|
+
---------
|
290
|
+
|
291
|
+
Abstract Feature Branch comes with a rake task to beautify feature files that have grown unorganized by sorting features
|
292
|
+
by name and getting rid of extra empty lines. It does so per section, without affecting the order of the sections
|
293
|
+
themselves.
|
294
|
+
|
295
|
+
For example, here is content before and after beautification.
|
296
|
+
|
297
|
+
Before:
|
298
|
+
|
299
|
+
> defaults: &defaults
|
300
|
+
>
|
301
|
+
>
|
302
|
+
> gallery: true
|
303
|
+
>
|
304
|
+
> carousel: true
|
305
|
+
>
|
306
|
+
> third_party_integration: false
|
307
|
+
> caching: true
|
308
|
+
>
|
309
|
+
> development:
|
310
|
+
> <<: *defaults
|
311
|
+
>
|
312
|
+
> test:
|
313
|
+
> <<: *defaults
|
314
|
+
>
|
315
|
+
> caching: false
|
316
|
+
>
|
317
|
+
> staging:
|
318
|
+
> <<: *defaults
|
319
|
+
> third_party_integration: true
|
320
|
+
> caching: true
|
321
|
+
>
|
322
|
+
> production:
|
323
|
+
> <<: *defaults
|
324
|
+
> third_party_integration: false
|
325
|
+
>
|
326
|
+
> caching: false
|
327
|
+
|
328
|
+
After:
|
329
|
+
|
330
|
+
> defaults: &defaults
|
331
|
+
> caching: true
|
332
|
+
> carousel: true
|
333
|
+
> gallery: true
|
334
|
+
> third_party_integration: false
|
335
|
+
>
|
336
|
+
> development:
|
337
|
+
> <<: *defaults
|
338
|
+
>
|
339
|
+
> test:
|
340
|
+
> <<: *defaults
|
341
|
+
> caching: false
|
342
|
+
>
|
343
|
+
> staging:
|
344
|
+
> <<: *defaults
|
345
|
+
> caching: true
|
346
|
+
> third_party_integration: true
|
347
|
+
>
|
348
|
+
> production:
|
349
|
+
> <<: *defaults
|
350
|
+
> caching: false
|
351
|
+
> third_party_integration: false
|
352
|
+
|
353
|
+
This is very useful in bigger applications that have scores of features since it allows a developer to quickly scan
|
354
|
+
for alphabetical sorted feature names. Although file find is an alternative solution, having tidy organized feature
|
355
|
+
names can help increase overall team productivity in the long term.
|
356
|
+
|
357
|
+
For Rails application use, the rake task is generated under <code>lib/tasks/abstract_feature_branch.rake</code>.
|
358
|
+
|
359
|
+
For Ruby application general use, here is the content of the rake task:
|
360
|
+
|
361
|
+
> namespace :abstract_feature_branch do
|
362
|
+
>
|
363
|
+
> 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"
|
364
|
+
> task :beautify_files, :file_path do |_, args|
|
365
|
+
> AbstractFeatureBranch::FileBeautifier.process(args[:file_path])
|
366
|
+
> end
|
367
|
+
>
|
368
|
+
> end
|
369
|
+
|
370
|
+
The rake task may be invoked in a number of ways:
|
371
|
+
- <code>rake abstract_feature_branch:beautify_files</code> beautifies all feature files under [application_root]/config
|
372
|
+
- <code>rake abstract_feature_branch:beautify_files[file_path]</code> beautifies a single feature file
|
373
|
+
- <code>rake abstract_feature_branch:beautify_files[directory_path]</code> beautifies all feature files under directory path recursively
|
374
|
+
|
375
|
+
Verify after the task has been invoked that your feature file contents are to your satisfaction before committing the
|
376
|
+
task changes.
|
377
|
+
|
283
378
|
Release Notes
|
284
379
|
-------------
|
285
380
|
|
381
|
+
Version 0.8.0:
|
382
|
+
- Added rake task for beautifying feature files, sorting feature names within environment sections and eliminating extra empty lines. Added support for externalized logger.
|
383
|
+
|
286
384
|
Version 0.7.1:
|
287
385
|
- Fixed undefined method issue with using <code>AbstractFeatureBranch.load_application_features</code> to improve first use performance
|
288
386
|
|
@@ -330,7 +428,6 @@ Version 0.2.0:
|
|
330
428
|
Upcoming
|
331
429
|
--------
|
332
430
|
|
333
|
-
- Add rake task to reorder feature entries in feature.yml alphabetically
|
334
431
|
- Support runtime read of features yml in development for easy testing purposes (trading off performance)
|
335
432
|
- Support configuring per environment whether features yml is read at runtime or not (given performance trade-off)
|
336
433
|
|
@@ -353,6 +450,10 @@ Contributors
|
|
353
450
|
---------------------------------------
|
354
451
|
[Christian Nennemann](https://github.com/XORwell)
|
355
452
|
|
453
|
+
Feedback and Idea Providers
|
454
|
+
---------------------------------------
|
455
|
+
[Ben Downey](https://github.com/bnd5k)
|
456
|
+
|
356
457
|
Copyright
|
357
458
|
---------------------------------------
|
358
459
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "abstract_feature_branch"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.8.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
12
|
s.date = "2013-11-25"
|
13
|
-
s.description = "
|
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"
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
"config/features/public.local.yml",
|
29
29
|
"config/features/public.yml",
|
30
30
|
"lib/abstract_feature_branch.rb",
|
31
|
+
"lib/abstract_feature_branch/file_beautifier.rb",
|
31
32
|
"lib/ext/feature_branch.rb",
|
32
33
|
"lib/generators/abstract_feature_branch/context_generator.rb",
|
33
34
|
"lib/generators/abstract_feature_branch/install_generator.rb",
|
@@ -35,9 +36,26 @@ Gem::Specification.new do |s|
|
|
35
36
|
"lib/generators/templates/config/features.local.yml",
|
36
37
|
"lib/generators/templates/config/features.yml",
|
37
38
|
"lib/generators/templates/config/initializers/abstract_feature_branch.rb",
|
38
|
-
"
|
39
|
-
"spec/
|
40
|
-
"spec/
|
39
|
+
"lib/generators/templates/lib/tasks/abstract_feature_branch.rake",
|
40
|
+
"spec/abstract_feature_branch/file_beautifier_spec.rb",
|
41
|
+
"spec/ext/feature_branch__feature_branch_spec.rb",
|
42
|
+
"spec/ext/feature_branch__feature_enabled_spec.rb",
|
43
|
+
"spec/fixtures/application_no_config/no_config",
|
44
|
+
"spec/fixtures/application_rails_config/config/features.local.yml",
|
45
|
+
"spec/fixtures/application_rails_config/config/features.yml",
|
46
|
+
"spec/fixtures/application_ugly_config_reference/config/another_application_configuration.yml",
|
47
|
+
"spec/fixtures/application_ugly_config_reference/config/database.yml",
|
48
|
+
"spec/fixtures/application_ugly_config_reference/config/features.local.yml",
|
49
|
+
"spec/fixtures/application_ugly_config_reference/config/features.yml",
|
50
|
+
"spec/fixtures/application_ugly_config_reference/config/features/admin.local.yml",
|
51
|
+
"spec/fixtures/application_ugly_config_reference/config/features/admin.yml",
|
52
|
+
"spec/fixtures/application_ugly_config_reference/config/features/empty.local.yml",
|
53
|
+
"spec/fixtures/application_ugly_config_reference/config/features/feature_empty_config.local.yml",
|
54
|
+
"spec/fixtures/application_ugly_config_reference/config/features/including_comments.local.yml",
|
55
|
+
"spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.local.yml",
|
56
|
+
"spec/fixtures/application_ugly_config_reference/config/features/internal/wiki.yml",
|
57
|
+
"spec/fixtures/application_ugly_config_reference/config/features/public.local.yml",
|
58
|
+
"spec/fixtures/application_ugly_config_reference/config/features/public.yml"
|
41
59
|
]
|
42
60
|
s.homepage = "http://github.com/AndyObtiva/abstract_feature_branch"
|
43
61
|
s.licenses = ["MIT"]
|
@@ -50,20 +68,17 @@ Gem::Specification.new do |s|
|
|
50
68
|
|
51
69
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
70
|
s.add_runtime_dependency(%q<deep_merge>, ["= 1.0.0"])
|
53
|
-
s.add_development_dependency(%q<rspec>, ["= 2.11.0"])
|
54
|
-
s.add_development_dependency(%q<rdoc>, ["= 3.12.2"])
|
55
71
|
s.add_development_dependency(%q<jeweler>, ["= 1.8.8"])
|
72
|
+
s.add_development_dependency(%q<rspec>, ["= 2.14.1"])
|
56
73
|
else
|
57
74
|
s.add_dependency(%q<deep_merge>, ["= 1.0.0"])
|
58
|
-
s.add_dependency(%q<rspec>, ["= 2.11.0"])
|
59
|
-
s.add_dependency(%q<rdoc>, ["= 3.12.2"])
|
60
75
|
s.add_dependency(%q<jeweler>, ["= 1.8.8"])
|
76
|
+
s.add_dependency(%q<rspec>, ["= 2.14.1"])
|
61
77
|
end
|
62
78
|
else
|
63
79
|
s.add_dependency(%q<deep_merge>, ["= 1.0.0"])
|
64
|
-
s.add_dependency(%q<rspec>, ["= 2.11.0"])
|
65
|
-
s.add_dependency(%q<rdoc>, ["= 3.12.2"])
|
66
80
|
s.add_dependency(%q<jeweler>, ["= 1.8.8"])
|
81
|
+
s.add_dependency(%q<rspec>, ["= 2.14.1"])
|
67
82
|
end
|
68
83
|
end
|
69
84
|
|
data/config/features/admin.yml
CHANGED
data/config/features/public.yml
CHANGED
@@ -9,6 +9,7 @@ rescue Bundler::BundlerError => e
|
|
9
9
|
$stderr.puts "Run `bundle install` to install missing gems"
|
10
10
|
exit e.status_code
|
11
11
|
end
|
12
|
+
require 'logger' unless defined?(Rails) && Rails.logger
|
12
13
|
require 'deep_merge' unless {}.respond_to?(:deep_merge!)
|
13
14
|
|
14
15
|
module AbstractFeatureBranch
|
@@ -19,7 +20,7 @@ module AbstractFeatureBranch
|
|
19
20
|
@application_root = path
|
20
21
|
end
|
21
22
|
def self.initialize_application_root
|
22
|
-
self.application_root =
|
23
|
+
self.application_root = defined?(Rails) ? Rails.root : '.'
|
23
24
|
end
|
24
25
|
def self.application_environment
|
25
26
|
@application_environment ||= initialize_application_environment
|
@@ -28,7 +29,16 @@ module AbstractFeatureBranch
|
|
28
29
|
@application_environment = environment
|
29
30
|
end
|
30
31
|
def self.initialize_application_environment
|
31
|
-
self.application_environment =
|
32
|
+
self.application_environment = defined?(Rails) ? Rails.env.to_s : ENV['APP_ENV'] || 'development'
|
33
|
+
end
|
34
|
+
def self.logger
|
35
|
+
@logger ||= initialize_logger
|
36
|
+
end
|
37
|
+
def self.logger=(logger)
|
38
|
+
@logger = logger
|
39
|
+
end
|
40
|
+
def self.initialize_logger
|
41
|
+
self.logger = defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
|
32
42
|
end
|
33
43
|
def self.environment_variable_overrides
|
34
44
|
@environment_variable_overrides ||= load_environment_variable_overrides
|
@@ -102,8 +112,9 @@ module AbstractFeatureBranch
|
|
102
112
|
end
|
103
113
|
|
104
114
|
def self.downcase_feature_hash_keys(hash)
|
105
|
-
Hash[hash.map {|k, v| [k, v && downcase_keys(v)]}]
|
115
|
+
Hash[(hash || {}).map {|k, v| [k, v && downcase_keys(v)]}]
|
106
116
|
end
|
107
117
|
end
|
108
118
|
|
109
119
|
require File.join(File.dirname(__FILE__), 'ext', 'feature_branch')
|
120
|
+
require File.join(File.dirname(__FILE__), 'abstract_feature_branch', 'file_beautifier')
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module AbstractFeatureBranch::FileBeautifier
|
2
|
+
def self.process(file_path=nil)
|
3
|
+
if file_path.nil?
|
4
|
+
feature_directory_path = File.join(AbstractFeatureBranch.application_root, 'config', 'features')
|
5
|
+
feature_file_path = File.join(AbstractFeatureBranch.application_root, 'config', 'features.yml')
|
6
|
+
local_feature_file_path = File.join(AbstractFeatureBranch.application_root, 'config', 'features.local.yml')
|
7
|
+
process_directory(feature_directory_path)
|
8
|
+
process_file(feature_file_path)
|
9
|
+
process_file(local_feature_file_path)
|
10
|
+
else
|
11
|
+
if File.directory?(file_path)
|
12
|
+
process_directory(file_path)
|
13
|
+
else
|
14
|
+
process_file(file_path)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
AbstractFeatureBranch.logger.info "File beautification done."
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.process_directory(directory_path)
|
21
|
+
Dir.glob(File.join(directory_path, '**', '*.yml')).each do |file_path|
|
22
|
+
process_file(file_path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.process_file(file_path)
|
27
|
+
AbstractFeatureBranch.logger.info "Beautifying #{file_path}..."
|
28
|
+
file_content = nil
|
29
|
+
File.open(file_path, 'r') do |file|
|
30
|
+
file_content = file.readlines.join
|
31
|
+
end
|
32
|
+
beautified_file_content = beautify(file_content)
|
33
|
+
File.open(file_path, 'w+') do |file|
|
34
|
+
file << beautified_file_content
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.beautify(content)
|
39
|
+
#Not relying on ordered hashes for backwards compatibility with Ruby 1.8.7
|
40
|
+
sections = []
|
41
|
+
section_features = []
|
42
|
+
content.split("\n").each do |line|
|
43
|
+
if line.strip.empty? || (line.strip.start_with?('#') && !section_features.flatten.empty?)
|
44
|
+
# ignore empty line
|
45
|
+
elsif line.start_with?(" ")
|
46
|
+
section_features.last << line
|
47
|
+
else
|
48
|
+
sections << line
|
49
|
+
section_features << []
|
50
|
+
end
|
51
|
+
end
|
52
|
+
beautified_file_content = ''
|
53
|
+
sections.each_with_index do |section, i|
|
54
|
+
if section.start_with?('#')
|
55
|
+
beautified_file_content << "#{section}\n"
|
56
|
+
else
|
57
|
+
beautified_file_content << "#{section}\n"
|
58
|
+
beautified_file_content << "#{section_features[i].sort.join("\n")}\n\n"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
beautified_file_content
|
62
|
+
end
|
63
|
+
end
|