Class: Rigor::Plugin::Loader
- Inherits:
-
Object
- Object
- Rigor::Plugin::Loader
- Defined in:
- lib/rigor/plugin/loader.rb
Overview
Resolves the project’s ‘.rigor.yml` `plugins:` entries into instantiated plugin instances, paired with a service container. Internal slice-1 implementation; the public surface is Loader.load returning a Registry.
Steps per entry (in order):
-
Normalise the entry into ‘{ gem:, id:, config: }`.
-
‘require` the gem (failures surface as a LoadError).
-
Look up the registered plugin class by id (or by gem name if the entry omitted an explicit id).
-
Validate the user’s config against the manifest’s ‘config_schema`.
-
Instantiate the plugin and call ‘init(services)`.
Loading is deterministic: configuration order, with plugin id alphabetical as the tie-breaker for entries that resolve to the same gem. Failures do not abort the run; the loader collects them on the Registry so the runner can convert each one into a ‘:plugin_loader` diagnostic.
Instance Attribute Summary collapse
-
#requirer ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#services ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(services:, requirer: ->(name) { require name }) ⇒ Loader
constructor
A new instance of Loader.
- #load(entries) ⇒ Registry
Constructor Details
#initialize(services:, requirer: ->(name) { require name }) ⇒ Loader
Returns a new instance of Loader.
37 38 39 40 |
# File 'lib/rigor/plugin/loader.rb', line 37 def initialize(services:, requirer: ->(name) { require name }) @services = services @requirer = requirer end |
Instance Attribute Details
#requirer ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
30 31 32 |
# File 'lib/rigor/plugin/loader.rb', line 30 def requirer @requirer end |
#services ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
30 31 32 |
# File 'lib/rigor/plugin/loader.rb', line 30 def services @services end |
Class Method Details
.load(configuration:, services:, requirer: ->(name) { require name }) ⇒ Object
42 43 44 |
# File 'lib/rigor/plugin/loader.rb', line 42 def self.load(configuration:, services:, requirer: ->(name) { require name }) new(services: services, requirer: requirer).load(configuration.plugins) end |
Instance Method Details
#load(entries) ⇒ Registry
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rigor/plugin/loader.rb', line 49 def load(entries) plugins = [] load_errors = [] seen_ids = {} Array(entries).each_with_index do |raw, index| entry = normalise_entry(raw, index) rescue LoadError => e load_errors << e else begin plugin = resolve_and_instantiate(entry, seen_ids) plugins << plugin if plugin rescue LoadError => e load_errors << e end end # ADR-9 slice 5 — topological sort by `manifest(consumes:)` # so producers run before consumers, plus early # `missing-producer` validation. Cycles surface as # `dependency-cycle` LoadErrors. When validation fails, the # offending plugin(s) drop from the returned plugins list # and the LoadError surfaces alongside any earlier failure. plugins, sort_errors = topo_sort_plugins(plugins) load_errors.concat(sort_errors) blueprints = plugins.map { |plugin| Blueprint.new(klass_name: plugin.class.name, config: plugin.config) } Registry.new(plugins: plugins, blueprints: blueprints, load_errors: load_errors) end |