simple_feature_flags 1.4.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 memory.
8
8
  class RamStorage < 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::Hash[Symbol, T::Hash[String, Object]]) }
17
+ #: Hash[Symbol, Hash[String, Object]]
16
18
  attr_reader :flags
17
19
 
18
- sig { params(file: String).void }
20
+ #: (String file) -> void
19
21
  def initialize(file)
20
22
  @file = file
21
23
  @mandatory_flags = []
@@ -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 flags.dig(feature.to_sym, 'active')
31
34
  when 'globally', :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? T.unsafe(flags.dig(feature.to_sym, '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? T.unsafe(flags.dig(feature.to_sym, '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? flags[feature.to_sym]
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
- T.unsafe(flags.dig(feature.to_sym, 'description'))
124
+ flags.dig(feature.to_sym, 'description') #: as untyped
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,11 +197,12 @@ 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
 
251
- flag = T.must flags[feature.to_sym]
205
+ flag = flags[feature.to_sym] #: as !nil
252
206
  flag['active'] = 'globally'
253
207
 
254
208
  true
@@ -256,15 +210,8 @@ module SimpleFeatureFlags
256
210
 
257
211
  alias activate_globally activate
258
212
 
259
- sig do
260
- override
261
- .type_parameters(:R)
262
- .params(
263
- feature: T.any(Symbol, String),
264
- block: T.proc.returns(T.type_parameter(:R)),
265
- )
266
- .returns(T.type_parameter(:R))
267
- end
213
+ # @override
214
+ #: [R] ((Symbol | String) feature) { -> R } -> R
268
215
  def do_activate(feature, &block)
269
216
  feature = feature.to_sym
270
217
  prev_value = flags.dig(feature, 'active')
@@ -277,25 +224,19 @@ module SimpleFeatureFlags
277
224
  alias do_activate_globally do_activate
278
225
 
279
226
  # Activates the given flag partially. Returns `false` if it does not exist.
280
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
227
+ # @override
228
+ #: ((Symbol | String) feature) -> bool
281
229
  def activate_partially(feature)
282
230
  return false unless exists?(feature)
283
231
 
284
- flag = T.must flags[feature.to_sym]
232
+ flag = flags[feature.to_sym] #: as !nil
285
233
  flag['active'] = 'partially'
286
234
 
287
235
  true
288
236
  end
289
237
 
290
- sig do
291
- override
292
- .type_parameters(:R)
293
- .params(
294
- feature: T.any(Symbol, String),
295
- block: T.proc.returns(T.type_parameter(:R)),
296
- )
297
- .returns(T.type_parameter(:R))
298
- end
238
+ # @override
239
+ #: [R] ((Symbol | String) feature) { -> R } -> R
299
240
  def do_activate_partially(feature, &block)
300
241
  feature = feature.to_sym
301
242
  prev_value = flags.dig(feature, 'active')
@@ -306,14 +247,8 @@ module SimpleFeatureFlags
306
247
  end
307
248
 
308
249
  # Activates the given flag for the given objects. Returns `false` if it does not exist.
309
- sig do
310
- override
311
- .params(
312
- feature: T.any(Symbol, String),
313
- objects: Object,
314
- object_id_method: Symbol,
315
- ).void
316
- end
250
+ # @override
251
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
317
252
  def activate_for(feature, *objects, object_id_method: CONFIG.default_id_method)
318
253
  return false unless exists?(feature)
319
254
 
@@ -326,7 +261,7 @@ module SimpleFeatureFlags
326
261
  active_objects_hash[klass]&.concat(ids)&.uniq!&.sort! # rubocop:disable Style/SafeNavigationChainLength
327
262
  end
328
263
 
329
- flag = T.must flags[feature.to_sym]
264
+ flag = flags[feature.to_sym] #: as !nil
330
265
  flag['active_for_objects'] = active_objects_hash
331
266
 
332
267
  true
@@ -334,14 +269,8 @@ module SimpleFeatureFlags
334
269
 
335
270
  # Activates the given flag for the given objects and sets the flag as partially active.
336
271
  # Returns `false` if it does not exist.
337
- sig do
338
- override
339
- .params(
340
- feature: T.any(Symbol, String),
341
- objects: Object,
342
- object_id_method: Symbol,
343
- ).void
344
- end
272
+ # @override
273
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
345
274
  def activate_for!(feature, *objects, object_id_method: CONFIG.default_id_method)
346
275
  return false unless T.unsafe(self).activate_for(feature, *objects, object_id_method: object_id_method)
347
276
 
@@ -351,11 +280,12 @@ module SimpleFeatureFlags
351
280
  # Deactivates the given flag for all objects.
352
281
  # Resets the list of objects that this flag has been turned on for.
353
282
  # Returns `false` if it does not exist.
354
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
283
+ # @override
284
+ #: ((Symbol | String) feature) -> bool
355
285
  def deactivate!(feature)
356
286
  return false unless exists?(feature)
357
287
 
358
- flag = T.must flags[feature.to_sym]
288
+ flag = flags[feature.to_sym] #: as !nil
359
289
  flag['active'] = 'false'
360
290
  flag['active_for_objects'] = nil
361
291
 
@@ -365,16 +295,28 @@ module SimpleFeatureFlags
365
295
  # Deactivates the given flag globally.
366
296
  # Does not reset the list of objects that this flag has been turned on for.
367
297
  # Returns `false` if it does not exist.
368
- sig { override.params(feature: T.any(Symbol, String)).returns(T::Boolean) }
298
+ # @override
299
+ #: ((Symbol | String) feature) -> bool
369
300
  def deactivate(feature)
370
301
  return false unless exists?(feature)
371
302
 
372
- flag = T.must flags[feature.to_sym]
303
+ flag = flags[feature.to_sym] #: as !nil
373
304
  flag['active'] = 'false'
374
305
 
375
306
  true
376
307
  end
377
308
 
309
+ # @override
310
+ #: [R] ((Symbol | String) feature) { -> R } -> R
311
+ def do_deactivate(feature, &block)
312
+ feature = feature.to_sym
313
+ prev_value = flags.dig(feature, 'active')
314
+ deactivate(feature)
315
+ block.call
316
+ ensure
317
+ T.unsafe(flags)[feature]['active'] = prev_value
318
+ end
319
+
378
320
  # Returns a hash of Objects that the given flag is turned on for.
379
321
  # The keys are class/model names, values are arrays of IDs of instances/records.
380
322
  #
@@ -382,24 +324,15 @@ module SimpleFeatureFlags
382
324
  #
383
325
  # { "Page" => [25, 89], "Book" => [152] }
384
326
  #
385
- sig do
386
- override
387
- .params(feature: T.any(Symbol, String))
388
- .returns(T::Hash[String, T::Array[Object]])
389
- end
327
+ # @override
328
+ #: ((Symbol | String) feature) -> Hash[String, Array[Object]]
390
329
  def active_objects(feature)
391
330
  T.unsafe(flags.dig(feature.to_sym, 'active_for_objects')) || {}
392
331
  end
393
332
 
394
333
  # Deactivates the given flag for the given objects. Returns `false` if it does not exist.
395
- sig do
396
- override
397
- .params(
398
- feature: T.any(Symbol, String),
399
- objects: Object,
400
- object_id_method: Symbol,
401
- ).void
402
- end
334
+ # @override
335
+ #: ((Symbol | String) feature, *Object objects, ?object_id_method: Symbol) -> void
403
336
  def deactivate_for(feature, *objects, object_id_method: CONFIG.default_id_method)
404
337
  return false unless exists?(feature)
405
338
 
@@ -414,37 +347,27 @@ module SimpleFeatureFlags
414
347
  active_ids.reject! { |id| ids_to_remove.include? id }
415
348
  end
416
349
 
417
- flag = T.must flags[feature.to_sym]
350
+ flag = flags[feature.to_sym] #: as !nil
418
351
  flag['active_for_objects'] = active_objects_hash
419
352
 
420
353
  true
421
354
  end
422
355
 
423
356
  # Returns the data of the flag in a hash.
424
- sig do
425
- override
426
- .params(
427
- feature: T.any(Symbol, String),
428
- ).returns(T.nilable(T::Hash[String, T.anything]))
429
- end
357
+ # @override
358
+ #: ((Symbol | String) feature) -> Hash[String, top]?
430
359
  def get(feature)
431
360
  return unless exists?(feature)
432
361
 
433
- flag = T.must flags[feature.to_sym]
362
+ flag = flags[feature.to_sym] #: as !nil
434
363
  flag['mandatory'] = mandatory_flags.include?(feature.to_s)
435
364
 
436
365
  flag
437
366
  end
438
367
 
439
368
  # Adds the given feature flag.
440
- sig do
441
- override
442
- .params(
443
- feature: T.any(Symbol, String),
444
- description: String,
445
- active: T.any(String, Symbol, T::Boolean, NilClass),
446
- ).returns(T.nilable(T::Hash[String, T.anything]))
447
- end
369
+ # @override
370
+ #: ((Symbol | String) feature, ?String description, ?(String | Symbol | bool)? active) -> Hash[String, top]?
448
371
  def add(feature, description = '', active = 'false')
449
372
  return if exists?(feature)
450
373
 
@@ -467,12 +390,8 @@ module SimpleFeatureFlags
467
390
 
468
391
  # Removes the given feature flag.
469
392
  # Returns its data or nil if it does not exist.
470
- sig do
471
- override
472
- .params(
473
- feature: T.any(Symbol, String),
474
- ).returns(T.nilable(T::Hash[String, T.anything]))
475
- end
393
+ # @override
394
+ #: ((Symbol | String) feature) -> Hash[String, top]?
476
395
  def remove(feature)
477
396
  return unless exists?(feature)
478
397
 
@@ -483,9 +402,8 @@ module SimpleFeatureFlags
483
402
  end
484
403
 
485
404
  # Returns the data of all feature flags.
486
- sig do
487
- override.returns(T::Array[T::Hash[String, T.anything]])
488
- end
405
+ # @override
406
+ #: -> Array[Hash[String, top]]
489
407
  def all
490
408
  hashes = []
491
409