magick-feature-flags 0.8.8 → 0.9.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 +4 -4
- data/lib/magick/feature.rb +72 -21
- data/lib/magick/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cf5b93d36c4bd726730dffae18e5af58cb9937c5579ce4acbadbdf35adfac3ce
|
|
4
|
+
data.tar.gz: a11dda7f5779416efad1a59256f2df0c2086d40e52dca36cb2af538123b75f1d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4e86e55dfbd8c5671d5d0808fa5109d8d5688a71a7d1db3b42c28a88e89b6302cc2a18500452060424a66ed93bbe9d58e433a13c329dd923057b1e87b7520eb7
|
|
7
|
+
data.tar.gz: bfec5102e084898856fe860574602c75cd8e9674fe456d24aa89f7937455dcbfe463417cca6cd040eb61b5675f57df95bbf8071a8a2b3d2ab8ebbef12471f0b9
|
data/lib/magick/feature.rb
CHANGED
|
@@ -20,6 +20,7 @@ module Magick
|
|
|
20
20
|
@display_name = options[:name] || options[:display_name]
|
|
21
21
|
@targeting = {}
|
|
22
22
|
@dependencies = options[:dependencies] ? Array(options[:dependencies]) : []
|
|
23
|
+
@stored_value_initialized = false # Track if @stored_value has been explicitly set
|
|
23
24
|
|
|
24
25
|
validate_type!
|
|
25
26
|
validate_default_value!
|
|
@@ -64,7 +65,9 @@ module Magick
|
|
|
64
65
|
duration = (Time.now - start_time) * 1000
|
|
65
66
|
Magick.performance_metrics.record(name, 'enabled?', duration, success: false)
|
|
66
67
|
end
|
|
67
|
-
|
|
68
|
+
# Return false on any error (fail-safe)
|
|
69
|
+
warn "Magick: Error checking feature '#{name}': #{e.message}" if defined?(Rails) && Rails.env.development?
|
|
70
|
+
false
|
|
68
71
|
end
|
|
69
72
|
|
|
70
73
|
def check_enabled(context = {})
|
|
@@ -99,6 +102,10 @@ module Magick
|
|
|
99
102
|
else
|
|
100
103
|
false
|
|
101
104
|
end
|
|
105
|
+
rescue StandardError => e
|
|
106
|
+
# Return false on any error (fail-safe)
|
|
107
|
+
warn "Magick: Error in check_enabled for '#{name}': #{e.message}" if defined?(Rails) && Rails.env.development?
|
|
108
|
+
false
|
|
102
109
|
end
|
|
103
110
|
|
|
104
111
|
def disabled?(context = {})
|
|
@@ -126,11 +133,26 @@ module Magick
|
|
|
126
133
|
targeting_result = check_targeting(context)
|
|
127
134
|
return targeting_result unless targeting_result.nil?
|
|
128
135
|
|
|
129
|
-
# Use instance variable if set
|
|
130
|
-
#
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
# Use instance variable if it has been set (check using defined? to handle nil vs uninitialized)
|
|
137
|
+
# We use a special check: if @stored_value was explicitly set (even to false), use it
|
|
138
|
+
# We track this by checking if @stored_value_initialized flag is set
|
|
139
|
+
return @stored_value if defined?(@stored_value_initialized) && @stored_value_initialized
|
|
140
|
+
|
|
141
|
+
# Load from adapter if instance variable hasn't been initialized
|
|
142
|
+
loaded_value = load_value_from_adapter
|
|
143
|
+
if loaded_value.nil?
|
|
144
|
+
# Value not found in adapter, use default
|
|
145
|
+
default_value
|
|
146
|
+
else
|
|
147
|
+
# Value found in adapter, use it and mark as initialized
|
|
148
|
+
@stored_value = loaded_value
|
|
149
|
+
@stored_value_initialized = true
|
|
150
|
+
loaded_value
|
|
151
|
+
end
|
|
152
|
+
rescue StandardError => e
|
|
153
|
+
# Return default value on error (fail-safe)
|
|
154
|
+
warn "Magick: Error in get_value for '#{name}': #{e.message}" if defined?(Rails) && Rails.env.development?
|
|
155
|
+
default_value
|
|
134
156
|
end
|
|
135
157
|
|
|
136
158
|
def enable_for_user(user_id)
|
|
@@ -326,11 +348,13 @@ module Magick
|
|
|
326
348
|
adapter_registry.set(name, 'description', description) if description
|
|
327
349
|
adapter_registry.set(name, 'display_name', display_name) if display_name
|
|
328
350
|
@stored_value = value
|
|
351
|
+
@stored_value_initialized = true # Mark as initialized
|
|
329
352
|
|
|
330
353
|
# Update registered feature instance if it exists
|
|
331
354
|
if Magick.features.key?(name)
|
|
332
355
|
registered = Magick.features[name]
|
|
333
356
|
registered.instance_variable_set(:@stored_value, value)
|
|
357
|
+
registered.instance_variable_set(:@stored_value_initialized, true)
|
|
334
358
|
registered.instance_variable_set(:@targeting, @targeting.dup) if @targeting
|
|
335
359
|
end
|
|
336
360
|
|
|
@@ -354,6 +378,21 @@ module Magick
|
|
|
354
378
|
end
|
|
355
379
|
|
|
356
380
|
def enable(user_id: nil)
|
|
381
|
+
# Check if this feature is a dependency of any disabled features
|
|
382
|
+
# If a main feature that depends on this feature is disabled, prevent enabling this dependency
|
|
383
|
+
dependent_features = find_dependent_features
|
|
384
|
+
disabled_dependents = dependent_features.select do |dep_feature_name|
|
|
385
|
+
dep_feature = Magick.features[dep_feature_name.to_s] || Magick[dep_feature_name]
|
|
386
|
+
# Check if the dependent feature (main feature) is disabled
|
|
387
|
+
dep_feature && !dep_feature.enabled?
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
unless disabled_dependents.empty?
|
|
391
|
+
# Return false if any main feature that depends on this feature is disabled
|
|
392
|
+
# This prevents enabling a dependency when the main feature is disabled
|
|
393
|
+
return false
|
|
394
|
+
end
|
|
395
|
+
|
|
357
396
|
# Clear all targeting to enable globally
|
|
358
397
|
@targeting = {}
|
|
359
398
|
save_targeting
|
|
@@ -434,6 +473,7 @@ module Magick
|
|
|
434
473
|
if Magick.features.key?(name)
|
|
435
474
|
registered = Magick.features[name]
|
|
436
475
|
registered.instance_variable_set(:@stored_value, @stored_value)
|
|
476
|
+
registered.instance_variable_set(:@stored_value_initialized, @stored_value_initialized)
|
|
437
477
|
registered.instance_variable_set(:@status, @status)
|
|
438
478
|
registered.instance_variable_set(:@description, @description)
|
|
439
479
|
registered.instance_variable_set(:@display_name, @display_name)
|
|
@@ -466,19 +506,31 @@ module Magick
|
|
|
466
506
|
end
|
|
467
507
|
|
|
468
508
|
def load_from_adapter
|
|
469
|
-
#
|
|
470
|
-
|
|
471
|
-
@stored_value
|
|
509
|
+
# Load value from adapter
|
|
510
|
+
loaded_value = load_value_from_adapter
|
|
511
|
+
# Set @stored_value if we got a value from adapter (can be false, true, '', 0, etc.)
|
|
512
|
+
# Only set if loaded_value is not nil (nil means not found in adapter)
|
|
513
|
+
unless loaded_value.nil?
|
|
514
|
+
@stored_value = loaded_value
|
|
515
|
+
@stored_value_initialized = true
|
|
516
|
+
end
|
|
517
|
+
|
|
472
518
|
status_value = adapter_registry.get(name, 'status')
|
|
473
519
|
@status = status_value ? status_value.to_sym : status
|
|
474
520
|
|
|
475
|
-
# Load description from adapter
|
|
476
|
-
|
|
477
|
-
@description
|
|
521
|
+
# Load description from adapter only if not provided in DSL
|
|
522
|
+
# DSL (features.rb) is the source of truth, so don't override DSL values
|
|
523
|
+
unless @description
|
|
524
|
+
description_value = adapter_registry.get(name, 'description')
|
|
525
|
+
@description = description_value if description_value
|
|
526
|
+
end
|
|
478
527
|
|
|
479
|
-
# Load display_name from adapter
|
|
480
|
-
|
|
481
|
-
@display_name
|
|
528
|
+
# Load display_name from adapter only if not provided in DSL
|
|
529
|
+
# DSL (features.rb) is the source of truth, so don't override DSL values
|
|
530
|
+
unless @display_name
|
|
531
|
+
display_name_value = adapter_registry.get(name, 'display_name')
|
|
532
|
+
@display_name = display_name_value if display_name_value
|
|
533
|
+
end
|
|
482
534
|
|
|
483
535
|
targeting_value = adapter_registry.get(name, 'targeting')
|
|
484
536
|
if targeting_value.is_a?(Hash)
|
|
@@ -493,12 +545,11 @@ module Magick
|
|
|
493
545
|
end
|
|
494
546
|
|
|
495
547
|
def save_metadata_if_new
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
if
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
return unless @display_name && !adapter_registry.get(name, 'display_name')
|
|
548
|
+
# Always save description and display_name from DSL to adapter
|
|
549
|
+
# The features.rb file is the source of truth for metadata
|
|
550
|
+
# This ensures metadata is always up-to-date even if feature already exists
|
|
551
|
+
adapter_registry.set(name, 'description', @description) if @description
|
|
552
|
+
return unless @display_name
|
|
502
553
|
|
|
503
554
|
adapter_registry.set(name, 'display_name', @display_name)
|
|
504
555
|
end
|
data/lib/magick/version.rb
CHANGED