Although we can run our code by calling the run function via mix, it isn’t friendly for other users. So let’s create something we can run from the command line.
Mix can package our code, along with its dependencies, into a single file that can be run on any Unix-based platform. This uses Erlang’s escript utility, which can run precompiled programs stored as a Zip archive. In our case, the program will be run as issues.
When escript runs a program, it looks in your mix.exs file for the option escript. This should return a keyword list of escript configuration settings. The most important of these is main_module:, which must be set to the name of a module containing a main function. It passes the command-line arguments to this main function as a list of character lists (not binaries). As this seems to be a command-line concern, we’ll put the main function in Issues.CLI. Here’s the update to mix.exs:
| defmodule Issues.MixProject do |
| use Mix.Project |
| |
| def project do |
| [ |
| app: :issues, |
» | escript: escript_config(), |
| version: "0.1.0", |
| elixir: "~> 1.6-dev", |
| start_permanent: Mix.env() == :prod, |
| deps: deps() |
| ] |
| end |
| |
| def application do |
| [ |
| extra_applications: [:logger] |
| ] |
| end |
| |
| defp deps do |
| [ |
| { :httpoison, "~> 1.0.0" }, |
| { :poison, "~> 3.1" }, |
| ] |
| end |
» | defp escript_config do |
» | [ |
» | main_module: Issues.CLI |
» | ] |
» | end |
| end |
Now let’s add a main function to our CLI. In fact, all we need to do is rename the existing run function:
| def main(argv) do |
| argv |
| |> parse_args |
| |> process |
| end |
Then we package our program using mix:
| $ mix escript.build |
| Generated escript issues |
Now we can run the app locally. We can also send it to a friend—it will run on any computer that has Erlang installed.
| $ ./issues pragdave earmark 4 |
| num | created_at | title |
| ----+----------------------+----------------------------------------------- |
| ---------- |
| 159 | 2017-09-21T10:01:24Z | Block level HTML ... messes up formatting |
| 161 | 2017-10-11T09:12:59Z | Be clear in README ... GFM are supported. |
| 162 | 2017-10-11T16:59:50Z | Working on #161, looking at rendering |
| 171 | 2017-12-03T11:08:40Z | Fix typespecs |