green_flag 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +138 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +43 -0
  7. data/Rakefile +38 -0
  8. data/app/assets/images/green_flag/.gitkeep +0 -0
  9. data/app/assets/javascripts/green_flag/admin/features.js +353 -0
  10. data/app/assets/javascripts/green_flag/admin/rules.js +2 -0
  11. data/app/assets/javascripts/green_flag/application.js +14 -0
  12. data/app/assets/stylesheets/green_flag/admin/features.css.scss +36 -0
  13. data/app/assets/stylesheets/green_flag/admin/rules.css.scss +3 -0
  14. data/app/assets/stylesheets/green_flag/application.css +13 -0
  15. data/app/controllers/green_flag/admin/feature_decision_summaries_controller.rb +33 -0
  16. data/app/controllers/green_flag/admin/features_controller.rb +32 -0
  17. data/app/controllers/green_flag/admin/rule_lists_controller.rb +28 -0
  18. data/app/controllers/green_flag/admin/white_list_users_controller.rb +39 -0
  19. data/app/controllers/green_flag/site_visitor_management.rb +51 -0
  20. data/app/helpers/green_flag/application_helper.rb +4 -0
  21. data/app/models/green_flag/feature.rb +84 -0
  22. data/app/models/green_flag/feature_decision.rb +77 -0
  23. data/app/models/green_flag/feature_event.rb +9 -0
  24. data/app/models/green_flag/rule.rb +66 -0
  25. data/app/models/green_flag/site_visitor.rb +49 -0
  26. data/app/models/green_flag/user_group.rb +8 -0
  27. data/app/models/green_flag/visitor_group.rb +60 -0
  28. data/app/views/green_flag/admin/features/index.html.erb +14 -0
  29. data/app/views/green_flag/admin/features/show.html.erb +144 -0
  30. data/app/views/layouts/green_flag/application.html.erb +25 -0
  31. data/config/routes.rb +12 -0
  32. data/db/migrate/20140502112602_create_green_flag_site_visitors.rb +9 -0
  33. data/db/migrate/20140502221059_create_green_flag_features.rb +10 -0
  34. data/db/migrate/20140502221423_create_green_flag_feature_decisions.rb +13 -0
  35. data/db/migrate/20140505204611_add_visitor_code_to_site_visitors.rb +8 -0
  36. data/db/migrate/20140511045110_create_green_flag_rules.rb +12 -0
  37. data/db/migrate/20140513203728_set_default_percentage_in_green_flag_rules.rb +10 -0
  38. data/db/migrate/20140514202337_require_ordering_for_green_flag_rules.rb +13 -0
  39. data/db/migrate/20140516214909_add_restrictions_to_green_flag_rules.rb +13 -0
  40. data/db/migrate/20150211214159_create_green_flag_feature_events.rb +13 -0
  41. data/db/migrate/20150213191101_add_rule_id_to_green_flag_feature_decisions.rb +5 -0
  42. data/db/migrate/20150218035000_add_version_number_to_green_flag_rules.rb +9 -0
  43. data/db/migrate/20150218035805_add_version_number_to_green_flag_features.rb +9 -0
  44. data/db/migrate/20150218171852_add_version_number_to_green_flag_rules_indices.rb +19 -0
  45. data/green_flag.gemspec +34 -0
  46. data/green_flag.png +0 -0
  47. data/green_flag_small.png +0 -0
  48. data/lib/green_flag/engine.rb +16 -0
  49. data/lib/green_flag/version.rb +3 -0
  50. data/lib/green_flag.rb +4 -0
  51. data/lib/tasks/green_flag_tasks.rake +4 -0
  52. data/script/rails +8 -0
  53. data/spec/controllers/admin/feature_decision_summaries_controller_spec.rb +17 -0
  54. data/spec/controllers/admin/features_controller_spec.rb +21 -0
  55. data/spec/controllers/admin/rule_lists_controller_spec.rb +25 -0
  56. data/spec/controllers/admin/white_list_users_controller_spec.rb +15 -0
  57. data/spec/controllers/site_visitor_management_spec.rb +54 -0
  58. data/spec/dummy/README.rdoc +261 -0
  59. data/spec/dummy/Rakefile +7 -0
  60. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  61. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  62. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  63. data/spec/dummy/app/controllers/feature_check_controller.rb +10 -0
  64. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  65. data/spec/dummy/app/mailers/.gitkeep +0 -0
  66. data/spec/dummy/app/models/.gitkeep +0 -0
  67. data/spec/dummy/app/models/user.rb +3 -0
  68. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  69. data/spec/dummy/config/application.rb +65 -0
  70. data/spec/dummy/config/boot.rb +10 -0
  71. data/spec/dummy/config/database.yml +43 -0
  72. data/spec/dummy/config/environment.rb +5 -0
  73. data/spec/dummy/config/environments/development.rb +37 -0
  74. data/spec/dummy/config/environments/production.rb +67 -0
  75. data/spec/dummy/config/environments/test.rb +37 -0
  76. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  77. data/spec/dummy/config/initializers/inflections.rb +15 -0
  78. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  79. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  80. data/spec/dummy/config/initializers/session_store.rb +8 -0
  81. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  82. data/spec/dummy/config/locales/en.yml +5 -0
  83. data/spec/dummy/config/routes.rb +6 -0
  84. data/spec/dummy/config.ru +4 -0
  85. data/spec/dummy/db/migrate/20150726195118_create_users.rb +8 -0
  86. data/spec/dummy/db/migrate/20150726204409_add_email_to_users.rb +5 -0
  87. data/spec/dummy/db/schema.rb +78 -0
  88. data/spec/dummy/lib/assets/.gitkeep +0 -0
  89. data/spec/dummy/log/.gitkeep +0 -0
  90. data/spec/dummy/log/development.log +8341 -0
  91. data/spec/dummy/log/test.log +34578 -0
  92. data/spec/dummy/public/404.html +26 -0
  93. data/spec/dummy/public/422.html +26 -0
  94. data/spec/dummy/public/500.html +25 -0
  95. data/spec/dummy/public/favicon.ico +0 -0
  96. data/spec/dummy/script/rails +6 -0
  97. data/spec/dummy/tmp/cache/assets/C47/3D0/sprockets%2F8f17c33229239b023190617bf2e915a3 +0 -0
  98. data/spec/dummy/tmp/cache/assets/C81/770/sprockets%2Fdbcf34796b062155788f0b550808541a +0 -0
  99. data/spec/dummy/tmp/cache/assets/C89/D60/sprockets%2F73cd073739a0655341b7278fae57518f +0 -0
  100. data/spec/dummy/tmp/cache/assets/CB6/8F0/sprockets%2F5ea0f1f2583683678e122a9a9391a80f +0 -0
  101. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  102. data/spec/dummy/tmp/cache/assets/CE7/FF0/sprockets%2Fe45f3a7675a8c5a5b064117792bf5e28 +0 -0
  103. data/spec/dummy/tmp/cache/assets/D07/670/sprockets%2F761d03a66b753d628feccd12072c814c +0 -0
  104. data/spec/dummy/tmp/cache/assets/D10/860/sprockets%2F4582878dbb5b72bfa76615d31b34ed51 +0 -0
  105. data/spec/dummy/tmp/cache/assets/D13/270/sprockets%2F701a30cd450ae3cfa114092bafc16004 +0 -0
  106. data/spec/dummy/tmp/cache/assets/D15/C10/sprockets%2F6f42f843c916d7864a0dfa912fb3194a +0 -0
  107. data/spec/dummy/tmp/cache/assets/D18/860/sprockets%2Fce00769800ae939cebb28501947ea96f +0 -0
  108. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  109. data/spec/dummy/tmp/cache/assets/D4A/970/sprockets%2F2a7d3b403cbdd8b59d57d26964ea5768 +0 -0
  110. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  111. data/spec/dummy/tmp/cache/assets/D59/090/sprockets%2F88788ba6a64e6279624e5c2ff7eead53 +0 -0
  112. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  113. data/spec/dummy/tmp/cache/assets/D5C/330/sprockets%2Fd1b1c9a53f4a8a5827e5b02bf0e100e8 +0 -0
  114. data/spec/dummy/tmp/cache/assets/D68/760/sprockets%2Fea24808c41a3dff75b995b0f090e1a6a +0 -0
  115. data/spec/dummy/tmp/cache/assets/D6A/580/sprockets%2F18c12847aa1bb46ce9b5661f0e9e5fb0 +0 -0
  116. data/spec/dummy/tmp/cache/assets/DA1/210/sprockets%2F25a2979e392c8bc3adce7075cf19ab4b +0 -0
  117. data/spec/dummy/tmp/cache/assets/DA9/2C0/sprockets%2Ff95d82b2bbb6db8ffe1a87f67b415291 +0 -0
  118. data/spec/dummy/tmp/cache/assets/DB2/0C0/sprockets%2F95cf35cd3e97774df3c41ee0ef564a8d +0 -0
  119. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  120. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  121. data/spec/dummy/tmp/cache/assets/E07/200/sprockets%2F82a8ce7f5bcfb07f773df4cbfeb04762 +0 -0
  122. data/spec/dummy/tmp/cache/assets/E34/D30/sprockets%2F99c2d0bbd78f1b867beeb3a2eefda618 +0 -0
  123. data/spec/factories/green_flag/feature.rb +7 -0
  124. data/spec/factories/green_flag/rule.rb +9 -0
  125. data/spec/features/admin_spec.rb +16 -0
  126. data/spec/features/visitor_spec.rb +36 -0
  127. data/spec/models/green_flag/feature_decision_spec.rb +102 -0
  128. data/spec/models/green_flag/feature_event_spec.rb +4 -0
  129. data/spec/models/green_flag/feature_spec.rb +135 -0
  130. data/spec/models/green_flag/rule_spec.rb +107 -0
  131. data/spec/models/green_flag/site_visitor_spec.rb +95 -0
  132. data/spec/models/green_flag/user_group_spec.rb +24 -0
  133. data/spec/models/green_flag/visitor_group_spec.rb +81 -0
  134. data/spec/spec_helper.rb +20 -0
  135. data/spec/support/controller_helpers.rb +7 -0
  136. metadata +359 -0
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe GreenFlag::SiteVisitor do
4
+
5
+ let(:site_visitor) { GreenFlag::SiteVisitor.create(visitor_code: 'asdf') }
6
+ let(:older_user) { User.new(created_at: (site_visitor.created_at-1)) }
7
+ let(:newer_user) { User.new(created_at: (site_visitor.created_at+1)) }
8
+
9
+ describe '#first_visited_at' do
10
+ subject { site_visitor.first_visited_at }
11
+
12
+ context 'when the site visitor has no user' do
13
+ it { should eq(site_visitor.created_at) }
14
+ end
15
+
16
+ context 'when the site visitor has a newer user' do
17
+ before(:each) do
18
+ site_visitor.user = newer_user
19
+ end
20
+ it { should eq(site_visitor.created_at) }
21
+ end
22
+
23
+ context 'when the site visitor has an older user' do
24
+ before(:each) do
25
+ site_visitor.user = older_user
26
+ end
27
+ it { should eq(older_user.created_at) }
28
+ end
29
+ end
30
+
31
+ describe '.for_user!' do
32
+ let(:user) { double(id: 1) }
33
+ subject { GreenFlag::SiteVisitor.for_user!(user, visitor_to_check) }
34
+
35
+ context 'when there is no existing SiteVisitor for the user' do
36
+ context 'when the vistor_to_check is nil' do
37
+ let(:visitor_to_check) { nil }
38
+
39
+ it 'creates a new SiteVisitor' do
40
+ expect { subject }.to change { GreenFlag::SiteVisitor.count }.by(1)
41
+ end
42
+ it 'assigns the new SiteVisitor to the user' do
43
+ expect(subject.user_id).to eq(user.id)
44
+ end
45
+ end
46
+ context 'when the vistor_to_check is a visitor with no user' do
47
+ let!(:visitor_to_check) { site_visitor }
48
+
49
+ it 'does not create a new SiteVisitor' do
50
+ expect { subject }.to_not change { GreenFlag::SiteVisitor.count }
51
+ end
52
+ it 'assigns the new SiteVisitor to the user' do
53
+ expect(subject.user_id).to eq(user.id)
54
+ end
55
+ end
56
+ context 'when the vistor_to_check is a visitor with a different user' do
57
+ let!(:visitor_to_check) { GreenFlag::SiteVisitor.create(visitor_code: 'asdf', user_id: (user.id+1)) }
58
+
59
+ it 'creates a new SiteVisitor' do
60
+ expect { subject }.to change { GreenFlag::SiteVisitor.count }.by(1)
61
+ end
62
+ it 'does not change the visitor_to_check' do
63
+ expect(visitor_to_check.user_id).to_not eq(user.id)
64
+ end
65
+ end
66
+ end
67
+ context 'when a SiteVisitor exists for the user' do
68
+ let!(:user_site_visitor) { GreenFlag::SiteVisitor.create(visitor_code: 'asdf2', user_id: user.id) }
69
+
70
+ context 'when the vistor_to_check is nil' do
71
+ let(:visitor_to_check) { nil }
72
+ it 'does not create a new SiteVisitor' do
73
+ expect { subject }.to_not change { GreenFlag::SiteVisitor.count }
74
+ end
75
+ it "returns the user's site visitor" do
76
+ expect(subject).to eq(user_site_visitor)
77
+ end
78
+ end
79
+ context 'when the vistor_to_check is a visitor with no user' do
80
+ let!(:visitor_to_check) { site_visitor }
81
+ it "returns the user's site visitor" do
82
+ expect(subject).to eq(user_site_visitor)
83
+ end
84
+ end
85
+ context 'when the vistor_to_check is a visitor with a different user' do
86
+ let!(:visitor_to_check) { GreenFlag::SiteVisitor.create(visitor_code: 'asdf', user_id: (user.id+1)) }
87
+
88
+ it 'does not change the visitor_to_check' do
89
+ expect(visitor_to_check.user_id).to_not eq(user.id)
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe GreenFlag::UserGroup do
4
+
5
+ let(:visitor) { double(user: nil) }
6
+
7
+ # includes noone
8
+ let(:exclusive_user_group) { GreenFlag::UserGroup.new('Foo') { false } }
9
+
10
+ # includes everyone
11
+ let(:inclusive_user_group) { GreenFlag::UserGroup.new('Foo') { true } }
12
+
13
+ describe '#includes_visitor?' do
14
+ subject { inclusive_user_group.includes_visitor?(visitor) }
15
+ context 'when the visitor has no user' do
16
+ it { should be_false }
17
+ end
18
+ context 'when the visitor has a user' do
19
+ let(:visitor) { double(user: double) }
20
+ it { should be_true }
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe GreenFlag::VisitorGroup do
4
+ before(:each) do
5
+ GreenFlag::VisitorGroup.clear!
6
+ end
7
+
8
+ describe '#define' do
9
+ it 'does not fail' do
10
+ GreenFlag::VisitorGroup.define {}
11
+ end
12
+ end
13
+
14
+ describe '#group' do
15
+ subject do
16
+ GreenFlag::VisitorGroup.group(:foo, 'desc') {}
17
+ end
18
+
19
+ it 'creates a VisitorGroup with the given attributes' do
20
+ expect(subject.key).to eq('foo')
21
+ expect(subject.description).to eq('desc')
22
+ end
23
+
24
+ it 'raises an error if there is already a group with that key' do
25
+ GreenFlag::VisitorGroup.group(:foo, 'desc') {}
26
+ expect { subject }.to raise_error GreenFlag::VisitorGroup::MultipleGroupsError
27
+ end
28
+ end
29
+
30
+ describe '#user_group' do
31
+ subject do
32
+ GreenFlag::VisitorGroup.user_group(:foo, 'desc') {}
33
+ end
34
+ it 'creates a UserGroup with the given attributes' do
35
+ expect(subject.key).to eq('foo')
36
+ expect(subject.description).to eq('desc')
37
+ expect(subject).to be_a(GreenFlag::UserGroup)
38
+ end
39
+ end
40
+
41
+ describe '#all' do
42
+ subject { GreenFlag::VisitorGroup.all }
43
+
44
+ it 'is empty by default' do
45
+ expect(subject).to be_empty
46
+ end
47
+ it 'includes groups defined in .group' do
48
+ g1 = GreenFlag::VisitorGroup.group(:foo)
49
+ g2 = GreenFlag::VisitorGroup.group(:bar)
50
+ expect(subject).to eq([g1, g2])
51
+ end
52
+ end
53
+
54
+ describe '#for_key' do
55
+ it 'gets a group by key' do
56
+ g = GreenFlag::VisitorGroup.group(:foo)
57
+ expect(GreenFlag::VisitorGroup.for_key(:foo)).to eq(g)
58
+ end
59
+ it 'gets a group by key string' do
60
+ g = GreenFlag::VisitorGroup.group(:foo)
61
+ expect(GreenFlag::VisitorGroup.for_key('foo')).to eq(g)
62
+ end
63
+ end
64
+
65
+ describe '.includes_visitor?' do
66
+ let(:visitor) { double(:is_visitor? => true) }
67
+ let(:yes_group) { GreenFlag::VisitorGroup.group(:yes) { |v| v.is_visitor? } }
68
+ let(:no_group) { GreenFlag::VisitorGroup.group(:no) { |v| !v.is_visitor? } }
69
+
70
+ it 'is true when the block passes' do
71
+ result = yes_group.includes_visitor?(visitor)
72
+ expect(result).to be_true
73
+ end
74
+
75
+ it 'is false when the block fails' do
76
+ result = no_group.includes_visitor?(visitor)
77
+ expect(result).to be_false
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,20 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+ require 'rspec/autorun'
6
+ require 'factory_girl_rails'
7
+
8
+ Rails.backtrace_cleaner.remove_silencers!
9
+
10
+ # Load support files
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
12
+
13
+ RSpec.configure do |config|
14
+ config.mock_with :rspec
15
+ config.use_transactional_fixtures = true
16
+ config.infer_base_class_for_anonymous_controllers = false
17
+ config.order = "random"
18
+
19
+ config.include ControllerHelpers, type: :controller
20
+ end
@@ -0,0 +1,7 @@
1
+ module ControllerHelpers
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ routes { GreenFlag::Engine.routes }
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,359 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: green_flag
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Morton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.18'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.18'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord-concurrent-index
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: sass-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: factory_girl_rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: capybara
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: " A feature-flag system that makes it *really easy* for application
112
+ developers\n to add and manage features. You can roll out features to a percentage
113
+ of \n your users, or you can define groups to see the new feature. \n Want
114
+ to test a new feature on 50% of your premium-plan users named \"Fred\"? \n GreenFlag
115
+ can do that.\n"
116
+ email:
117
+ - tim@timothymorton.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - .gitignore
123
+ - Gemfile
124
+ - Gemfile.lock
125
+ - MIT-LICENSE
126
+ - README.md
127
+ - Rakefile
128
+ - app/assets/images/green_flag/.gitkeep
129
+ - app/assets/javascripts/green_flag/admin/features.js
130
+ - app/assets/javascripts/green_flag/admin/rules.js
131
+ - app/assets/javascripts/green_flag/application.js
132
+ - app/assets/stylesheets/green_flag/admin/features.css.scss
133
+ - app/assets/stylesheets/green_flag/admin/rules.css.scss
134
+ - app/assets/stylesheets/green_flag/application.css
135
+ - app/controllers/green_flag/admin/feature_decision_summaries_controller.rb
136
+ - app/controllers/green_flag/admin/features_controller.rb
137
+ - app/controllers/green_flag/admin/rule_lists_controller.rb
138
+ - app/controllers/green_flag/admin/white_list_users_controller.rb
139
+ - app/controllers/green_flag/site_visitor_management.rb
140
+ - app/helpers/green_flag/application_helper.rb
141
+ - app/models/green_flag/feature.rb
142
+ - app/models/green_flag/feature_decision.rb
143
+ - app/models/green_flag/feature_event.rb
144
+ - app/models/green_flag/rule.rb
145
+ - app/models/green_flag/site_visitor.rb
146
+ - app/models/green_flag/user_group.rb
147
+ - app/models/green_flag/visitor_group.rb
148
+ - app/views/green_flag/admin/features/index.html.erb
149
+ - app/views/green_flag/admin/features/show.html.erb
150
+ - app/views/layouts/green_flag/application.html.erb
151
+ - config/routes.rb
152
+ - db/migrate/20140502112602_create_green_flag_site_visitors.rb
153
+ - db/migrate/20140502221059_create_green_flag_features.rb
154
+ - db/migrate/20140502221423_create_green_flag_feature_decisions.rb
155
+ - db/migrate/20140505204611_add_visitor_code_to_site_visitors.rb
156
+ - db/migrate/20140511045110_create_green_flag_rules.rb
157
+ - db/migrate/20140513203728_set_default_percentage_in_green_flag_rules.rb
158
+ - db/migrate/20140514202337_require_ordering_for_green_flag_rules.rb
159
+ - db/migrate/20140516214909_add_restrictions_to_green_flag_rules.rb
160
+ - db/migrate/20150211214159_create_green_flag_feature_events.rb
161
+ - db/migrate/20150213191101_add_rule_id_to_green_flag_feature_decisions.rb
162
+ - db/migrate/20150218035000_add_version_number_to_green_flag_rules.rb
163
+ - db/migrate/20150218035805_add_version_number_to_green_flag_features.rb
164
+ - db/migrate/20150218171852_add_version_number_to_green_flag_rules_indices.rb
165
+ - green_flag.gemspec
166
+ - green_flag.png
167
+ - green_flag_small.png
168
+ - lib/green_flag.rb
169
+ - lib/green_flag/engine.rb
170
+ - lib/green_flag/version.rb
171
+ - lib/tasks/green_flag_tasks.rake
172
+ - script/rails
173
+ - spec/controllers/admin/feature_decision_summaries_controller_spec.rb
174
+ - spec/controllers/admin/features_controller_spec.rb
175
+ - spec/controllers/admin/rule_lists_controller_spec.rb
176
+ - spec/controllers/admin/white_list_users_controller_spec.rb
177
+ - spec/controllers/site_visitor_management_spec.rb
178
+ - spec/dummy/README.rdoc
179
+ - spec/dummy/Rakefile
180
+ - spec/dummy/app/assets/javascripts/application.js
181
+ - spec/dummy/app/assets/stylesheets/application.css
182
+ - spec/dummy/app/controllers/application_controller.rb
183
+ - spec/dummy/app/controllers/feature_check_controller.rb
184
+ - spec/dummy/app/helpers/application_helper.rb
185
+ - spec/dummy/app/mailers/.gitkeep
186
+ - spec/dummy/app/models/.gitkeep
187
+ - spec/dummy/app/models/user.rb
188
+ - spec/dummy/app/views/layouts/application.html.erb
189
+ - spec/dummy/config.ru
190
+ - spec/dummy/config/application.rb
191
+ - spec/dummy/config/boot.rb
192
+ - spec/dummy/config/database.yml
193
+ - spec/dummy/config/environment.rb
194
+ - spec/dummy/config/environments/development.rb
195
+ - spec/dummy/config/environments/production.rb
196
+ - spec/dummy/config/environments/test.rb
197
+ - spec/dummy/config/initializers/backtrace_silencers.rb
198
+ - spec/dummy/config/initializers/inflections.rb
199
+ - spec/dummy/config/initializers/mime_types.rb
200
+ - spec/dummy/config/initializers/secret_token.rb
201
+ - spec/dummy/config/initializers/session_store.rb
202
+ - spec/dummy/config/initializers/wrap_parameters.rb
203
+ - spec/dummy/config/locales/en.yml
204
+ - spec/dummy/config/routes.rb
205
+ - spec/dummy/db/migrate/20150726195118_create_users.rb
206
+ - spec/dummy/db/migrate/20150726204409_add_email_to_users.rb
207
+ - spec/dummy/db/schema.rb
208
+ - spec/dummy/lib/assets/.gitkeep
209
+ - spec/dummy/log/.gitkeep
210
+ - spec/dummy/log/development.log
211
+ - spec/dummy/log/test.log
212
+ - spec/dummy/public/404.html
213
+ - spec/dummy/public/422.html
214
+ - spec/dummy/public/500.html
215
+ - spec/dummy/public/favicon.ico
216
+ - spec/dummy/script/rails
217
+ - spec/dummy/tmp/cache/assets/C47/3D0/sprockets%2F8f17c33229239b023190617bf2e915a3
218
+ - spec/dummy/tmp/cache/assets/C81/770/sprockets%2Fdbcf34796b062155788f0b550808541a
219
+ - spec/dummy/tmp/cache/assets/C89/D60/sprockets%2F73cd073739a0655341b7278fae57518f
220
+ - spec/dummy/tmp/cache/assets/CB6/8F0/sprockets%2F5ea0f1f2583683678e122a9a9391a80f
221
+ - spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953
222
+ - spec/dummy/tmp/cache/assets/CE7/FF0/sprockets%2Fe45f3a7675a8c5a5b064117792bf5e28
223
+ - spec/dummy/tmp/cache/assets/D07/670/sprockets%2F761d03a66b753d628feccd12072c814c
224
+ - spec/dummy/tmp/cache/assets/D10/860/sprockets%2F4582878dbb5b72bfa76615d31b34ed51
225
+ - spec/dummy/tmp/cache/assets/D13/270/sprockets%2F701a30cd450ae3cfa114092bafc16004
226
+ - spec/dummy/tmp/cache/assets/D15/C10/sprockets%2F6f42f843c916d7864a0dfa912fb3194a
227
+ - spec/dummy/tmp/cache/assets/D18/860/sprockets%2Fce00769800ae939cebb28501947ea96f
228
+ - spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705
229
+ - spec/dummy/tmp/cache/assets/D4A/970/sprockets%2F2a7d3b403cbdd8b59d57d26964ea5768
230
+ - spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655
231
+ - spec/dummy/tmp/cache/assets/D59/090/sprockets%2F88788ba6a64e6279624e5c2ff7eead53
232
+ - spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6
233
+ - spec/dummy/tmp/cache/assets/D5C/330/sprockets%2Fd1b1c9a53f4a8a5827e5b02bf0e100e8
234
+ - spec/dummy/tmp/cache/assets/D68/760/sprockets%2Fea24808c41a3dff75b995b0f090e1a6a
235
+ - spec/dummy/tmp/cache/assets/D6A/580/sprockets%2F18c12847aa1bb46ce9b5661f0e9e5fb0
236
+ - spec/dummy/tmp/cache/assets/DA1/210/sprockets%2F25a2979e392c8bc3adce7075cf19ab4b
237
+ - spec/dummy/tmp/cache/assets/DA9/2C0/sprockets%2Ff95d82b2bbb6db8ffe1a87f67b415291
238
+ - spec/dummy/tmp/cache/assets/DB2/0C0/sprockets%2F95cf35cd3e97774df3c41ee0ef564a8d
239
+ - spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994
240
+ - spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af
241
+ - spec/dummy/tmp/cache/assets/E07/200/sprockets%2F82a8ce7f5bcfb07f773df4cbfeb04762
242
+ - spec/dummy/tmp/cache/assets/E34/D30/sprockets%2F99c2d0bbd78f1b867beeb3a2eefda618
243
+ - spec/factories/green_flag/feature.rb
244
+ - spec/factories/green_flag/rule.rb
245
+ - spec/features/admin_spec.rb
246
+ - spec/features/visitor_spec.rb
247
+ - spec/models/green_flag/feature_decision_spec.rb
248
+ - spec/models/green_flag/feature_event_spec.rb
249
+ - spec/models/green_flag/feature_spec.rb
250
+ - spec/models/green_flag/rule_spec.rb
251
+ - spec/models/green_flag/site_visitor_spec.rb
252
+ - spec/models/green_flag/user_group_spec.rb
253
+ - spec/models/green_flag/visitor_group_spec.rb
254
+ - spec/spec_helper.rb
255
+ - spec/support/controller_helpers.rb
256
+ homepage: https://github.com/websdotcom/green_flag
257
+ licenses:
258
+ - MIT
259
+ metadata: {}
260
+ post_install_message:
261
+ rdoc_options: []
262
+ require_paths:
263
+ - lib
264
+ required_ruby_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - '>='
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
269
+ required_rubygems_version: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - '>='
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ requirements: []
275
+ rubyforge_project:
276
+ rubygems_version: 2.4.8
277
+ signing_key:
278
+ specification_version: 4
279
+ summary: A feature-flag system.
280
+ test_files:
281
+ - spec/controllers/admin/feature_decision_summaries_controller_spec.rb
282
+ - spec/controllers/admin/features_controller_spec.rb
283
+ - spec/controllers/admin/rule_lists_controller_spec.rb
284
+ - spec/controllers/admin/white_list_users_controller_spec.rb
285
+ - spec/controllers/site_visitor_management_spec.rb
286
+ - spec/dummy/app/assets/javascripts/application.js
287
+ - spec/dummy/app/assets/stylesheets/application.css
288
+ - spec/dummy/app/controllers/application_controller.rb
289
+ - spec/dummy/app/controllers/feature_check_controller.rb
290
+ - spec/dummy/app/helpers/application_helper.rb
291
+ - spec/dummy/app/models/user.rb
292
+ - spec/dummy/app/views/layouts/application.html.erb
293
+ - spec/dummy/config/application.rb
294
+ - spec/dummy/config/boot.rb
295
+ - spec/dummy/config/database.yml
296
+ - spec/dummy/config/environment.rb
297
+ - spec/dummy/config/environments/development.rb
298
+ - spec/dummy/config/environments/production.rb
299
+ - spec/dummy/config/environments/test.rb
300
+ - spec/dummy/config/initializers/backtrace_silencers.rb
301
+ - spec/dummy/config/initializers/inflections.rb
302
+ - spec/dummy/config/initializers/mime_types.rb
303
+ - spec/dummy/config/initializers/secret_token.rb
304
+ - spec/dummy/config/initializers/session_store.rb
305
+ - spec/dummy/config/initializers/wrap_parameters.rb
306
+ - spec/dummy/config/locales/en.yml
307
+ - spec/dummy/config/routes.rb
308
+ - spec/dummy/config.ru
309
+ - spec/dummy/db/migrate/20150726195118_create_users.rb
310
+ - spec/dummy/db/migrate/20150726204409_add_email_to_users.rb
311
+ - spec/dummy/db/schema.rb
312
+ - spec/dummy/log/development.log
313
+ - spec/dummy/log/test.log
314
+ - spec/dummy/public/404.html
315
+ - spec/dummy/public/422.html
316
+ - spec/dummy/public/500.html
317
+ - spec/dummy/public/favicon.ico
318
+ - spec/dummy/Rakefile
319
+ - spec/dummy/README.rdoc
320
+ - spec/dummy/script/rails
321
+ - spec/dummy/tmp/cache/assets/C47/3D0/sprockets%2F8f17c33229239b023190617bf2e915a3
322
+ - spec/dummy/tmp/cache/assets/C81/770/sprockets%2Fdbcf34796b062155788f0b550808541a
323
+ - spec/dummy/tmp/cache/assets/C89/D60/sprockets%2F73cd073739a0655341b7278fae57518f
324
+ - spec/dummy/tmp/cache/assets/CB6/8F0/sprockets%2F5ea0f1f2583683678e122a9a9391a80f
325
+ - spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953
326
+ - spec/dummy/tmp/cache/assets/CE7/FF0/sprockets%2Fe45f3a7675a8c5a5b064117792bf5e28
327
+ - spec/dummy/tmp/cache/assets/D07/670/sprockets%2F761d03a66b753d628feccd12072c814c
328
+ - spec/dummy/tmp/cache/assets/D10/860/sprockets%2F4582878dbb5b72bfa76615d31b34ed51
329
+ - spec/dummy/tmp/cache/assets/D13/270/sprockets%2F701a30cd450ae3cfa114092bafc16004
330
+ - spec/dummy/tmp/cache/assets/D15/C10/sprockets%2F6f42f843c916d7864a0dfa912fb3194a
331
+ - spec/dummy/tmp/cache/assets/D18/860/sprockets%2Fce00769800ae939cebb28501947ea96f
332
+ - spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705
333
+ - spec/dummy/tmp/cache/assets/D4A/970/sprockets%2F2a7d3b403cbdd8b59d57d26964ea5768
334
+ - spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655
335
+ - spec/dummy/tmp/cache/assets/D59/090/sprockets%2F88788ba6a64e6279624e5c2ff7eead53
336
+ - spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6
337
+ - spec/dummy/tmp/cache/assets/D5C/330/sprockets%2Fd1b1c9a53f4a8a5827e5b02bf0e100e8
338
+ - spec/dummy/tmp/cache/assets/D68/760/sprockets%2Fea24808c41a3dff75b995b0f090e1a6a
339
+ - spec/dummy/tmp/cache/assets/D6A/580/sprockets%2F18c12847aa1bb46ce9b5661f0e9e5fb0
340
+ - spec/dummy/tmp/cache/assets/DA1/210/sprockets%2F25a2979e392c8bc3adce7075cf19ab4b
341
+ - spec/dummy/tmp/cache/assets/DA9/2C0/sprockets%2Ff95d82b2bbb6db8ffe1a87f67b415291
342
+ - spec/dummy/tmp/cache/assets/DB2/0C0/sprockets%2F95cf35cd3e97774df3c41ee0ef564a8d
343
+ - spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994
344
+ - spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af
345
+ - spec/dummy/tmp/cache/assets/E07/200/sprockets%2F82a8ce7f5bcfb07f773df4cbfeb04762
346
+ - spec/dummy/tmp/cache/assets/E34/D30/sprockets%2F99c2d0bbd78f1b867beeb3a2eefda618
347
+ - spec/factories/green_flag/feature.rb
348
+ - spec/factories/green_flag/rule.rb
349
+ - spec/features/admin_spec.rb
350
+ - spec/features/visitor_spec.rb
351
+ - spec/models/green_flag/feature_decision_spec.rb
352
+ - spec/models/green_flag/feature_event_spec.rb
353
+ - spec/models/green_flag/feature_spec.rb
354
+ - spec/models/green_flag/rule_spec.rb
355
+ - spec/models/green_flag/site_visitor_spec.rb
356
+ - spec/models/green_flag/user_group_spec.rb
357
+ - spec/models/green_flag/visitor_group_spec.rb
358
+ - spec/spec_helper.rb
359
+ - spec/support/controller_helpers.rb