Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 92 additions & 12 deletions lib/tower/igniter.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
if Code.ensure_loaded?(Igniter) do
defmodule Tower.Igniter do
@runtime_file_path "config/runtime.exs"
@default_runtime_file_content """
import Config
"""

def reporters_list_append(igniter, module) do
Igniter.Project.Config.configure(
igniter,
Expand All @@ -11,18 +16,93 @@ if Code.ensure_loaded?(Igniter) do
)
end

def runtime_configure_reporter(igniter, application, items) do
items
|> Enum.reduce(igniter, fn {key, value}, igniter ->
Igniter.Project.Config.configure(
igniter,
"runtime.exs",
application,
[key],
value,
updater: &{:ok, &1}
)
end)
def runtime_configure_reporter(igniter, application, items, opts \\ []) do
env = opts[:env]

igniter
|> Igniter.include_or_create_file(@runtime_file_path, @default_runtime_file_content)
|> Igniter.update_elixir_file(
@runtime_file_path,
fn zipper ->
if Igniter.Project.Config.configures_root_key?(zipper, application) do
{:ok, zipper}
else
if env do
patterns = env_config_patterns(env)

zipper
|> Igniter.Code.Common.move_to_cursor_match_in_scope(patterns)
|> case do
{:ok, zipper} ->
{:ok, zipper}

:error ->
zipper
|> Igniter.Code.Common.add_code("""
if config_env() == #{inspect(env)} do
end
""")
|> Igniter.Code.Common.move_to_cursor_match_in_scope(patterns)
end
else
{:ok, zipper}
end
|> case do
{:ok, zipper} ->
items
|> Enum.map(fn {key, value} ->
{
key,
case value do
{:code, code} ->
code

other ->
other
|> Macro.escape()
|> Sourceror.to_string()
|> Sourceror.parse_string!()
end
}
end)
|> Enum.reduce_while(
{:ok, zipper},
fn {key, value}, {:ok, zipper} ->
Igniter.Project.Config.modify_config_code(
zipper,
[key],
application,
value,
updater: &{:ok, &1}
)
|> case do
{:ok, _} = ok_result -> {:cont, ok_result}
other_result -> {:halt, other_result}
end
end
)

:error ->
{:error, "Could not modify #{@runtime_file_path}"}
end
end
end
)
end

defp env_config_patterns(env) do
[
"""
if config_env() == #{inspect(env)} do
__cursor__()
end
""",
"""
if #{inspect(env)} == config_env() do
__cursor__()
end
"""
]
end
end
end
86 changes: 77 additions & 9 deletions test/tower/igniter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,21 @@ defmodule TowerIgniterTest do
)
end

test "from scratch with env" do
test_project()
|> Tower.Igniter.runtime_configure_reporter(:reporter, [api_key: "123"], env: :prod)
|> assert_creates(
"config/runtime.exs",
"""
import Config

if config_env() == :prod do
config :reporter, api_key: "123"
end
"""
)
end

test "appends to existing runtime config" do
test_project(
files: %{
Expand All @@ -100,46 +115,85 @@ defmodule TowerIgniterTest do
"""
}
)
|> Tower.Igniter.runtime_configure_reporter(:reporter, api_key: "123")
|> Tower.Igniter.runtime_configure_reporter(:reporter, [api_key: "123"], env: :prod)
|> assert_has_patch(
"config/runtime.exs",
"""
|import Config
|
+ |if config_env() == :prod do
+ | config :reporter, api_key: "123"
+ |end
+ |
"""
)
end

test "writes inside existing prod block if present" do
test_project(
files: %{
"config/runtime.exs" => """
import Config

if config_env() == :prod do
IO.puts("hello")
end
"""
}
)
|> Tower.Igniter.runtime_configure_reporter(:reporter, [api_key: "123"], env: :prod)
|> assert_has_patch(
"config/runtime.exs",
"""
|if config_env() == :prod do
| IO.puts("hello")
+ |config :reporter, api_key: "123"
|end
|
"""
)
end

test "does not append same config again" do
test "does not append same config again in existing env block" do
test_project(
files: %{
"config/runtime.exs" => """
import Config

config :reporter, api_key: "123"
if config_env() == :prod do
config :reporter, api_key: "123"
end
"""
}
)
|> Tower.Igniter.runtime_configure_reporter(:reporter, api_key: "123")
|> Tower.Igniter.runtime_configure_reporter(:reporter, [api_key: "123"], env: :prod)
|> assert_unchanged()
end

test "does not modify existing key value yet appends new key" do
test "does not modify existing key value yet appends new key in env block" do
test_project(
files: %{
"config/runtime.exs" => """
import Config

config :reporter, api_key: "123"
if config_env() == :prod do
config :reporter, api_key: "123"
end
"""
}
)
|> Tower.Igniter.runtime_configure_reporter(:reporter, api_key: "456", other_key: "789")
|> Tower.Igniter.runtime_configure_reporter(
:reporter,
[api_key: "456", other_key: "789"],
env: :prod
)
|> assert_has_patch(
"config/runtime.exs",
"""
- |config :reporter, api_key: "123"
+ |config :reporter, api_key: "123", other_key: "789"
|if config_env() == :prod do
- | config :reporter, api_key: "123"
+ | config :reporter, api_key: "123", other_key: "789"
|end
"""
)
end
Expand All @@ -158,6 +212,20 @@ defmodule TowerIgniterTest do
|> assert_unchanged()
end

test "does not modify existing config in top level if configured for env" do
test_project(
files: %{
"config/runtime.exs" => """
import Config

config :reporter, api_key: "123"
"""
}
)
|> Tower.Igniter.runtime_configure_reporter(:reporter, [api_key: "123"], env: :prod)
|> assert_unchanged()
end

test "is idempotent" do
test_project()
|> Tower.Igniter.runtime_configure_reporter(:reporter, api_key: "123")
Expand Down
Loading