smon
What is the correct way to pass command line options?
I tried something like this in my mix.exs:
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?
Marked As Solved
benwilson512
It sounds like you want a mix task or an escript.
Also Liked
sger
Hello,
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
finally from the command line:
mix escript.build
$ ./my_app --name=Elixir
Oliver
Hello.
I was looking for a thread similar to my original post which I can no longer reply to (Google group got closed): https://groups.google.com/forum/#!topic/elixir-lang-talk/EbVag1bErEk
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
There is no escript involved.
And I found a solution for commandline arguments: http://erlang.org/doc/man/init.html#get_plain_arguments-0
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.
smon
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!







