On of my projects needs to receive files from outside, like for example being uploaded from Github CI and I'd like to simulate this behaviour on my local machine. So, I needed a mix task which I will trigger and it would upload a file to the application.
Easiest way would be to start the application in one terminal tab and trigger this mix task in another.But Phoenix has all needed to make these both tasks simultanesly. In other words mix tasks can start up your application and shut it down when it's finished.
defmodule AppForArticleWeb.PageController do
use AppForArticleWeb, :controller
def home(conn, %{"id" => id}) do
text conn, "Showing id #{id}"
end
end
Just for the sake of explanation I will keep it simple. Just a controller action that accepts get request with one query parameter.
defmodule Mix.Tasks.UploadDevReport do
use Mix.Task
@shortdoc "Uploads a development report to the local server"
@impl Mix.Task
def run(_args) do
start_backend()
%Req.Response{body: body} = Req.get!("http://localhost:4000?id=1")
IO.puts(body)
end
defp phoenix_running?(address, port) do
case :gen_tcp.connect(to_char_list(address), port, [:binary, active: false], 1000) do
{:ok, _} -> true
{:error, _} -> false
end
end
defp start_backend do
case phoenix_running?("localhost", 4000) do
false ->
Application.put_env(:phoenix, :serve_endpoints, true, persistent: true)
Mix.Task.run("app.start", [])
true ->
Mix.Task.run("app.start", [])
end
end
end
The mix task itself is relatively simple as well. I just check if TCP server is running. If not it starts the application. Main part is taken from the Phoenix github repo.