Elixir v1.3.1 OptionParser

This module contains functions to parse command line options.

Summary

Functions

Low-level function that parses one option

Parses argv into a keywords list

The same as parse/2 but raises an OptionParser.ParseError exception if any invalid options are given

Similar to parse/2 but only parses the head of argv; as soon as it finds a non-switch, it stops parsing

The same as parse_head/2 but raises an OptionParser.ParseError exception if any invalid options are given

Splits a string into argv chunks

Receives a key-value enumerable and converts it to argv

Types

argv :: [String.t]
errors :: [{String.t, String.t | nil}]
options :: [switches: Keyword.t, strict: Keyword.t, aliases: Keyword.t]

Functions

next(argv, opts \\ [])

Specs

next(argv, options) ::
  {:ok, key :: atom, value :: term, argv} |
  {:invalid, String.t, String.t | nil, argv} |
  {:undefined, String.t, String.t | nil, argv} |
  {:error, argv}

Low-level function that parses one option.

It accepts the same options as parse/2 and parse_head/2 as both functions are built on top of next. This function may return:

  • {:ok, key, value, rest} - the option key with value was successfully parsed

  • {:invalid, key, value, rest} - the option key is invalid with value (returned when the switch type does not match the one given via the command line)

  • {:undefined, key, value, rest} - the option key is undefined (returned in strict mode when the switch is unknown)

  • {:error, rest} - there are no switches at the top of the given argv
parse(argv, opts \\ [])

Specs

parse(argv, options) :: {parsed, argv, errors}

Parses argv into a keywords list.

It returns a three-element tuple as follows:

  1. parsed switches,
  2. remaining arguments,
  3. invalid options.

Examples

iex> OptionParser.parse(["--debug"])
{[debug: true], [], []}

iex> OptionParser.parse(["--source", "lib"])
{[source: "lib"], [], []}

iex> OptionParser.parse(["--source-path", "lib", "test/enum_test.exs", "--verbose"])
{[source_path: "lib", verbose: true], ["test/enum_test.exs"], []}

By default, Elixir will try to automatically parse all switches. Switches followed by a value will be assigned the value, as a string. Switches without an argument, like --debug will automatically be set to true.

Note: Elixir also converts the switches to underscore atoms, so --source-path becomes :source_path, to better suit Elixir conventions. This means that option names on the command line cannot contain underscores; such options will be put in the invalid options list.

Switch Definitions

Often it is better to explicitly list the known switches and their formats. The switches can be specified via two alternative options:

  • :switches - defines some switches. An attempt is still made to parse switches that do not appear in the list.

  • :strict - the switches are strict. Any switch that is not specified in the list is returned in the invalid options list.

Note that you should only supply the :switches or :strict option. If you supply both, an error will be raised.

Types

Option parser switches may take 0 or 1 argument.

The following switches take no argument:

  • :boolean - sets the value to true when given
  • :count - counts the number of times the switch is given

The following switches take 1 argument:

  • :integer - parses the upcoming value as an integer.
  • :float - parses the upcoming value as a float.
  • :string - parses the upcoming value as a string.

If a switch can’t be parsed, it is returned in the invalid options list.

Modifiers

Switches can be specified with modifiers, which change how they behave. The following modifiers are supported:

  • :keep - keeps duplicated items instead of overriding them. Works with all types except :count.

Note: if you want to use :keep with a non-string type, use a list, e.g. [foo: [:integer, :keep]].

Examples

Here are some examples of option parser working with different types and modifiers:

iex> OptionParser.parse(["--unlock", "path/to/file"], strict: [unlock: :boolean])
{[unlock: true], ["path/to/file"], []}

iex> OptionParser.parse(["--unlock", "--limit", "0", "path/to/file"],
...>                    strict: [unlock: :boolean, limit: :integer])
{[unlock: true, limit: 0], ["path/to/file"], []}

iex> OptionParser.parse(["--limit", "3"], strict: [limit: :integer])
{[limit: 3], [], []}

iex> OptionParser.parse(["--limit", "xyz"], strict: [limit: :integer])
{[], [], [{"--limit", "xyz"}]}

iex> OptionParser.parse(["--verbose"], switches: [verbose: :count])
{[verbose: 1], [], []}

iex> OptionParser.parse(["-v", "-v"], aliases: [v: :verbose], strict: [verbose: :count])
{[verbose: 2], [], []}

iex> OptionParser.parse(["--unknown", "xyz"], strict: [])
{[], ["xyz"], [{"--unknown", nil}]}

iex> OptionParser.parse(["--limit", "3", "--unknown", "xyz"],
...>                    switches: [limit: :integer])
{[limit: 3, unknown: "xyz"], [], []}

iex> OptionParser.parse(["--unlock", "path/to/file", "--unlock", "path/to/another/file"], strict: [unlock: :keep])
{[unlock: "path/to/file", unlock: "path/to/another/file"], [], []}

Negation switches

In case a switch is declared as boolean, it may be passed as --no-SWITCH which will set the option to false:

iex> OptionParser.parse(["--no-op", "path/to/file"], switches: [op: :boolean])
{[op: false], ["path/to/file"], []}

Aliases

A set of aliases can be given as options too:

iex> OptionParser.parse(["-d"], aliases: [d: :debug])
{[debug: true], [], []}
parse!(argv, opts \\ [])

Specs

parse!(argv, options) ::
  {parsed, argv} |
  no_return

The same as parse/2 but raises an OptionParser.ParseError exception if any invalid options are given.

If there weren’t any errors, returns a three-element tuple as follows:

1. parsed options,
2. remaining arguments,
3. empty list.

Examples

iex> OptionParser.parse!(["--limit", "xyz"], strict: [limit: :integer])
** (OptionParser.ParseError) 1 error found!
--limit : Expected type integer, got "xyz"

iex> OptionParser.parse!(["--unknown", "xyz"], strict: [])
** (OptionParser.ParseError) 1 error found!
--unknown : Unknown option

iex> OptionParser.parse!(["-l", "xyz", "-f", "bar"],
...>                     switches: [limit: :integer, foo: :integer], aliases: [l: :limit, f: :foo])
** (OptionParser.ParseError) 2 errors found!
-l : Expected type integer, got "xyz"
-f : Expected type integer, got "bar"
parse_head(argv, opts \\ [])

Specs

parse_head(argv, options) :: {parsed, argv, errors}

Similar to parse/2 but only parses the head of argv; as soon as it finds a non-switch, it stops parsing.

See parse/2 for more information.

Example

iex> OptionParser.parse_head(["--source", "lib", "test/enum_test.exs", "--verbose"])
{[source: "lib"], ["test/enum_test.exs", "--verbose"], []}

iex> OptionParser.parse_head(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"])
{[verbose: true, source: "lib"], ["test/enum_test.exs", "--unlock"], []}
parse_head!(argv, opts \\ [])

Specs

parse_head!(argv, options) ::
  {parsed, argv, errors} |
  no_return

The same as parse_head/2 but raises an OptionParser.ParseError exception if any invalid options are given.

If there weren’t any errors, returns a three-element tuple as follows:

1. parsed options,
2. remaining arguments,
3. empty list.

Examples

iex> OptionParser.parse_head!(["--number", "lib", "test/enum_test.exs", "--verbose"], strict: [number: :integer])
** (OptionParser.ParseError) 1 error found!
--number : Expected type integer, got "lib"

iex> OptionParser.parse_head!(["--verbose", "--source", "lib", "test/enum_test.exs", "--unlock"],
...>                          strict: [verbose: :integer, source: :integer])
** (OptionParser.ParseError) 2 errors found!
--verbose : Missing argument of type integer
--source : Expected type integer, got "lib"
split(string)

Specs

split(String.t) :: argv

Splits a string into argv chunks.

Examples

iex> OptionParser.split("foo bar")
["foo", "bar"]

iex> OptionParser.split("foo \"bar baz\"")
["foo", "bar baz"]
to_argv(enum)

Specs

to_argv(Enumerable.t) :: argv

Receives a key-value enumerable and converts it to argv.

Keys must be atoms. Keys with nil value are discarded, boolean values are converted to --key or --no-key and all other values are converted using to_string/1.

Examples

iex>  OptionParser.to_argv([foo_bar: "baz"])
["--foo-bar", "baz"]

iex>  OptionParser.to_argv([bool: true, bool: false, discarded: nil])
["--bool", "--no-bool"]