mbu/lib/buildtask.ex
2018-03-18 17:35:39 +02:00

80 lines
2.6 KiB
Elixir

defmodule MBU.BuildTask do
@moduledoc """
BuildTask contains the macros that are used for making the tasks look nicer.
"""
@doc """
Sets up the necessary things for a build task.
Each build task should have `use MBU.BuildTask` at its beginning. BuildTask automatically
imports Mix.Task and Logger so they don't need to be added into the task itself.
The following options may be passed to the use clause:
- `:auto_path`: Set to `true` to autogenerate an `out_path/0` function for this task. Default:
`false`. Overrides the `:auto_paths` config.
- `:create_out_path`: Set to `true` to create the output path specified by `out_path/0` when the
task is started. Default: `false`. Overrides the `:create_out_paths` config.
"""
defmacro __using__(opts \\ []) do
quote do
use Mix.Task
require Logger
import MBU.BuildTask
# Dependencies of the task that will be automatically run before it
@deps []
@create_out_path Keyword.get(unquote(opts), :create_out_path, nil)
auto_path = Keyword.get(unquote(opts), :auto_path, nil)
if auto_path || (Application.get_env(:mbu, :auto_paths, false) and auto_path == nil) do
def out_path() do
Path.join([tmp_path(), Mix.Task.task_name(__MODULE__)])
end
defp tmp_path() do
# Get temporary directory or raise error
case Application.get_env(:mbu, :tmp_path) do
nil ->
raise "MBU must be configured with a directory to put temporary files in if automatic "
"directory handling is used! Use the `:tmp_path` key to set a desired path."
path ->
path
end
end
end
end
end
@doc """
Replacement for Mix.Task's run/1, used similarly. Code inside will be run when the task
is called, with @deps being run first unless `deps: false` is given in the arguments.
"""
defmacro task(args, do: block) do
quote do
def run(unquote(args) = mbu_buildtask_args) do
task = Mix.Task.task_name(__MODULE__)
Logger.info("[#{task}] Started")
if @create_out_path ||
(Application.get_env(:mbu, :create_out_paths, false) and @create_out_path == nil) do
op = apply(__MODULE__, :out_path, [])
Logger.info("[#{task}] Creating output path #{op}...")
:ok = File.mkdir_p!(op)
end
if Keyword.get(mbu_buildtask_args, :deps, true) and not Enum.empty?(@deps) do
MBU.TaskUtils.run_tasks(@deps)
end
unquote(block)
Logger.info("[#{task}] Finished")
end
end
end
end