rebar3_erli18n_prv_merge (rebar3_erli18n v0.1.0)

Copy Markdown View Source

rebar3 erli18n merge — msgmerge-style sync of a .po against the fresh .pot.

For each {Domain, Locale} it parses the existing .po (via erli18n_po:parse) for the translations and serializes the merged result through rebar3_erli18n_po_meta, applying the lifecycle the plain parse/dump round-trip cannot:

  • a .pot msgid present in the old .po keeps its translation and gains the fresh #: references;
  • a .pot msgid ABSENT from the old .po is added as an untranslated entry, fuzzy-matched (rebar3_erli18n_jaro) against the removed msgids so a renamed string carries its old translation as #, fuzzy with a #| previous-msgid hint;
  • an old msgid no longer in the .pot (and not consumed as a fuzzy source) is demoted to a #~ obsolete entry rather than deleted;
  • msgid equality is wrapping-insensitive (--no-wrap / line-wrapped msgids compare equal), because both sides are decoded binaries.

Summary

Functions

Run the merge for the selected {Domain, Locale} catalogs.

Render a provider error to a human string.

Register the merge provider under the erli18n namespace.

Build the #| previous-msgid hint for a fuzzy match: the old context+msgid, plus the old msgid_plural when the matched entry carried one.

Functions

do(State)

-spec do(rebar3_erli18n_host:state()) -> {ok, rebar3_erli18n_host:state()} | {error, string()}.

Run the merge for the selected {Domain, Locale} catalogs.

format_error(Reason)

-spec format_error(term()) -> string().

Render a provider error to a human string.

init(State)

Register the merge provider under the erli18n namespace.

previous_of/1

-spec previous_of(erli18n_po:entry()) ->
                     {undefined | binary(), binary()} | {undefined | binary(), binary(), binary()}.

Build the #| previous-msgid hint for a fuzzy match: the old context+msgid, plus the old msgid_plural when the matched entry carried one.

This is a build-tool internal, exported only so the CT suite can white-box every clause; it is not part of any published (Hex) API surface.

erli18n_po:entry() types a plural's msgid_plural as undefined | binary(), so the clause head below must cover undefined for the match to be total over the imported type (dialyzer/eqwalizer exhaustiveness). In practice erli18n_po:parse/1 never yields a plural with an undefined msgid_plural — a degenerate msgstr[N]-without-msgid_plural block is parsed as a SINGULAR entry — so the undefined clause is type-mandated, not behaviourally reachable through the merge's parse-driven inputs.