Packages

phoenix_kit

1.2.2
1.7.210 1.7.209 1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib mix tasks phoenix_kit.status.ex
Raw

lib/mix/tasks/phoenix_kit.status.ex

defmodule Mix.Tasks.PhoenixKit.Status do
@moduledoc """
Shows comprehensive status of PhoenixKit installation.
This task provides a detailed overview of your PhoenixKit installation status,
including version information, database connectivity, assets status, and
suggested next actions.
## Usage
$ mix phoenix_kit.status
$ mix phoenix_kit.status --prefix=myapp
## Options
* `--prefix` - Database schema prefix (default: "public")
* `--verbose` - Show detailed diagnostic information
## Examples
# Show status for default installation
mix phoenix_kit.status
# Show status for custom schema prefix
mix phoenix_kit.status --prefix=auth
# Show detailed diagnostic information
mix phoenix_kit.status --verbose
## Sample Output
PhoenixKit v1.2.1
├── Installed: V03 ✅
├── Database: Connected ✅
├── Assets: Built ✅
└── Status: Ready to use
"""
use Mix.Task
alias Ecto.Adapters.SQL
alias PhoenixKit.Migrations.Postgres
alias PhoenixKit.Install.{AssetRebuild, Common}
@impl Mix.Task
@spec run([String.t()]) :: :ok
@shortdoc "Shows comprehensive PhoenixKit installation status"
@switches [
prefix: :string,
verbose: :boolean
]
@aliases [
p: :prefix,
v: :verbose
]
def run(argv) do
{opts, _argv, _errors} = OptionParser.parse(argv, switches: @switches, aliases: @aliases)
prefix = opts[:prefix] || "public"
verbose = opts[:verbose] || false
show_comprehensive_status(prefix, verbose)
end
# Main status display function
defp show_comprehensive_status(prefix, verbose) do
# Get all status information
phoenix_kit_version = get_phoenix_kit_version()
installation_status = get_installation_status(prefix)
database_status = get_database_status(prefix)
assets_status = get_assets_status()
next_action = determine_next_action(installation_status, prefix)
# Display header
IO.puts("\n#{IO.ANSI.bright()}PhoenixKit v#{phoenix_kit_version}#{IO.ANSI.reset()}")
# Display status tree
display_status_tree([
{"Installed", format_installation_status(installation_status)},
{"Database", format_database_status(database_status)},
{"Assets", format_assets_status(assets_status)},
{"Next", format_next_action(next_action)}
])
# Show verbose information if requested
if verbose do
show_verbose_diagnostics(prefix, installation_status, database_status, assets_status)
end
IO.puts("")
end
# Get PhoenixKit module version
defp get_phoenix_kit_version do
case :application.get_key(:phoenix_kit, :vsn) do
{:ok, vsn} when is_list(vsn) -> List.to_string(vsn)
{:ok, vsn} -> to_string(vsn)
:undefined -> "unknown"
end
end
# Get installation status
defp get_installation_status(prefix) do
case Common.check_installation_status(prefix) do
{:not_installed} ->
{:not_installed}
{:current_version, version} ->
target_version = Postgres.current_version()
if version >= target_version do
{:up_to_date, version}
else
{:needs_update, version, target_version}
end
end
end
# Get database connectivity status
defp get_database_status(prefix) do
repo = Application.get_env(:phoenix_kit, :repo)
if repo do
# Test database connection with a simple query
case SQL.query(repo, "SELECT 1", []) do
{:ok, _result} ->
check_phoenix_kit_tables(prefix)
{:error, reason} ->
{:connection_error, reason}
end
else
{:no_repo_configured}
end
rescue
error -> {:error, error}
end
# Helper function to check if PhoenixKit tables exist
defp check_phoenix_kit_tables(prefix) do
opts = %{prefix: prefix, escaped_prefix: String.replace(prefix, "'", "\\'")}
version = Postgres.migrated_version_runtime(opts)
if version > 0 do
{:connected_with_tables, version}
else
{:connected_no_tables}
end
end
# Get assets build status
defp get_assets_status do
cond do
AssetRebuild.asset_rebuild_needed?(false) ->
{:needs_rebuild}
File.exists?("priv/static/assets/app.css") || File.exists?("priv/static/css/app.css") ->
{:built}
true ->
{:not_built}
end
end
# Determine next recommended action
defp determine_next_action({:not_installed}, _prefix) do
{:install, "mix phoenix_kit.install"}
end
defp determine_next_action({:needs_update, _current, _target}, prefix) do
cmd =
if prefix != "public",
do: "mix phoenix_kit.update --prefix=#{prefix}",
else: "mix phoenix_kit.update"
{:update, cmd}
end
defp determine_next_action({:up_to_date, _version}, _prefix) do
{:ready, "Ready to use"}
end
# Format installation status for display
defp format_installation_status({:not_installed}) do
"#{IO.ANSI.red()}Not installed#{IO.ANSI.reset()}"
end
defp format_installation_status({:up_to_date, version}) do
"#{IO.ANSI.green()}V#{pad_version(version)}#{IO.ANSI.reset()}"
end
defp format_installation_status({:needs_update, current, target}) do
"#{IO.ANSI.yellow()}V#{pad_version(current)} (needs update to V#{pad_version(target)})#{IO.ANSI.reset()}"
end
# Format database status for display
defp format_database_status({:connected_with_tables, _version}) do
"#{IO.ANSI.green()}Connected ✅#{IO.ANSI.reset()}"
end
defp format_database_status({:connected_no_tables}) do
"#{IO.ANSI.yellow()}Connected (no tables)#{IO.ANSI.reset()}"
end
defp format_database_status({:connection_error, _reason}) do
"#{IO.ANSI.red()}Connection failed ❌#{IO.ANSI.reset()}"
end
defp format_database_status({:no_repo_configured}) do
"#{IO.ANSI.red()}No repo configured ❌#{IO.ANSI.reset()}"
end
defp format_database_status({:error, _error}) do
"#{IO.ANSI.red()}Error ❌#{IO.ANSI.reset()}"
end
# Format assets status for display
defp format_assets_status({:built}) do
"#{IO.ANSI.green()}Built ✅#{IO.ANSI.reset()}"
end
defp format_assets_status({:needs_rebuild}) do
"#{IO.ANSI.yellow()}Needs rebuild#{IO.ANSI.reset()}"
end
defp format_assets_status({:not_built}) do
"#{IO.ANSI.yellow()}Not built#{IO.ANSI.reset()}"
end
# Format next action for display
defp format_next_action({:install, command}) do
"#{IO.ANSI.cyan()}#{command}#{IO.ANSI.reset()}"
end
defp format_next_action({:update, command}) do
"#{IO.ANSI.cyan()}#{command}#{IO.ANSI.reset()}"
end
defp format_next_action({:ready, message}) do
"#{IO.ANSI.green()}#{message}#{IO.ANSI.reset()}"
end
# Display status information in tree format
defp display_status_tree(items) do
items
|> Enum.with_index()
|> Enum.each(fn {{label, value}, index} ->
is_last = index == length(items) - 1
prefix = if is_last, do: "└── ", else: "├── "
IO.puts("#{prefix}#{IO.ANSI.bright()}#{label}#{IO.ANSI.reset()}: #{value}")
end)
end
# Show detailed diagnostic information
defp show_verbose_diagnostics(prefix, installation_status, database_status, assets_status) do
IO.puts("\n#{IO.ANSI.bright()}═══ Detailed Diagnostics ═══#{IO.ANSI.reset()}")
show_installation_diagnostics(installation_status, prefix)
show_database_diagnostics(database_status, prefix)
show_assets_diagnostics(assets_status)
show_configuration_diagnostics()
end
# Show installation diagnostics
defp show_installation_diagnostics(status, prefix) do
IO.puts("\n#{IO.ANSI.bright()}Installation:#{IO.ANSI.reset()}")
IO.puts(" Schema prefix: #{prefix}")
case status do
{:not_installed} ->
IO.puts(" Migration files: #{inspect(Common.find_existing_phoenix_kit_migrations())}")
{:up_to_date, version} ->
IO.puts(" Current version: V#{pad_version(version)}")
IO.puts(" Target version: V#{pad_version(Postgres.current_version())}")
{:needs_update, current, target} ->
IO.puts(" Current version: V#{pad_version(current)}")
IO.puts(" Target version: V#{pad_version(target)}")
changes = Common.describe_version_changes(current, target)
IO.puts(" Available changes:")
String.split(changes, "\n") |> Enum.each(&IO.puts(" #{&1}"))
end
end
# Show database diagnostics
defp show_database_diagnostics(status, _prefix) do
IO.puts("\n#{IO.ANSI.bright()}Database:#{IO.ANSI.reset()}")
repo = Application.get_env(:phoenix_kit, :repo)
IO.puts(" Configured repo: #{inspect(repo)}")
case status do
{:connected_with_tables, version} ->
IO.puts(" Connection: OK")
IO.puts(" PhoenixKit tables: Present (V#{pad_version(version)})")
{:connected_no_tables} ->
IO.puts(" Connection: OK")
IO.puts(" PhoenixKit tables: Missing")
{:connection_error, reason} ->
IO.puts(" Connection: Failed")
IO.puts(" Error: #{inspect(reason)}")
{:no_repo_configured} ->
IO.puts(" Connection: No repo configured")
{:error, error} ->
IO.puts(" Connection: Error")
IO.puts(" Details: #{inspect(error)}")
end
end
# Show assets diagnostics
defp show_assets_diagnostics(status) do
IO.puts("\n#{IO.ANSI.bright()}Assets:#{IO.ANSI.reset()}")
css_paths = [
"assets/css/app.css",
"priv/static/assets/app.css",
"priv/static/css/app.css"
]
existing_css = Enum.filter(css_paths, &File.exists?/1)
IO.puts(" CSS files found: #{inspect(existing_css)}")
case status do
{:built} ->
IO.puts(" Status: Built and up to date")
{:needs_rebuild} ->
IO.puts(" Status: Needs rebuild")
IO.puts(" Reason: PhoenixKit assets have been updated")
{:not_built} ->
IO.puts(" Status: Not built or not found")
end
end
# Show configuration diagnostics
defp show_configuration_diagnostics do
IO.puts("\n#{IO.ANSI.bright()}Configuration:#{IO.ANSI.reset()}")
# Check layout configuration
layout_config = Application.get_env(:phoenix_kit, :layout)
IO.puts(" Layout integration: #{if layout_config, do: "Configured", else: "Using defaults"}")
# Check theme configuration
theme_config = Application.get_env(:phoenix_kit, :theme_enabled, false)
IO.puts(" Theme system: #{if theme_config, do: "Enabled", else: "Disabled"}")
# Check mailer configuration
mailer_config = Application.get_env(:phoenix_kit, PhoenixKit.Mailer)
IO.puts(" Mailer: #{if mailer_config, do: "Configured", else: "Not configured"}")
end
# Pad version number for consistent display
defp pad_version(version) when version < 10, do: "0#{version}"
defp pad_version(version), do: to_string(version)
end