mirror of
https://github.com/TangentFoxy/argparse.git
synced 2025-07-28 11:02:20 +00:00
Merge remote-tracking branch 'luarocks/refs/pull/3/head'
This commit is contained in:
@@ -68,3 +68,24 @@ If more than one argument can be consumed, a table is used to store the data.
|
||||
pair = {"foo", "bar"},
|
||||
optional = "baz"
|
||||
}
|
||||
|
||||
Setting argument choices
|
||||
------------------------
|
||||
|
||||
The ``choices`` property can be used to restrict an argument to a set of choices. Its value is an array of string choices.
|
||||
|
||||
.. code-block:: lua
|
||||
:linenos:
|
||||
|
||||
parser:argument "direction"
|
||||
:choices {"north", "south", "east", "west"}
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ lua script.lua foo
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Usage: script.lua [-h] {north,south,east,west}
|
||||
|
||||
Error: argument 'direction' must be one of 'north', 'south', 'east', 'west'
|
||||
|
@@ -242,6 +242,7 @@ Property Type
|
||||
``defmode`` String
|
||||
``show_default`` Boolean
|
||||
``argname`` String or table
|
||||
``choices`` Table
|
||||
``action`` Function or string
|
||||
``init`` Any
|
||||
``hidden`` Boolean
|
||||
@@ -273,6 +274,7 @@ Property Type
|
||||
``show_default`` Boolean
|
||||
``overwrite`` Booleans
|
||||
``argname`` String or table
|
||||
``choices`` Table
|
||||
``action`` Function or string
|
||||
``init`` Any
|
||||
``hidden`` Boolean
|
||||
|
@@ -107,6 +107,27 @@ Just as arguments, options can be configured to take several command line argume
|
||||
|
||||
Note that the data passed to ``optional`` option is stored in an array. That is necessary to distinguish whether the option was invoked without an argument or it was not invoked at all.
|
||||
|
||||
Setting argument choices
|
||||
------------------------
|
||||
|
||||
The ``choices`` property can be used to specify a list of choices for an option argument in the same way as for arguments.
|
||||
|
||||
.. code-block:: lua
|
||||
:linenos:
|
||||
|
||||
parser:option "--format"
|
||||
:choices {"short", "medium", "full"}
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ lua script.lua --format foo
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Usage: script.lua [-h] [--format {short,medium,full}]
|
||||
|
||||
Error: argument for option '--format' must be one of 'short', 'medium', 'full'
|
||||
|
||||
Setting number of invocations
|
||||
-----------------------------
|
||||
|
||||
|
@@ -161,5 +161,15 @@ describe("tests related to positional arguments", function()
|
||||
}
|
||||
assert.has_error(function() parser:parse{} end, "missing argument 'foo1'")
|
||||
end)
|
||||
|
||||
it("handles invalid argument choices correctly", function()
|
||||
local parse = Parser()
|
||||
parse:argument "foo" {
|
||||
choices = {"bar", "baz", "qu"}
|
||||
}
|
||||
assert.has_error(function()
|
||||
parse:parse{"foo", "quu"}
|
||||
end, "argument 'foo' must be one of 'bar', 'baz', 'qu'")
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
@@ -77,6 +77,34 @@ Options:
|
||||
--config <config>]], parser:get_help())
|
||||
end)
|
||||
|
||||
it("creates correct help message for arguments with choices", function()
|
||||
local parser = Parser "foo"
|
||||
parser:argument "move"
|
||||
:choices {"rock", "paper", "scissors"}
|
||||
|
||||
assert.equal([[
|
||||
Usage: foo [-h] {rock,paper,scissors}
|
||||
|
||||
Arguments:
|
||||
{rock,paper,scissors}
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message and exit.]], parser:get_help())
|
||||
end)
|
||||
|
||||
it("creates correct help message for options with argument choices", function()
|
||||
local parser = Parser "foo"
|
||||
parser:option "--format"
|
||||
:choices {"short", "medium", "full"}
|
||||
|
||||
assert.equal([[
|
||||
Usage: foo [-h] [--format {short,medium,full}]
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message and exit.
|
||||
--format {short,medium,full}]], parser:get_help())
|
||||
end)
|
||||
|
||||
it("adds margin for multiline descriptions", function()
|
||||
local parser = Parser "foo"
|
||||
parser:flag "-v"
|
||||
|
@@ -290,6 +290,16 @@ describe("tests related to options", function()
|
||||
end, "too many arguments")
|
||||
end)
|
||||
|
||||
it("handles invalid argument choices correctly", function()
|
||||
local parse = Parser()
|
||||
parse:option "-s" "--server" {
|
||||
choices = {"foo", "bar", "baz"}
|
||||
}
|
||||
assert.has_error(function()
|
||||
parse:parse{"-slocalhost"}
|
||||
end, "argument for option '-s' must be one of 'foo', 'bar', 'baz'")
|
||||
end)
|
||||
|
||||
it("doesn't accept GNU-like long options when it doesn't need arguments", function()
|
||||
local parser = Parser()
|
||||
parser:flag "-q" "--quiet"
|
||||
|
@@ -89,6 +89,30 @@ Usage: foo <first> <second-and-third> <second-and-third>
|
||||
)
|
||||
end)
|
||||
|
||||
it("creates correct usage message for arguments with choices", function()
|
||||
local parser = Parser "foo"
|
||||
:add_help(false)
|
||||
parser:argument "move"
|
||||
:choices {"rock", "paper", "scissors"}
|
||||
|
||||
assert.equal(
|
||||
[=[Usage: foo {rock,paper,scissors}]=],
|
||||
parser:get_usage()
|
||||
)
|
||||
end)
|
||||
|
||||
it("creates correct usage message for options with argument choices", function()
|
||||
local parser = Parser "foo"
|
||||
:add_help(false)
|
||||
parser:option "--format"
|
||||
:choices {"short", "medium", "full"}
|
||||
|
||||
assert.equal(
|
||||
[=[Usage: foo [--format {short,medium,full}]]=],
|
||||
parser:get_usage()
|
||||
)
|
||||
end)
|
||||
|
||||
it("creates correct usage message for commands", function()
|
||||
local parser = Parser "foo"
|
||||
:add_help(false)
|
||||
|
@@ -341,6 +341,7 @@ local Argument = class({
|
||||
typechecked("defmode", "string"),
|
||||
typechecked("show_default", "boolean"),
|
||||
typechecked("argname", "string", "table"),
|
||||
typechecked("choices", "table"),
|
||||
typechecked("hidden", "boolean"),
|
||||
option_action,
|
||||
option_init
|
||||
@@ -363,6 +364,7 @@ local Option = class({
|
||||
typechecked("show_default", "boolean"),
|
||||
typechecked("overwrite", "boolean"),
|
||||
typechecked("argname", "string", "table"),
|
||||
typechecked("choices", "table"),
|
||||
typechecked("hidden", "boolean"),
|
||||
option_action,
|
||||
option_init
|
||||
@@ -511,17 +513,33 @@ function Argument:_get_argname(narg)
|
||||
end
|
||||
end
|
||||
|
||||
function Argument:_get_choices_list()
|
||||
return "{" .. table.concat(self._choices, ",") .. "}"
|
||||
end
|
||||
|
||||
function Argument:_get_default_argname()
|
||||
return "<" .. self._name .. ">"
|
||||
if self._choices then
|
||||
return self:_get_choices_list()
|
||||
else
|
||||
return "<" .. self._name .. ">"
|
||||
end
|
||||
end
|
||||
|
||||
function Option:_get_default_argname()
|
||||
return "<" .. self:_get_default_target() .. ">"
|
||||
if self._choices then
|
||||
return self:_get_choices_list()
|
||||
else
|
||||
return "<" .. self:_get_default_target() .. ">"
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns labels to be shown in the help message.
|
||||
function Argument:_get_label_lines()
|
||||
return {self._name}
|
||||
if self._choices then
|
||||
return {self:_get_choices_list()}
|
||||
else
|
||||
return {self._name}
|
||||
end
|
||||
end
|
||||
|
||||
function Option:_get_label_lines()
|
||||
@@ -1204,7 +1222,21 @@ function ElementState:invoke()
|
||||
return self.open
|
||||
end
|
||||
|
||||
function ElementState:check_choices(argument)
|
||||
if self.element._choices then
|
||||
for _, choice in ipairs(self.element._choices) do
|
||||
if argument == choice then
|
||||
return
|
||||
end
|
||||
end
|
||||
local choices_list = "'" .. table.concat(self.element._choices, "', '") .. "'"
|
||||
local is_option = getmetatable(self.element) == Option
|
||||
self:error("%s%s must be one of %s", is_option and "argument for " or "", self.name, choices_list)
|
||||
end
|
||||
end
|
||||
|
||||
function ElementState:pass(argument)
|
||||
self:check_choices(argument)
|
||||
argument = self:convert(argument, #self.args + 1)
|
||||
table.insert(self.args, argument)
|
||||
|
||||
|
Reference in New Issue
Block a user