Repository navigation
v0.3.0
Changed
- The shell template engine now claims the
.shtplsuffix only (it claimed
every suffix before, as the documented fallback). The suffix picks the engine
and the stem names the artifact, which is the conventioninstall.ks.j2
already used: renameboot.cfgtoboot.cfg.shtplandctx.render("boot.cfg")
keeps working unchanged. A file no engine claims is copied as is by the new
CopyTemplate, last in the defaulttemplate_types— so a staticgrub.cfg
needs no engine, and a file that does carry%{NAME}placeholders ships them
unrendered until it is renamed. That one case logs a warning naming the rename.
Narrowingtemplate_typesso nothing claims a file raises
netboot.templates.TemplateEngineError, which names the file and every
engine's suffixes.
Added
- Seven more template engines, each claiming its own suffix and costing
nothing when unused:MakoTemplate(.mako,netboot[mako]),
LiquidTemplate(.liquid,netboot[liquid]),HandlebarsTemplate
(.hbs/.handlebars,netboot[handlebars]),MustacheTemplate(.mustache,
netboot[mustache]), andERBTemplate(.erb) /EppTemplate(.epp),
which render through the systemrubyandpuppet epp renderso an existing
template behaves as its author tested it (PIXIE_RUBY/PIXIE_PUPPETname
the program if it is not onPATH). Every engine is registered whether or not
its dependency is present — a claimed file reports what is missing instead of
being copied — and nothing is imported until a file claims it. What each engine
does withtemplates_undefineddiffers by library and is tabulated in the
configuration guide; handlebars and mustache cannot fail on an undefined name
at all. template_data()/DataView/jsonable()— a lazy mapping view of the
render context for engines that read data rather than evaluate Python
({{ target.hostname }}beside{{ ctx.target.hostname }}), and its
JSON-serialisable form for the subprocess engines.SubprocessTemplate— the base for an engine that renders through another
language's own tooling: program lookup with an env override, a temporary
template and values file, a timeout, and the program's stderr in the error.ShellTemplateis configured by subclassing, through three class attributes:
EXT(a string or a sequence, dots optional, case-insensitive;Noneor
"*"claims any suffix),DELIMITER(default"%") andPATTERN—
"braced"(default,%{NAME}),"unbraced"(%NAME) or"all".- POSIX default expressions in the braced form:
%{NAME:-fallback}substitutes
the fallback when the value is unset or empty,%{NAME-fallback}only when
it is unset. One layer of'/"quotes is stripped, the fallback is literal
text, and a placeholder with a default never fails whatever
templates_undefinedsays.:=,:?and:+are not implemented and stay
literal text. CopyTemplate— the copy-as-is engine described above, working in bytes:
the loader no longer decodes a file before knowing which engine claims it, so
the copy is byte-exact for anything (CRLF, latin-1, a binary) and
ctx.render()returnsbytesfor such a file.EXTnarrows it to chosen
suffixes;Template.BINARYis the flag any engine can set to be handed raw
bytes. A non-UTF-8 file claimed by a text engine now raises
TemplateEngineErrornaming the file, where it used to fail inside the read.Loader.find_source()— the byte-returning counterpart ofget_source()
(which keeps jinja2's text contract).- A template-engine registry:
register_template_type()(bare or as a
decorator, with an optionalpriority=),unregister_template_type(),
TEMPLATE_TYPESandby_priority().Loader(template_types=None)— the new
default — uses every registered engine, so a--load-moduleplugin is picked
up without rebuilding the list, and the list is snapshotted at construction. Template.PRIORITY, so engine selection does not depend on registration
order: engines are consulted highest first,DEFAULT_PRIORITY(0) for an
ordinary engine andFALLBACK_PRIORITY(-100) forCopyTemplate. A plugin is
registered after the shipped engines, so without this every plugin would sit
behind the catch-all and never see a file. Equal priorities keep the order they
were given, so an explicittemplate_typeslist still means what it says.Template.EXTandJinjaTemplate.EXT, so suffix ownership is one declarative
attribute per engine, plusnetboot.templates.template_extensions()to read it
back normalised.
Full Changelog: v0.2.4...v0.3.0