defmodule Igniter.Upgrades.Igniter do @moduledoc false alias Igniter.Code.Common alias Igniter.Code.Function alias Igniter.Code.Module alias Sourceror.Zipper require Common require Function @doc """ Rewrites deprecated `igniter/2` callback to `igniter/1` if the module is an `Igniter.Mix.Task`. """ @spec rewrite_deprecated_igniter_callback(Zipper.t()) :: {:ok, Zipper.t()} | :error def rewrite_deprecated_igniter_callback(%Zipper{} = zipper) do with {:ok, zipper} <- Module.move_to_module_using(zipper, [Igniter.Mix.Task]), {:ok, zipper} <- Common.move_to_pattern(zipper, {:def, _, [{:igniter, _, [_, _]} | _]}) do with :error <- remove_ignored_argv(zipper), :error <- replace_generated_argv_usage(zipper) do {:ok, zipper} end else _ -> {:ok, zipper} end end defp remove_ignored_argv(zipper) do with %Zipper{node: {argv_var, _, nil}} <- Zipper.search_pattern(zipper, "igniter(__, __cursor__())"), "_" <> _ <- to_string(argv_var) do remove_argv_arg(zipper) else _ -> :error end end defp replace_generated_argv_usage(zipper) do with {:ok, zipper} <- remove_argv_arg(zipper), {:ok, zipper} <- Common.move_to_do_block(zipper), zipper <- Common.maybe_move_to_block(zipper), true <- generated_argv_usage?(zipper) do zipper = zipper |> Zipper.remove() |> Zipper.next() |> Common.replace_code(""" arguments = igniter.args.positional options = igniter.args.options argv = igniter.args.argv_flags """) {:ok, zipper} else _ -> :error end end defp generated_argv_usage?(zipper) do with ^zipper <- Zipper.search_pattern(zipper, "{arguments, argv} = positional_args!(argv)"), {:ok, zipper} <- Common.move_right(zipper, 1), ^zipper <- Zipper.search_pattern(zipper, "options = options!(argv)") do true else _ -> false end end defp remove_argv_arg(zipper) do Common.within(zipper, fn zipper -> case Zipper.search_pattern(zipper, "igniter(__, __cursor__())") do %Zipper{} = zipper -> {:ok, Zipper.remove(zipper)} _ -> :error end end) end end