Module: OpenLoam::Overrides

Defined in:
lib/open_loam/overrides.rb

Overview

Disable or replace an entry in one of OpenLoam's OWN keyed registries from an initializer — customization without forking the gem, and without monkeypatching. This is deliberately SMALL: Rails already handles structural overriding (shadow a view/controller by path, prepend a module). Overrides only covers the in-gem keyed registries, where path-shadowing doesn't reach:

OpenLoam::Overrides.disable(:widgets, "open_progress")            # drop a built-in widget
OpenLoam::Overrides.replace(:widgets, "audit_recent") { |actor| { kind: "count", value: 0 } }
OpenLoam::Overrides.disable(:broadcast_events, "open_loam.progress.")  # stop pushing an event over SSE

THE VALUE-ADD over raw monkeypatching: a stale override (a typo, or an entry that no longer exists) is caught at boot by check! and warned about, so a silently-ineffective override is visible instead of a mystery.

Registries with a keyed API — :widgets, :broadcast_events — honor disable AND replace. Seams that are a single swappable object (Search.driver, EventStream.broadcaster) are replaced by assigning them directly; Overrides doesn't wrap those. Controllers/views/routes are NOT here — that's Rails' path-shadowing job (see docs).

Constant Summary collapse

DISABLED =
:__open_loam_disabled__

Class Method Summary collapse

Class Method Details

.all ⇒ Object



49
50
51
# File 'lib/open_loam/overrides.rb', line 49

def all
  store
end

.check! ⇒ Object

Warn (once, at boot) about every stale override, and return them.



81
82
83
84
85
86
87
88
# File 'lib/open_loam/overrides.rb', line 81

def check!
  found = stale
  found.each do |registry, key|
    message = "[open_loam] stale override: #{registry} has no entry #{key.inspect} to disable/replace — the override is doing nothing."
    logger ? logger.warn(message) : warn(message)
  end
  found
end

.disable(registry, key) ⇒ Object



25
26
27
# File 'lib/open_loam/overrides.rb', line 25

def disable(registry, key)
  store[registry.to_sym][key.to_s] = DISABLED
end

.disabled?(registry, key) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/open_loam/overrides.rb', line 35

def disabled?(registry, key)
  store[registry.to_sym][key.to_s] == DISABLED
end

.entries(registry) ⇒ Object



45
46
47
# File 'lib/open_loam/overrides.rb', line 45

def entries(registry)
  store[registry.to_sym]
end

.replace(registry, key, &block) ⇒ Object

Raises:

  • (ArgumentError)


29
30
31
32
33
# File 'lib/open_loam/overrides.rb', line 29

def replace(registry, key, &block)
  raise ArgumentError, "replace needs a block" unless block

  store[registry.to_sym][key.to_s] = block
end

.replacement(registry, key) ⇒ Object

The replacement block for a key, or nil (also nil when disabled).



40
41
42
43
# File 'lib/open_loam/overrides.rb', line 40

def replacement(registry, key)
  value = store[registry.to_sym][key.to_s]
  value unless value == DISABLED || value.nil?
end

.reset! ⇒ Object



53
54
55
# File 'lib/open_loam/overrides.rb', line 53

def reset!
  @store = Hash.new { |hash, key| hash[key] = {} }
end

.restore(snapshot) ⇒ Object



63
64
65
66
# File 'lib/open_loam/overrides.rb', line 63

def restore(snapshot)
  reset!
  snapshot.each { |registry, keys| store[registry].merge!(keys) }
end

.snapshot ⇒ Object

For tests: capture and restore the process-global override state so a test's overrides don't leak (and the app's boot-time overrides survive).



59
60
61
# File 'lib/open_loam/overrides.rb', line 59

def snapshot
  store.each_with_object({}) { |(registry, keys), out| out[registry] = keys.dup }
end

.stale ⇒ Object

Overrides whose key isn't present in the live registry — a typo or a removed entry. Only registries we can introspect are checked; others are skipped (returned as safe). Returns [[registry, key], ...].



71
72
73
74
75
76
77
78
# File 'lib/open_loam/overrides.rb', line 71

def stale
  store.flat_map do |registry, keys|
    known = known_keys(registry)
    next [] if known.nil?

    keys.keys.reject { |key| known.include?(key) }.map { |key| [ registry, key ] }
  end
end