igniter/lib/config.ex

90 lines
2.7 KiB
Elixir
Raw Normal View History

2024-05-28 15:30:41 +12:00
defmodule Igniter.Config do
@moduledoc "Codemods and utilities for configuring Elixir applications."
2024-05-28 15:30:41 +12:00
require Igniter.Common
alias Igniter.Common
alias Sourceror.Zipper
def configure(igniter, file_path, app_name, config_path, value, updater \\ nil) do
file_path = Path.join("config", file_path)
config_path = List.wrap(config_path)
value = Macro.escape(value)
updater = updater || fn zipper -> Zipper.replace(zipper, value) end
igniter
|> Igniter.include_or_create_elixir_file(file_path, "import Config\n")
|> Igniter.update_file(file_path, fn source ->
quoted = Rewrite.Source.get(source, :quoted)
zipper = Zipper.zip(quoted)
case try_update_three_arg(zipper, config_path, app_name, updater) do
{:ok, zipper} ->
Rewrite.Source.update(source, :configure, :quoted, Zipper.root(zipper))
:error ->
case try_update_two_arg(zipper, config_path, app_name, value, updater) do
{:ok, zipper} ->
Rewrite.Source.update(source, :configure, :quoted, Zipper.root(zipper))
:error ->
# add new code here
[first | rest] = config_path
2024-05-28 15:30:41 +12:00
config =
{:config, [], [app_name, [{first, Igniter.Common.keywordify(rest, value)}]]}
2024-05-28 15:30:41 +12:00
code =
zipper
|> Igniter.Common.add_code(config)
|> Zipper.root()
Rewrite.Source.update(
source,
:configure,
:quoted,
code
)
end
end
end)
end
defp try_update_three_arg(zipper, config_path, app_name, updater) do
if Enum.count(config_path) == 1 do
config_item = Enum.at(config_path, 0)
case Common.move_to_function_call_in_current_scope(zipper, :config, 3, fn function_call ->
Common.argument_matches_pattern?(function_call, 0, ^app_name) &&
Common.argument_matches_pattern?(function_call, 1, ^config_item)
2024-05-28 15:30:41 +12:00
end) do
:error ->
2024-05-28 15:30:41 +12:00
:error
{:ok, zipper} ->
Common.update_nth_argument(zipper, 2, updater)
2024-05-28 15:30:41 +12:00
end
else
:error
end
end
defp try_update_two_arg(zipper, config_path, app_name, value, updater) do
case Common.move_to_function_call_in_current_scope(zipper, :config, 2, fn function_call ->
2024-05-28 15:30:41 +12:00
Common.argument_matches_pattern?(function_call, 0, ^app_name)
end) do
:error ->
2024-05-28 15:30:41 +12:00
:error
{:ok, zipper} ->
2024-05-28 15:30:41 +12:00
Common.update_nth_argument(zipper, 1, fn zipper ->
case Igniter.Common.put_in_keyword(zipper, config_path, value, updater) do
{:ok, new_zipper} ->
new_zipper
2024-05-28 15:30:41 +12:00
_ ->
zipper
end
end)
2024-05-28 15:30:41 +12:00
end
end
end