Reads and rewrites the appup source named by the :appup project key.
Appup source is arbitrary Elixir evaluated for its value. This module rewrites
only a pure literal whose value is determined by its AST. Computed source,
structs, and bitstrings that require runtime truncation are refused. Literal
aliases, lists, maps, tuples, binaries and uninterpolated ~c/~C sigils are
accepted.
New entries are inserted as text so comments, formatting and existing entries remain unchanged. The result is parsed again and must equal the intended merged term before it can be written.
Summary
Types
The kind of appup source being written, which selects its header.
The result of reading a source file.
A pure-literal source file and what is needed to rewrite it.
Functions
Creates an appup source exclusively.
Returns a compact line diff suitable for terminal output.
Renders one from-version entry with its generated comments.
Inserts entries into the upgrade and downgrade lists of a literal source.
Reads an appup source file.
Renders a complete appup source for an application with no source file.
Atomically replaces a literal source with merged text.
Converts a literal AST to its term.
Types
The kind of appup source being written, which selects its header.
:project is the file named by the :appup key, compiled by the :appup
compiler. {:dependency, app, vsn} is rel/appups/<app>-<from>-<to>.exs,
which Forecastle.Appup.Dep places into an assembled release.
The result of reading a source file.
:absent means no file exists and {:literal, t()} can be merged into. The
other two are refusals, carrying the reason to report.
A pure-literal source file and what is needed to rewrite it.
Functions
Creates an appup source exclusively.
Returns an error if the path already exists or cannot be written, preventing a concurrent edit from being replaced.
Returns a compact line diff suitable for terminal output.
Changed lines use + and - prefixes. Unchanged context uses two spaces,
with omitted regions marked by ....
@spec entry_text(Forecastle.Appup.Draft.entry()) :: binary()
Renders one from-version entry with its generated comments.
The generator uses the same text for source updates and manual-merge output.
@spec merge(t(), [{:up | :down, Forecastle.Appup.Draft.entry()}]) :: {:ok, binary()} | {:error, binary()}
Inserts entries into the upgrade and downgrade lists of a literal source.
A direction may be omitted when it already has a matching entry. The function preserves all other source text and verifies the merged term.
Reads an appup source file.
Returns :absent, a literal source that can be merged, or a computed or
malformed source with a reason for refusing it.
@spec render( binary(), Forecastle.Appup.Draft.entry(), Forecastle.Appup.Draft.entry(), kind() ) :: {:ok, binary()} | {:error, binary()}
Renders a complete appup source for an application with no source file.
The header says whether the file is for the project or a dependency, and what the draft cannot decide.
Atomically replaces a literal source with merged text.
The function refuses a file that changed after it was read. It writes a staging file beside the resolved target, preserves the file mode, and renames the completed file into place. Symlink chains are followed to the source file.
Converts a literal AST to its term.
Returns :error when evaluating the AST requires computation.