feature 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +8 -0
- data/README.md +23 -7
- data/lib/feature/generators/install_generator.rb +16 -1
- data/lib/feature/generators/templates/feature_toggle_without_attr_accessible.rb +4 -0
- data/lib/feature/repository/yaml_repository.rb +4 -1
- data/spec/feature/active_record_repository_spec.rb +6 -6
- data/spec/feature/feature_spec.rb +24 -24
- data/spec/feature/simple_repository_spec.rb +6 -6
- data/spec/feature/testing_spec.rb +6 -6
- data/spec/feature/yaml_repository_spec.rb +37 -10
- data/spec/integration/rails/gemfiles/rails3.gemfile +4 -0
- data/spec/integration/rails/gemfiles/rails3.gemfile.lock +86 -0
- data/spec/integration/rails/gemfiles/rails4.gemfile +4 -0
- data/spec/integration/rails/gemfiles/rails4.gemfile.lock +85 -0
- data/spec/integration/rails/test-against-several-rails-versions.sh +7 -0
- data/spec/integration/rails/test-against-specific-rails-version.sh +24 -0
- metadata +31 -45
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3f9b9580a7aa39fe081df357dce3bcfaf4611ba9
|
4
|
+
data.tar.gz: 5ec1b69eb13c4c20689fd227194796e26969b4ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5d12f49a521091b2d2ad0787f33bfa4352f5db57ea3801a86088e03ea2c61ddf116e5c9cae9f6f2fb83cb560b196f47a1916455e78e293cba4f1b3b4705bd794
|
7
|
+
data.tar.gz: d84ff821a0bd30c0534ce68e971b671640881c829a46384d9f2165ea5945f1594e1db0d1264d38b1ad80caa766e8b31a775879c36faecd22f14157992ce9984d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 1.1.0 (2014-09-30)
|
2
|
+
|
3
|
+
* generator compatible with Rails 3/4 (mumoshu)
|
4
|
+
* add LICENSE (pivotalfish)
|
5
|
+
* add optional environment flag for YamlRepository (cherbst-medidata)
|
6
|
+
* documentation fixes (asmega, crackofdusk)
|
7
|
+
* update to rspec 3
|
8
|
+
|
1
9
|
## 1.0.0 (2014-03-26)
|
2
10
|
|
3
11
|
* drop ruby 1.8 support
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Feature is a battle-tested [feature toggle](http://martinfowler.com/bliki/FeatureToggle.html) library for ruby.
|
4
4
|
|
5
|
-
The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active features (symbols!). Unknown features are assumed
|
5
|
+
The feature toggle functionality has to be configured by feature repositories. A feature repository simply provides lists of active features (symbols!). Unknown features are assumed inactive.
|
6
6
|
With this approach Feature is higly configurable and not bound to a specific kind of configuration.
|
7
7
|
|
8
8
|
**NOTE:** Ruby 1.8 is only supported until version 0.7.0. Later Versions require at least Ruby 1.9.
|
@@ -28,9 +28,9 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
28
28
|
|
29
29
|
* Use Feature in your production code
|
30
30
|
|
31
|
-
Feature.active(:feature_name) # => true/false
|
31
|
+
Feature.active?(:feature_name) # => true/false
|
32
32
|
|
33
|
-
Feature.
|
33
|
+
Feature.inactive?(:feature_name) # => true/false
|
34
34
|
|
35
35
|
Feature.with(:feature_name) do
|
36
36
|
# code
|
@@ -80,7 +80,7 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
80
80
|
### Rails using YamlRepository
|
81
81
|
|
82
82
|
# File: Gemfile
|
83
|
-
gem 'feature'
|
83
|
+
gem 'feature'
|
84
84
|
|
85
85
|
# File: config/feature.yml
|
86
86
|
features:
|
@@ -96,11 +96,27 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
96
96
|
<%# Feature implementation goes here %>
|
97
97
|
<% end %>
|
98
98
|
|
99
|
+
You may also specify a Rails environment to use a new feature in development and test, but not production:
|
100
|
+
|
101
|
+
# File: config/feature.yml
|
102
|
+
development:
|
103
|
+
features:
|
104
|
+
a_new_feature: true
|
105
|
+
test:
|
106
|
+
features:
|
107
|
+
a_new_feature: true
|
108
|
+
production:
|
109
|
+
features:
|
110
|
+
a_new_feature: false
|
111
|
+
|
112
|
+
# File: config/initializers/feature.rb
|
113
|
+
repo = Feature::Repository::YamlRepository.new("#{Rails.root}/config/feature.yml", Rails.env)
|
114
|
+
Feature.set_repository repo
|
99
115
|
|
100
116
|
### Rails using ActiveRecordRepository
|
101
117
|
|
102
118
|
# File: Gemfile
|
103
|
-
gem 'feature'
|
119
|
+
gem 'feature'
|
104
120
|
|
105
121
|
# Run generator and migrations
|
106
122
|
$ rails g feature:install
|
@@ -108,8 +124,8 @@ With this approach Feature is higly configurable and not bound to a specific kin
|
|
108
124
|
|
109
125
|
# Add Features to table FeaturesToggle for example in
|
110
126
|
# File: db/schema.rb
|
111
|
-
FeatureToggle.
|
112
|
-
FeatureToggle.
|
127
|
+
FeatureToggle.create!(name: "ActiveFeature", active: true)
|
128
|
+
FeatureToggle.create!(name: "InActiveFeature", active: false)
|
113
129
|
|
114
130
|
# or in initializer
|
115
131
|
# File: config/initializers/feature.rb
|
@@ -12,8 +12,23 @@ module Feature
|
|
12
12
|
|
13
13
|
def create_model_file
|
14
14
|
template 'feature.rb', 'config/initializers/feature.rb'
|
15
|
-
template
|
15
|
+
template appropriate_feature_toggle_rb, 'app/models/feature_toggle.rb'
|
16
16
|
migration_template 'create_feature_toggles.rb', 'db/migrate/create_feature_toggles.rb'
|
17
17
|
end
|
18
|
+
|
19
|
+
def self.next_migration_number(path)
|
20
|
+
ActiveRecord::Generators::Base.next_migration_number(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def appropriate_feature_toggle_rb
|
26
|
+
# For Rails 4 + protected_attributes or Rails 3, we prefer the model with `attr_accessible` pre-populated
|
27
|
+
if ActiveRecord::Base.respond_to? :attr_accessible
|
28
|
+
'feature_toggle.rb'
|
29
|
+
else
|
30
|
+
'feature_toggle_without_attr_accessible.rb'
|
31
|
+
end
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
@@ -18,9 +18,11 @@ module Feature
|
|
18
18
|
# Constructor
|
19
19
|
#
|
20
20
|
# @param [String] yaml_file_name the yaml config filename
|
21
|
+
# @param [String] environment optional environment to use from config
|
21
22
|
#
|
22
|
-
def initialize(yaml_file_name)
|
23
|
+
def initialize(yaml_file_name, environment='')
|
23
24
|
@yaml_file_name = yaml_file_name
|
25
|
+
@environment = environment
|
24
26
|
end
|
25
27
|
|
26
28
|
# Returns list of active features
|
@@ -41,6 +43,7 @@ module Feature
|
|
41
43
|
raw_data = File.read(@yaml_file_name)
|
42
44
|
evaluated_data = ERB.new(raw_data).result
|
43
45
|
data = YAML.load(evaluated_data)
|
46
|
+
data = data[@environment] unless @environment.empty?
|
44
47
|
|
45
48
|
if !data.is_a?(Hash) or !data.has_key?('features')
|
46
49
|
raise ArgumentError, "content of #{@yaml_file_name} does not contain proper config"
|
@@ -10,14 +10,14 @@ describe Feature::Repository::ActiveRecordRepository do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should have no active features after initialization" do
|
13
|
-
@features.
|
13
|
+
allow(@features).to receive(:where) { Hash.new }
|
14
14
|
|
15
|
-
@repository.active_features.
|
15
|
+
expect(@repository.active_features).to eq([])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should add an active feature" do
|
19
|
-
@features.
|
20
|
-
@features.
|
19
|
+
expect(@features).to receive(:exists?).with("feature_a").and_return(false)
|
20
|
+
expect(@features).to receive(:new).with(name: "feature_a", active: true).and_return(double(save: true))
|
21
21
|
|
22
22
|
@repository.add_active_feature :feature_a
|
23
23
|
end
|
@@ -29,8 +29,8 @@ describe Feature::Repository::ActiveRecordRepository do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should raise an exception when adding a active feature already added as active" do
|
32
|
-
@features.
|
33
|
-
@features.
|
32
|
+
expect(@features).to receive(:new).with(name: "feature_a", active: true).and_return(double(save: true))
|
33
|
+
allow(@features).to receive(:exists?).and_return(false, true)
|
34
34
|
|
35
35
|
@repository.add_active_feature :feature_a
|
36
36
|
expect {
|
@@ -3,29 +3,29 @@ require 'spec_helper'
|
|
3
3
|
describe Feature do
|
4
4
|
context "without FeatureRepository" do
|
5
5
|
it "should raise an exception when calling active?" do
|
6
|
-
|
6
|
+
expect do
|
7
7
|
Feature.active?(:feature_a)
|
8
|
-
end.
|
8
|
+
end.to raise_error("Feature is missing Repository for obtaining feature lists")
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should raise an exception when calling inactive?" do
|
12
|
-
|
12
|
+
expect do
|
13
13
|
Feature.inactive?(:feature_a)
|
14
|
-
end.
|
14
|
+
end.to raise_error("Feature is missing Repository for obtaining feature lists")
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should raise an exception when calling with" do
|
18
|
-
|
18
|
+
expect do
|
19
19
|
Feature.with(:feature_a) do
|
20
20
|
end
|
21
|
-
end.
|
21
|
+
end.to raise_error("Feature is missing Repository for obtaining feature lists")
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should raise an exception when calling without" do
|
25
|
-
|
25
|
+
expect do
|
26
26
|
Feature.without(:feature_a) do
|
27
27
|
end
|
28
|
-
end.
|
28
|
+
end.to raise_error("Feature is missing Repository for obtaining feature lists")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -36,14 +36,14 @@ describe Feature do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should raise an exception when add repository with wrong class" do
|
39
|
-
|
39
|
+
expect do
|
40
40
|
Feature.set_repository("not a repository")
|
41
|
-
end.
|
41
|
+
end.to raise_error(ArgumentError, "given repository does not respond to active_features")
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should get active features from repository once" do
|
45
45
|
@repository.add_active_feature(:feature_a)
|
46
|
-
Feature.active?(:feature_a).
|
46
|
+
expect(Feature.active?(:feature_a)).to be_falsey
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -56,7 +56,7 @@ describe Feature do
|
|
56
56
|
it "should refresh active feature lists from repository" do
|
57
57
|
@repository.add_active_feature(:feature_a)
|
58
58
|
Feature.refresh!
|
59
|
-
Feature.active?(:feature_a).
|
59
|
+
expect(Feature.active?(:feature_a)).to be_truthy
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -68,19 +68,19 @@ describe Feature do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should affirm active feature is active" do
|
71
|
-
Feature.active?(:feature_active).
|
71
|
+
expect(Feature.active?(:feature_active)).to be_truthy
|
72
72
|
end
|
73
73
|
|
74
74
|
it "should not affirm active feature is inactive" do
|
75
|
-
Feature.inactive?(:feature_active).
|
75
|
+
expect(Feature.inactive?(:feature_active)).to be_falsey
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should affirm inactive feature is inactive" do
|
79
|
-
Feature.inactive?(:feature_inactive).
|
79
|
+
expect(Feature.inactive?(:feature_inactive)).to be_truthy
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should not affirm inactive feature is active" do
|
83
|
-
Feature.active?(:feature_inactive).
|
83
|
+
expect(Feature.active?(:feature_inactive)).to be_falsey
|
84
84
|
end
|
85
85
|
|
86
86
|
it "should call block with active feature in active list" do
|
@@ -90,7 +90,7 @@ describe Feature do
|
|
90
90
|
reached = true
|
91
91
|
end
|
92
92
|
|
93
|
-
reached.
|
93
|
+
expect(reached).to be_truthy
|
94
94
|
end
|
95
95
|
|
96
96
|
it "should not call block with active feature not in active list" do
|
@@ -100,13 +100,13 @@ describe Feature do
|
|
100
100
|
reached = true
|
101
101
|
end
|
102
102
|
|
103
|
-
reached.
|
103
|
+
expect(reached).to be_falsey
|
104
104
|
end
|
105
105
|
|
106
106
|
it "should raise exception when no block given to with" do
|
107
|
-
|
107
|
+
expect do
|
108
108
|
Feature.with(:feature_active)
|
109
|
-
end.
|
109
|
+
end.to raise_error(ArgumentError, "no block given to with")
|
110
110
|
end
|
111
111
|
|
112
112
|
it "should call block without inactive feature in inactive list" do
|
@@ -116,7 +116,7 @@ describe Feature do
|
|
116
116
|
reached = true
|
117
117
|
end
|
118
118
|
|
119
|
-
reached.
|
119
|
+
expect(reached).to be_truthy
|
120
120
|
end
|
121
121
|
|
122
122
|
it "should not call block without inactive feature in inactive list" do
|
@@ -126,13 +126,13 @@ describe Feature do
|
|
126
126
|
reached = true
|
127
127
|
end
|
128
128
|
|
129
|
-
reached.
|
129
|
+
expect(reached).to be_falsey
|
130
130
|
end
|
131
131
|
|
132
132
|
it "should raise exception when no block given to without" do
|
133
|
-
|
133
|
+
expect do
|
134
134
|
Feature.without(:feature_inactive)
|
135
|
-
end.
|
135
|
+
end.to raise_error(ArgumentError, "no block given to without")
|
136
136
|
end
|
137
137
|
|
138
138
|
describe 'switch()' do
|
@@ -8,24 +8,24 @@ describe Feature::Repository::SimpleRepository do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should have no active features after initialization" do
|
11
|
-
@repository.active_features.
|
11
|
+
expect(@repository.active_features).to eq([])
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should add an active feature" do
|
15
15
|
@repository.add_active_feature :feature_a
|
16
|
-
@repository.active_features.
|
16
|
+
expect(@repository.active_features).to eq([:feature_a])
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should raise an exception when adding not a symbol as active feature" do
|
20
|
-
|
20
|
+
expect do
|
21
21
|
@repository.add_active_feature 'feature_a'
|
22
|
-
end.
|
22
|
+
end.to raise_error(ArgumentError, "given feature feature_a is not a symbol")
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should raise an exception when adding a active feature already added as active" do
|
26
26
|
@repository.add_active_feature :feature_a
|
27
|
-
|
27
|
+
expect do
|
28
28
|
@repository.add_active_feature :feature_a
|
29
|
-
end.
|
29
|
+
end.to raise_error(ArgumentError, "feature :feature_a already added to list of active features")
|
30
30
|
end
|
31
31
|
end
|
@@ -9,22 +9,22 @@ describe "Feature testing support" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should execute code block with an deactivated feature" do
|
12
|
-
Feature.active?(:another_feature).
|
12
|
+
expect(Feature.active?(:another_feature)).to be_falsey
|
13
13
|
|
14
14
|
Feature.run_with_activated(:another_feature) do
|
15
|
-
Feature.active?(:another_feature).
|
15
|
+
expect(Feature.active?(:another_feature)).to be_truthy
|
16
16
|
end
|
17
17
|
|
18
|
-
Feature.active?(:another_feature).
|
18
|
+
expect(Feature.active?(:another_feature)).to be_falsey
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should execute code block with an deactivated feature" do
|
22
|
-
Feature.active?(:active_feature).
|
22
|
+
expect(Feature.active?(:active_feature)).to be_truthy
|
23
23
|
|
24
24
|
Feature.run_with_deactivated(:active_feature) do
|
25
|
-
Feature.active?(:active_feature).
|
25
|
+
expect(Feature.active?(:active_feature)).to be_falsey
|
26
26
|
end
|
27
27
|
|
28
|
-
Feature.active?(:active_feature).
|
28
|
+
expect(Feature.active?(:active_feature)).to be_truthy
|
29
29
|
end
|
30
30
|
end
|
@@ -25,7 +25,7 @@ EOF
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should read active features from a config file" do
|
28
|
-
@repo.active_features.
|
28
|
+
expect(@repo.active_features).to eq([:feature_a_active, :feature_b_active])
|
29
29
|
end
|
30
30
|
|
31
31
|
context "re-read config file" do
|
@@ -40,7 +40,7 @@ EOF
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should read active features new on each request" do
|
43
|
-
@repo.active_features.
|
43
|
+
expect(@repo.active_features).to eq([:feature_a_active])
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -55,7 +55,34 @@ EOF
|
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should read active features new on each request" do
|
58
|
-
@repo.active_features.
|
58
|
+
expect(@repo.active_features).to eq([])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with optional environment name" do
|
63
|
+
before(:each) do
|
64
|
+
fp = File.new(@filename, 'w')
|
65
|
+
fp.write <<"EOF";
|
66
|
+
development:
|
67
|
+
features:
|
68
|
+
feature_a: true
|
69
|
+
feature_b: true
|
70
|
+
production:
|
71
|
+
features:
|
72
|
+
feature_a: true
|
73
|
+
feature_b: false
|
74
|
+
EOF
|
75
|
+
fp.close
|
76
|
+
end
|
77
|
+
|
78
|
+
it "has two active features for development environment" do
|
79
|
+
repo = YamlRepository.new(@filename, 'development')
|
80
|
+
expect(repo.active_features).to eq([:feature_a, :feature_b])
|
81
|
+
end
|
82
|
+
|
83
|
+
it "has one active feature for production environment" do
|
84
|
+
repo = YamlRepository.new(@filename, 'production')
|
85
|
+
expect(repo.active_features).to eq([:feature_a])
|
59
86
|
end
|
60
87
|
end
|
61
88
|
|
@@ -78,16 +105,16 @@ EOF
|
|
78
105
|
end
|
79
106
|
|
80
107
|
it "should read active features from the config file" do
|
81
|
-
@repo.active_features.
|
108
|
+
expect(@repo.active_features).to eq([:feature_a_active, :feature_b_active])
|
82
109
|
end
|
83
110
|
end
|
84
111
|
end
|
85
112
|
|
86
113
|
it "should raise exception on no file found" do
|
87
114
|
repo = YamlRepository.new("/this/file/should/not/exist")
|
88
|
-
|
115
|
+
expect do
|
89
116
|
repo.active_features
|
90
|
-
end.
|
117
|
+
end.to raise_error(Errno::ENOENT, /No such file or directory/)
|
91
118
|
end
|
92
119
|
|
93
120
|
it "should raise exception on invalid yaml" do
|
@@ -97,9 +124,9 @@ EOF
|
|
97
124
|
fp.close
|
98
125
|
|
99
126
|
repo = YamlRepository.new(@filename)
|
100
|
-
|
127
|
+
expect do
|
101
128
|
repo.active_features
|
102
|
-
end.
|
129
|
+
end.to raise_error(ArgumentError, "content of #{@filename} does not contain proper config")
|
103
130
|
end
|
104
131
|
|
105
132
|
it "should raise exception on not true/false value in config" do
|
@@ -112,8 +139,8 @@ EOF
|
|
112
139
|
fp.close
|
113
140
|
|
114
141
|
repo = YamlRepository.new(@filename)
|
115
|
-
|
142
|
+
expect do
|
116
143
|
repo.active_features
|
117
|
-
end.
|
144
|
+
end.to raise_error(ArgumentError, "neither_true_or_false is not allowed value in config, use true/false")
|
118
145
|
end
|
119
146
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (3.2.19)
|
5
|
+
actionpack (= 3.2.19)
|
6
|
+
mail (~> 2.5.4)
|
7
|
+
actionpack (3.2.19)
|
8
|
+
activemodel (= 3.2.19)
|
9
|
+
activesupport (= 3.2.19)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
journey (~> 1.0.4)
|
13
|
+
rack (~> 1.4.5)
|
14
|
+
rack-cache (~> 1.2)
|
15
|
+
rack-test (~> 0.6.1)
|
16
|
+
sprockets (~> 2.2.1)
|
17
|
+
activemodel (3.2.19)
|
18
|
+
activesupport (= 3.2.19)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
activerecord (3.2.19)
|
21
|
+
activemodel (= 3.2.19)
|
22
|
+
activesupport (= 3.2.19)
|
23
|
+
arel (~> 3.0.2)
|
24
|
+
tzinfo (~> 0.3.29)
|
25
|
+
activeresource (3.2.19)
|
26
|
+
activemodel (= 3.2.19)
|
27
|
+
activesupport (= 3.2.19)
|
28
|
+
activesupport (3.2.19)
|
29
|
+
i18n (~> 0.6, >= 0.6.4)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
arel (3.0.3)
|
32
|
+
builder (3.0.4)
|
33
|
+
erubis (2.7.0)
|
34
|
+
hike (1.2.3)
|
35
|
+
i18n (0.6.11)
|
36
|
+
journey (1.0.4)
|
37
|
+
json (1.8.1)
|
38
|
+
mail (2.5.4)
|
39
|
+
mime-types (~> 1.16)
|
40
|
+
treetop (~> 1.4.8)
|
41
|
+
mime-types (1.25.1)
|
42
|
+
multi_json (1.10.1)
|
43
|
+
polyglot (0.3.5)
|
44
|
+
rack (1.4.5)
|
45
|
+
rack-cache (1.2)
|
46
|
+
rack (>= 0.4)
|
47
|
+
rack-ssl (1.3.4)
|
48
|
+
rack
|
49
|
+
rack-test (0.6.2)
|
50
|
+
rack (>= 1.0)
|
51
|
+
rails (3.2.19)
|
52
|
+
actionmailer (= 3.2.19)
|
53
|
+
actionpack (= 3.2.19)
|
54
|
+
activerecord (= 3.2.19)
|
55
|
+
activeresource (= 3.2.19)
|
56
|
+
activesupport (= 3.2.19)
|
57
|
+
bundler (~> 1.0)
|
58
|
+
railties (= 3.2.19)
|
59
|
+
railties (3.2.19)
|
60
|
+
actionpack (= 3.2.19)
|
61
|
+
activesupport (= 3.2.19)
|
62
|
+
rack-ssl (~> 1.3.2)
|
63
|
+
rake (>= 0.8.7)
|
64
|
+
rdoc (~> 3.4)
|
65
|
+
thor (>= 0.14.6, < 2.0)
|
66
|
+
rake (10.3.2)
|
67
|
+
rdoc (3.12.2)
|
68
|
+
json (~> 1.4)
|
69
|
+
sprockets (2.2.2)
|
70
|
+
hike (~> 1.2)
|
71
|
+
multi_json (~> 1.0)
|
72
|
+
rack (~> 1.0)
|
73
|
+
tilt (~> 1.1, != 1.3.0)
|
74
|
+
thor (0.19.1)
|
75
|
+
tilt (1.4.1)
|
76
|
+
treetop (1.4.15)
|
77
|
+
polyglot
|
78
|
+
polyglot (>= 0.3.1)
|
79
|
+
tzinfo (0.3.40)
|
80
|
+
|
81
|
+
PLATFORMS
|
82
|
+
ruby
|
83
|
+
|
84
|
+
DEPENDENCIES
|
85
|
+
rails (~> 3.2.19)
|
86
|
+
railties
|
@@ -0,0 +1,85 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (4.1.4)
|
5
|
+
actionpack (= 4.1.4)
|
6
|
+
actionview (= 4.1.4)
|
7
|
+
mail (~> 2.5.4)
|
8
|
+
actionpack (4.1.4)
|
9
|
+
actionview (= 4.1.4)
|
10
|
+
activesupport (= 4.1.4)
|
11
|
+
rack (~> 1.5.2)
|
12
|
+
rack-test (~> 0.6.2)
|
13
|
+
actionview (4.1.4)
|
14
|
+
activesupport (= 4.1.4)
|
15
|
+
builder (~> 3.1)
|
16
|
+
erubis (~> 2.7.0)
|
17
|
+
activemodel (4.1.4)
|
18
|
+
activesupport (= 4.1.4)
|
19
|
+
builder (~> 3.1)
|
20
|
+
activerecord (4.1.4)
|
21
|
+
activemodel (= 4.1.4)
|
22
|
+
activesupport (= 4.1.4)
|
23
|
+
arel (~> 5.0.0)
|
24
|
+
activesupport (4.1.4)
|
25
|
+
i18n (~> 0.6, >= 0.6.9)
|
26
|
+
json (~> 1.7, >= 1.7.7)
|
27
|
+
minitest (~> 5.1)
|
28
|
+
thread_safe (~> 0.1)
|
29
|
+
tzinfo (~> 1.1)
|
30
|
+
arel (5.0.1.20140414130214)
|
31
|
+
builder (3.2.2)
|
32
|
+
erubis (2.7.0)
|
33
|
+
hike (1.2.3)
|
34
|
+
i18n (0.6.11)
|
35
|
+
json (1.8.1)
|
36
|
+
mail (2.5.4)
|
37
|
+
mime-types (~> 1.16)
|
38
|
+
treetop (~> 1.4.8)
|
39
|
+
mime-types (1.25.1)
|
40
|
+
minitest (5.4.0)
|
41
|
+
multi_json (1.10.1)
|
42
|
+
polyglot (0.3.5)
|
43
|
+
rack (1.5.2)
|
44
|
+
rack-test (0.6.2)
|
45
|
+
rack (>= 1.0)
|
46
|
+
rails (4.1.4)
|
47
|
+
actionmailer (= 4.1.4)
|
48
|
+
actionpack (= 4.1.4)
|
49
|
+
actionview (= 4.1.4)
|
50
|
+
activemodel (= 4.1.4)
|
51
|
+
activerecord (= 4.1.4)
|
52
|
+
activesupport (= 4.1.4)
|
53
|
+
bundler (>= 1.3.0, < 2.0)
|
54
|
+
railties (= 4.1.4)
|
55
|
+
sprockets-rails (~> 2.0)
|
56
|
+
railties (4.1.4)
|
57
|
+
actionpack (= 4.1.4)
|
58
|
+
activesupport (= 4.1.4)
|
59
|
+
rake (>= 0.8.7)
|
60
|
+
thor (>= 0.18.1, < 2.0)
|
61
|
+
rake (10.3.2)
|
62
|
+
sprockets (2.12.1)
|
63
|
+
hike (~> 1.2)
|
64
|
+
multi_json (~> 1.0)
|
65
|
+
rack (~> 1.0)
|
66
|
+
tilt (~> 1.1, != 1.3.0)
|
67
|
+
sprockets-rails (2.1.3)
|
68
|
+
actionpack (>= 3.0)
|
69
|
+
activesupport (>= 3.0)
|
70
|
+
sprockets (~> 2.8)
|
71
|
+
thor (0.19.1)
|
72
|
+
thread_safe (0.3.4)
|
73
|
+
tilt (1.4.1)
|
74
|
+
treetop (1.4.15)
|
75
|
+
polyglot
|
76
|
+
polyglot (>= 0.3.1)
|
77
|
+
tzinfo (1.2.1)
|
78
|
+
thread_safe (~> 0.1)
|
79
|
+
|
80
|
+
PLATFORMS
|
81
|
+
ruby
|
82
|
+
|
83
|
+
DEPENDENCIES
|
84
|
+
rails (~> 4.1.4)
|
85
|
+
railties
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
BUNDLE_GEMFILE=gemfiles/rails${RAILS_VERSION}.gemfile
|
6
|
+
|
7
|
+
TESTAPP_NAME=testapp
|
8
|
+
|
9
|
+
if [ -d $TESTAPP_NAME ]; then
|
10
|
+
rm -Rf $TESTAPP_NAME
|
11
|
+
fi
|
12
|
+
|
13
|
+
bundle install
|
14
|
+
bundle exec rails new $TESTAPP_NAME --skip-bundle
|
15
|
+
|
16
|
+
unset BUNDLE_GEMFILE
|
17
|
+
|
18
|
+
echo "gem 'feature', path: '../../../..'" >> $TESTAPP_NAME/Gemfile
|
19
|
+
|
20
|
+
cd $TESTAPP_NAME
|
21
|
+
|
22
|
+
bundle install
|
23
|
+
bundle exec rails g feature:install
|
24
|
+
bundle exec rake db:migrate
|
metadata
CHANGED
@@ -1,37 +1,31 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: feature
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 0
|
9
|
-
- 0
|
10
|
-
version: 1.0.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Markus Gerdes
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2014-03-26 00:00:00 Z
|
11
|
+
date: 2014-09-30 00:00:00.000000000 Z
|
19
12
|
dependencies: []
|
20
|
-
|
21
13
|
description:
|
22
14
|
email: github@mgsnova.de
|
23
15
|
executables: []
|
24
|
-
|
25
16
|
extensions: []
|
26
|
-
|
27
17
|
extra_rdoc_files: []
|
28
|
-
|
29
|
-
|
18
|
+
files:
|
19
|
+
- CHANGELOG.md
|
20
|
+
- Gemfile
|
21
|
+
- README.md
|
22
|
+
- Rakefile
|
30
23
|
- lib/feature.rb
|
31
24
|
- lib/feature/generators/install_generator.rb
|
32
25
|
- lib/feature/generators/templates/create_feature_toggles.rb
|
33
26
|
- lib/feature/generators/templates/feature.rb
|
34
27
|
- lib/feature/generators/templates/feature_toggle.rb
|
28
|
+
- lib/feature/generators/templates/feature_toggle_without_attr_accessible.rb
|
35
29
|
- lib/feature/repository.rb
|
36
30
|
- lib/feature/repository/active_record_repository.rb
|
37
31
|
- lib/feature/repository/simple_repository.rb
|
@@ -42,43 +36,35 @@ files:
|
|
42
36
|
- spec/feature/simple_repository_spec.rb
|
43
37
|
- spec/feature/testing_spec.rb
|
44
38
|
- spec/feature/yaml_repository_spec.rb
|
39
|
+
- spec/integration/rails/gemfiles/rails3.gemfile
|
40
|
+
- spec/integration/rails/gemfiles/rails3.gemfile.lock
|
41
|
+
- spec/integration/rails/gemfiles/rails4.gemfile
|
42
|
+
- spec/integration/rails/gemfiles/rails4.gemfile.lock
|
43
|
+
- spec/integration/rails/test-against-several-rails-versions.sh
|
44
|
+
- spec/integration/rails/test-against-specific-rails-version.sh
|
45
45
|
- spec/spec_helper.rb
|
46
|
-
- Rakefile
|
47
|
-
- Gemfile
|
48
|
-
- README.md
|
49
|
-
- CHANGELOG.md
|
50
46
|
homepage: http://github.com/mgsnova/feature
|
51
|
-
licenses:
|
52
|
-
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
53
50
|
post_install_message:
|
54
51
|
rdoc_options: []
|
55
|
-
|
56
|
-
require_paths:
|
52
|
+
require_paths:
|
57
53
|
- lib
|
58
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
-
|
60
|
-
requirements:
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
61
56
|
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
version: "0"
|
67
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
-
none: false
|
69
|
-
requirements:
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
70
61
|
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
version: "0"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
76
64
|
requirements: []
|
77
|
-
|
78
65
|
rubyforge_project:
|
79
|
-
rubygems_version:
|
66
|
+
rubygems_version: 2.2.2
|
80
67
|
signing_key:
|
81
|
-
specification_version:
|
68
|
+
specification_version: 4
|
82
69
|
summary: Feature Toggle library for ruby
|
83
70
|
test_files: []
|
84
|
-
|