rebar3_erli18n_keycheck (rebar3_erli18n v0.2.0)

Copy Markdown View Source

Pure key-existence checker for compile-time catalogs.

Compares the literal msgids of a project's facade call sites (as deduplicated by rebar3_erli18n_common:extract_project/1) against the per-domain key universe of the compiled catalogs, and reports every call site whose {Context, Msgid} has no matching compiled key. Each missing key is reported exactly ONCE: the universe is the locale-invariant UNION of every compiled locale's keys for a domain, and the call sites are already deduplicated to one logical message each, so a msgid used in three locales (or from three source files) yields a single diagnostic carrying all of its call sites.

The module is PURE: no file or process I/O, no codegen, and no persistent_term access. The reference universe is built by the caller (the compile provider) by keying each parsed .po/.pot entry through rebar3_erli18n_common:entry_key/1; check/3 only consults the resulting sets. Domain scoping (restricting the check to domains that actually have a compiled catalog) is also the CALLER's responsibility: a call site whose domain is ABSENT from the universe map is never flagged, so the checker stays silent about domains the project did not opt into compiling.

Policy

check/3 is policy-driven: off short-circuits to ok without inspecting anything; warn and strict both perform the comparison and return the same {violations, [diag()]} when keys are missing (or ok when none are). The distinction between warn (log and continue) and strict (fail the build) is mapped by the provider that calls this function, not here — keeping the checker a deterministic pure predicate.

Determinism

The returned diagnostics are sorted by {Domain, File, Line} (then context and msgid as tie-breakers), and each diagnostic's call sites are themselves sorted and de-duplicated, so the output is byte-stable across runs and machines. format_diag/1 renders a diagnostic to a byte-pinnable message that carries the exact rebar3 erli18n extract then rebar3 erli18n compile remediation commands.

Summary

Types

One missing-key diagnostic: a logical message that a facade call site references but the compiled catalog does not define.

The check policy.

Functions

Compare call sites against the compiled key universe under Policy.

Render a diag() to a byte-pinnable, remediation-carrying message.

Types

call_sites()

-type call_sites() :: #{atom() => [rebar3_erli18n_common:dedup_entry()]}.

diag()

-type diag() ::
          {Domain :: atom(),
           Ctx :: undefined | binary(),
           Msgid :: binary(),
           Sites :: [{file:filename(), pos_integer()}]}.

One missing-key diagnostic: a logical message that a facade call site references but the compiled catalog does not define.

Domain is the gettext domain; Ctx the message context (undefined for the bare, context-less form); Msgid the literal message id; and Sites the sorted, de-duplicated {SourceFile, Line} call sites that reference it.

policy()

-type policy() :: off | warn | strict.

The check policy.

off disables the check entirely (always ok); warn and strict both run the comparison and return any {violations, _} identically — the caller maps warn to a logged warning and strict to a build failure.

universe()

-type universe() :: #{atom() => sets:set({undefined | binary(), binary()})}.

Functions

check/3

-spec check(universe(), call_sites(), policy()) -> ok | {violations, [diag()]}.

Compare call sites against the compiled key universe under Policy.

When Policy is off, returns ok without inspecting either map. Otherwise, for every domain that is present in BOTH Universe and CallSites, each call site whose {Context, Msgid} key is not an element of that domain's universe set becomes a diagnostic. Domains in CallSites but ABSENT from Universe are skipped (the caller's domain scoping). Returns ok when nothing is missing, or {violations, Diags} with the diagnostics sorted by {Domain, File, Line}.

format_diag/1

-spec format_diag(diag()) -> binary().

Render a diag() to a byte-pinnable, remediation-carrying message.

The output is deterministic for a given diagnostic and names the exact rebar3 erli18n extract then rebar3 erli18n compile commands that regenerate the compiled catalog so the missing key is defined.