Module: Esp::Mw::Loader
- Defined in:
- lib/esp/mw/loader.rb
Overview
Loads a mod’s source records from one of the supported formats.
The contract: every loader returns an Array of record hashes shaped for tes3conv. Keys are normalised to strings so downstream code (preflight, builder) doesn’t have to care which format the source was authored in.
Supported source files (per mod folder, exactly one):
mods/<Mod>/<Mod>.json — straight JSON
mods/<Mod>/<Mod>.rb — Ruby file; last expression is the Array
mods/<Mod>/<Mod>.py — Python script; prints JSON Array to stdout
mods/<Mod>/<Mod>.js — Node script; same contract
mods/<Mod>/<Mod>.mjs — Node ES module; same contract
mods/<Mod>/<Mod>.ts — Deno TypeScript; same contract
For subprocess loaders (py/js/mjs/ts) the interpreter runs with cwd set to the mod’s source directory, so relative file reads from the script just work. The script’s own path is passed as the last arg.
Defined Under Namespace
Classes: LoadError
Class Attribute Summary collapse
-
.interpreters ⇒ Object
Extension -> command vector.
Class Method Summary collapse
Class Attribute Details
.interpreters ⇒ Object
Extension -> command vector. Mutable so tests / local config can poke at it without freeze/unfreeze dances.
30 31 32 |
# File 'lib/esp/mw/loader.rb', line 30 def interpreters @interpreters end |
Class Method Details
.load(path, i18n: nil) ⇒ Object
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/esp/mw/loader.rb', line 52 def load(path, i18n: nil) raise LoadError, Esp.t('errors.loader.not_found', path: path) unless File.exist?(path) records = dispatch(path, i18n) unless records.is_a?(Array) raise LoadError, Esp.t('errors.loader.not_array', path: path, klass: records.class) end records.map { |r| stringify_keys(r) } end |
.resolve(mod, root: Esp::ROOT) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/esp/mw/loader.rb', line 36 def resolve(mod, root: Esp::ROOT) candidates = supported_exts .map { |ext| File.join(root, 'mods', mod, "#{mod}#{ext}") } .select { |p| File.exist?(p) } if candidates.empty? wanted = supported_exts.map { |e| "#{mod}#{e}" }.join(', ') raise LoadError, Esp.t('errors.loader.no_source', mod: mod.inspect, exts: wanted) end if candidates.size > 1 names = candidates.map { |c| File.basename(c) }.join(', ') raise LoadError, Esp.t('errors.loader.multiple_sources', mod: mod.inspect, names: names) end candidates.first end |
.supported_exts ⇒ Object
32 33 34 |
# File 'lib/esp/mw/loader.rb', line 32 def supported_exts %w[.rb .json] + interpreters.keys end |