def application do
[
applications: [:logger, :httpoison, :poison],
mod: {Test, []}
]
end
In my Test.ex:
defmodule Test do
use Application
def start(_mode, _args) do
System.argv
|> Test.CLI.main
end
end
But how do I pass arguments to the start function without “confusing” the mix run script? If I try to mix run --type marc, I get
** (Mix) Could not invoke task "run": 1 error found! --type : Unknown option
Ok, I kind of get that. But then I noticed that if I add some random argument in between like mix run what --type marc, it kind of works: The what gets lost on the way, meaning it is missing from System.argv, which leaves ["--type", "marc"].
You may have noticed: I am somewhat confused.
What is the correct way to do this besides turning to escript?
You need escript for this job for example in your mix.exs you must pass
escript: [main_module: MyApp]
then in your module define something like this:
defmodule MyApp do
def main(args) do
args |> parse_args |> process
end
def process([]) do
IO.puts "No arguments given"
end
def process(options) do
IO.puts "Hello #{options[:name]}"
end
defp parse_args(args) do
{options, _, _} = OptionParser.parse(args, switches: [name: :string])
options
end
end
My idea was to avoid the mix escript.build step. Looking at mix tasks, it seems like I would have to start all dependencies manually - so maybe an escript is still the more elegant solution. Thank you for your example!
My original solution was indeed based on escript, but in order to enable “-mode embedded” for code preloading I had to switch away from it and over to building my software with distillery.
distillery builds you scripts to start your application like this: bin/myapp foreground
I filtered, joined, and processed the results and I had all the commandline arguments I needed. Finally solved my problem with commandline arguments.
My final commandline looks like this: bin/myapp foreground --config "something". (You have other options to start the application, of course, like detached or with an attached console.) I then put the parsed results in my applications environment with Application.put_env(:myapp, <key, <value>) and retrieve them later when needed easily.