What is this article all about?
This article explains all about creating custom mix tasks and documenting the created task.
Here, we fly in the space of Elixir to create mix tasks in mix project including with docs and short docs.
What is our Task?
Our Task is to list out the functions in the module passing as parameter to the task.
So, when you run the command
mix my_tasks.functions ModuleName , it has to list out all the functions defined in the module
Before diving into coding, we have to understand few terms which will play a key role in creation of task.
This is the simple module responsible for creating and controlling tasks.
To behave our module as a task we have to follow some naming conventions.
Our module name should start with
Mix.Tasks for an example, if our task name is
functions , then module name is
Mix.Tasks.Functions and we have to use the task behavior module
use Mix.Task a first line of code in our module .
This acts as a callback function to our task. All your task logic resides inside this function. This function takes list of binary
[binary] values and returns
1 run([binary]) :: any
This module attribute makes the task public with a short description that appears on
mix help . It means when you execute a command
mix help you can see all tasks available in the scope along with single line description about the task.
In addition we have two more attributes.
@recursive used in umbrella projects to keep the task running continuously and
@referred_cli_env which recommends environment to run task. We don’t need them now.
This module attribute is used to describe all about task. So, when some one wants help about your task, The binary of this attribute is shown as a response to a request
mix help my_tasks.functions .
Lets Create Task
Now it is time to create our task which list out all the functions defined inside the module passed as parameter.
Lets do this.
Create a new project
1 mix new my_tasks
Create Task directory
After creation of the project go to your
lib directory and create one nested directory as
mix/tasks . This is where all our tasks reside.
1 2 3 $ cd path/to/your/project $ cd lib $ mkdir -p mix/tasks
Testing Module Files
Now we will create two files in
lib directory one
hello.ex and other one is
hi.ex with some random functions. We are going to list out those module functions using our task as proof of working.
This is how our files looks.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #hello.ex defmodule Hello do def hello1 do IO.puts "hello1" end def hello2 do IO.puts "hello2" end def hello3 do IO.puts "hello3" end end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #hi.ex defmodule Hi do def hi1 do IO.puts "hi1" end def hi2 do IO.puts "hi2" end def hi3 do IO.puts "hi3" end end
These files do nothing with the task literally. They are just for showing task demo.
Creating Task file
Now create a file
functions.ex in the directory of tasks
/lib/mix/tasks and add the following content.
1 2 3 4 5 6 7 8 9 10 defmodule Mix.Tasks.MyTasks.Functions do use Mix.Task def run([module_name]) do module = Module.concat Elixir,module_name data = apply(module, :__info__, [:functions]) IO.inspect data end end #Task file with out shortdoc
Every module defined in the project has its own
__info__ function, with that you can get all the information about the module. So, I am using this function by passing an atom
:functions to get the list of functions.
So far we have created three files
lib/mix/tasks/functions.ex which is our task file and two more files
Compiling the Project
So far we have created a task but it is not available until you compile your project.
Run the following command in your project root directory.
1 mix compile
After successful compilation you can run your task as
1 2 3 4 5 $ mix my_tasks.functions Hello [hello1: 0, hello2: 0, hello3: 0] $mix my_tasks.functions Hi [hi1: 0, hi2: 0, hi3: 0]
If you see above outputs in your terminal, it means you are good to go.
As a final touch, let’s add docs to our task.
Till now, we have just created a task. We have not provided any docs for the task. So, you cannot find your task shown in the list when you try to execute
mix help or
mix help my_tasks.functions to available your task in the list, you suppose to add some module attributes to your task file.
Lets do that now .
You have to add module attributes
@moduledoc in task module . Keep your description simple and smart.
After adding the module attributes our file will look like following
1 2 3 4 5 6 7 8 9 #functions.ex defmodule Mix.Tasks.MyTasks.Functions do use Mix.Task @shortdoc "Returns functions in Module" @moduledoc ~S""" This is used to list out the all available functions in the module. You suppose to pass module_name as parameter to the task. #Usage
1 2 3 4 mix my_tasks.functins Hello ``` This list out all the functins in the module Hello """ def run([module_name]) do module = Module.concat Elixir,module_name data = apply(module, :__info__, [:functions]) IO.inspect data end end
#Task with @shortdoc and @moduledoc
1 2 3 4 5 6 7 ![img](/images/blog/SOFSiJHylCKMOb-9.png) ```elixir mix help
shortdoc information of task
You can see your task in the list here with
@shortdoc information saying #Returns functions in module
1 mix help my_tasks.functions
moduledoc information of task
Well, you successfully created your Elixir Project Tasks. Do some funny things playing with tasks to master the creation of tasks.
Happy long coding life !!