I’m beginning to learn a little Elixir & Phoenix and I ran into a case
where I wish I had a Mix task for something. Specifically I wanted to
npm scripts with mix so I’d only have one command to run instead
npm for my toy Phoenix project.
Writing a Mix task is reasonably straightforward with only a few steps:
- If you want to create a mix task called “echo” then create a module
Mix.Tasks.Echo. The task name seen in
mix helpis based upon the name of the module minus
Mix.Tasks. (The module needs to be called
mixwill not see it.)
use Mix.Taskto this module.
- Write a public method called
run. It has the type signature:
run([binary]) :: any. That means that it will get a list of strings (the command line arguments) and can return anything.
- Add a
@shortdoc. This will be used as the text in
mix help. Without this your task will not appear in
mix helpbut will still be usable.
- Optionally add a
@moduledoc. This will be used if you run
mix help YOURTASK
You can put this module where ever you want in
lib but typically you
would put it into
An interesting thing I found was that step #2 was not actually needed.
That behaviour defines
@shortdoc so without it you cannot use
@shortdoc to add the task to
mix help output.
Since I was creating a mix task for use in a build I needed to make
sure that if the task was not successful that
mix would return an
error code so that the shell could see the error and fail a build. At
first I assumed that the return value of the task was how that would
be done; however I didn’t find much documentation about this. I
experimented with some likely return values like
"something"} but that had no effect, it always returned a zero exit
status to the shell. Ultimately I choose to raise an error when the
task didn’t work and that definitely caused a non-zero exit status.