How to pass named arguments into a Mix Task?

354 views Asked by At

I have this code:

defmodule Mix.Tasks.Echo do
  use Mix.Task

  @impl Mix.Task
  def run(args) do
    IO.puts("running!")
    Mix.shell().info(Enum.join(args, " "))
    IO.inspect(args, label: "Received args")
  end
end

Which can be used like this:


$ mix echo foo.bar 123
running!
foo.bar 123
Received args: ["foo.bar", "123"]

How to change the code so that I'd be able to pass and get access to, by name named arguments?

$ mix echo --arg1=123 --my_arg2="fdsafdsafds"

===>

Received args: %{"arg1" => 123, "my_arg2" => "fdsafdsafds"}

?

2

There are 2 answers

0
smallbutton On BEST ANSWER

I think you are searching for the OptionParser module.

defmodule Mix.Tasks.Echo do
  use Mix.Task

  @impl Mix.Task
  def run(args) do
    {parsed, _, _} = OptionParser.parse(args, strict: [my_arg1: :string, my_arg2: :boolean])
    IO.inspect(parsed, label: "Received args")
  end
end

This will give you a keyword list instead, which makes sense since it preserves order and allows for duplicate arguments. From there you can use Enum.into/1 if you really need a map. You can also see that it allows for types.

0
Aleksei Matiushkin On

One can use literally any existing task in any existing project to check how is it done.

E. g. mix xref accepts arguments and parses them with OptionParser.

NB the standard format of naming arguments to is not --foo=bar, but --foo bar.

mix echo --arg1 123 --my_arg2 "fdsafdsafds"