mirror of
https://github.com/TangentFoxy/argparse.git
synced 2025-07-28 11:02:20 +00:00
Added help message generation; Improved optional arguments handling.
This commit is contained in:
@@ -15,6 +15,14 @@ describe("tests related to positional arguments", function()
|
|||||||
assert.same({foo = "bar"}, args)
|
assert.same({foo = "bar"}, args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("handles optional argument correctly", function()
|
||||||
|
local parser = argparse.parser()
|
||||||
|
parser:argument "foo"
|
||||||
|
:args "?"
|
||||||
|
local args = parser:parse({"bar"})
|
||||||
|
assert.same({foo = "bar"}, args)
|
||||||
|
end)
|
||||||
|
|
||||||
it("handles several arguments correctly", function()
|
it("handles several arguments correctly", function()
|
||||||
local parser = argparse.parser()
|
local parser = argparse.parser()
|
||||||
parser:argument "foo1"
|
parser:argument "foo1"
|
||||||
@@ -86,6 +94,7 @@ describe("tests related to positional arguments", function()
|
|||||||
|
|
||||||
it("handles sudden option correctly", function()
|
it("handles sudden option correctly", function()
|
||||||
local parser = argparse.parser()
|
local parser = argparse.parser()
|
||||||
|
:add_help(false)
|
||||||
parser:argument "foo"
|
parser:argument "foo"
|
||||||
|
|
||||||
assert.has_error(function() parser:parse{"-q"} end, "unknown option '-q'")
|
assert.has_error(function() parser:parse{"-q"} end, "unknown option '-q'")
|
||||||
|
@@ -13,6 +13,7 @@ describe("tests related to commands", function()
|
|||||||
|
|
||||||
it("switches context properly", function()
|
it("switches context properly", function()
|
||||||
local parser = argparse.parser "name"
|
local parser = argparse.parser "name"
|
||||||
|
:add_help(false)
|
||||||
local install = parser:command "install"
|
local install = parser:command "install"
|
||||||
install:flag "-q" "--quiet"
|
install:flag "-q" "--quiet"
|
||||||
|
|
||||||
|
@@ -185,6 +185,7 @@ describe("tests related to options", function()
|
|||||||
|
|
||||||
it("handles unknown options correctly", function()
|
it("handles unknown options correctly", function()
|
||||||
local parser = argparse.parser()
|
local parser = argparse.parser()
|
||||||
|
:add_help(false)
|
||||||
assert.has_error(function() parser:parse{"--server"} end, "unknown option '--server'")
|
assert.has_error(function() parser:parse{"--server"} end, "unknown option '--server'")
|
||||||
assert.has_error(function() parser:parse{"--server=localhost"} end, "unknown option '--server'")
|
assert.has_error(function() parser:parse{"--server=localhost"} end, "unknown option '--server'")
|
||||||
assert.has_error(function() parser:parse{"-s"} end, "unknown option '-s'")
|
assert.has_error(function() parser:parse{"-s"} end, "unknown option '-s'")
|
||||||
|
@@ -3,11 +3,13 @@ local argparse = require "argparse"
|
|||||||
describe("tests related to usage message generation", function()
|
describe("tests related to usage message generation", function()
|
||||||
it("creates correct usage message for empty parser", function()
|
it("creates correct usage message for empty parser", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
assert.equal(parser:prepare():get_usage(), "Usage: foo")
|
assert.equal(parser:prepare():get_usage(), "Usage: foo")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("creates correct usage message for arguments", function()
|
it("creates correct usage message for arguments", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:argument "first"
|
parser:argument "first"
|
||||||
parser:argument "second-and-third"
|
parser:argument "second-and-third"
|
||||||
:args "2"
|
:args "2"
|
||||||
@@ -24,6 +26,7 @@ describe("tests related to usage message generation", function()
|
|||||||
|
|
||||||
it("creates correct usage message for options", function()
|
it("creates correct usage message for options", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:flag "-q" "--quiet"
|
parser:flag "-q" "--quiet"
|
||||||
parser:option "--from"
|
parser:option "--from"
|
||||||
:count "1"
|
:count "1"
|
||||||
@@ -38,6 +41,7 @@ describe("tests related to usage message generation", function()
|
|||||||
|
|
||||||
it("creates correct usage message for commands", function()
|
it("creates correct usage message for commands", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:flag "-q" "--quiet"
|
parser:flag "-q" "--quiet"
|
||||||
local run = parser:command "run"
|
local run = parser:command "run"
|
||||||
run:option "--where"
|
run:option "--where"
|
||||||
@@ -50,8 +54,10 @@ describe("tests related to usage message generation", function()
|
|||||||
|
|
||||||
it("creates correct usage message for subcommands", function()
|
it("creates correct usage message for subcommands", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:flag "-q" "--quiet"
|
parser:flag "-q" "--quiet"
|
||||||
local run = parser:command "run"
|
local run = parser:command "run"
|
||||||
|
:add_help(false)
|
||||||
run:option "--where"
|
run:option "--where"
|
||||||
|
|
||||||
parser:prepare()
|
parser:prepare()
|
||||||
@@ -66,6 +72,7 @@ describe("tests related to usage message generation", function()
|
|||||||
it("uses message provided by user", function()
|
it("uses message provided by user", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
:usage "Usage: obvious"
|
:usage "Usage: obvious"
|
||||||
|
:add_help(false)
|
||||||
parser:flag "-q" "--quiet"
|
parser:flag "-q" "--quiet"
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
@@ -76,6 +83,7 @@ describe("tests related to usage message generation", function()
|
|||||||
|
|
||||||
it("uses per-option message provided by user", function()
|
it("uses per-option message provided by user", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:flag "-q" "--quiet"
|
parser:flag "-q" "--quiet"
|
||||||
:usage "[-q | --quiet]"
|
:usage "[-q | --quiet]"
|
||||||
|
|
||||||
@@ -87,6 +95,7 @@ describe("tests related to usage message generation", function()
|
|||||||
|
|
||||||
it("uses argnames provided by user", function()
|
it("uses argnames provided by user", function()
|
||||||
local parser = argparse.parser "foo"
|
local parser = argparse.parser "foo"
|
||||||
|
:add_help(false)
|
||||||
parser:argument "inputs"
|
parser:argument "inputs"
|
||||||
:args "1-2"
|
:args "1-2"
|
||||||
:argname "<input>"
|
:argname "<input>"
|
||||||
|
@@ -51,9 +51,10 @@ local Parser = class {
|
|||||||
_options = {},
|
_options = {},
|
||||||
_commands = {},
|
_commands = {},
|
||||||
_require_command = false,
|
_require_command = false,
|
||||||
|
_add_help = true,
|
||||||
_fields = {
|
_fields = {
|
||||||
"name", "description", "target", "require_command",
|
"name", "description", "target", "require_command",
|
||||||
"action", "usage"
|
"action", "usage", "help", "add_help"
|
||||||
}
|
}
|
||||||
}:include(Declarative)
|
}:include(Declarative)
|
||||||
|
|
||||||
@@ -169,7 +170,7 @@ function Parser:error(fmt, ...)
|
|||||||
if _TEST then
|
if _TEST then
|
||||||
error(msg)
|
error(msg)
|
||||||
else
|
else
|
||||||
io.stderr:write(("%s\r\nError: %s\r\n"):format(self:get_usage(), msg))
|
io.stderr:write(("%s\r\n\r\nError: %s\r\n"):format(self:get_usage(), msg))
|
||||||
os.exit(1)
|
os.exit(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -275,7 +276,7 @@ function Parser:make_types()
|
|||||||
if element._maxcount == 1 then
|
if element._maxcount == 1 then
|
||||||
if element._maxargs == 0 then
|
if element._maxargs == 0 then
|
||||||
element._type = "flag"
|
element._type = "flag"
|
||||||
elseif element._maxargs == 1 and element._minargs == 1 then
|
elseif element._maxargs == 1 and (element._minargs == 1 or element._mincount == 1) then
|
||||||
element._type = "arg"
|
element._type = "arg"
|
||||||
else
|
else
|
||||||
element._type = "multi-arg"
|
element._type = "multi-arg"
|
||||||
@@ -294,11 +295,21 @@ function Parser:make_types()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Parser:prepare()
|
function Parser:prepare()
|
||||||
|
if self._add_help then
|
||||||
|
self:flag "-h" "--help"
|
||||||
|
:description "Show this help message and exit. "
|
||||||
|
:action(function()
|
||||||
|
print(self:get_help())
|
||||||
|
os.exit(0)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
self:make_charset()
|
self:make_charset()
|
||||||
self:make_targets()
|
self:make_targets()
|
||||||
self:make_boundaries()
|
self:make_boundaries()
|
||||||
self:make_command_names()
|
self:make_command_names()
|
||||||
self:make_types()
|
self:make_types()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -329,6 +340,88 @@ function Parser:get_usage()
|
|||||||
return self._usage
|
return self._usage
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function make_two_columns(s1, s2)
|
||||||
|
if #s1 < 22 then
|
||||||
|
return " " .. s1 .. (" "):rep(22 - #s1) .. s2
|
||||||
|
else
|
||||||
|
if s2 == "" then
|
||||||
|
return " " .. s1
|
||||||
|
else
|
||||||
|
return " " .. s1 .. "\r\n" .. (" "):rep(25) .. s2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_description(element)
|
||||||
|
if element._default then
|
||||||
|
if element._description then
|
||||||
|
return ("%s (default: %s)"):format(element._description, element._default)
|
||||||
|
else
|
||||||
|
return ("default: %s"):format(element._default)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return element._description or ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_name(option)
|
||||||
|
local variants = {}
|
||||||
|
local variant
|
||||||
|
|
||||||
|
for _, alias in ipairs(option._aliases) do
|
||||||
|
variant = option:get_arg_usage("<" .. option._target .. ">")
|
||||||
|
table.insert(variant, 1, alias)
|
||||||
|
variant = table.concat(variant, " ")
|
||||||
|
table.insert(variants, variant)
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(variants, ", ")
|
||||||
|
end
|
||||||
|
|
||||||
|
function Parser:get_help()
|
||||||
|
if not self._help then
|
||||||
|
local blocks = {self:get_usage()}
|
||||||
|
|
||||||
|
if self._description then
|
||||||
|
table.insert(blocks, self._description)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #self._arguments > 0 then
|
||||||
|
local buf = {"Arguments: "}
|
||||||
|
|
||||||
|
for _, argument in ipairs(self._arguments) do
|
||||||
|
table.insert(buf, make_two_columns(argument._name, make_description(argument)))
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(blocks, table.concat(buf, "\r\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
if #self._options > 0 then
|
||||||
|
local buf = {"Options: "}
|
||||||
|
|
||||||
|
for _, option in ipairs(self._options) do
|
||||||
|
table.insert(buf, make_two_columns(make_name(option), make_description(option)))
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(blocks, table.concat(buf, "\r\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
if #self._commands > 0 then
|
||||||
|
local buf = {"Commands: "}
|
||||||
|
|
||||||
|
for _, command in ipairs(self._commands) do
|
||||||
|
table.insert(buf, make_two_columns(table.concat(command._aliases, ", "), command._description or ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(blocks, table.concat(buf, "\r\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
self._help = table.concat(blocks, "\r\n\r\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
return self._help
|
||||||
|
end
|
||||||
|
|
||||||
local function get_tip(context, wrong_name)
|
local function get_tip(context, wrong_name)
|
||||||
local context_pool = {}
|
local context_pool = {}
|
||||||
local possible_name
|
local possible_name
|
||||||
|
Reference in New Issue
Block a user