Last active
March 25, 2025 14:01
-
-
Save andreaseriksson/e454b9244a734310d4ab74d8595f98cd to your computer and use it in GitHub Desktop.
Revisions
-
andreaseriksson revised this gist
Mar 3, 2023 . 1 changed file with 26 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -40,15 +40,19 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do end def ask_about_replacement(content, route, learnings) do route = String.trim(route) if verified_route = find_verified_route_from_string(route) do replacement = Map.get(learnings, route) || ask_for_direct_match(route, verified_route) || ask_for_fallback(route, verified_route) if replacement && (String.starts_with?(replacement, "~p\"/") || String.starts_with?(replacement, "url")) do replace_content( String.replace(content, route, replacement), Map.put(learnings, route, replacement) ) end else {:ok, content, learnings} end end @@ -57,10 +61,8 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do """ What is the verified route for (type "skip" for skipping): #{IO.ANSI.red}#{route}#{IO.ANSI.reset} Start with: ~p"/.. """) response = String.trim("#{response}") response != "" && response @@ -69,13 +71,10 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do def ask_for_direct_match(route, verified_route) do if Mix.shell().yes?( """ Should we replace #{IO.ANSI.red}#{route}#{IO.ANSI.reset} with #{IO.ANSI.green}#{verified_route}#{IO.ANSI.reset} """) do verified_route end @@ -103,8 +102,13 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do |> case do %{path: "" <> path} -> path = interpolate_path_with_vars(path, arguments) path = maybe_add_params(path, arguments) if String.contains?(route_helper, "_url") do ~s[url(~p"#{path}")] else ~s(~p"#{path}") end _ -> nil end @@ -124,4 +128,19 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do String.replace(memo, slot, "##{argument}", global: false) end) end def maybe_add_params(path, arguments) do case Enum.filter(arguments, &String.contains?(&1, ": ")) do [] -> if "params" in arguments do query_params = "{params}" "#{path}?##{query_params}" else path end query_params -> query_params = "{#{inspect(query_params) |> String.replace("\"", "") }}" "#{path}?##{query_params}" end end end -
andreaseriksson revised this gist
Mar 2, 2023 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,11 +3,12 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do use Mix.Task @regex ~r/(Routes\.)(.*)_(path|url)\(.*?\)/ @web_module MyAppWeb def run(_) do Path.wildcard("lib/**/*.*ex") |> Enum.concat(Path.wildcard("test/**/*.*ex*")) |> Enum.sort() |> Enum.filter(&(File.read!(&1) |> String.contains?("Routes."))) |> Enum.reduce(%{}, fn filename, learnings -> -
andreaseriksson revised this gist
Mar 2, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -23,7 +23,7 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do content = File.read!(filename) case replace_content(content, learnings) do {:ok, content, learnings} -> File.write!(filename, content) learnings _ -> -
andreaseriksson created this gist
Mar 2, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,126 @@ defmodule Mix.Tasks.ConvertToVerifiedRoutes do @shortdoc "Fix routes" use Mix.Task @regex ~r/(Routes\.)(.*)_path\(.*?\)/ @web_module LiveSaasKitWeb def run(_) do Path.wildcard("lib/**/*.*ex") |> Enum.sort() |> Enum.filter(&(File.read!(&1) |> String.contains?("Routes."))) |> Enum.reduce(%{}, fn filename, learnings -> test_filename(filename, learnings) end) :ok end def test_filename(filename, learnings) do Mix.shell().info(filename) content = File.read!(filename) case replace_content(content, learnings) do {:ok, _content, learnings} -> File.write!(filename, content) learnings _ -> learnings end end def replace_content(content, learnings) do case Regex.run(@regex, content) do [route|_] -> ask_about_replacement(content, route, learnings) _ -> {:ok, content, learnings} end end def ask_about_replacement(content, route, learnings) do if verified_route = find_verified_route_from_string(route) do replacement = Map.get(learnings, route) || ask_for_direct_match(route, verified_route) || ask_for_fallback(route, verified_route) if replacement && String.starts_with?(replacement, "~p\"/") do replace_content( String.replace(content, route, replacement), Map.put(learnings, route, replacement) ) end end end def ask_for_fallback(route, _verified_route) do response = Mix.shell().prompt( """ What is the verified route for (type "skip" for skipping): #{IO.ANSI.red}#{route}#{IO.ANSI.reset} Start with: ~p"/.. """) response = String.trim("#{response}") response != "" && response end def ask_for_direct_match(route, verified_route) do if Mix.shell().yes?( """ Should we replace #{IO.ANSI.red}#{route}#{IO.ANSI.reset} with #{IO.ANSI.green}#{verified_route}#{IO.ANSI.reset} """) do verified_route end end def find_verified_route_from_string(route) do parts = route |> String.replace("Routes.", "") |> String.split("(") with [route_helper, arguments|_] <- parts do arguments = arguments |> String.replace_trailing(")", "") |> String.split(",") |> Enum.map(&String.trim/1) @web_module.Router.__routes__() |> Enum.find(fn %{helper: helper, plug_opts: plug_opts} -> is_atom(plug_opts) && Enum.member?(arguments, ":#{plug_opts}") && String.starts_with?(route_helper, helper) end) |> case do %{path: "" <> path} -> path = interpolate_path_with_vars(path, arguments) ~s(~p"#{path}") _ -> nil end end end def interpolate_path_with_vars(path, arguments) do arguments = Enum.slice(arguments, 2..10) path |> String.split("/") |> Enum.filter(&String.starts_with?(&1, ":")) |> Enum.with_index() |> Enum.reduce(path, fn {slot, idx}, memo -> argument = Enum.at(arguments, idx) argument = "{#{argument}}" String.replace(memo, slot, "##{argument}", global: false) end) end end