SvEx.Template (SvEx v0.4.2)

Converts a meta-project file into a name-agnostic EEx template, and back.

A meta project must be a real, compiling project with a real name or you cannot develop against it. A plugin captured from one must be name-agnostic, because it is installed into a project called something else. This module is that converter (SDD R1).

The two directions carry very different risk. capture/2 must MATCH the project name in arbitrary text and can over- or under-reach. render/2 is a pure EEx evaluation with no matching at all. All the danger is in capture, and capture only ever runs against meta-project names we choose.

This module must NOT be merged with SvEx.Hash, which strips comments for manifest hashing, or SvEx.Baseline, which placeholders secrets for drift checking. Three normalisers with three different jobs.

Summary

Functions

Converts source into a template, verified by rendering it back.

Replaces the project name inside a PATH with SDD 7.1's bare APP placeholder.

Renders a template back into project source.

Resolves SDD 7.1's bare APP path token against a target project.

True when bytes is valid UTF-8 and may be templated.

Types

names()

@type names() :: %{module: String.t(), app: String.t(), name: String.t()}

Functions

capture(source, names)

@spec capture(binary(), names()) :: {:ok, binary()} | {:error, term()}

Converts source into a template, verified by rendering it back.

Returns {:error, {:render_mismatch, byte_offset}} when the template does not reproduce source exactly under the original names.

placeholder_path(path, names)

@spec placeholder_path(Path.t(), names()) :: Path.t()

Replaces the project name inside a PATH with SDD 7.1's bare APP placeholder.

Paths are not EEx. 7.1 spells a plugin's file list {"lib/APP/cache.ex", :sole_owner}, and a path is low-collision enough that a bare token is safe where file content needs a delimited one. The same segment-boundary rule applies, so lib/new_otp_app/cache.ex becomes lib/APP/cache.ex while lib/new_otp_apparatus.ex is left alone.

render(template, names)

@spec render(binary(), names()) :: binary()

Renders a template back into project source.

resolve_path(path, names)

@spec resolve_path(Path.t(), names()) :: Path.t()

Resolves SDD 7.1's bare APP path token against a target project.

The inverse of placeholder_path/2. A plain replacement, not a match: APP is a token this project wrote, so there is nothing to disambiguate.

text?(bytes)

@spec text?(binary()) :: boolean()

True when bytes is valid UTF-8 and may be templated.

Binary payload takes a verbatim copy path owned by the caller: EEx tokenizes a charlist and raises on non-UTF-8 input.