Skip to content

Commit 142ebc3

Browse files
committed
Fix handling of boolean options with bad values
1 parent 339c57f commit 142ebc3

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

lib/elixir/lib/option_parser.ex

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ defmodule OptionParser do
167167

168168
defp next(["-" <> option|rest], aliases, switches, strict) do
169169
{option, value} = split_option(option)
170-
opt = tag_option(option, switches, aliases)
170+
opt = tag_option(option, value, switches, aliases)
171171

172172
if strict and not option_defined?(opt, switches) do
173173
{_, opt_name} = opt
@@ -236,11 +236,11 @@ defmodule OptionParser do
236236
end
237237
end
238238

239-
defp tag_option(<<?-, option :: binary>>, switches, _aliases) do
240-
get_negated(option, switches)
239+
defp tag_option(<<?-, option :: binary>>, value, switches, _aliases) do
240+
get_negated(option, value, switches)
241241
end
242242

243-
defp tag_option(option, _switches, aliases) when is_binary(option) do
243+
defp tag_option(option, _value, _switches, aliases) when is_binary(option) do
244244
opt = get_option(option)
245245
if alias = aliases[opt] do
246246
{:default, alias}
@@ -324,13 +324,17 @@ defmodule OptionParser do
324324
option |> to_underscore |> String.to_atom
325325
end
326326

327-
defp get_negated("no-" <> rest = option, switches) do
327+
defp get_negated("no-" <> rest = option, value, switches) do
328328
negated = get_option(rest)
329-
option = if Keyword.has_key?(switches, negated), do: negated, else: get_option(option)
329+
option = if Keyword.has_key?(switches, negated) and value == nil do
330+
negated
331+
else
332+
get_option(option)
333+
end
330334
{:negated, option}
331335
end
332336

333-
defp get_negated(rest, _switches) do
337+
defp get_negated(rest, _value, _switches) do
334338
{:default, get_option(rest)}
335339
end
336340
end

lib/elixir/test/elixir/option_parser_test.exs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ defmodule OptionParserTest do
6767
assert OptionParser.parse(["--no-docs", "foo"], switches: [docs: :boolean])
6868
== {[docs: false], ["foo"], []}
6969
assert OptionParser.parse(["--no-docs=foo", "bar"], switches: [docs: :boolean])
70-
== {[], ["bar"], [docs: "foo"]}
70+
== {[], ["bar"], [no_docs: "foo"]}
7171
assert OptionParser.parse(["--no-docs=", "bar"], switches: [docs: :boolean])
72-
== {[], ["bar"], [docs: ""]}
72+
== {[], ["bar"], [no_docs: ""]}
7373
end
7474

7575
test "does not set unparsed booleans" do
@@ -194,6 +194,8 @@ defmodule OptionParserTest do
194194
== {:error, {:undefined, :str, nil}, ["13", "..."]}
195195
assert OptionParser.next(["--int=hello", "..."], config)
196196
== {:error, {:undefined, :int, "hello"}, ["..."]}
197+
assert OptionParser.next(["--no-bool=other", "..."], config)
198+
== {:error, {:undefined, :no_bool, "other"}, ["..."]}
197199
end
198200

199201
test "next strict: bad type" do
@@ -216,5 +218,7 @@ defmodule OptionParserTest do
216218
== {:error, {:value, :int, nil}, []}
217219
assert OptionParser.next(["--bool=", "..."], config)
218220
== {:error, {:value, :bool, ""}, ["..."]}
221+
assert OptionParser.next(["--no-bool=", "..."], config)
222+
== {:error, {:undefined, :no_bool, ""}, ["..."]}
219223
end
220224
end

0 commit comments

Comments
 (0)