distillery v2.0.0-rc.1 Mix.Releases.Appup.Transform behaviour

A transform is an appup compilation pass which receives a list of appup instructions, along with metadata about those instructions, such as the source application, the source and target versions involved, and an optional list of configuration options for the transform.

The job of a transform is to, well, apply a transformation to the instruction set, in order to accomplish some objective that one desires to be automated. A trivial example of one such transform would be a transform which ensures the purge mode is set to :soft_purge for all :update instructions, and would look like so:

defmodule Distillery.Test.SoftPurgeTransform do
  use Mix.Releases.Appup.Transform

  def up(app, _v1, _v2, instructions, opts) do
    apply_transform(instructions, app, opts)
  end

  def down(app, _v1, _v2, instructions, opts) do
    apply_transform(instructions, app, opts)
  end

  defp apply_transform(instructions, app, opts) do
    default = Keyword.get(opts, :default, :soft_purge)
    exclusions = Keyword.get(opts, :overrides, [])
    apply_transform(instructions, [], app, default, exclusions)
  end

  defp apply_transform([], acc, _app, _default, _exclusions), do: Enum.reverse(acc)

  defp apply_transform([i | ixs], acc, app, default, exclusions) do
    purge_mode = Keyword.get(exclusions, app, default)

    cond do
      elem(i, 0) == :update ->
        new_i = handle_update(i, purge_mode)
        apply_transform(ixs, [new_i | acc], app, default, exclusions)

      elem(i, 0) in [:load_module, :load] ->
        new_i = handle_load(i, purge_mode)
        apply_transform(ixs, [new_i | acc], app, default, exclusions)

      :else ->
        apply_transform(ixs, [i | acc], app, default, exclusions)
    end
  end

  defp handle_update({:update, m}, purge), do: {:update, m, :soft, purge, purge, []}
  defp handle_update({:update, _, :supervisor} = i, _purge), do: i

  defp handle_update({:update, m, dep_mods}, purge) when is_list(dep_mods),
    do: {:update, m, :soft, purge, purge, dep_mods}

  defp handle_update({:update, m, c}, purge), do: {:update, m, c, purge, purge, []}

  defp handle_update({:update, m, c, dep_mods}, purge),
    do: {:update, m, c, purge, purge, dep_mods}

  defp handle_update({:update, m, c, _, _, dep_mods}, purge),
    do: {:update, m, c, purge, purge, dep_mods}

  defp handle_update({:update, m, to, c, _, _, dep_mods}, purge),
    do: {:update, m, to, c, purge, purge, dep_mods}

  defp handle_update({:update, m, mt, to, c, _, _, dep_mods}, purge),
    do: {:update, m, mt, to, c, purge, purge, dep_mods}

  defp handle_load({:load_module, m}, purge), do: {:load_module, m, purge, purge, []}

  defp handle_load({:load_module, m, dep_mods}, purge),
    do: {:load_module, m, purge, purge, dep_mods}

  defp handle_load({:load_module, m, _, _, dep_mods}, purge),
    do: {:load_module, m, purge, purge, dep_mods}

  defp handle_load({:load, {m, _, _}}, purge), do: {:load, {m, purge, purge}}
end

Link to this section Summary

Functions

Applies all transforms against the current downgrade instruction

Applies all transforms against the current upgrade instruction

Link to this section Types

Link to this type instruction()
instruction() :: Mix.Releases.Appup.instruction()
Link to this type options()
options() :: [term()]
Link to this type transform()
transform() :: module() | {module(), options()}

Link to this section Functions

Link to this function down(instructions, app, v1, v2, list)
down([instruction()], app(), version(), version(), [transform()]) :: [
  instruction()
]

Applies all transforms against the current downgrade instruction.

Additional information required as arguments and passed to transforms are the app the instruction applies to, and the source and target versions involved.

Link to this function up(instructions, app, v1, v2, list)
up([instruction()], app(), version(), version(), [transform()]) :: [
  instruction()
]

Applies all transforms against the current upgrade instruction.

Additional information required as arguments and passed to transforms are the app the instruction applies to, and the source and target versions involved.

Link to this section Callbacks

Link to this callback down(app, version, version, list, options)
down(app(), version(), version(), [instruction()], options()) :: [
  instruction()
]
Link to this callback up(app, version, version, list, options)
up(app(), version(), version(), [instruction()], options()) :: [instruction()]