PhoenixKit.Install.StatusReport (phoenix_kit v2.0.0)

Copy Markdown View Source

Decides what mix phoenix_kit.status should tell the operator to do next.

Extracted from the status task for the same reason PhoenixKit.Install.StatusTree was: it is pure decision logic that could otherwise only be observed by pointing the task at a live database in each of five states, so in practice it went unverified.

The task keeps the ANSI styling; this module returns plain data.

Why the wording matters

status compares the schema in the database against the version compiled into the running release (PhoenixKit.Migrations.Postgres.current_version/0). It never asks Hex what exists. So it can never report "a newer PhoenixKit is available" — it can only report that the database disagrees with the code already querying it, which surfaces as runtime errors on whatever the newer version added.

That is why nothing here says "update available": there is no optional upgrade being offered, only a mismatch to reconcile.

Summary

Types

What the operator should do.

Functions

The command an action asks for, or nil when it isn't a command.

Plain-text rendering, no ANSI — what the task colours and prints.

Picks the action for a given installation status and module list.

The mix phoenix_kit.update invocation for a prefix.

Types

action()

@type action() ::
  {:install, String.t()}
  | {:fix_connection, String.t()}
  | {:fix_version_comment, String.t()}
  | {:update, String.t(), [String.t()]}
  | {:check_modules, [String.t()]}
  | {:ready, String.t()}

What the operator should do.

  • {:install, command} — PhoenixKit has never been installed
  • {:fix_connection, message} — the database could not be reached
  • {:fix_version_comment, message} — installed, but the version comment is missing or unreadable; the fix is a restamp by hand, not an update
  • {:update, command, reasons} — schema behind the code; reasons says how
  • {:check_modules, names} — a module's version could not be read
  • {:ready, message} — database and code agree

Functions

command(arg1)

@spec command(action()) :: String.t() | nil

The command an action asks for, or nil when it isn't a command.

iex> PhoenixKit.Install.StatusReport.command({:update, "mix phoenix_kit.update", []})
"mix phoenix_kit.update"

describe(arg)

@spec describe(action()) :: String.t()

Plain-text rendering, no ANSI — what the task colours and prints.

iex> PhoenixKit.Install.StatusReport.describe({:ready, "Ready"})
"Ready"

iex> PhoenixKit.Install.StatusReport.describe(
...>   {:update, "mix phoenix_kit.update", ["database is V159, code expects V160"]}
...> )
"mix phoenix_kit.update — database is V159, code expects V160"

next_action(installation_status, modules, prefix)

@spec next_action(tuple(), [map()] | :not_queried, String.t()) :: action()

Picks the action for a given installation status and module list.

modules is a PhoenixKit.Migrations.Modules.list/1 result, or :not_queried when the database was unreachable and nothing was asked.

Examples

iex> alias PhoenixKit.Install.StatusReport
iex> StatusReport.next_action({:up_to_date, 159}, [], "public")
{:ready, "Ready"}

iex> alias PhoenixKit.Install.StatusReport
iex> StatusReport.next_action({:needs_update, 159, 160}, [], "public")
{:update, "mix phoenix_kit.update", ["database is V159, code expects V160"]}

update_command(prefix)

@spec update_command(String.t()) :: String.t()

The mix phoenix_kit.update invocation for a prefix.