Packages

phoenix_kit

1.7.172
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 runtime_detector.ex
Raw

lib/phoenix_kit/install/runtime_detector.ex

defmodule PhoenixKit.Install.RuntimeDetector do
@moduledoc """
Detects Phoenix runtime configuration patterns and determines appropriate config strategy.
This module analyzes Phoenix project configuration files to determine:
- Whether the project uses runtime.exs patterns
- The appropriate configuration file to modify
- The correct insertion location for PhoenixKit configuration
"""
@doc """
Detects if the project uses runtime configuration patterns.
## Returns
- `:runtime` - Uses runtime.exs with conditional blocks
- `:dev_exs` - Uses simple dev.exs file
- `:config_exs` - Uses config.exs with environment variables
## Examples
iex> RuntimeDetector.detect_config_pattern()
:runtime
"""
def detect_config_pattern do
cond do
runtime_exists?() && has_runtime_patterns?() -> :runtime
dev_exs_exists?() && simple_dev_config?() -> :dev_exs
true -> :config_exs
end
end
@doc """
Checks if runtime.exs file exists in the project.
## Returns
`true` if runtime.exs exists, `false` otherwise.
"""
def runtime_exists? do
File.exists?("config/runtime.exs")
end
@doc """
Checks if runtime.exs contains runtime configuration patterns.
## Returns
`true` if runtime patterns are detected, `false` otherwise.
"""
def has_runtime_patterns? do
case File.read("config/runtime.exs") do
{:ok, content} ->
runtime_patterns?(content)
{:error, _} ->
false
end
end
@doc """
Checks if dev.exs file exists and is simple enough to modify.
## Returns
`true` if simple dev.exs exists, `false` otherwise.
"""
def simple_dev_config? do
case File.read("config/dev.exs") do
{:ok, content} ->
not (runtime_patterns?(content) or has_complex_conditionals?(content))
{:error, _} ->
false
end
end
@doc """
Checks if dev.exs file exists.
## Returns
`true` if dev.exs exists, `false` otherwise.
"""
def dev_exs_exists? do
File.exists?("config/dev.exs")
end
@doc """
Finds the appropriate insertion point for PhoenixKit configuration.
## Returns
- `{:runtime, line_number}` - Insert at specific line in runtime.exs
- `{:dev_exs, line_number}` - Insert at end of dev.exs
- `{:config_exs, line_number}` - Insert in config.exs with env check
## Examples
iex> RuntimeDetector.find_insertion_point()
{:runtime, 76}
"""
def find_insertion_point do
case detect_config_pattern() do
:runtime ->
line_num = find_runtime_insertion_point()
{:runtime, line_num}
:dev_exs ->
{:dev_exs, find_end_of_file("config/dev.exs")}
:config_exs ->
{:config_exs, find_end_of_file("config/config.exs")}
end
end
@doc """
Finds the appropriate location within runtime.exs for development configuration.
## Returns
`line_number` where PhoenixKit config should be inserted.
"""
def find_runtime_insertion_point do
case File.read("config/runtime.exs") do
{:ok, content} ->
lines = String.split(content, "\n")
# Look for the dev configuration block
case find_dev_block_end(lines) do
{:ok, line_num} ->
line_num
{:error, :no_dev_block} ->
# If no dev block found, insert after imports
find_insertion_after_imports(lines)
end
{:error, _} ->
1
end
end
# Private functions
defp runtime_patterns?(content) do
patterns = [
~r/config_env\(\)/,
~r/System\.get_env/,
~r/Dotenvy\.env!/,
~r/\.env\.\s*Atom\.to_string/,
~r/if.*config_env.*==/
]
Enum.any?(patterns, &Regex.match?(&1, content))
end
defp has_complex_conditionals?(content) do
patterns = [
# Multi-line if blocks
~r/if.*do.*end/s,
# Case statements
~r/case.*do.*end/s,
# Cond statements
~r/cond.*do/s
]
Enum.any?(patterns, &Regex.match?(&1, content))
end
defp find_dev_block_end(lines) do
lines
|> Enum.with_index()
|> Enum.find(fn {line, _index} ->
String.contains?(line, "config :swoosh, :api_client, false") &&
String.contains?(line, "end")
end)
|> case do
{_line, index} ->
# Find the actual "end" of the dev block
remaining_lines = Enum.drop(lines, index + 1)
case find_next_config_block(remaining_lines) do
{:ok, next_line_num} ->
{:ok, index + 1 + next_line_num - 1}
:not_found ->
{:ok, index + 1}
end
nil ->
{:error, :no_dev_block}
end
end
defp find_next_config_block(lines) do
lines
|> Enum.with_index()
|> Enum.find(fn {line, _index} ->
String.starts_with?(String.trim(line), "config ") ||
String.starts_with?(String.trim(line), "if config_env")
end)
|> case do
{_, index} -> {:ok, index}
nil -> :not_found
end
end
defp find_insertion_after_imports(lines) do
lines
|> Enum.with_index()
|> Enum.find(fn {line, _index} ->
String.starts_with?(String.trim(line), "import Config")
end)
|> case do
{_, index} -> index + 1
nil -> 1
end
end
defp find_end_of_file(file_path) do
case File.read(file_path) do
{:ok, content} ->
String.split(content, "\n") |> length()
{:error, _} ->
1
end
end
end