From 91d6f58aec303da96940ff0b3cbacea2b1d395b7 Mon Sep 17 00:00:00 2001 From: Scott Ming Date: Thu, 21 Mar 2024 15:58:35 +0800 Subject: [PATCH] Maybe insert special folder for PhoenixWeb's module --- .../remote_control/code_mod/rename/file.ex | 73 ++++++++++++++++++- .../remote_control/code_mod/rename_test.exs | 69 ++++++++++++++++++ 2 files changed, 138 insertions(+), 4 deletions(-) diff --git a/apps/remote_control/lib/lexical/remote_control/code_mod/rename/file.ex b/apps/remote_control/lib/lexical/remote_control/code_mod/rename/file.ex index 96a94328a..d03790d67 100644 --- a/apps/remote_control/lib/lexical/remote_control/code_mod/rename/file.ex +++ b/apps/remote_control/lib/lexical/remote_control/code_mod/rename/file.ex @@ -32,10 +32,15 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.File do root_path = root_path() relative_path = relative_path(entry.path, root_path) - with {:ok, prefix} <- fetch_conventional_prefix(relative_path), + with {:ok, prefix, old_module_paths} <- fetch_conventional_prefix(relative_path), {:ok, new_name} <- fetch_new_name(entry, new_suffix) do extname = Path.extname(entry.path) - suffix = Macro.underscore(new_name) + + suffix = + new_name + |> Macro.underscore() + |> maybe_insert_special_phoenix_folder(old_module_paths, new_name) + new_path = Path.join([root_path, prefix, "#{suffix}#{extname}"]) {Document.Path.ensure_uri(entry.path), Document.Path.ensure_uri(new_path)} @@ -92,9 +97,69 @@ defmodule Lexical.RemoteControl.CodeMod.Rename.File do {_, []} -> :error - {_module_path, prefix} -> + {module_paths, prefix} -> prefix = prefix |> Enum.reverse() |> Enum.join("/") - {:ok, prefix} + {:ok, prefix, module_paths} end end + + defp maybe_insert_special_phoenix_folder(suffix, old_module_paths, new_name) do + web_app? = new_name |> String.split(".") |> hd() |> String.ends_with?("Web") + + insertions = + cond do + not web_app? -> + "" + + phoenix_component?(old_module_paths, new_name) -> + "components" + + phoenix_controller?(old_module_paths, new_name) -> + "controllers" + + phoenix_live_view?(old_module_paths, new_name) -> + "live" + + true -> + "" + end + + suffix + |> String.split("/") + |> List.insert_at(1, insertions) + |> Enum.reject(&(&1 == "")) + |> Enum.join("/") + end + + defp phoenix_component?(old_module_paths, new_name) do + under_components? = "components" in old_module_paths + component? = String.ends_with?(new_name, ["Components", "Layouts", "Component"]) + + under_components? and component? + end + + defp phoenix_controller?(old_module_paths, new_name) do + under_controllers? = "controllers" in old_module_paths + controller? = String.ends_with?(new_name, ["Controller", "JSON", "HTML"]) + + under_controllers? and controller? + end + + defp phoenix_live_view?(old_module_paths, new_name) do + under_live_views? = "live" in old_module_paths + new_name_list = String.split(new_name, ".") + + live_view? = + if match?([_, _ | _], new_name_list) do + parent = Enum.at(new_name_list, -2) + local_module = Enum.at(new_name_list, -1) + + # `LiveDemoWeb.SomeLive` or `LiveDemoWeb.SomeLive.Index` + String.ends_with?(parent, "Live") or String.ends_with?(local_module, "Live") + else + false + end + + under_live_views? and live_view? + end end diff --git a/apps/remote_control/test/lexical/remote_control/code_mod/rename_test.exs b/apps/remote_control/test/lexical/remote_control/code_mod/rename_test.exs index bbcdc08a9..6fd01af62 100644 --- a/apps/remote_control/test/lexical/remote_control/code_mod/rename_test.exs +++ b/apps/remote_control/test/lexical/remote_control/code_mod/rename_test.exs @@ -389,6 +389,75 @@ defmodule Lexical.RemoteControl.CodeMod.RenameTest do assert {_, to_uri} = rename_file assert to_uri == subject_uri(project, "test/renamed_test.exs") end + + test "leaves the `components` folder as is when renaming the live view", %{project: project} do + {:ok, {_applied, rename_file}} = + ~q[ + defmodule DemoWeb.|FooComponents do + end + ] |> rename("DemoWeb.RenamedComponent", "lib/demo_web/components/foo_component.ex") + + assert {_, to_uri} = rename_file + assert to_uri == subject_uri(project, "lib/demo_web/components/renamed_component.ex") + end + + test "leaves the `components` folder as is when renaming a component", %{project: project} do + {:ok, {_applied, rename_file}} = + ~q[ + defmodule DemoWeb.SomeContext.|FooComponent do + end + ] + |> rename( + "DemoWeb.SomeContext.RenamedComponent", + "lib/demo_web/components/some_context/foo_component.ex" + ) + + assert {_, to_uri} = rename_file + + assert to_uri == + subject_uri(project, "lib/demo_web/components/some_context/renamed_component.ex") + end + + test "leaves the `controllers` folder as is when renaming the controller", %{project: project} do + {:ok, {_applied, rename_file}} = + ~q[ + defmodule DemoWeb.|FooController do + end + ] |> rename("DemoWeb.RenamedController", "lib/demo_web/controllers/foo_controller.ex") + + assert {_, to_uri} = rename_file + assert to_uri == subject_uri(project, "lib/demo_web/controllers/renamed_controller.ex") + end + + test "leaves the `controller` folder as is when renaming the `JSON` module", %{ + project: project + } do + {:ok, {_applied, rename_file}} = + ~q[ + defmodule DemoWeb.FooController.|JSON do + end + ] + |> rename( + "DemoWeb.FooController.RenamedJSON", + "lib/demo_web/controllers/foo_controller/json.ex" + ) + + assert {_, to_uri} = rename_file + + assert to_uri == + subject_uri(project, "lib/demo_web/controllers/foo_controller/renamed_json.ex") + end + + test "leaves the `live` folder as is when renaming the live view", %{project: project} do + {:ok, {_applied, rename_file}} = + ~q[ + defmodule DemoWeb.|FooLive do + end + ] |> rename("DemoWeb.RenamedLive", "lib/demo_web/live/foo_live.ex") + + assert {_, to_uri} = rename_file + assert to_uri == subject_uri(project, "lib/demo_web/live/renamed_live.ex") + end end defp rename(source, new_name, path \\ nil) do