I added a compiler (pasted below) to the end of the list of compilers in mix.exs and it works for regular compilation, like running recompile in iex or when the app starts but it doesn’t run when phoenix does a live reload. Any idea how I can make that work?
defmodule Mix.Tasks.Compile.Notifications do
use Mix.Task
def run(_args) do
Task.start(fn ->
System.cmd("afplay", ["/Applications/Slack.app/Contents/Resources/confirm_delivery.mp3"])
end)
System.cmd("noti", ["-t", "Compile complete", "-m", "Fuck yeah"])
IO.puts "Compile complete."
:ok
end
end
1 Like
To anyone googling for something similar, I tracked this down with the help of @bryanjos. You have to add the compiler to the list of reloadable_compilers
in config/dev.exs
. This gets called multiple times when you’re refreshing a page so I updated the compiler to only send notifications every 10 seconds using a GenServer for the hell of it. Hope this helps someone.
defmodule Mix.Tasks.Compile.Notifications do
@moduledoc """
Send notifications when compiling is done
Uses a GenServer to limit the number of notifications it sends to one every
@notification_timeout_ms milliseconds. This is because phoenix checks if any
files need to be compiled on every request.
Setup:
* Put this in lib/mix/tasks/compile
* add :notifications to the end of the list of compilers in mix.exs
* add :notifications to the end of the list of reloadable_compilers in config/dev.exs
* install noti if you want system notifications
"""
use Mix.Task
use GenServer
@notification_timeout_ms 10_000
@doc """
This is called when the compiler runs
"""
def run(_args) do
case GenServer.start(__MODULE__, [], name: __MODULE__) do
{:ok, pid} ->
send(pid, :queue_notification)
{:error, {:already_started, pid}} ->
send(pid, :queue_notification)
error ->
IO.inspect error
IO.puts("Error starting compiler notifications")
end
IO.puts "Compile complete."
:ok
end
def init(args) do
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:ok, args}
end
# Sets the state to :ok meaning it should send notifications
def handle_info(:queue_notification, _state) do
{:noreply, :ok}
end
# when the state is nil, notifications should not be sent
def handle_info(:send_notifications, nil) do
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:noreply, nil}
end
# send notifications then set the state to nil
def handle_info(:send_notifications, :ok) do
# this is in a task because afplay blocks for about 1.1 seconds
Task.start(fn ->
System.cmd("afplay", ["/Applications/Slack.app/Contents/Resources/confirm_delivery.mp3"])
end)
System.cmd("noti", ["-t", "Compile complete", "-m", "Fuck yeah"])
Process.send_after(self(), :send_notifications, @notification_timeout_ms)
{:noreply, nil}
end
end
1 Like