Reads appups and applies OTP's entry-selection and instruction semantics.
mix castle.relup uses this module to decide whether an appup covers a
transition. mix castle.appup uses it to check what the selected entry loads
and removes.
From-version charlists match exactly. Binary keys are regular expressions,
selected through :systools_relup.appup_search_for_version/2.
script/2 expands short instructions and splices one level of list fragments
in the same order as :systools. Coverage credits only legal instructions:
update,load_module,add_moduleandloadload a module.delete_moduleandremoveremove a module.add_application,remove_applicationandrestart_applicationaffect the modules listed in the corresponding.appresources.
Dependency-order lists and apply instructions do not load code. An edge that
ends with restart_emulator needs no module coverage because the new VM loads
the release from disk. An upgrade using restart_new_emulator still runs the
remaining relup after the emulator restart and is rejected by Forecastle.
Summary
Types
The upgrade or downgrade list of an appup.
What an instruction does to a module.
A from-version and its script.
The effect of a script on one module.
An appup term: the application version and its upgrade and downgrade entries.
Functions
Returns the final load or removal effect for each module touched by a script.
Makes :systools and :systools_relup available.
Returns the upgrade or downgrade entries from an appup.
Returns module instructions placed before point_of_no_return.
Returns modules defined by more than one dependency-ordered instruction.
Returns modules named directly by instructions with the requested effect.
Returns the applications whose appups the project owns.
Reads an appup file.
Returns instructions in this module's vocabulary that OTP will reject.
Returns whether an edge ends by restarting the emulator.
Selects and expands the script for a from-version using OTP semantics.
Returns remove_application instructions for the application owning the appup.
Returns whether an upgrade requests unsupported restart_new_emulator.
Returns the first binary entry key that is not a valid regular expression.
Returns the version named by the appup.
Types
@type direction() :: :up | :down
The upgrade or downgrade list of an appup.
@type effect() :: :load | :removal
What an instruction does to a module.
Changed and added modules need :load; removed modules need :removal. No
instruction does both.
A from-version and its script.
The effect of a script on one module.
{:conflict, instructions} means the instructions disagree and the outcome
depends on an order that effects/4 does not model.
An appup term: the application version and its upgrade and downgrade entries.
Functions
@spec effects([term()], atom(), Enumerable.t(module()), Enumerable.t(module())) :: %{ required(module()) => resolution() }
Returns the final load or removal effect for each module touched by a script.
A result is :load, :removal, or {:conflict, instructions} when load and
removal effects disagree. The function does not guess the order after
:systools reorders dependency-connected instructions. Repeated effects that
agree retain that effect. A single restart_application leaves modules in
the target inventory loaded.
load_inventory and removal_inventory are the target and source module
lists from their .app resources. Application-level instructions use these
inventories rather than every BEAM file in ebin.
@spec ensure_systools!() :: :ok
Makes :systools and :systools_relup available.
Elixir prunes unused OTP applications from the build's code path, so these
:sasl modules are missing in projects that do not depend on :sasl.
Returns the upgrade or downgrade entries from an appup.
The two directions are independent.
Returns module instructions placed before point_of_no_return.
OTP permits only load_object_code and apply before this marker. A script
without the marker returns an empty list.
@spec multiply_defined([term()], atom(), Enumerable.t(module())) :: [module()]
Returns modules defined by more than one dependency-ordered instruction.
OTP rejects these as muldef_module. Module-level load and delete instructions
contribute one definition. add_application and restart_application
contribute every module in the target inventory. Low-level load and
remove instructions do not contribute dependency-graph vertices.
Returns modules named directly by instructions with the requested effect.
Application-level instructions are not expanded. Use effects/4 when checking
coverage across a complete application.
@spec project_apps() :: [atom()]
Returns the applications whose appups the project owns.
The list contains the current application and all umbrella children. Relup
generation uses it to distinguish owned applications from dependencies, and
mix castle.appup uses it as the default application set.
Reads an appup file.
Returns {:error, phrase} for a missing, unreadable or malformed file so the
caller can place the reason in its own diagnostic.
Returns instructions in this module's vocabulary that OTP will reject.
Coverage functions ignore malformed instructions. This function returns them for diagnostics. It also reports list fragments left after one expansion level, which OTP treats as bad instructions.
Returns whether an edge ends by restarting the emulator.
A downgrade containing restart_new_emulator becomes a trailing
restart_emulator; an upgrade remains a two-stage transition.
Selects and expands the script for a from-version using OTP semantics.
Returns :error when no entry matches. Malformed scripts that are not lists
are returned unchanged for the caller to report.
Returns remove_application instructions for the application owning the appup.
OTP rejects such an instruction while the application remains in the target release.
Returns whether an upgrade requests unsupported restart_new_emulator.
Returns the first binary entry key that is not a valid regular expression.
Binary from-version keys are regexes. OTP raises while selecting an entry when
one cannot be compiled, so callers should check before calling script/2.
Returns the version named by the appup.
:systools_relup warns with bad_vsn when it differs from the application
version, but still uses matching entries.