This gave me back a lot of my existing routes as missing because of the way that /live routes are defined with and without an action (for liveview >= v1.7.5 that I tested this with) . Check the structure for these dummy routes:
[%{
helper: "nope",
metadata: %{
log: :debug,
phoenix_live_view: {MyappWeb.NopeLive, :index,
[action: :index, router: MyappWeb.Router],
%{extra: %{session: %{}}, name: :default, vsn: 1642751438384822700}}
},
path: "/nope/index",
plug: Phoenix.LiveView.Plug,
plug_opts: :index,
verb: :get
},
%{
helper: "live",
metadata: %{
log: :debug,
phoenix_live_view: {MyappWeb.NopeLive, nil,
[action: nil, router: MyappWeb.Router],
%{extra: %{session: %{}}, name: :default, vsn: 1642751438384822700}}
},
path: "/nope",
plug: Phoenix.LiveView.Plug,
plug_opts: MyappWeb.NopeLive,
verb: :get
}]
I extracted the reduction to its own function. Note the argument to loaded
in the :live_module
cond, and the route.plug
and function_exported?(...) == false
checks on the :func
cond.
def check_routes(router, endpoint \\ nil) do
routes =
Phoenix.Router.routes(router)
|> Enum.reverse()
column_widths = calculate_column_widths(routes, endpoint)
routes = find_missing(routes)
if Enum.empty?(routes) do
Mix.shell().info("\nRoutes Check - No errors found")
else
routes
|> Enum.map_join("", &format_msg(&1, column_widths))
|> Mix.shell().error()
end
end
defp find_missing(routes) do
Enum.reduce(routes, [], fn route, acc ->
cond do
route.plug == Phoenix.LiveView.Plug and
is_atom(route.plug_opts) and
loaded(elem(route.metadata.phoenix_live_view, 0)) == nil ->
[{:live_module, route} | acc]
loaded(route.plug) == nil ->
[{:module, route} | acc]
route.plug != Phoenix.LiveView.Plug and is_atom(route.plug_opts) and
function_exported?(route.plug, route.plug_opts, 2) == false ->
[{:func, route} | acc]
true ->
acc
end
end)
end