* Added new script type to pre-job startup tasks * Updated Dockerfile to create the needful directories * added tests
73 lines
2.1 KiB
Elixir
73 lines
2.1 KiB
Elixir
defmodule Pinchflat.Lifecycle.UserScripts.CommandRunner do
|
|
@moduledoc """
|
|
Runs custom user commands commands using the `System.cmd/3` function
|
|
"""
|
|
|
|
require Logger
|
|
|
|
alias Pinchflat.Utils.CliUtils
|
|
alias Pinchflat.Utils.FilesystemUtils
|
|
alias Pinchflat.Lifecycle.UserScripts.UserScriptCommandRunner
|
|
|
|
@behaviour UserScriptCommandRunner
|
|
|
|
@event_types [
|
|
:app_init,
|
|
:media_pre_download,
|
|
:media_downloaded,
|
|
:media_deleted
|
|
]
|
|
|
|
@doc """
|
|
Runs the user script command for the given event type. Passes the event
|
|
and the encoded data to the user script command.
|
|
|
|
This function will succeed in almost all cases, even if the user script command
|
|
failed - this is because I don't want bad scripts to stop the whole process.
|
|
If something fails, it'll be logged and returned BUT the tuple will always
|
|
start with {:ok, ...}.
|
|
|
|
The only things that can cause a true failure are passing in an invalid event
|
|
type or if the passed data cannot be encoded into JSON - both indicative of
|
|
failures in the development process.
|
|
|
|
Returns {:ok, :no_executable} | {:ok, output, exit_code}
|
|
"""
|
|
@impl UserScriptCommandRunner
|
|
def run(event_type, encodable_data) when event_type in @event_types do
|
|
case backend_executable() do
|
|
{:ok, :no_executable} ->
|
|
{:ok, :no_executable}
|
|
|
|
{:ok, executable_path} ->
|
|
{:ok, encoded_data} = Phoenix.json_library().encode(encodable_data)
|
|
|
|
{output, exit_code} =
|
|
CliUtils.wrap_cmd(
|
|
executable_path,
|
|
[to_string(event_type), encoded_data],
|
|
[],
|
|
logging_arg_override: "[suppressed]"
|
|
)
|
|
|
|
{:ok, output, exit_code}
|
|
end
|
|
end
|
|
|
|
def run(event_type, _encodable_data) do
|
|
raise ArgumentError, "Invalid event type: #{inspect(event_type)}"
|
|
end
|
|
|
|
defp backend_executable do
|
|
base_dir = Application.get_env(:pinchflat, :extras_directory)
|
|
filepath = Path.join([base_dir, "user-scripts", "lifecycle"])
|
|
|
|
if FilesystemUtils.exists_and_nonempty?(filepath) do
|
|
{:ok, filepath}
|
|
else
|
|
Logger.info("User scripts lifecyle file either not present or is empty. Skipping.")
|
|
|
|
{:ok, :no_executable}
|
|
end
|
|
end
|
|
end
|