diff options
Diffstat (limited to 'lib/elixir')
-rw-r--r-- | lib/elixir/lib/option_parser.ex | 31 | ||||
-rw-r--r-- | lib/elixir/test/elixir/option_parser_test.exs | 17 |
2 files changed, 45 insertions, 3 deletions
diff --git a/lib/elixir/lib/option_parser.ex b/lib/elixir/lib/option_parser.ex index 89a76f057..cce5cd63c 100644 --- a/lib/elixir/lib/option_parser.ex +++ b/lib/elixir/lib/option_parser.ex @@ -33,7 +33,8 @@ defmodule OptionParser do switches: keyword, strict: keyword, aliases: keyword, - allow_nonexistent_atoms: boolean + allow_nonexistent_atoms: boolean, + return_separator: boolean ] defmodule ParseError do @@ -83,6 +84,7 @@ defmodule OptionParser do * `:switches` or `:strict` - see the "Switch definitions" section below * `:allow_nonexistent_atoms` - see the "Parsing unknown switches" section below * `:aliases` - see the "Aliases" section below + * `:return_separator` - see the "Return separator" section below ## Switch definitions @@ -230,6 +232,21 @@ defmodule OptionParser do ...> ) {[unlock: "path/to/file", unlock: "path/to/another/file"], [], []} + ## Return separator + + The separator `--` implies options should no longer be processed. + By default, the separator is not returned as parts of the arguments, + but that can be changed via the `:return_separator` option: + + iex> OptionParser.parse(["--", "lib"], return_separator: true, strict: []) + {[], ["--", "lib"], []} + + iex> OptionParser.parse(["--no-halt", "--", "lib"], return_separator: true, switches: [halt: :boolean]) + {[halt: false], ["--", "lib"], []} + + iex> OptionParser.parse(["script.exs", "--no-halt", "--", "foo"], return_separator: true, switches: [halt: :boolean]) + {[{:halt, false}], ["script.exs", "--", "foo"], []} + """ @spec parse(argv, options) :: {parsed, argv, errors} def parse(argv, opts \\ []) when is_list(argv) and is_list(opts) do @@ -363,8 +380,15 @@ defmodule OptionParser do invalid = if config.strict?, do: [{option, nil} | invalid], else: invalid do_parse(rest, config, opts, args, invalid, all?) - {:error, ["--" | rest]} -> - {Enum.reverse(opts), Enum.reverse(args, rest), Enum.reverse(invalid)} + {:error, ["--" | rest] = remaining_args} -> + args = + if config.return_separator? do + Enum.reverse(args, remaining_args) + else + Enum.reverse(args, rest) + end + + {Enum.reverse(opts), args, Enum.reverse(invalid)} {:error, [arg | rest] = remaining_args} -> # there is no option @@ -616,6 +640,7 @@ defmodule OptionParser do %{ aliases: opts[:aliases] || [], allow_nonexistent_atoms?: opts[:allow_nonexistent_atoms] || false, + return_separator?: opts[:return_separator] || false, strict?: strict?, switches: switches } diff --git a/lib/elixir/test/elixir/option_parser_test.exs b/lib/elixir/test/elixir/option_parser_test.exs index 7f38e4264..c589a1165 100644 --- a/lib/elixir/test/elixir/option_parser_test.exs +++ b/lib/elixir/test/elixir/option_parser_test.exs @@ -148,6 +148,23 @@ defmodule OptionParserTest do ) == {[source: "foo"], ["bar", "--", "-x"], []} end + test "return separators" do + assert OptionParser.parse_head(["--", "foo"], + switches: [], + return_separator: true + ) == {[], ["--", "foo"], []} + + assert OptionParser.parse_head(["--no-halt", "--", "foo"], + switches: [halt: :boolean], + return_separator: true + ) == {[halt: false], ["--", "foo"], []} + + assert OptionParser.parse_head(["foo.exs", "--no-halt", "--", "foo"], + switches: [halt: :boolean], + return_separator: true + ) == {[], ["foo.exs", "--no-halt", "--", "foo"], []} + end + test "parses - as argument" do argv = ["--foo", "-", "-b", "-"] opts = [strict: [foo: :boolean, boo: :string], aliases: [b: :boo]] |