simple_feature_flags 1.3.0 → 1.4.1

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.
@@ -6,16 +6,18 @@ require 'yaml'
6
6
  module SimpleFeatureFlags
7
7
  # Stores feature flags in Redis.
8
8
  class RedisStorage < BaseStorage
9
- sig { override.returns(String) }
9
+ # @override
10
+ #: String
10
11
  attr_reader :file
11
12
 
12
- sig { override.returns(T::Array[String]) }
13
+ # @override
14
+ #: Array[String]
13
15
  attr_reader :mandatory_flags
14
16
 
15
- sig { returns(T.any(::Redis, ::Redis::Namespace)) }
17
+ #: (::Redis | ::Redis::Namespace)
16
18
  attr_reader :redis
17
19
 
18
- sig { params(redis: T.any(::Redis, ::Redis::Namespace), file: String).void }
20
+ #: ((::Redis | ::Redis::Namespace) redis, String file) -> void
19
21
  def initialize(redis, file)
20
22
  @file = file
21
23
  @redis = redis
@@ -25,7 +27,8 @@ module SimpleFeatureFlags
25
27
  end
26
28
 
27
29
  # Checks whether the flag is active. Returns `true`, `false`, `:globally` or `:partially`
28
- sig { override.params(feature: T.any(Symbol, String)).returns(T.any(Symbol, T::Boolean)) }
30
+ # @override
31
+ #: ((Symbol | String) feature) -> (Symbol | bool)
29
32
  def active(feature)
30
33
  case redis.hget(feature.to_s, 'active')
31
34
  when 'globally'
@@ -40,7 +43,8 @@ module SimpleFeatureFlags
40
43
  end
41
44
 
42
45
  # Checks whether the flag is active.
43
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
46
+ # @override
47
+ #: ((Symbol | String) feature) -> bool
44
48
  def active?(feature)
45
49
  return true if active(feature)
46
50
 
@@ -48,45 +52,43 @@ module SimpleFeatureFlags
48
52
  end
49
53
 
50
54
  # Checks whether the flag is inactive.
51
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
55
+ # @override
56
+ #: ((Symbol | String) feature) -> bool
52
57
  def inactive?(feature)
53
58
  !active?(feature)
54
59
  end
55
60
 
56
61
  # Checks whether the flag is active globally, for every object.
57
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
62
+ # @override
63
+ #: ((Symbol | String) feature) -> bool
58
64
  def active_globally?(feature)
59
65
  ACTIVE_GLOBALLY.include? redis.hget(feature.to_s, 'active')
60
66
  end
61
67
 
62
68
  # Checks whether the flag is inactive globally, for every object.
63
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
69
+ # @override
70
+ #: ((Symbol | String) feature) -> bool
64
71
  def inactive_globally?(feature)
65
72
  !active_globally?(feature)
66
73
  end
67
74
 
68
75
  # Checks whether the flag is active partially, only for certain objects.
69
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
76
+ # @override
77
+ #: ((Symbol | String) feature) -> bool
70
78
  def active_partially?(feature)
71
79
  ACTIVE_PARTIALLY.include? redis.hget(feature.to_s, 'active')
72
80
  end
73
81
 
74
82
  # Checks whether the flag is inactive partially, only for certain objects.
75
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
83
+ # @override
84
+ #: ((Symbol | String) feature) -> bool
76
85
  def inactive_partially?(feature)
77
86
  !active_partially?(feature)
78
87
  end
79
88
 
80
89
  # Checks whether the flag is active for the given object.
81
- sig do
82
- override
83
- .params(
84
- feature: T.any(Symbol, String),
85
- object: Object,
86
- object_id_method: Symbol,
87
- )
88
- .returns(T::Boolean)
89
- end
90
+ # @override
91
+ #: ((Symbol | String) feature, Object object, ?object_id_method: Symbol) -> bool
90
92
  def active_for?(feature, object, object_id_method: CONFIG.default_id_method)
91
93
  return false unless active?(feature)
92
94
  return true if active_globally?(feature)
@@ -100,21 +102,15 @@ module SimpleFeatureFlags
100
102
  end
101
103
 
102
104
  # Checks whether the flag is inactive for the given object.
103
- sig do
104
- override
105
- .params(
106
- feature: T.any(Symbol, String),
107
- object: Object,
108
- object_id_method: Symbol,
109
- )
110
- .returns(T::Boolean)
111
- end
105
+ # @override
106
+ #: ((Symbol | String) feature, Object object, ?object_id_method: Symbol) -> bool
112
107
  def inactive_for?(feature, object, object_id_method: CONFIG.default_id_method)
113
108
  !active_for?(feature, object, object_id_method: object_id_method)
114
109
  end
115
110
 
116
111
  # Checks whether the flag exists.
117
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
112
+ # @override
113
+ #: ((Symbol | String) feature) -> bool
118
114
  def exists?(feature)
119
115
  return false if [nil, ''].include? redis.hget(feature.to_s, 'name')
120
116
 
@@ -122,19 +118,15 @@ module SimpleFeatureFlags
122
118
  end
123
119
 
124
120
  # Returns the description of the flag if it exists.
125
- sig { override.params(feature: T.any(Symbol, String)).returns(T.nilable(String)) }
121
+ # @override
122
+ #: ((Symbol | String) feature) -> String?
126
123
  def description(feature)
127
124
  redis.hget(feature.to_s, 'description')
128
125
  end
129
126
 
130
127
  # Calls the given block if the flag is active.
131
- sig do
132
- override
133
- .params(
134
- feature: T.any(Symbol, String),
135
- block: T.proc.void,
136
- ).void
137
- end
128
+ # @override
129
+ #: ((Symbol | String) feature) { -> void } -> void
138
130
  def when_active(feature, &block)
139
131
  return unless active?(feature)
140
132
 
@@ -142,13 +134,8 @@ module SimpleFeatureFlags
142
134
  end
143
135
 
144
136
  # Calls the given block if the flag is inactive.
145
- sig do
146
- override
147
- .params(
148
- feature: T.any(Symbol, String),
149
- block: T.proc.void,
150
- ).void
151
- end
137
+ # @override
138
+ #: ((Symbol | String) feature) { -> void } -> void
152
139
  def when_inactive(feature, &block)
153
140
  return unless inactive?(feature)
154
141
 
@@ -156,13 +143,8 @@ module SimpleFeatureFlags
156
143
  end
157
144
 
158
145
  # Calls the given block if the flag is active globally.
159
- sig do
160
- override
161
- .params(
162
- feature: T.any(Symbol, String),
163
- block: T.proc.void,
164
- ).void
165
- end
146
+ # @override
147
+ #: ((Symbol | String) feature) { -> void } -> void
166
148
  def when_active_globally(feature, &block)
167
149
  return unless active_globally?(feature)
168
150
 
@@ -170,13 +152,8 @@ module SimpleFeatureFlags
170
152
  end
171
153
 
172
154
  # Calls the given block if the flag is inactive globally.
173
- sig do
174
- override
175
- .params(
176
- feature: T.any(Symbol, String),
177
- block: T.proc.void,
178
- ).void
179
- end
155
+ # @override
156
+ #: ((Symbol | String) feature) { -> void } -> void
180
157
  def when_inactive_globally(feature, &block)
181
158
  return unless inactive_globally?(feature)
182
159
 
@@ -184,13 +161,8 @@ module SimpleFeatureFlags
184
161
  end
185
162
 
186
163
  # Calls the given block if the flag is active partially.
187
- sig do
188
- override
189
- .params(
190
- feature: T.any(Symbol, String),
191
- block: T.proc.void,
192
- ).void
193
- end
164
+ # @override
165
+ #: ((Symbol | String) feature) { -> void } -> void
194
166
  def when_active_partially(feature, &block)
195
167
  return unless active_partially?(feature)
196
168
 
@@ -198,13 +170,8 @@ module SimpleFeatureFlags
198
170
  end
199
171
 
200
172
  # Calls the given block if the flag is inactive partially.
201
- sig do
202
- override
203
- .params(
204
- feature: T.any(Symbol, String),
205
- block: T.proc.void,
206
- ).void
207
- end
173
+ # @override
174
+ #: ((Symbol | String) feature) { -> void } -> void
208
175
  def when_inactive_partially(feature, &block)
209
176
  return unless inactive_partially?(feature)
210
177
 
@@ -212,15 +179,8 @@ module SimpleFeatureFlags
212
179
  end
213
180
 
214
181
  # Calls the given block if the flag is active for the given object.
215
- sig do
216
- override
217
- .params(
218
- feature: T.any(Symbol, String),
219
- object: Object,
220
- object_id_method: Symbol,
221
- block: T.proc.void,
222
- ).void
223
- end
182
+ # @override
183
+ #: ((Symbol | String) feature, Object object, ?object_id_method: Symbol) { -> void } -> void
224
184
  def when_active_for(feature, object, object_id_method: CONFIG.default_id_method, &block)
225
185
  return unless active_for?(feature, object, object_id_method: object_id_method)
226
186
 
@@ -228,15 +188,8 @@ module SimpleFeatureFlags
228
188
  end
229
189
 
230
190
  # Calls the given block if the flag is inactive for the given object.
231
- sig do
232
- override
233
- .params(
234
- feature: T.any(Symbol, String),
235
- object: Object,
236
- object_id_method: Symbol,
237
- block: T.proc.void,
238
- ).void
239
- end
191
+ # @override
192
+ #: ((Symbol | String) feature, Object object, ?object_id_method: Symbol) { -> void } -> void
240
193
  def when_inactive_for(feature, object, object_id_method: CONFIG.default_id_method, &block)
241
194
  return unless inactive_for?(feature, object, object_id_method: object_id_method)
242
195
 
@@ -244,7 +197,8 @@ module SimpleFeatureFlags
244
197
  end
245
198
 
246
199
  # Activates the given flag. Returns `false` if it does not exist.
247
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
200
+ # @override
201
+ #: ((Symbol | String) feature) -> bool
248
202
  def activate(feature)
249
203
  return false unless exists?(feature)
250
204
 
@@ -253,10 +207,24 @@ module SimpleFeatureFlags
253
207
  true
254
208
  end
255
209
 
210
+ # @override
211
+ #: [R] ((Symbol | String) feature) { -> R } -> R
212
+ def do_activate(feature, &block)
213
+ feature = feature.to_s
214
+ prev_value = redis.hget(feature, 'active')
215
+ activate(feature)
216
+ block.call
217
+ ensure
218
+ redis.hset(feature, 'active', prev_value)
219
+ end
220
+
221
+ alias do_activate_globally do_activate
222
+
256
223
  alias activate_globally activate
257
224
 
258
225
  # Activates the given flag partially. Returns `false` if it does not exist.
259
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
226
+ # @override
227
+ #: ((Symbol | String) feature) -> bool
260
228
  def activate_partially(feature)
261
229
  return false unless exists?(feature)
262
230
 
@@ -265,15 +233,20 @@ module SimpleFeatureFlags
265
233
  true
266
234
  end
267
235
 
268
- # Activates the given flag for the given objects. Returns `false` if it does not exist.
269
- sig do
270
- override
271
- .params(
272
- feature: T.any(Symbol, String),
273
- objects: Object,
274
- object_id_method: Symbol,
275
- ).void
236
+ # @override
237
+ #: [R] ((Symbol | String) feature) { -> R } -> R
238
+ def do_activate_partially(feature, &block)
239
+ feature = feature.to_s
240
+ prev_value = redis.hget(feature, 'active')
241
+ activate_partially(feature)
242
+ block.call
243
+ ensure
244
+ redis.hset(feature, 'active', prev_value)
276
245
  end
246
+
247
+ # Activates the given flag for the given objects. Returns `false` if it does not exist.
248
+ # @override
249
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
277
250
  def activate_for(feature, *objects, object_id_method: CONFIG.default_id_method)
278
251
  return false unless exists?(feature)
279
252
 
@@ -293,14 +266,8 @@ module SimpleFeatureFlags
293
266
 
294
267
  # Activates the given flag for the given objects and sets the flag as partially active.
295
268
  # Returns `false` if it does not exist.
296
- sig do
297
- override
298
- .params(
299
- feature: T.any(Symbol, String),
300
- objects: Object,
301
- object_id_method: Symbol,
302
- ).void
303
- end
269
+ # @override
270
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
304
271
  def activate_for!(feature, *objects, object_id_method: CONFIG.default_id_method)
305
272
  return false unless T.unsafe(self).activate_for(feature, *objects, object_id_method: object_id_method)
306
273
 
@@ -310,7 +277,8 @@ module SimpleFeatureFlags
310
277
  # Deactivates the given flag for all objects.
311
278
  # Resets the list of objects that this flag has been turned on for.
312
279
  # Returns `false` if it does not exist.
313
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
280
+ # @override
281
+ #: ((Symbol | String) feature) -> bool
314
282
  def deactivate!(feature)
315
283
  return false unless exists?(feature)
316
284
 
@@ -323,7 +291,8 @@ module SimpleFeatureFlags
323
291
  # Deactivates the given flag globally.
324
292
  # Does not reset the list of objects that this flag has been turned on for.
325
293
  # Returns `false` if it does not exist.
326
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
294
+ # @override
295
+ #: ((Symbol | String) feature) -> bool
327
296
  def deactivate(feature)
328
297
  return false unless exists?(feature)
329
298
 
@@ -332,6 +301,17 @@ module SimpleFeatureFlags
332
301
  true
333
302
  end
334
303
 
304
+ # @override
305
+ #: [R] ((Symbol | String) feature) { -> R } -> R
306
+ def do_deactivate(feature, &block)
307
+ feature = feature.to_s
308
+ prev_value = redis.hget(feature, 'active')
309
+ deactivate(feature)
310
+ block.call
311
+ ensure
312
+ redis.hset(feature, 'active', prev_value)
313
+ end
314
+
335
315
  # Returns a hash of Objects that the given flag is turned on for.
336
316
  # The keys are class/model names, values are arrays of IDs of instances/records.
337
317
  #
@@ -339,11 +319,8 @@ module SimpleFeatureFlags
339
319
  #
340
320
  # { "Page" => [25, 89], "Book" => [152] }
341
321
  #
342
- sig do
343
- override
344
- .params(feature: T.any(Symbol, String))
345
- .returns(T::Hash[String, T::Array[Object]])
346
- end
322
+ # @override
323
+ #: ((Symbol | String) feature) -> Hash[String, Array[Object]]
347
324
  def active_objects(feature)
348
325
  ::JSON.parse(redis.hget(feature.to_s, 'active_for_objects').to_s)
349
326
  rescue ::JSON::ParserError
@@ -351,14 +328,8 @@ module SimpleFeatureFlags
351
328
  end
352
329
 
353
330
  # Deactivates the given flag for the given objects. Returns `false` if it does not exist.
354
- sig do
355
- override
356
- .params(
357
- feature: T.any(Symbol, String),
358
- objects: Object,
359
- object_id_method: Symbol,
360
- ).void
361
- end
331
+ # @override
332
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
362
333
  def deactivate_for(feature, *objects, object_id_method: CONFIG.default_id_method)
363
334
  return false unless exists?(feature)
364
335
 
@@ -379,12 +350,8 @@ module SimpleFeatureFlags
379
350
  end
380
351
 
381
352
  # Returns the data of the flag in a hash.
382
- sig do
383
- override
384
- .params(
385
- feature: T.any(Symbol, String),
386
- ).returns(T.nilable(T::Hash[String, T.anything]))
387
- end
353
+ # @override
354
+ #: ((Symbol | String) feature) -> Hash[String, top]?
388
355
  def get(feature)
389
356
  return unless exists?(feature)
390
357
 
@@ -400,15 +367,9 @@ module SimpleFeatureFlags
400
367
  end
401
368
 
402
369
  # Adds the given feature flag.
403
- sig do
404
- override
405
- .params(
406
- feature: T.any(Symbol, String),
407
- description: String,
408
- active: T.any(String, Symbol, T::Boolean, NilClass),
409
- ).returns(T.nilable(T::Hash[String, T.anything]))
410
- end
411
- def add(feature, description, active = 'false')
370
+ # @override
371
+ #: ((Symbol | String) feature, ?String description, ?(String | Symbol | bool)? active) -> Hash[String, top]?
372
+ def add(feature, description = '', active = 'false')
412
373
  return if exists?(feature)
413
374
 
414
375
  active = if ACTIVE_GLOBALLY.include?(active)
@@ -431,12 +392,8 @@ module SimpleFeatureFlags
431
392
 
432
393
  # Removes the given feature flag.
433
394
  # Returns its data or nil if it does not exist.
434
- sig do
435
- override
436
- .params(
437
- feature: T.any(Symbol, String),
438
- ).returns(T.nilable(T::Hash[String, T.anything]))
439
- end
395
+ # @override
396
+ #: ((Symbol | String) feature) -> Hash[String, top]?
440
397
  def remove(feature)
441
398
  return unless exists?(feature)
442
399
 
@@ -447,9 +404,8 @@ module SimpleFeatureFlags
447
404
  end
448
405
 
449
406
  # Returns the data of all feature flags.
450
- sig do
451
- override.returns(T::Array[T::Hash[String, T.anything]])
452
- end
407
+ # @override
408
+ #: -> Array[Hash[String, top]]
453
409
  def all
454
410
  keys = []
455
411
  hashes = []
@@ -463,7 +419,7 @@ module SimpleFeatureFlags
463
419
  hashes
464
420
  end
465
421
 
466
- sig { returns(T.nilable(Redis::Namespace)) }
422
+ #: -> Redis::Namespace?
467
423
  def namespaced_redis
468
424
  r = redis
469
425
  return unless r.is_a?(Redis::Namespace)
@@ -4,7 +4,8 @@
4
4
  module SimpleFeatureFlags
5
5
  # Used in tests
6
6
  class TestRamStorage < RamStorage
7
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
7
+ # @override
8
+ #: ((Symbol | String) feature) -> bool
8
9
  def active?(feature)
9
10
  unless mandatory_flags.include?(feature.to_s)
10
11
  raise(FlagNotDefinedError,
@@ -1,5 +1,6 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module SimpleFeatureFlags
4
- VERSION = '1.3.0'
5
+ VERSION = '1.4.1'
5
6
  end
@@ -2,23 +2,19 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'json'
5
- require 'set'
6
5
  require 'sorbet-runtime'
7
6
 
8
7
  Dir[File.expand_path('simple_feature_flags/*.rb', __dir__)].each { |file| require file }
9
8
 
10
9
  # Tha main namespace of the `simple_feature_flags` gem.
11
10
  module SimpleFeatureFlags
12
- extend T::Sig
13
-
14
11
  NOT_PRESENT = ::Object.new.freeze
15
- UI_GEM = T.let('simple_feature_flags-ui', String)
16
- UI_CLASS_NAME = T.let('::SimpleFeatureFlags::Ui', String)
17
- WEB_UI_CLASS_NAME = T.let('::SimpleFeatureFlags::Ui::Web', String)
12
+ UI_GEM = 'simple_feature_flags-ui'
13
+ UI_CLASS_NAME = '::SimpleFeatureFlags::Ui'
14
+ WEB_UI_CLASS_NAME = '::SimpleFeatureFlags::Ui::Web'
18
15
 
19
- ACTIVE_GLOBALLY = T.let(::Set['globally', :globally, 'true', true].freeze,
20
- T::Set[T.any(String, Symbol, T::Boolean, NilClass)],)
21
- ACTIVE_PARTIALLY = T.let(::Set['partially', :partially].freeze, T::Set[T.any(String, Symbol, T::Boolean, NilClass)])
16
+ ACTIVE_GLOBALLY = ::Set['globally', :globally, 'true', true].freeze #: Set[(String | Symbol | bool | NilClass)]
17
+ ACTIVE_PARTIALLY = ::Set['partially', :partially].freeze #: Set[(String | Symbol | bool | NilClass)]
22
18
 
23
19
  class NoSuchCommandError < StandardError; end
24
20
 
@@ -26,12 +22,10 @@ module SimpleFeatureFlags
26
22
 
27
23
  class FlagNotDefinedError < StandardError; end
28
24
 
29
- CONFIG = T.let(Configuration.new, Configuration)
25
+ CONFIG = Configuration.new #: Configuration
30
26
 
31
27
  class << self
32
- extend T::Sig
33
-
34
- sig { params(block: T.proc.params(arg0: Configuration).void).returns(Configuration) }
28
+ #: { (Configuration arg0) -> void } -> Configuration
35
29
  def configure(&block)
36
30
  block.call(CONFIG)
37
31
  CONFIG
@@ -14,7 +14,7 @@ require_relative 'lib/simple_feature_flags/version'
14
14
  DESC
15
15
  spec.homepage = 'https://github.com/espago/simple_feature_flags'
16
16
  spec.license = 'MIT'
17
- spec.required_ruby_version = '>= 3.1.0'
17
+ spec.required_ruby_version = '>= 3.2.0'
18
18
 
19
19
  spec.metadata['homepage_uri'] = spec.homepage
20
20
  spec.metadata['source_code_uri'] = 'https://github.com/espago/simple_feature_flags'
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_feature_flags
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Espago
8
8
  - Mateusz Drewniak
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2024-11-15 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: sorbet-runtime
@@ -75,7 +74,6 @@ metadata:
75
74
  homepage_uri: https://github.com/espago/simple_feature_flags
76
75
  source_code_uri: https://github.com/espago/simple_feature_flags
77
76
  rubygems_mfa_required: 'true'
78
- post_install_message:
79
77
  rdoc_options: []
80
78
  require_paths:
81
79
  - lib
@@ -83,15 +81,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
81
  requirements:
84
82
  - - ">="
85
83
  - !ruby/object:Gem::Version
86
- version: 3.1.0
84
+ version: 3.2.0
87
85
  required_rubygems_version: !ruby/object:Gem::Requirement
88
86
  requirements:
89
87
  - - ">="
90
88
  - !ruby/object:Gem::Version
91
89
  version: '0'
92
90
  requirements: []
93
- rubygems_version: 3.5.22
94
- signing_key:
91
+ rubygems_version: 3.6.7
95
92
  specification_version: 4
96
93
  summary: Simple feature flag functionality for your Ruby/Rails/Sinatra app!
97
94
  test_files: []