Packages

phoenix_kit

1.7.39
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 phoenix_kit install asset_rebuild.ex
Raw

lib/phoenix_kit/install/asset_rebuild.ex

defmodule PhoenixKit.Install.AssetRebuild do
@moduledoc """
Handles asset rebuilding for PhoenixKit installations and updates.
This module provides asset rebuilding using the standard Phoenix asset pipeline.
It tries multiple build commands in order of preference:
1. `mix assets.build` - Phoenix 1.8+ standard asset pipeline
2. `mix esbuild default --minify` - Individual ESBuild compilation
3. `mix tailwind default --minify` - Individual Tailwind compilation
4. `npm run build` - NPM build script fallback
5. `npm run build.css` - NPM CSS build script fallback
Assets are always rebuilt to ensure consistency after PhoenixKit updates.
"""
@doc """
Executes asset rebuilding using standard Phoenix asset pipeline.
## Options
- `:verbose` - Show detailed output (default: true)
## Returns
- `:rebuild_completed` - Assets were successfully rebuilt
- `:rebuild_failed` - Asset rebuild failed (non-critical)
"""
def check_and_rebuild(opts \\ []) do
verbose = Keyword.get(opts, :verbose, true)
# Execute rebuild using Phoenix standard commands
execute_asset_rebuild(verbose)
end
# Execute the actual asset rebuild process using Phoenix standards
defp execute_asset_rebuild(verbose) do
if verbose do
IO.puts("🎨 Rebuilding assets using Phoenix asset pipeline...")
end
# Try Phoenix standard asset build commands in order of preference
commands_to_try = [
# Phoenix 1.8+ standard asset pipeline
{"mix", ["assets.build"]},
# Individual asset builders
{"mix", ["esbuild", "default", "--minify"]},
{"mix", ["tailwind", "default", "--minify"]},
# Fallback to npm
{"npm", ["run", "build"]},
{"npm", ["run", "build.css"]}
]
execute_first_available_command(commands_to_try, verbose)
end
# Try commands in order until one succeeds
defp execute_first_available_command([], verbose) do
if verbose do
IO.puts("ℹ️ No asset build commands available - skipping asset rebuild")
end
:rebuild_completed
end
defp execute_first_available_command([{cmd, args} | rest], verbose) do
if verbose do
IO.puts("🔧 Trying: #{cmd} #{Enum.join(args, " ")}")
end
try do
# Run command with 60 second timeout to prevent hanging
result = run_with_timeout(cmd, args, 60_000)
case result do
{:ok, _output} ->
if verbose, do: IO.puts("✅ Assets rebuilt successfully with #{cmd}!")
:rebuild_completed
{:error, :timeout} ->
if verbose do
IO.puts("⚠️ Command timed out after 60 seconds, trying next option...")
end
execute_first_available_command(rest, verbose)
{:error, output} ->
if verbose do
IO.puts("⚠️ Command failed, trying next option...")
IO.puts("Output: #{String.slice(output, 0, 200)}")
end
execute_first_available_command(rest, verbose)
end
rescue
_ ->
if verbose do
IO.puts("❌ #{cmd} not available, trying next option...")
end
execute_first_available_command(rest, verbose)
end
end
# Run a command with a timeout
defp run_with_timeout(cmd, args, timeout_ms) do
parent = self()
ref = make_ref()
# Spawn a process to run the command
{pid, _} =
spawn_monitor(fn ->
result =
try do
case System.cmd(cmd, args, stderr_to_stdout: true) do
{output, 0} -> {:ok, output}
{output, _} -> {:error, output}
end
rescue
e -> {:error, inspect(e)}
end
send(parent, {ref, result})
end)
# Wait for result or timeout
receive do
{^ref, result} ->
result
{:DOWN, _, :process, ^pid, _reason} ->
{:error, "process crashed"}
after
timeout_ms ->
# Kill the spawned process if it's still running
Process.exit(pid, :kill)
# Drain any pending messages from the killed process
receive do
{^ref, _} -> :ok
{:DOWN, _, :process, ^pid, _} -> :ok
after
100 -> :ok
end
{:error, :timeout}
end
end
end