defmodule Mix.Tasks.Crosswake.Inspect do use Mix.Task alias Crosswake.OperatorInspection alias Crosswake.OperatorInspection.Formatter alias Crosswake.OperatorInspection.JSONFormatter @shortdoc "Inspect route-level Crosswake operator readiness" @moduledoc """ Emits a route-authoritative Crosswake operator inspection document. """ @switches [ format: :string, router: :string ] @impl Mix.Task def run(args) do {opts, _argv, invalid} = OptionParser.parse(args, strict: @switches) if invalid != [] do Mix.raise("invalid options: #{inspect(invalid)}") end document = OperatorInspection.inspect( route_source: router_module!(opts[:router]), cwd: File.cwd!() ) output = case opts[:format] do nil -> Formatter.render(document) "human" -> Formatter.render(document) "json" -> JSONFormatter.render(document) other -> Mix.raise("unsupported format: #{inspect(other)}") end Mix.shell().info(output) end defp router_module!(nil) do Mix.raise("pass --router Elixir.YourAppWeb.Router so inspect can compile Crosswake policy") end defp router_module!(name) when is_binary(name) do module = try do String.to_existing_atom(name) rescue ArgumentError -> Mix.raise("router module #{name} is not available") end if Code.ensure_loaded?(module) do module else Mix.raise("router module #{name} is not available") end end end