Packages

phoenix_kit

1.7.13
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 repo_detection.ex
Raw

lib/phoenix_kit/install/repo_detection.ex

defmodule PhoenixKit.Install.RepoDetection do
@moduledoc """
Handles repository detection and validation for PhoenixKit installation.
This module provides functionality to:
- Auto-detect Ecto repositories from various sources
- Validate PostgreSQL adapter usage
- Handle custom repository specifications
"""
use PhoenixKit.Install.IgniterCompat
alias Igniter.Libs.Ecto
alias Igniter.Project.Config
alias Igniter.Project.Module, as: IgniterModule
alias PhoenixKit.Install.IgniterHelpers
@doc """
Adds PhoenixKit configuration with detected or specified repository.
## Parameters
- `igniter` - The igniter context
- `custom_repo` - Custom repository module (optional)
## Returns
Updated igniter with repository configuration or warning if not found.
"""
def add_phoenix_kit_configuration(igniter, custom_repo) do
case find_or_detect_repo(igniter, custom_repo) do
{igniter, nil} ->
warning = create_repo_not_found_warning()
Igniter.add_warning(igniter, warning)
{igniter, repo_module} ->
{updated_igniter, _} = validate_postgresql_adapter(igniter, repo_module)
add_repo_config_to_files(updated_igniter, repo_module)
end
end
# Find specified repo or auto-detect from project
defp find_or_detect_repo(igniter, nil) do
# Try multiple methods to find repos
with {igniter, nil} <- try_igniter_ecto_list(igniter),
{igniter, nil} <- try_application_config(igniter) do
try_naming_patterns(igniter)
end
end
defp find_or_detect_repo(igniter, repo_string) when is_binary(repo_string) do
repo_module = Module.concat([repo_string])
case IgniterModule.module_exists(igniter, repo_module) do
{true, igniter} ->
validate_postgres_adapter(igniter, repo_module)
{false, igniter} ->
Igniter.add_warning(igniter, "Specified repo #{repo_string} does not exist")
{igniter, nil}
end
end
# Method 1: Use Igniter's Ecto lib
defp try_igniter_ecto_list(igniter) do
case Ecto.list_repos(igniter) do
{igniter, [repo | _]} -> validate_postgres_adapter(igniter, repo)
{igniter, []} -> {igniter, nil}
end
end
# Method 2: Try Application config directly
defp try_application_config(igniter) do
parent_app_name = IgniterHelpers.get_parent_app_name(igniter)
case Elixir.Application.get_env(parent_app_name, :ecto_repos, []) do
[repo | _] -> validate_postgres_adapter(igniter, repo)
[] -> {igniter, nil}
end
rescue
_ -> {igniter, nil}
end
# Method 3: Try common naming patterns
defp try_naming_patterns(igniter) do
parent_app_name = IgniterHelpers.get_parent_app_name(igniter)
case parent_app_name do
nil ->
{igniter, nil}
app_name ->
# Try most common pattern: AppName.Repo
repo_module = Module.concat([Macro.camelize(to_string(app_name)), "Repo"])
case IgniterModule.module_exists(igniter, repo_module) do
{true, igniter} -> validate_postgres_adapter(igniter, repo_module)
{false, igniter} -> {igniter, nil}
end
end
rescue
_ -> {igniter, nil}
end
# Validate that the repo uses PostgreSQL adapter
defp validate_postgresql_adapter(igniter, repo_module) do
# Check if module is loaded and has __adapter__ function
if Code.ensure_loaded?(repo_module) and function_exported?(repo_module, :__adapter__, 0) do
case repo_module.__adapter__() do
Ecto.Adapters.Postgres ->
# PostgreSQL detected - add informational notice
notice = """
✅ PostgreSQL adapter detected (#{inspect(repo_module)})
"""
Igniter.add_notice(igniter, notice)
other_adapter ->
# Non-PostgreSQL adapter - add warning but continue
warning = """
⚠️ PhoenixKit is optimized for PostgreSQL (Ecto.Adapters.Postgres)
Current adapter: #{inspect(other_adapter)}
Some features may not work as expected with other databases.
Consider switching to PostgreSQL for the best experience.
"""
Igniter.add_warning(igniter, warning)
end
else
# Cannot determine adapter - add notice
notice = """
💡 Cannot determine database adapter at install time.
PhoenixKit is optimized for PostgreSQL (Ecto.Adapters.Postgres).
"""
Igniter.add_notice(igniter, notice)
end
{igniter, repo_module}
rescue
_ ->
# Error checking adapter - just continue silently
{igniter, repo_module}
end
# Alternative validate function for when we just want to trust detection
defp validate_postgres_adapter(igniter, repo_module) do
# Trust Igniter's detection - no need for verbose notices
{igniter, repo_module}
end
# Add repo configuration to config files
defp add_repo_config_to_files(igniter, repo_module) do
igniter
# Add repo config to main config.exs
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:repo],
repo_module
)
# Also add repo config to test.exs for testing
|> Config.configure_new(
"test.exs",
:phoenix_kit,
[:repo],
repo_module
)
rescue
_ ->
# Fallback to simple file operations
add_repo_config_simple(igniter, repo_module)
end
# Simple file append for repo configuration when Igniter fails
defp add_repo_config_simple(igniter, repo_module) do
repo_config = """
# PhoenixKit repo configuration
config :phoenix_kit, repo: #{inspect(repo_module)}
"""
try do
# Try appending to config.exs using Igniter
igniter =
Igniter.update_file(igniter, "config/config.exs", fn source ->
content = Rewrite.Source.get(source, :content)
# Check if already configured
if String.contains?(content, "config :phoenix_kit, repo:") do
source
else
# Find insertion point before import_config
updated_content =
case find_import_config_location_simple(content) do
{:before_import, before_content, after_content} ->
before_content <> repo_config <> "\n" <> after_content
:append_to_end ->
content <> repo_config
end
Rewrite.Source.update(source, :content, updated_content)
end
end)
# Try appending to test.exs using Igniter
igniter =
Igniter.update_file(igniter, "config/test.exs", fn source ->
content = Rewrite.Source.get(source, :content)
if String.contains?(content, "config :phoenix_kit, repo:") do
source
else
updated_content = content <> repo_config
Rewrite.Source.update(source, :content, updated_content)
end
end)
igniter
rescue
e ->
IO.warn("Failed to configure repo automatically: #{inspect(e)}")
add_repo_config_manual_notice(igniter, repo_module)
end
end
# Helper to find import_config location (simplified version)
defp find_import_config_location_simple(content) do
if String.contains?(content, "import_config") do
lines = String.split(content, "\n")
import_index =
Enum.find_index(lines, fn line ->
String.contains?(line, "import_config")
end)
case import_index do
nil ->
:append_to_end
index ->
# Find start of import block
start_index = max(0, index - 3)
before_lines = Enum.take(lines, start_index)
after_lines = Enum.drop(lines, start_index)
before_content = Enum.join(before_lines, "\n")
after_content = Enum.join(after_lines, "\n")
{:before_import, before_content, after_content}
end
else
:append_to_end
end
end
# Manual configuration notice for repo
defp add_repo_config_manual_notice(igniter, repo_module) do
notice = """
⚠️ Manual Repo Configuration Required
PhoenixKit couldn't automatically configure the repository.
Please add this to config/config.exs:
config :phoenix_kit, repo: #{inspect(repo_module)}
And also add to config/test.exs:
config :phoenix_kit, repo: #{inspect(repo_module)}
"""
Igniter.add_notice(igniter, notice)
end
# Create warning message when repository cannot be found
defp create_repo_not_found_warning do
"""
Could not determine application name or find Ecto repo automatically.
Please specify with --repo option:
mix phoenix_kit.install --repo YourApp.Repo
Common repo names:
- MyAppRepo, MyApp.Repo
Or manually add to config/config.exs:
config :phoenix_kit, repo: YourApp.Repo
"""
end
end