flipper 0.20.1 → 0.20.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3419ab68fa52334e5a6f71463c213a039f819439dc71c836c8c3b70b4c80270b
4
- data.tar.gz: d6ade104432d5f5eaab36f00ccd0b559ee9bd9af4772a224cb9f70d26f578062
3
+ metadata.gz: df90e63870767caa4d32363658e4515d0822a1453cc3a5325d7dbf932c326b59
4
+ data.tar.gz: 125256e9cdee5bd0e2bfe065203140eb7fa015cac56043711c7eb45bd5421aa8
5
5
  SHA512:
6
- metadata.gz: 48bc857cb049418b020bc1216de81238df104321b62c7ff3b3967dfdc8dfedf18a1779d58c84db233cc67d9058a1b7beb295e671739a232f8384cf324879b950
7
- data.tar.gz: b5e0c90341f3b0a4f61a72ee26810ccdec216f32bd7e07b022f15ca04b075eb44a53bd392afdb91d7a868d3c724c96b2a962a37ed54fd5614a3a5f385e0ac147
6
+ metadata.gz: 9598a0a2f62b5c160a8a7c81b50ed9d2bd06f6e70898037c8321f9060780875347552b66919c62b5deb40647f734efa6bef1382b0e9fb1caefe2c8f4b5eaec01
7
+ data.tar.gz: 8bb413f54398cf90e9aafc7feba144a2e15343e8a75e28ca197d52505ae4771659b3fc7bfafec899388e71c76832859396d86fa52438ba22327f6b6522ade3a5
@@ -0,0 +1,49 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ services:
7
+ redis:
8
+ image: redis
9
+ ports: ['6379:6379']
10
+ options: >-
11
+ --health-cmd "redis-cli ping"
12
+ --health-interval 10s
13
+ --health-timeout 5s
14
+ --health-retries 5
15
+ strategy:
16
+ matrix:
17
+ ruby: ['2.5', '2.6', '2.7']
18
+ env:
19
+ RAILS_VERSION: 6.0.0
20
+ SQLITE3_VERSION: 1.4.1
21
+ REDIS_URL: redis://localhost:6379/0
22
+ steps:
23
+ - name: Setup memcached
24
+ uses: KeisukeYamashita/memcached-actions@v1
25
+ - name: Start MongoDB
26
+ uses: supercharge/mongodb-github-action@1.3.0
27
+ with:
28
+ mongodb-version: 4.0
29
+ - name: Check out repository code
30
+ uses: actions/checkout@v2
31
+ - name: Do some action caching
32
+ uses: actions/cache@v1
33
+ with:
34
+ path: vendor/bundle
35
+ key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
36
+ restore-keys: |
37
+ ${{ runner.os }}-gem-
38
+ - name: Set up Ruby
39
+ uses: actions/setup-ruby@v1
40
+ with:
41
+ ruby-version: ${{ matrix.ruby }}
42
+ - name: Install libpq-dev
43
+ run: sudo apt-get -yqq install libpq-dev
44
+ - name: Install bundler
45
+ run: gem install bundler
46
+ - name: Run bundler
47
+ run: bundle install --jobs 4 --retry 3
48
+ - name: Run Rake
49
+ run: bundle exec rake
@@ -1,3 +1,10 @@
1
+ ## 0.20.2
2
+
3
+ ### Additions/Changes
4
+
5
+ * Http adapter now raises error when enable/disable/add/remove/clear fail.
6
+ * Cloud adapter sends some extra info like hostname, ruby version, etc. for debugging and decision making.
7
+
1
8
  ## 0.20.1
2
9
 
3
10
  ### Additions/Changes
@@ -35,12 +35,6 @@ module Flipper
35
35
  end
36
36
  end
37
37
 
38
- def add(feature)
39
- body = JSON.generate(name: feature.key)
40
- response = @client.post('/features', body)
41
- response.is_a?(Net::HTTPOK)
42
- end
43
-
44
38
  def get_multi(features)
45
39
  csv_keys = features.map(&:key).join(',')
46
40
  response = @client.get("/features?keys=#{csv_keys}")
@@ -87,51 +81,61 @@ module Flipper
87
81
  parsed_response['features'].map { |feature| feature['key'] }.to_set
88
82
  end
89
83
 
84
+ def add(feature)
85
+ body = JSON.generate(name: feature.key)
86
+ response = @client.post('/features', body)
87
+ raise Error, response unless response.is_a?(Net::HTTPOK)
88
+ true
89
+ end
90
+
90
91
  def remove(feature)
91
92
  response = @client.delete("/features/#{feature.key}")
92
- response.is_a?(Net::HTTPNoContent)
93
+ raise Error, response unless response.is_a?(Net::HTTPNoContent)
94
+ true
93
95
  end
94
96
 
95
97
  def enable(feature, gate, thing)
96
98
  body = request_body_for_gate(gate, thing.value.to_s)
97
99
  query_string = gate.key == :groups ? "?allow_unregistered_groups=true" : ""
98
100
  response = @client.post("/features/#{feature.key}/#{gate.key}#{query_string}", body)
99
- response.is_a?(Net::HTTPOK)
101
+ raise Error, response unless response.is_a?(Net::HTTPOK)
102
+ true
100
103
  end
101
104
 
102
105
  def disable(feature, gate, thing)
103
106
  body = request_body_for_gate(gate, thing.value.to_s)
104
107
  query_string = gate.key == :groups ? "?allow_unregistered_groups=true" : ""
105
- response =
106
- case gate.key
107
- when :percentage_of_actors, :percentage_of_time
108
- @client.post("/features/#{feature.key}/#{gate.key}#{query_string}", body)
109
- else
110
- @client.delete("/features/#{feature.key}/#{gate.key}#{query_string}", body)
111
- end
112
- response.is_a?(Net::HTTPOK)
108
+ response = case gate.key
109
+ when :percentage_of_actors, :percentage_of_time
110
+ @client.post("/features/#{feature.key}/#{gate.key}#{query_string}", body)
111
+ else
112
+ @client.delete("/features/#{feature.key}/#{gate.key}#{query_string}", body)
113
+ end
114
+ raise Error, response unless response.is_a?(Net::HTTPOK)
115
+ true
113
116
  end
114
117
 
115
118
  def clear(feature)
116
119
  response = @client.delete("/features/#{feature.key}/clear")
117
- response.is_a?(Net::HTTPNoContent)
120
+ raise Error, response unless response.is_a?(Net::HTTPNoContent)
121
+ true
118
122
  end
119
123
 
120
124
  private
121
125
 
122
126
  def request_body_for_gate(gate, value)
123
127
  data = case gate.key
124
- when :boolean
125
- {}
126
- when :groups
127
- { name: value }
128
- when :actors
129
- { flipper_id: value }
130
- when :percentage_of_actors, :percentage_of_time
131
- { percentage: value }
132
- else
133
- raise "#{gate.key} is not a valid flipper gate key"
134
- end
128
+ when :boolean
129
+ {}
130
+ when :groups
131
+ { name: value }
132
+ when :actors
133
+ { flipper_id: value }
134
+ when :percentage_of_actors, :percentage_of_time
135
+ { percentage: value }
136
+ else
137
+ raise "#{gate.key} is not a valid flipper gate key"
138
+ end
135
139
  JSON.generate(data)
136
140
  end
137
141
 
@@ -19,7 +19,7 @@ module Flipper
19
19
  # Public: Initializes a new interval synchronizer.
20
20
  #
21
21
  # synchronizer - The Synchronizer to call when the interval has passed.
22
- # interval - The Integer number of milliseconds between invocations of
22
+ # interval - The Integer number of seconds between invocations of
23
23
  # the wrapped synchronizer.
24
24
  def initialize(synchronizer, interval: nil)
25
25
  @synchronizer = synchronizer
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.20.1'.freeze
2
+ VERSION = '0.20.2'.freeze
3
3
  end
@@ -76,9 +76,9 @@ RSpec.describe Flipper::Adapters::Http do
76
76
  .to_return(status: 503, body: "", headers: {})
77
77
 
78
78
  adapter = described_class.new(url: 'http://app.com/flipper')
79
- expect do
79
+ expect {
80
80
  adapter.get(flipper[:feature_panel])
81
- end.to raise_error(Flipper::Adapters::Http::Error)
81
+ }.to raise_error(Flipper::Adapters::Http::Error)
82
82
  end
83
83
  end
84
84
 
@@ -88,9 +88,9 @@ RSpec.describe Flipper::Adapters::Http do
88
88
  .to_return(status: 503, body: "", headers: {})
89
89
 
90
90
  adapter = described_class.new(url: 'http://app.com/flipper')
91
- expect do
91
+ expect {
92
92
  adapter.get_multi([flipper[:feature_panel]])
93
- end.to raise_error(Flipper::Adapters::Http::Error)
93
+ }.to raise_error(Flipper::Adapters::Http::Error)
94
94
  end
95
95
  end
96
96
 
@@ -100,9 +100,9 @@ RSpec.describe Flipper::Adapters::Http do
100
100
  .to_return(status: 503, body: "", headers: {})
101
101
 
102
102
  adapter = described_class.new(url: 'http://app.com/flipper')
103
- expect do
103
+ expect {
104
104
  adapter.get_all
105
- end.to raise_error(Flipper::Adapters::Http::Error)
105
+ }.to raise_error(Flipper::Adapters::Http::Error)
106
106
  end
107
107
  end
108
108
 
@@ -112,9 +112,75 @@ RSpec.describe Flipper::Adapters::Http do
112
112
  .to_return(status: 503, body: "", headers: {})
113
113
 
114
114
  adapter = described_class.new(url: 'http://app.com/flipper')
115
- expect do
115
+ expect {
116
116
  adapter.features
117
- end.to raise_error(Flipper::Adapters::Http::Error)
117
+ }.to raise_error(Flipper::Adapters::Http::Error)
118
+ end
119
+ end
120
+
121
+ describe "#add" do
122
+ it "raises error when not successful" do
123
+ stub_request(:post, /app.com/)
124
+ .to_return(status: 503, body: "{}", headers: {})
125
+
126
+ adapter = described_class.new(url: 'http://app.com/flipper')
127
+ expect {
128
+ adapter.add(Flipper::Feature.new(:search, adapter))
129
+ }.to raise_error(Flipper::Adapters::Http::Error)
130
+ end
131
+ end
132
+
133
+ describe "#remove" do
134
+ it "raises error when not successful" do
135
+ stub_request(:delete, /app.com/)
136
+ .to_return(status: 503, body: "{}", headers: {})
137
+
138
+ adapter = described_class.new(url: 'http://app.com/flipper')
139
+ expect {
140
+ adapter.remove(Flipper::Feature.new(:search, adapter))
141
+ }.to raise_error(Flipper::Adapters::Http::Error)
142
+ end
143
+ end
144
+
145
+ describe "#clear" do
146
+ it "raises error when not successful" do
147
+ stub_request(:delete, /app.com/)
148
+ .to_return(status: 503, body: "{}", headers: {})
149
+
150
+ adapter = described_class.new(url: 'http://app.com/flipper')
151
+ expect {
152
+ adapter.clear(Flipper::Feature.new(:search, adapter))
153
+ }.to raise_error(Flipper::Adapters::Http::Error)
154
+ end
155
+ end
156
+
157
+ describe "#enable" do
158
+ it "raises error when not successful" do
159
+ stub_request(:post, /app.com/)
160
+ .to_return(status: 503, body: "{}", headers: {})
161
+
162
+ adapter = described_class.new(url: 'http://app.com/flipper')
163
+ feature = Flipper::Feature.new(:search, adapter)
164
+ gate = feature.gate(:boolean)
165
+ thing = gate.wrap(true)
166
+ expect {
167
+ adapter.enable(feature, gate, thing)
168
+ }.to raise_error(Flipper::Adapters::Http::Error)
169
+ end
170
+ end
171
+
172
+ describe "#disable" do
173
+ it "raises error when not successful" do
174
+ stub_request(:delete, /app.com/)
175
+ .to_return(status: 503, body: "{}", headers: {})
176
+
177
+ adapter = described_class.new(url: 'http://app.com/flipper')
178
+ feature = Flipper::Feature.new(:search, adapter)
179
+ gate = feature.gate(:boolean)
180
+ thing = gate.wrap(false)
181
+ expect {
182
+ adapter.disable(feature, gate, thing)
183
+ }.to raise_error(Flipper::Adapters::Http::Error)
118
184
  end
119
185
  end
120
186
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.1
4
+ version: 0.20.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-31 00:00:00.000000000 Z
11
+ date: 2021-01-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -18,6 +18,7 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - ".codeclimate.yml"
21
+ - ".github/workflows/ci.yml"
21
22
  - CODE_OF_CONDUCT.md
22
23
  - Changelog.md
23
24
  - Dockerfile