From b878903e26ccf732ab73da74665ad69f89ce7bf2 Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 1 Jul 2024 18:27:41 -0400 Subject: [PATCH] chore: fix bugs/build --- lib/igniter.ex | 1 + lib/igniter/code/common.ex | 47 ++++++++++++++++++++++++++++++------ test/project/config_test.exs | 2 +- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/igniter.ex b/lib/igniter.ex index 36a5e7e..a261124 100644 --- a/lib/igniter.ex +++ b/lib/igniter.ex @@ -378,6 +378,7 @@ defmodule Igniter do * `:error_on_abort?` - If `true`, raises an error if the user aborts the operation. Returns the original igniter if not. """ + # sobelow_skip ["RCE.CodeModule"] def apply_and_fetch_dependencies(igniter, opts \\ []) do if has_changes?(igniter, ["mix.exs"]) do case Igniter.do_or_dry_run(igniter, ["--dry-run"], diff --git a/lib/igniter/code/common.ex b/lib/igniter/code/common.ex index 0c19bcc..6297c9c 100644 --- a/lib/igniter/code/common.ex +++ b/lib/igniter/code/common.ex @@ -147,7 +147,7 @@ defmodule Igniter.Code.Common do current_code = Zipper.root(current_code) case current_code do - {:__block__, meta, stuff} -> + {:__block__, meta, stuff} when length(stuff) > 1 -> new_stuff = if placement == :after do stuff ++ [new_code] @@ -446,21 +446,54 @@ defmodule Igniter.Code.Common do |> maybe_move_to_single_child_block() end + defp multi_child_block?(zipper) do + node_matches_pattern?(zipper, {:__block__, _, [_, _ | _]}) + end + @doc """ - Moves right in the zipper, until the provided predicate returns `true`. + Moves rightwards, entering blocks (and exiting them if no match is found), until the provided predicate returns `true`. Returns `:error` if the end is reached without finding a match. """ @spec move_right(Zipper.t(), (Zipper.t() -> boolean)) :: {:ok, Zipper.t()} | :error def move_right(%Zipper{} = zipper, pred) do - zipper_in_block = maybe_move_to_single_child_block(zipper) + zipper_in_single_child_block = maybe_move_to_single_child_block(zipper) cond do pred.(zipper) -> {:ok, zipper} - pred.(zipper_in_block) -> - {:ok, zipper_in_block} + pred.(zipper_in_single_child_block) -> + {:ok, zipper_in_single_child_block} + + multi_child_block?(zipper) -> + zipper + |> Zipper.down() + |> case do + nil -> + case Zipper.right(zipper) do + nil -> + :error + + zipper -> + move_right(zipper, pred) + end + + zipper -> + case move_right(zipper, pred) do + {:ok, zipper} -> + {:ok, zipper} + + :error -> + case Zipper.right(zipper) do + nil -> + :error + + zipper -> + move_right(zipper, pred) + end + end + end true -> case Zipper.right(zipper) do @@ -468,13 +501,11 @@ defmodule Igniter.Code.Common do :error zipper -> - zipper - |> move_right(pred) + move_right(zipper, pred) end end end - # keeping in mind that version returns `nil` on no match @doc """ Matches and moves to the location of a `__cursor__` in provided source code. diff --git a/test/project/config_test.exs b/test/project/config_test.exs index 80b64c8..939ef3d 100644 --- a/test/project/config_test.exs +++ b/test/project/config_test.exs @@ -179,7 +179,7 @@ defmodule Igniter.Project.ConfigTest do """ end - test "we workaround trailing comments bug" do + test "we merge configs even in large config files" do %{rewrite: rewrite} = Igniter.new() |> Igniter.create_new_elixir_file("config/fake.exs", """