magick-feature-flags 0.9.33 → 0.9.34

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: a5a00b216a8309fb592dd86b9ac4ec11c6cd958790864833ac7a023e06f26517
4
- data.tar.gz: 0c6178010b7a588386fce54e089f43d630968bb41376ce94a4665383be183853
3
+ metadata.gz: 72089ec7fc15f5c7f854f03caf17896d4810f99d1067be9fadc17c9c5569b341
4
+ data.tar.gz: e928f66dd35ada0bb734c424178ba3c6db78f934b49599c21296506da697c4c2
5
5
  SHA512:
6
- metadata.gz: 974ca2a2cafe3a28fbb6bbe7416eb54b668a4923b3c500bba2b7772c4d70286283a3b49852042a037289ed2e6114debdd88a67436c0df527a4969ed545997ea3
7
- data.tar.gz: df5455d68e3d95581c48717e09021618a19d5e3b6e323a4fe25515191e67fcd1c92a7a8f69e2db2b55043dd90c6cf7b1fb0a038e258af3aac7b1da8ad9d5e8aa
6
+ metadata.gz: 0241c50192a89be6f429eac0367538687d8bb5d5dcd897cb1e7804cca4ce452d8e975132b62a0e1bc193f380294df1f0a9b2923680559964944fb9046be8fd94
7
+ data.tar.gz: dadadc9da7abcb0d031ec65c2ca016d9be0c4d914f1dd7240fbae12c614c8fc140e697a095e1fba744e0f691a6b2cacd3ab843c24ed479b4ecfdbd01c9ad04d6
data/README.md CHANGED
@@ -111,9 +111,6 @@ Magick.configure do
111
111
  audit_log enabled: true
112
112
  versioning enabled: true
113
113
  warn_on_deprecated enabled: true
114
-
115
- # Enable Admin UI (optional)
116
- admin_ui enabled: true
117
114
  end
118
115
  ```
119
116
 
@@ -524,23 +521,17 @@ Magick includes a web-based Admin UI for managing feature flags. It's a Rails En
524
521
 
525
522
  **Setup:**
526
523
 
527
- 1. Enable Admin UI in `config/initializers/magick.rb`:
528
-
529
- ```ruby
530
- Magick.configure do
531
- admin_ui enabled: true
532
- end
533
- ```
534
-
535
- 2. Configure roles (optional) for targeting management:
524
+ 1. Configure roles (optional) for targeting management in `config/initializers/magick.rb`:
536
525
 
537
526
  ```ruby
538
- Magick::AdminUI.configure do |config|
539
- config.available_roles = ['admin', 'user', 'manager', 'guest']
527
+ Rails.application.config.after_initialize do
528
+ Magick::AdminUI.configure do |config|
529
+ config.available_roles = ['admin', 'user', 'manager', 'guest']
530
+ end
540
531
  end
541
532
  ```
542
533
 
543
- 3. Mount the engine in `config/routes.rb`:
534
+ 2. Mount the engine in `config/routes.rb`:
544
535
 
545
536
  ```ruby
546
537
  Rails.application.routes.draw do
@@ -0,0 +1,46 @@
1
+ # Example features configuration file
2
+ # Copy this to config/features.rb in your Rails application
3
+
4
+ # Boolean features
5
+ boolean_feature :new_dashboard,
6
+ default: false,
7
+ name: "New Dashboard",
8
+ description: "New dashboard UI with improved navigation"
9
+
10
+ boolean_feature :dark_mode,
11
+ default: false,
12
+ name: "Dark Mode",
13
+ description: "Dark mode theme support"
14
+
15
+ # String features
16
+ string_feature :api_version,
17
+ default: "v1",
18
+ description: "API version to use for requests"
19
+
20
+ # Number features
21
+ number_feature :max_results,
22
+ default: 10,
23
+ description: "Maximum number of results per page"
24
+
25
+ # Features with status
26
+ feature :experimental_feature,
27
+ type: :boolean,
28
+ default_value: false,
29
+ status: :deprecated,
30
+ description: "Experimental feature (deprecated, will be removed)"
31
+
32
+ # Features with dependencies
33
+ # A feature can depend on other features being enabled
34
+ boolean_feature :advanced_feature,
35
+ default: false,
36
+ description: "Advanced feature that requires base_feature to be enabled",
37
+ dependencies: [:base_feature]
38
+
39
+ # Multiple dependencies
40
+ boolean_feature :premium_feature,
41
+ default: false,
42
+ description: "Premium feature requiring multiple base features",
43
+ dependencies: [:base_feature, :auth_feature]
44
+
45
+ # You can also add dependencies after feature definition
46
+ add_dependency(:another_feature, :required_feature)
@@ -0,0 +1,50 @@
1
+ # Magick Configuration DSL
2
+ # Copy this to config/initializers/magick.rb in your Rails application
3
+
4
+ Magick.configure do
5
+ # Configure environment
6
+ environment Rails.env
7
+
8
+ # Configure memory adapter TTL (default: 3600 seconds)
9
+ memory_ttl 7200 # 2 hours
10
+
11
+ # Configure Redis adapter
12
+ redis url: ENV['REDIS_URL'], namespace: 'magick:features'
13
+
14
+ # Configure circuit breaker
15
+ circuit_breaker threshold: 5, timeout: 60
16
+
17
+ # Enable async updates for Redis (non-blocking)
18
+ async_updates true
19
+
20
+ # Enable performance metrics tracking
21
+ performance_metrics enabled: true
22
+
23
+ # Enable audit logging
24
+ audit_log enabled: true
25
+
26
+ # Enable versioning support
27
+ versioning enabled: true
28
+
29
+ # Enable deprecation warnings
30
+ warn_on_deprecated true
31
+ end
32
+
33
+ # Alternative simpler configuration:
34
+ # Magick.configure do
35
+ # redis url: ENV['REDIS_URL']
36
+ # performance_metrics enabled: true
37
+ # audit_log enabled: true
38
+ # end
39
+
40
+ # Advanced configuration with nested adapter setup:
41
+ # Magick.configure do
42
+ # adapter :registry do
43
+ # memory_ttl 3600
44
+ # redis url: ENV['REDIS_URL']
45
+ # async_updates true
46
+ # circuit_breaker threshold: 5, timeout: 60
47
+ # end
48
+ # performance_metrics enabled: true
49
+ # audit_log enabled: true
50
+ # end
@@ -7,6 +7,9 @@ Magick::AdminUI::Engine.routes.draw do
7
7
  put :enable
8
8
  put :disable
9
9
  put :enable_for_user
10
+ put :enable_for_role
11
+ put :disable_for_role
12
+ put :update_targeting
10
13
  end
11
14
  end
12
15
  resources :stats, only: [:show]
@@ -15,116 +15,6 @@ module Magick
15
15
  isolate_namespace Magick::AdminUI
16
16
 
17
17
  engine_name 'magick_admin_ui'
18
-
19
- # Critical fix: Prevent the engine from interfering with Warden/Devise
20
- # Rails engines with isolate_namespace create their own middleware stack
21
- # This can break Warden/Devise in the main app if not handled correctly
22
- # We ensure the engine doesn't modify the main app's middleware or request handling
23
-
24
- # Don't add any middleware that could interfere
25
- # The engine will use its own middleware stack (due to isolate_namespace)
26
- # but this shouldn't affect the main app's middleware stack
27
-
28
- # Rails engines automatically detect app/views and app/controllers directories
29
- # With isolate_namespace, views should be at:
30
- # app/views/magick/adminui/[controller]/[action].html.erb
31
- # Controllers should be at:
32
- # app/controllers/magick/adminui/[controller]_controller.rb
33
- # Rails handles this automatically, but we explicitly add app/controllers to autoload paths
34
- # to ensure controllers are found
35
- config.autoload_paths += %W[#{root}/app/controllers] if root.join('app', 'controllers').exist?
36
-
37
- # Explicitly require controllers early to ensure they're loaded when gem is from RubyGems
38
- # This initializer runs after Warden/Devise is set up to avoid interfering with authentication
39
- initializer 'magick.admin_ui.require_controllers', after: :load_config_initializers do
40
- engine_root = Magick::AdminUI::Engine.root
41
- controller_path = engine_root.join('app', 'controllers', 'magick', 'adminui', 'features_controller.rb')
42
- require controller_path.to_s if controller_path.exist?
43
-
44
- stats_controller_path = engine_root.join('app', 'controllers', 'magick', 'adminui', 'stats_controller.rb')
45
- require stats_controller_path.to_s if stats_controller_path.exist?
46
- end
47
-
48
- # Explicitly add app/views to view paths
49
- # Rails engines should do this automatically, but we ensure it's configured
50
- initializer 'magick.admin_ui.append_view_paths', after: :add_view_paths do |app|
51
- engine_root = Magick::AdminUI::Engine.root
52
- app.paths['app/views'] << engine_root.join('app', 'views').to_s if engine_root.join('app', 'views').exist?
53
- end
54
-
55
- # Also ensure view paths are added when ActionController loads
56
- initializer 'magick.admin_ui.append_view_paths_to_controller', after: :add_view_paths do
57
- ActiveSupport.on_load(:action_controller) do
58
- view_path = Magick::AdminUI::Engine.root.join('app', 'views').to_s
59
- append_view_path view_path unless view_paths.include?(view_path)
60
- end
61
- end
62
-
63
- # Ensure controllers are loaded and view paths are added in to_prepare
64
- # This runs before each request in development and once at boot in production
65
- config.to_prepare do
66
- # Explicitly require controllers first to ensure they're loaded
67
- # This is necessary when the gem is loaded from RubyGems
68
- engine_root = Magick::AdminUI::Engine.root
69
- controller_path = engine_root.join('app', 'controllers', 'magick', 'adminui', 'features_controller.rb')
70
- require controller_path.to_s if controller_path.exist?
71
-
72
- stats_controller_path = engine_root.join('app', 'controllers', 'magick', 'adminui', 'stats_controller.rb')
73
- require stats_controller_path.to_s if stats_controller_path.exist?
74
-
75
- # Then add view paths
76
- view_path = engine_root.join('app', 'views').to_s
77
- if File.directory?(view_path)
78
- if defined?(Magick::AdminUI::FeaturesController)
79
- Magick::AdminUI::FeaturesController.append_view_path(view_path)
80
- end
81
- Magick::AdminUI::StatsController.append_view_path(view_path) if defined?(Magick::AdminUI::StatsController)
82
- end
83
- end
84
- end
85
- end
86
- end
87
-
88
- # Draw routes directly - Rails engines should auto-load config/routes.rb
89
- # but for gems we need to ensure routes are drawn at the right time
90
- # Use both to_prepare (for development reloading) and an initializer (for production)
91
- if defined?(Rails)
92
- # Initializer runs once during app initialization
93
- Magick::AdminUI::Engine.initializer 'magick.admin_ui.draw_routes', after: :load_config_initializers do
94
- Magick::AdminUI::Engine.routes.draw do
95
- root 'features#index'
96
- resources :features, only: %i[index show edit update] do
97
- member do
98
- put :enable
99
- put :disable
100
- put :enable_for_user
101
- put :enable_for_role
102
- put :disable_for_role
103
- put :update_targeting
104
- end
105
- end
106
- resources :stats, only: [:show]
107
- end
108
- end
109
-
110
- # to_prepare runs before each request in development (for code reloading)
111
- Magick::AdminUI::Engine.config.to_prepare do
112
- # Routes are already drawn by initializer, but redraw if needed for development reloading
113
- if Magick::AdminUI::Engine.routes.routes.empty?
114
- Magick::AdminUI::Engine.routes.draw do
115
- root 'features#index'
116
- resources :features, only: %i[index show edit update] do
117
- member do
118
- put :enable
119
- put :disable
120
- put :enable_for_user
121
- put :enable_for_role
122
- put :disable_for_role
123
- put :update_targeting
124
- end
125
- end
126
- resources :stats, only: [:show]
127
- end
128
18
  end
129
19
  end
130
20
  end
data/lib/magick/config.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Magick
4
4
  class Config
5
5
  attr_accessor :adapter_registry, :performance_metrics, :audit_log, :versioning, :warn_on_deprecated,
6
- :async_updates, :memory_ttl, :circuit_breaker_threshold, :circuit_breaker_timeout, :redis_url, :redis_namespace, :redis_db, :environment, :active_record_model_class, :enable_admin_ui
6
+ :async_updates, :memory_ttl, :circuit_breaker_threshold, :circuit_breaker_timeout, :redis_url, :redis_namespace, :redis_db, :environment, :active_record_model_class
7
7
 
8
8
  def initialize
9
9
  @warn_on_deprecated = false
@@ -14,7 +14,6 @@ module Magick
14
14
  @redis_namespace = 'magick:features'
15
15
  @redis_db = nil # Use default database (0) unless specified
16
16
  @environment = defined?(Rails) ? Rails.env.to_s : 'development'
17
- @enable_admin_ui = false # Admin UI disabled by default
18
17
  end
19
18
 
20
19
  # DSL methods for configuration
@@ -161,10 +160,6 @@ module Magick
161
160
  @environment = name.to_s
162
161
  end
163
162
 
164
- def admin_ui(enabled: true)
165
- @enable_admin_ui = enabled
166
- end
167
-
168
163
  def apply!
169
164
  # Apply configuration to Magick module
170
165
  Magick.adapter_registry = adapter_registry if adapter_registry
@@ -194,13 +189,6 @@ module Magick
194
189
  Magick.audit_log = audit_log if audit_log
195
190
  Magick.versioning = versioning if versioning
196
191
  Magick.warn_on_deprecated = warn_on_deprecated
197
-
198
- # Load optional components if enabled
199
- return unless @enable_admin_ui && defined?(Rails)
200
-
201
- # Load Admin UI - routes need to be drawn during initialization, not after
202
- # The engine's isolate_namespace should prevent interference with Warden/Devise
203
- require_relative '../magick/admin_ui' unless defined?(Magick::AdminUI)
204
192
  end
205
193
 
206
194
  private
@@ -6,6 +6,7 @@ if defined?(Rails)
6
6
  # DSL is already loaded by magick.rb, but ensure it's available
7
7
  require 'magick/dsl' unless defined?(Magick::DSL)
8
8
  require_relative 'events'
9
+ # Admin UI engine is now loaded in magick.rb when Rails is detected
9
10
 
10
11
  module Magick
11
12
  module Rails
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '0.9.33'
4
+ VERSION = '0.9.34'
5
5
  end
data/lib/magick.rb CHANGED
@@ -35,6 +35,13 @@ require_relative 'magick/config'
35
35
  # Always load DSL - it will make itself available when Rails is detected
36
36
  require_relative 'magick/dsl'
37
37
 
38
+ # Always require Admin UI engine when Rails is detected, so Rails can discover it as a railtie
39
+ # Rails discovers railties during gem loading, not during initialization hooks
40
+ # Users control whether the engine is active by mounting it in their routes file
41
+ if defined?(Rails)
42
+ require_relative 'magick/admin_ui' unless defined?(Magick::AdminUI)
43
+ end
44
+
38
45
  module Magick
39
46
  class << self
40
47
  attr_accessor :adapter_registry, :default_adapter, :audit_log, :versioning,
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: 0.9.33
4
+ version: 0.9.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Lobanov
@@ -102,6 +102,9 @@ files:
102
102
  - app/views/magick/adminui/features/index.html.erb
103
103
  - app/views/magick/adminui/features/show.html.erb
104
104
  - app/views/magick/adminui/stats/show.html.erb
105
+ - config/features.rb.example
106
+ - config/magick.rb.example
107
+ - config/routes.rb
105
108
  - lib/generators/magick/active_record/active_record_generator.rb
106
109
  - lib/generators/magick/active_record/templates/create_magick_features.rb
107
110
  - lib/generators/magick/install/install_generator.rb
@@ -114,7 +117,6 @@ files:
114
117
  - lib/magick/adapters/redis.rb
115
118
  - lib/magick/adapters/registry.rb
116
119
  - lib/magick/admin_ui.rb
117
- - lib/magick/admin_ui/config/routes.rb
118
120
  - lib/magick/admin_ui/engine.rb
119
121
  - lib/magick/admin_ui/helpers.rb
120
122
  - lib/magick/admin_ui/routes.rb