View Source Mix.Task behaviour (Mix v1.18.0-dev)
Provides conveniences for creating, loading, and manipulating Mix tasks.
To create a new Mix task, you'll need to:
- Create a module whose name begins with
Mix.Tasks.
(for example,Mix.Tasks.MyTask
). - Call
use Mix.Task
in that module. - Implement the
Mix.Task
behaviour in that module (that is, implement therun/1
callback).
Typically, task modules live inside the lib/mix/tasks/
directory,
and their file names use dot separators instead of underscores
(for example, deps.clean.ex
) - although ultimately the file name is not
relevant.
For example:
# lib/mix/tasks/echo.ex
defmodule Mix.Tasks.Echo do
@moduledoc "Printed when the user requests `mix help echo`"
@shortdoc "Echoes arguments"
use Mix.Task
@impl Mix.Task
def run(args) do
Mix.shell().info(Enum.join(args, " "))
end
end
The command name will correspond to the portion of the module
name following Mix.Tasks.
. For example, a module name of
Mix.Tasks.Deps.Clean
corresponds to a task name of deps.clean
.
The run/1
function will receive a list of all command line
arguments passed, according to the user's terminal.
For example, if the args
in the above echo
task were
inspected, you might see something like this:
$ mix echo 'A and B' C --test
["A and B", "C", "--test"]
use Mix.Task
When you use Mix.Task
, the Mix.Task
module will
set @behaviour Mix.Task
and define default values
for the module attributes documented in the section
below.
Module attributes
You can control some behavior of your Mix task by setting module attributes. This section documents the available attributes.
@shortdoc
Define the @shortdoc
attribute if you wish to make the task
publicly visible on mix help
. Omit this attribute if you do
not want your task to be listed via mix help
.
@moduledoc
The @moduledoc
attribute may override @shortdoc
. The task
will not appear in mix help
if documentation for the entire
module is hidden with @moduledoc false
.
@requirements
If a task has requirements, they can be listed using the
@requirements
attribute. Requirements are other Mix
tasks that this task requires to have run. For example:
@requirements ["app.config"]
A task will typically depend on one of the following tasks:
"loadpaths" - this ensures dependencies are available and compiled. If you are publishing a task as part of a library to be used by others, and your task does not need to interact with the user code in any way, this is the recommended requirement
"app.config" - additionally compiles and load the runtime configuration for the current project. If you are creating a task to be used within your application or as part of a library, which must invoke or interact with the user code, this is the minimum recommended requirement
"app.start" - additionally starts the supervision tree of the current project and its dependencies
@recursive
Set @recursive true
if you want the task to run
on each umbrella child in an umbrella project.
@preferred_cli_env
Sets the preferred Mix environment for this task. For example, if your task is meant to be used for testing, you could set
@preferred_cli_env :test
Documentation
Users can read the documentation for public Mix tasks by
running mix help my_task
. The documentation that will be
shown is the @moduledoc
of the task's module.
Summary
Callbacks
A task needs to implement run
which receives
a list of command line args.
Functions
Checks if the given task
name is an alias.
Returns all loaded task modules.
Clears all invoked tasks, allowing them to be reinvoked.
Receives a task name and returns the corresponding task module if one exists.
Receives a task name and retrieves the corresponding task module.
Loads all tasks in all code paths.
Loads all tasks in the given paths
.
Gets the moduledoc for the given task module
.
Available for backwards compatibility.
Indicates if the current task is recursing.
Checks if the task should be run recursively for all sub-apps in umbrella projects.
Reenables a given task so it can be executed again down the stack.
Gets the list of requirements for the given task.
Reruns task
with the given arguments.
Conditionally runs the task (or alias) with the given args
.
Runs recursive tasks in the specified list of children apps for umbrella projects.
Gets the shortdoc for the given task module
.
Returns true
if given module is a task.
Returns the task name for the given module
.
Types
Callbacks
Functions
Checks if the given task
name is an alias.
Returns false
if the given name is not an alias or if it is not a task.
For more information about task aliasing, take a look at the
"Aliases" section in the
docs for Mix
.
@spec all_modules() :: [task_module()]
Returns all loaded task modules.
Modules that are not yet loaded won't show up.
Check load_all/0
if you want to preload all tasks.
@spec clear() :: :ok
Clears all invoked tasks, allowing them to be reinvoked.
This operation is not recursive.
@spec get(task_name()) :: task_module() | nil
Receives a task name and returns the corresponding task module if one exists.
Returns nil
if the module cannot be found, if it is an alias, or if it is
not a valid Mix.Task
.
@spec get!(task_name()) :: task_module()
Receives a task name and retrieves the corresponding task module.
Exceptions
Mix.NoTaskError
- raised if the task could not be foundMix.InvalidTaskError
- raised if the task is not a validMix.Task
@spec load_all() :: [task_module()]
Loads all tasks in all code paths.
@spec load_tasks([List.Chars.t()]) :: [task_module()]
Loads all tasks in the given paths
.
@spec moduledoc(task_module()) :: String.t() | nil | false
Gets the moduledoc for the given task module
.
Returns the moduledoc or nil
.
Available for backwards compatibility.
@spec recursing?() :: boolean()
Indicates if the current task is recursing.
This returns true
if a task is marked as recursive
and it is being executed inside an umbrella project.
@spec recursive(task_module()) :: boolean()
Checks if the task should be run recursively for all sub-apps in umbrella projects.
Returns true
or false
.
@spec reenable(task_name()) :: :ok
Reenables a given task so it can be executed again down the stack.
Both alias and the regular stack are re-enabled when this function is called.
If an umbrella project reenables a task, it is re-enabled for all child projects.
@spec requirements(task_module()) :: []
Gets the list of requirements for the given task.
Returns a list of strings, where the string is expected to be a task optionally followed by its arguments.
Reruns task
with the given arguments.
This function reruns the given task; to do that, it first re-enables the task and then runs it as normal.
Conditionally runs the task (or alias) with the given args
.
If there exists a task matching the given task name and it has not yet been
invoked, this will run the task with the given args
and return the result.
If there is an alias defined for the given task name, the alias will be invoked instead of the original task.
If the task or alias has already been invoked, subsequent calls to run/2
will abort without executing and return :noop
.
Remember: by default, tasks will only run once, even when called repeatedly!
If you need to run a task multiple times, you need to re-enable it via
reenable/1
or call it using rerun/2
.
run/2
raises an exception if an alias or a task cannot be found or if the
task is invalid. See get!/1
for more information.
Examples
iex> Mix.Task.run("format", ["mix.exs"])
:ok
Runs recursive tasks in the specified list of children apps for umbrella projects.
If the task is not recursive (whose purpose is to be run in children applications), it runs at the project root level as usual. Calling this function outside of an umbrella project root fails.
@spec shortdoc(task_module()) :: String.t() | nil
Gets the shortdoc for the given task module
.
Returns the shortdoc or nil
.
@spec task?(task_module()) :: boolean()
Returns true
if given module is a task.
@spec task_name(task_module()) :: task_name()
Returns the task name for the given module
.
Examples
iex> Mix.Task.task_name(Mix.Tasks.Test)
"test"