Class: Cabriolet::PluginManager
- Inherits:
-
Object
- Object
- Cabriolet::PluginManager
- Includes:
- Singleton
- Defined in:
- lib/cabriolet/plugin_manager.rb
Overview
Manages plugin lifecycle and registry for Cabriolet
The PluginManager is a thread-safe singleton that handles plugin discovery, loading, activation, and deactivation. It maintains plugin states and resolves dependencies.
Instance Attribute Summary collapse
-
#formats ⇒ Hash
readonly
Format registry.
-
#plugins ⇒ Hash
readonly
Plugin registry by name.
Instance Method Summary collapse
-
#activate_plugin(name) ⇒ Boolean
Activate a plugin.
-
#deactivate_plugin(name) ⇒ Boolean
Deactivate a plugin.
-
#discover_plugins ⇒ Array<String>
Discover available plugins.
-
#format_handler(format) ⇒ Class?
Get format handler.
-
#initialize ⇒ PluginManager
constructor
Initialize the plugin manager.
-
#list_plugins(state: nil) ⇒ Hash
List plugins.
-
#load_plugin(name) ⇒ Boolean
Load a plugin.
-
#plugin(name) ⇒ Plugin?
Get a plugin by name.
-
#plugin_active?(name) ⇒ Boolean
Check if a plugin is active.
-
#register(plugin_instance) ⇒ Boolean
Register a plugin instance.
-
#register_format(format, handler) ⇒ void
private
Register a format handler.
Constructor Details
#initialize ⇒ PluginManager
Initialize the plugin manager
32 33 34 35 36 37 |
# File 'lib/cabriolet/plugin_manager.rb', line 32 def initialize @plugins = {} @formats = {} @mutex = Mutex.new @config = load_config end |
Instance Attribute Details
#formats ⇒ Hash (readonly)
Returns Format registry.
29 30 31 |
# File 'lib/cabriolet/plugin_manager.rb', line 29 def formats @formats end |
#plugins ⇒ Hash (readonly)
Returns Plugin registry by name.
26 27 28 |
# File 'lib/cabriolet/plugin_manager.rb', line 26 def plugins @plugins end |
Instance Method Details
#activate_plugin(name) ⇒ Boolean
Activate a plugin
Activates a loaded plugin. Calls the plugin’s activate method and transitions to :active state.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/cabriolet/plugin_manager.rb', line 165 def activate_plugin(name) @mutex.synchronize do entry = @plugins[name] raise PluginError, "Plugin '#{name}' not found" unless entry if entry[:state] == :active return true end unless entry[:state] == :loaded raise PluginError, "Plugin '#{name}' must be loaded before activation" end begin plugin = entry[:instance] plugin.activate plugin.send(:update_state, :active) entry[:state] = :active true rescue StandardError => e plugin.send(:update_state, :failed) entry[:state] = :failed entry[:error] = e. raise PluginError, "Failed to activate plugin '#{name}': #{e.message}" end end end |
#deactivate_plugin(name) ⇒ Boolean
Deactivate a plugin
Deactivates an active plugin. Calls the plugin’s deactivate method and transitions back to :loaded state.
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/cabriolet/plugin_manager.rb', line 209 def deactivate_plugin(name) @mutex.synchronize do entry = @plugins[name] raise PluginError, "Plugin '#{name}' not found" unless entry if entry[:state] != :active return true end begin plugin = entry[:instance] plugin.deactivate plugin.send(:update_state, :loaded) entry[:state] = :loaded true rescue StandardError => e entry[:error] = e. raise PluginError, "Failed to deactivate plugin '#{name}': #{e.message}" end end end |
#discover_plugins ⇒ Array<String>
Discover available plugins
Searches for plugins in gem paths using the pattern ‘cabriolet/plugins/*/.rb’. Discovered plugins are added to the registry in :discovered state.
50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/cabriolet/plugin_manager.rb', line 50 def discover_plugins @mutex.synchronize do plugin_files = Gem.find_files("cabriolet/plugins/**/*.rb") plugin_files.each do |file| load_plugin_file(file) rescue StandardError => e warn "Failed to load plugin from #{file}: #{e.message}" end @plugins.keys end end |
#format_handler(format) ⇒ Class?
Get format handler
325 326 327 328 329 |
# File 'lib/cabriolet/plugin_manager.rb', line 325 def format_handler(format) @mutex.synchronize do @formats[format] end end |
#list_plugins(state: nil) ⇒ Hash
List plugins
Returns plugin information, optionally filtered by state.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/cabriolet/plugin_manager.rb', line 249 def list_plugins(state: nil) @mutex.synchronize do if state.nil? @plugins.transform_values do |entry| { metadata: entry[:metadata], state: entry[:state], error: entry[:error], } end else @plugins.select { |_, entry| entry[:state] == state } .transform_values do |entry| { metadata: entry[:metadata], state: entry[:state], error: entry[:error], } end end end end |
#load_plugin(name) ⇒ Boolean
Load a plugin
Loads and validates a discovered plugin. Calls the plugin’s setup method and transitions to :loaded state.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/cabriolet/plugin_manager.rb', line 122 def load_plugin(name) @mutex.synchronize do entry = @plugins[name] raise PluginError, "Plugin '#{name}' not found" unless entry if i[loaded active].include?(entry[:state]) return true end begin plugin = entry[:instance] # Check dependencies check_dependencies!(entry[:metadata]) # Call setup plugin.setup plugin.send(:update_state, :loaded) entry[:state] = :loaded true rescue StandardError => e plugin.send(:update_state, :failed) entry[:state] = :failed entry[:error] = e. raise PluginError, "Failed to load plugin '#{name}': #{e.message}" end end end |
#plugin(name) ⇒ Plugin?
Get a plugin by name
280 281 282 283 284 |
# File 'lib/cabriolet/plugin_manager.rb', line 280 def plugin(name) @mutex.synchronize do @plugins[name]&.dig(:instance) end end |
#plugin_active?(name) ⇒ Boolean
Check if a plugin is active
294 295 296 297 298 |
# File 'lib/cabriolet/plugin_manager.rb', line 294 def plugin_active?(name) @mutex.synchronize do @plugins[name]&.dig(:state) == :active end end |
#register(plugin_instance) ⇒ Boolean
Register a plugin instance
Adds a plugin to the registry. The plugin must be a valid Plugin instance with proper metadata.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/cabriolet/plugin_manager.rb', line 78 def register(plugin_instance) @mutex.synchronize do unless plugin_instance.is_a?(Plugin) raise PluginError, "Plugin must inherit from Cabriolet::Plugin" end # Validate plugin validation = PluginValidator.validate(plugin_instance.class) unless validation[:valid] raise PluginError, "Plugin validation failed: #{validation[:errors].join(', ')}" end = plugin_instance. name = [:name] if @plugins.key?(name) raise PluginError, "Plugin '#{name}' already registered" end @plugins[name] = { instance: plugin_instance, metadata: , state: :discovered, } true end end |
#register_format(format, handler) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Register a format handler
Called by plugins to register format handlers. This is used internally by Plugin#register_format.
311 312 313 314 315 |
# File 'lib/cabriolet/plugin_manager.rb', line 311 def register_format(format, handler) @mutex.synchronize do @formats[format] = handler end end |