magick-feature-flags 1.4.1 → 1.4.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/app/controllers/magick/adminui/features_controller.rb +2 -5
- data/lib/magick/feature.rb +14 -48
- data/lib/magick/version.rb +1 -1
- data/lib/magick.rb +0 -1
- metadata +1 -2
- data/lib/magick/feature_dependency.rb +0 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ce69954c64fae4d8ec9d10d177621ef508c1f0d8db98b9012849250d90cc974f
|
|
4
|
+
data.tar.gz: 41024341850d984dc1b16c8e85913160a94eb92b96f5eaf07477d9ff93a46de4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a16aa4722424020d4d4ab0d45c1dc5bfec6452ae6f24177d713e6f98790d33b4851bb340e39603aecf52c06bf2d669d0876c0b3835bc9ebf4f63cd92e7776ccc
|
|
7
|
+
data.tar.gz: 3a49561daaf30a060abefd7c11413dd5e87e27771b59e089d287cb2788920f5f9c334c4922e064d03c18ce692b6f37a6bfeaf419f09ba12891313c3be1eb1f8a
|
|
@@ -87,11 +87,8 @@ module Magick
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def enable
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
else
|
|
93
|
-
redirect_to magick_admin_ui.feature_path(@feature.name), alert: 'Cannot enable feature — its dependencies must be enabled first'
|
|
94
|
-
end
|
|
90
|
+
@feature.enable
|
|
91
|
+
redirect_to magick_admin_ui.features_path, notice: 'Feature enabled'
|
|
95
92
|
end
|
|
96
93
|
|
|
97
94
|
def disable
|
data/lib/magick/feature.rb
CHANGED
|
@@ -107,6 +107,11 @@ module Magick
|
|
|
107
107
|
return false if status == :inactive
|
|
108
108
|
return false if status == :deprecated && !context[:allow_deprecated]
|
|
109
109
|
|
|
110
|
+
# Dependency check: a feature with unmet prerequisites evaluates as disabled,
|
|
111
|
+
# regardless of its own configured state. Evaluation-only — prerequisite state
|
|
112
|
+
# is never written into this feature.
|
|
113
|
+
return false unless dependencies_satisfied?(context)
|
|
114
|
+
|
|
110
115
|
# Fast path: skip targeting checks if targeting is empty (most common case)
|
|
111
116
|
unless @_targeting_empty
|
|
112
117
|
# Check exclusions FIRST — exclusions always take priority over inclusions
|
|
@@ -532,18 +537,6 @@ module Magick
|
|
|
532
537
|
end
|
|
533
538
|
|
|
534
539
|
def enable(user_id: nil)
|
|
535
|
-
# Check that all of this feature's own dependencies are enabled
|
|
536
|
-
# e.g. if checkout depends on payments, checkout can't be enabled until payments is
|
|
537
|
-
deps = @dependencies || []
|
|
538
|
-
unless deps.empty?
|
|
539
|
-
disabled_deps = deps.select do |dep_name|
|
|
540
|
-
dep_feature = Magick.features[dep_name.to_s] || Magick[dep_name]
|
|
541
|
-
dep_feature && !dep_feature.enabled?
|
|
542
|
-
end
|
|
543
|
-
|
|
544
|
-
return false unless disabled_deps.empty?
|
|
545
|
-
end
|
|
546
|
-
|
|
547
540
|
# Clear all targeting to enable globally
|
|
548
541
|
@targeting = {}
|
|
549
542
|
save_targeting
|
|
@@ -589,9 +582,6 @@ module Magick
|
|
|
589
582
|
registered.instance_variable_set(:@targeting, {})
|
|
590
583
|
end
|
|
591
584
|
|
|
592
|
-
# Cascade disable: disable all features that depend on this one
|
|
593
|
-
disable_dependent_features(user_id: user_id)
|
|
594
|
-
|
|
595
585
|
# Rails 8+ event
|
|
596
586
|
if defined?(Magick::Rails::Events) && Magick::Rails::Events.rails8?
|
|
597
587
|
Magick::Rails::Events.feature_disabled_globally(name, user_id: user_id)
|
|
@@ -1015,42 +1005,18 @@ module Magick
|
|
|
1015
1005
|
context
|
|
1016
1006
|
end
|
|
1017
1007
|
|
|
1018
|
-
def
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
dependents = find_dependent_features
|
|
1022
|
-
return if dependents.empty?
|
|
1023
|
-
|
|
1024
|
-
dependents.each do |dep_name|
|
|
1025
|
-
dep_feature = Magick.features[dep_name.to_s] || Magick[dep_name]
|
|
1026
|
-
next unless dep_feature
|
|
1008
|
+
def dependencies_satisfied?(context)
|
|
1009
|
+
deps = @dependencies
|
|
1010
|
+
return true if deps.nil? || deps.empty?
|
|
1027
1011
|
|
|
1028
|
-
|
|
1029
|
-
dep_feature.
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
dep_feature.set_value(false, user_id: user_id)
|
|
1034
|
-
when :string
|
|
1035
|
-
dep_feature.set_value('', user_id: user_id)
|
|
1036
|
-
when :number
|
|
1037
|
-
dep_feature.set_value(0, user_id: user_id)
|
|
1038
|
-
end
|
|
1039
|
-
|
|
1040
|
-
if defined?(Magick::Rails::Events) && Magick::Rails::Events.rails8?
|
|
1041
|
-
Magick::Rails::Events.feature_disabled_globally(dep_name, user_id: user_id)
|
|
1042
|
-
end
|
|
1043
|
-
end
|
|
1044
|
-
end
|
|
1012
|
+
deps.all? do |dep_name|
|
|
1013
|
+
dep_feature = Magick.features[dep_name.to_s] || Magick.features[dep_name.to_sym]
|
|
1014
|
+
# Unknown dependency is treated as satisfied — matches prior behavior
|
|
1015
|
+
# where missing features were skipped in cascade logic.
|
|
1016
|
+
next true unless dep_feature
|
|
1045
1017
|
|
|
1046
|
-
|
|
1047
|
-
# Find all features that have this feature in their dependencies
|
|
1048
|
-
dependent_features = []
|
|
1049
|
-
Magick.features.each do |_name, feature|
|
|
1050
|
-
feature_deps = feature.instance_variable_get(:@dependencies) || []
|
|
1051
|
-
dependent_features << feature.name if feature_deps.include?(name.to_s) || feature_deps.include?(name.to_sym)
|
|
1018
|
+
dep_feature.enabled?(context)
|
|
1052
1019
|
end
|
|
1053
|
-
dependent_features
|
|
1054
1020
|
end
|
|
1055
1021
|
|
|
1056
1022
|
def excluded?(context)
|
data/lib/magick/version.rb
CHANGED
data/lib/magick.rb
CHANGED
|
@@ -31,7 +31,6 @@ require_relative 'magick/export_import'
|
|
|
31
31
|
require_relative 'magick/versioning'
|
|
32
32
|
require_relative 'magick/circuit_breaker'
|
|
33
33
|
require_relative 'magick/testing_helpers'
|
|
34
|
-
require_relative 'magick/feature_dependency'
|
|
35
34
|
require_relative 'magick/documentation'
|
|
36
35
|
# AdminUI is loaded conditionally via configuration
|
|
37
36
|
# It is not loaded by default - must be enabled in Magick.configure
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: magick-feature-flags
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Lobanov
|
|
@@ -128,7 +128,6 @@ files:
|
|
|
128
128
|
- lib/magick/errors.rb
|
|
129
129
|
- lib/magick/export_import.rb
|
|
130
130
|
- lib/magick/feature.rb
|
|
131
|
-
- lib/magick/feature_dependency.rb
|
|
132
131
|
- lib/magick/feature_variant.rb
|
|
133
132
|
- lib/magick/log_safe.rb
|
|
134
133
|
- lib/magick/performance_metrics.rb
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Magick
|
|
4
|
-
class FeatureDependency
|
|
5
|
-
def self.check(feature_name, context = {})
|
|
6
|
-
feature = Magick.features[feature_name.to_s] || Magick[feature_name]
|
|
7
|
-
dependencies = feature.instance_variable_get(:@dependencies) || []
|
|
8
|
-
|
|
9
|
-
dependencies.all? do |dep_name|
|
|
10
|
-
Magick.enabled?(dep_name, context)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.add_dependency(feature_name, dependency_name)
|
|
15
|
-
feature = Magick.features[feature_name.to_s] || Magick[feature_name]
|
|
16
|
-
dependencies = feature.instance_variable_get(:@dependencies) || []
|
|
17
|
-
dependencies << dependency_name.to_s unless dependencies.include?(dependency_name.to_s)
|
|
18
|
-
feature.instance_variable_set(:@dependencies, dependencies)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self.remove_dependency(feature_name, dependency_name)
|
|
22
|
-
feature = Magick.features[feature_name.to_s] || Magick[feature_name]
|
|
23
|
-
dependencies = feature.instance_variable_get(:@dependencies) || []
|
|
24
|
-
dependencies.delete(dependency_name.to_s)
|
|
25
|
-
feature.instance_variable_set(:@dependencies, dependencies)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|