Module: Rigor::Effects::EntryPoints
- Defined in:
- lib/rigor/effects/entry_points.rb
Overview
The named entry-point presets effects.snapshot.reach: may adopt (ADR-103 WD14).
reach: entries are of two kinds, told apart syntactically:
- a path glob — anything carrying a glob or path character (
* ? [ ] / .) — matched against the project-relative file a method is defined in, with therigor unused --entry-pointsemantics (File.fnmatch?withFile::FNM_PATHNAME, so**is the only way across a directory boundary); - a preset name — a bare
[a-z0-9_-]+token — resolved here to the globs the preset stands for.
Presets are named by the plugin that models a framework — rigor-actionpack's controller actions,
rigor-activejob's perform, rigor-actionmailer's mailer methods, rigor-actioncable's channels —
through the effect_entry_points: manifest field (#387), and registered here through
EntryPoints.register_all once the plugin set is loaded. Configuration checks only that a reach: entry is
SHAPED like a preset name; the existence check runs where the snapshot expands it, which is the
first point at which the registered set is complete.
Registration is process-global and happens before a snapshot is built, in the parent process — the same shape the other CLI-time registries take. Nothing here crosses a fork or a Ractor boundary.
Defined Under Namespace
Classes: Error, UnknownPreset
Constant Summary collapse
- GLOB_CHARACTERS =
What makes a
reach:entry a path glob rather than a preset name. Kept deliberately wide: a name that looks at all like a path is read as one, because a mistyped preset that matched a file would be the confusing failure. %r{[*?\[\]/.]}- NAME_PATTERN =
What a preset name may be spelled with, so a malformed name is rejected at registration rather than becoming an unfindable key.
/\A[a-z0-9][a-z0-9_-]*\z/
Class Method Summary collapse
-
.availability ⇒ String
What this project may write in
effects.snapshot.reach:, as one parenthetical clause. -
.glob?(entry) ⇒ Boolean
Whether
entryis a path glob rather than a preset name. -
.globs_for(name) ⇒ Object
The globs
namestands for, ornilwhen nothing registered it. - .known?(name) ⇒ Boolean
-
.name?(entry) ⇒ Boolean
Whether
entryis spelled like a preset name at all — the shape checkConfigurationruns at load, before any plugin has had the chance to register one. -
.names ⇒ Object
Every registered preset name, sorted.
-
.register(name, globs) ⇒ Object
Registers
nameas standing forglobs. -
.register_all(presets) ⇒ Object
Registers every
effect_entry_points:preset the loaded plugins declare. -
.reset! ⇒ Object
Drops every registration.
-
.resolve!(name) ⇒ Object
The globs
namestands for, or the configuration error that says what this project could have written instead.
Class Method Details
.availability ⇒ String
What this project may write in effects.snapshot.reach:, as one parenthetical clause.
Single-homed here because the answer is a property of the loaded plugin set rather than of any
one message: the unregistered-preset error (#433) and the note rigor effects update prints
when reach: is empty (#436) have to give the same answer, and neither can hard-code a list
that moves with plugins:.
122 123 124 125 126 127 128 129 130 |
# File 'lib/rigor/effects/entry_points.rb', line 122 def availability if @presets.empty? return "no plugin in this project registers an entry-point preset — a preset is named by the " \ "plugin that models the framework, so listing that plugin under `plugins:` is what " \ "registers one" end "presets registered in this project: #{names.join(', ')}" end |
.glob?(entry) ⇒ Boolean
Whether entry is a path glob rather than a preset name.
52 53 54 |
# File 'lib/rigor/effects/entry_points.rb', line 52 def glob?(entry) GLOB_CHARACTERS.match?(entry) end |
.globs_for(name) ⇒ Object
The globs name stands for, or nil when nothing registered it.
95 96 97 |
# File 'lib/rigor/effects/entry_points.rb', line 95 def globs_for(name) @presets[name.to_s] end |
.known?(name) ⇒ Boolean
71 72 73 |
# File 'lib/rigor/effects/entry_points.rb', line 71 def known?(name) @presets.key?(name.to_s) end |
.name?(entry) ⇒ Boolean
Whether entry is spelled like a preset name at all — the shape check Configuration runs at
load, before any plugin has had the chance to register one.
77 78 79 |
# File 'lib/rigor/effects/entry_points.rb', line 77 def name?(entry) NAME_PATTERN.match?(entry) end |
.names ⇒ Object
Every registered preset name, sorted. Empty until a plugin declaring effect_entry_points:
loads, which is what makes availability worth printing.
90 91 92 |
# File 'lib/rigor/effects/entry_points.rb', line 90 def names @presets.keys.sort.freeze end |
.register(name, globs) ⇒ Object
Registers name as standing for globs. Re-registering the same name with the same globs is a
no-op, so a plugin loaded twice in one process does not raise.
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rigor/effects/entry_points.rb', line 58 def register(name, globs) key = name.to_s raise Error, "not a well-formed entry-point preset name: #{key.inspect}" unless NAME_PATTERN.match?(key) patterns = Array(globs).map(&:to_s).uniq.sort.freeze existing = @presets[key] return key if existing == patterns raise Error, "entry-point preset already registered with different globs: #{key.inspect}" if existing @presets[key] = patterns key end |
.register_all(presets) ⇒ Object
Registers every effect_entry_points: preset the loaded plugins declare. Idempotent per name +
glob set, so two runs in one process (the spec suite, the LSP) do not collide; two plugins
claiming one name with different globs is a genuine conflict and raises.
84 85 86 |
# File 'lib/rigor/effects/entry_points.rb', line 84 def register_all(presets) Array(presets).each { |preset| register(preset.name, preset.globs) } end |
.reset! ⇒ Object
Drops every registration. For specs only — production code registers and never unregisters.
133 134 135 |
# File 'lib/rigor/effects/entry_points.rb', line 133 def reset! @presets = {} end |
.resolve!(name) ⇒ Object
The globs name stands for, or the configuration error that says what this project could have
written instead.
The existence check lives here and runs from the snapshot build rather than from
Configuration — presets are registered by plugins, and the plugins load FROM the configuration
being validated, so at load time the registry is still empty. See name? for the shape check
that does run at load.
106 107 108 109 110 111 112 |
# File 'lib/rigor/effects/entry_points.rb', line 106 def resolve!(name) globs_for(name) || raise( UnknownPreset, "effects.snapshot.reach names no registered entry-point preset: #{name.to_s.inspect} " \ "(#{availability})" ) end |