Skip to content

Commit b7f7541

Browse files
authored
improvement: Implement removal of configuration (#309)
improvement: add `required?` option to `Igniter.update_elixir_file/3` making it `Igniter.update_elixir_file/4`
1 parent c66a5d8 commit b7f7541

3 files changed

Lines changed: 120 additions & 31 deletions

File tree

lib/igniter.ex

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,24 +501,35 @@ defmodule Igniter do
501501

502502
@doc """
503503
Updates the source code of the given elixir file
504+
505+
## Options
506+
507+
- `:required?` - Tracks an issue for the file missing. Defaults to `true`.
508+
504509
"""
505-
@spec update_elixir_file(t(), Path.t(), zipper_updater()) :: Igniter.t()
506-
def update_elixir_file(igniter, path, func) do
507-
if Rewrite.has_source?(igniter.rewrite, path) do
508-
igniter
509-
|> apply_func_with_zipper(path, func)
510-
|> format(path)
511-
else
512-
if exists?(igniter, path) do
510+
@spec update_elixir_file(t(), Path.t(), zipper_updater(), keyword) :: Igniter.t()
511+
def update_elixir_file(igniter, path, func, opts \\ []) do
512+
required? = Keyword.get(opts, :required?, true)
513+
514+
cond do
515+
Rewrite.has_source?(igniter.rewrite, path) ->
516+
igniter
517+
|> apply_func_with_zipper(path, func)
518+
|> format(path)
519+
520+
exists?(igniter, path) ->
513521
source = read_ex_source!(igniter, path)
514522

515523
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
516524
|> format(path)
517525
|> apply_func_with_zipper(path, func)
518526
|> format(path)
519-
else
527+
528+
required? ->
520529
add_issue(igniter, "Required #{path} but it did not exist")
521-
end
530+
531+
true ->
532+
igniter
522533
end
523534
end
524535

@@ -606,7 +617,14 @@ defmodule Igniter do
606617
include_existing_file(igniter, path, Keyword.put(opts, :source_handler, Rewrite.Source.Ex))
607618
end
608619

609-
@doc "Includes the given file in the project, expecting it to exist. Does nothing if its already been added."
620+
@doc """
621+
Includes the given file in the project, expecting it to exist. Does nothing if its already been added.
622+
623+
## Options
624+
625+
- `:required?` - Tracks an issue for the file missing. Defaults to `false`.
626+
627+
"""
610628
@spec include_existing_file(t(), Path.t(), opts :: Keyword.t()) :: t()
611629
def include_existing_file(igniter, path, opts \\ []) do
612630
required? = Keyword.get(opts, :required?, false)

lib/igniter/project/config.ex

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,7 @@ defmodule Igniter.Project.Config do
9797
|> Igniter.include_or_create_file(config_file_path, file_contents)
9898
|> ensure_default_configs_exist(file_path)
9999
|> Igniter.update_elixir_file(config_file_path, fn zipper ->
100-
case Zipper.find(zipper, fn
101-
{:import, _, [Config]} ->
102-
true
103-
104-
{:import, _, [{:__aliases__, _, [:Config]}]} ->
105-
true
106-
107-
_ ->
108-
false
109-
end) do
100+
case find_config(zipper) do
110101
nil ->
111102
{:warning,
112103
bad_config_message(
@@ -272,16 +263,7 @@ defmodule Igniter.Project.Config do
272263
|> ensure_default_configs_exist(file_name)
273264
|> Igniter.include_or_create_file(file_path, file_contents)
274265
|> Igniter.update_elixir_file(file_path, fn zipper ->
275-
case Zipper.find(zipper, fn
276-
{:import, _, [Config]} ->
277-
true
278-
279-
{:import, _, [{:__aliases__, _, [:Config]}]} ->
280-
true
281-
282-
_ ->
283-
false
284-
end) do
266+
case find_config(zipper) do
285267
nil ->
286268
{:warning, bad_config_message(app_name, file_path, config_path, value, opts)}
287269

@@ -294,6 +276,44 @@ defmodule Igniter.Project.Config do
294276
end)
295277
end
296278

279+
@doc """
280+
Removes an applications config completely.
281+
"""
282+
@spec remove_application_configuration(Igniter.t(), Path.t(), atom()) :: Igniter.t()
283+
def remove_application_configuration(igniter, file_name, app_name) do
284+
file_path = config_file_path(igniter, file_name)
285+
286+
Igniter.update_elixir_file(
287+
igniter,
288+
file_path,
289+
fn zipper ->
290+
case find_config(zipper) do
291+
nil -> igniter
292+
_ -> recursively_remove_configurations(zipper, app_name)
293+
end
294+
end,
295+
required?: false
296+
)
297+
end
298+
299+
defp recursively_remove_configurations(zipper, app_name) do
300+
case Igniter.Code.Function.move_to_function_call_in_current_scope(
301+
zipper,
302+
:config,
303+
[2, 3],
304+
&Igniter.Code.Function.argument_equals?(&1, 0, app_name)
305+
) do
306+
:error ->
307+
zipper
308+
309+
{:ok, zipper} ->
310+
zipper
311+
|> Zipper.remove()
312+
|> Zipper.top()
313+
|> recursively_remove_configurations(app_name)
314+
end
315+
end
316+
297317
defp config_file_path(igniter, file_name) do
298318
case igniter |> Igniter.Project.Application.config_path() |> Path.split() do
299319
[path] -> [path]
@@ -734,4 +754,17 @@ defmodule Igniter.Project.Config do
734754
defp simple_atom(value) do
735755
is_atom(value) and Regex.match?(~r/^[a-z_][a-zA-Z0-9_?!]*$/, to_string(value))
736756
end
757+
758+
defp find_config(zipper) do
759+
Zipper.find(zipper, fn
760+
{:import, _, [Config]} ->
761+
true
762+
763+
{:import, _, [{:__aliases__, _, [:Config]}]} ->
764+
true
765+
766+
_ ->
767+
false
768+
end)
769+
end
737770
end

test/igniter/project/config_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,4 +719,42 @@ defmodule Igniter.Project.ConfigTest do
719719
""")
720720
end
721721
end
722+
723+
describe "remove_application_configuration/3" do
724+
test "it does not create the config file if it does not exist" do
725+
test_project()
726+
|> Igniter.Project.Config.remove_application_configuration("fake.exs", :fake)
727+
|> refute_creates("config/fake.exs")
728+
end
729+
730+
test "it removes the applications configuration if it exists" do
731+
test_project()
732+
|> Igniter.create_new_file("config/fake.exs", """
733+
import Config
734+
735+
config :fake, buz: [:blat]
736+
""")
737+
|> apply_igniter!()
738+
|> Igniter.Project.Config.remove_application_configuration("fake.exs", :fake)
739+
|> assert_has_patch("config/fake.exs", """
740+
3 - |config :fake, buz: [:blat]
741+
""")
742+
end
743+
744+
test "it removes duplicate application configurations" do
745+
test_project()
746+
|> Igniter.create_new_file("config/fake.exs", """
747+
import Config
748+
749+
config :fake, buz: [:blat]
750+
config :fake, bar: [:blot]
751+
""")
752+
|> apply_igniter!()
753+
|> Igniter.Project.Config.remove_application_configuration("fake.exs", :fake)
754+
|> assert_has_patch("config/fake.exs", """
755+
3 - |config :fake, buz: [:blat]
756+
4 - |config :fake, bar: [:blot]
757+
""")
758+
end
759+
end
722760
end

0 commit comments

Comments
 (0)