Got rid of :prepare()

This commit is contained in:
mpeterv
2014-03-02 02:03:44 +04:00
parent 085f152127
commit f24cfe9627
3 changed files with 79 additions and 59 deletions

View File

@@ -8,7 +8,7 @@ describe("tests related to help message generation", function()
"", "",
"Options: ", "Options: ",
" -h, --help Show this help message and exit. " " -h, --help Show this help message and exit. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("does not create extra help options when :prepare is called several times", function() it("does not create extra help options when :prepare is called several times", function()
@@ -18,7 +18,7 @@ describe("tests related to help message generation", function()
"", "",
"Options: ", "Options: ",
" -h, --help Show this help message and exit. " " -h, --help Show this help message and exit. "
}, "\r\n"), parser:prepare():prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("uses custom help option", function() it("uses custom help option", function()
@@ -29,7 +29,7 @@ describe("tests related to help message generation", function()
"", "",
"Options: ", "Options: ",
" /? Show this help message and exit. " " /? Show this help message and exit. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("uses description and epilog", function() it("uses description and epilog", function()
@@ -46,7 +46,7 @@ describe("tests related to help message generation", function()
" -h, --help Show this help message and exit. ", " -h, --help Show this help message and exit. ",
"", "",
"An epilog. " "An epilog. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("creates correct help message for arguments", function() it("creates correct help message for arguments", function()
@@ -72,7 +72,7 @@ describe("tests related to help message generation", function()
"", "",
"Options: ", "Options: ",
" -h, --help Show this help message and exit. " " -h, --help Show this help message and exit. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("creates correct help message for options", function() it("creates correct help message for options", function()
@@ -91,7 +91,7 @@ describe("tests related to help message generation", function()
" --from <server>", " --from <server>",
" --config <config>", " --config <config>",
" -h, --help Show this help message and exit. " " -h, --help Show this help message and exit. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("adds margin for multiline descriptions", function() it("adds margin for multiline descriptions", function()
@@ -112,7 +112,7 @@ Sets verbosity level.
" -v: Report all warnings. ", " -v: Report all warnings. ",
" -vv: Report all debugging information. ", " -vv: Report all debugging information. ",
" -h, --help Show this help message and exit. " " -h, --help Show this help message and exit. "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("creates correct help message for commands", function() it("creates correct help message for commands", function()
@@ -131,7 +131,7 @@ Sets verbosity level.
"", "",
"Commands: ", "Commands: ",
" run Run! " " run Run! "
}, "\r\n"), parser:prepare():get_help()) }, "\r\n"), parser:get_help())
end) end)
it("creates correct help message for subcommands", function() it("creates correct help message for subcommands", function()
@@ -140,15 +140,13 @@ Sets verbosity level.
local run = parser:command "run" local run = parser:command "run"
run:option "--where" run:option "--where"
parser:prepare()
assert.equal(table.concat({ assert.equal(table.concat({
"Usage: foo run [--where <where>] [-h]", "Usage: foo run [--where <where>] [-h]",
"", "",
"Options: ", "Options: ",
" --where <where>", " --where <where>",
" -h, --help Show this help message and exit. ", " -h, --help Show this help message and exit. ",
}, "\r\n"), run:prepare():get_help()) }, "\r\n"), run:get_help())
end) end)
it("uses message provided by user", function() it("uses message provided by user", function()
@@ -158,7 +156,7 @@ Sets verbosity level.
assert.equal( assert.equal(
[=[I don't like your format of help messages]=], [=[I don't like your format of help messages]=],
parser:prepare():get_help() parser:get_help()
) )
end) end)
end) end)

View File

@@ -4,7 +4,7 @@ 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 = Parser "foo" local parser = Parser "foo"
:add_help(false) :add_help(false)
assert.equal(parser:prepare():get_usage(), "Usage: foo") assert.equal(parser:get_usage(), "Usage: foo")
end) end)
it("creates correct usage message for arguments", function() it("creates correct usage message for arguments", function()
@@ -21,7 +21,7 @@ describe("tests related to usage message generation", function()
assert.equal(table.concat({ assert.equal(table.concat({
"Usage: foo <first> <second-and-third> <second-and-third>", "Usage: foo <first> <second-and-third> <second-and-third>",
" [<maybe-fourth>] [<others>] ..." " [<maybe-fourth>] [<others>] ..."
}, "\r\n"), parser:prepare():get_usage() }, "\r\n"), parser:get_usage()
) )
end) end)
@@ -36,7 +36,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo [-q] --from <server> [--config <config>]]=], [=[Usage: foo [-q] --from <server> [--config <config>]]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -55,7 +55,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo [<input>] [<pair> <pair>] [<pair2>] [<pair2>]]=], [=[Usage: foo [<input>] [<pair> <pair>] [<pair2>] [<pair2>]]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -70,7 +70,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo [-f <from>] [-o [<output>]]]=], [=[Usage: foo [-f <from>] [-o [<output>]]]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -83,7 +83,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo [-q] <command> ...]=], [=[Usage: foo [-q] <command> ...]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -95,15 +95,13 @@ describe("tests related to usage message generation", function()
:add_help(false) :add_help(false)
run:option "--where" run:option "--where"
parser:prepare()
assert.equal( assert.equal(
[=[Usage: foo run [--where <where>]]=], [=[Usage: foo run [--where <where>]]=],
run:prepare():get_usage() run:get_usage()
) )
end) end)
it("usage messages for commands are correct after several :prepare() invocations", function() it("usage messages for commands are correct after several invocations", function()
local parser = Parser "foo" local parser = Parser "foo"
:add_help(false) :add_help(false)
parser:flag "-q" "--quiet" parser:flag "-q" "--quiet"
@@ -111,12 +109,12 @@ describe("tests related to usage message generation", function()
:add_help(false) :add_help(false)
run:option "--where" run:option "--where"
parser:prepare() parser:parse{"run"}
parser:prepare() parser:parse{"run"}
assert.equal( assert.equal(
[=[Usage: foo run [--where <where>]]=], [=[Usage: foo run [--where <where>]]=],
run:prepare():get_usage() run:get_usage()
) )
end) end)
@@ -129,7 +127,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: obvious]=], [=[Usage: obvious]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -141,7 +139,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo [-q | --quiet]]=], [=[Usage: foo [-q | --quiet]]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
@@ -154,7 +152,7 @@ describe("tests related to usage message generation", function()
assert.equal( assert.equal(
[=[Usage: foo <input> [<input>]]=], [=[Usage: foo <input> [<input>]]=],
parser:prepare():get_usage() parser:get_usage()
) )
end) end)
end) end)

View File

@@ -88,8 +88,6 @@ local typecheck = setmetatable({}, {
end end
}) })
local noop = false
local function aliased_name(self, name) local function aliased_name(self, name)
typecheck.string "name" (self, name) typecheck.string "name" (self, name)
@@ -129,16 +127,14 @@ local Parser = add_setters(class {
_arguments = {}, _arguments = {},
_options = {}, _options = {},
_commands = {}, _commands = {},
_require_command = true, _require_command = true
_add_help = true
}, { }, {
name = typecheck.string "name", name = typecheck.string "name",
description = typecheck.string "description", description = typecheck.string "description",
epilog = typecheck.string "epilog", epilog = typecheck.string "epilog",
require_command = typecheck.boolean "require_command", require_command = typecheck.boolean "require_command",
usage = typecheck.string "usage", usage = typecheck.string "usage",
help = typecheck.string "help", help = typecheck.string "help"
add_help = noop
}) })
local Command = add_setters(Parser:extends { local Command = add_setters(Parser:extends {
@@ -153,8 +149,7 @@ local Command = add_setters(Parser:extends {
require_command = typecheck.boolean "require_command", require_command = typecheck.boolean "require_command",
action = typecheck["function"] "action", action = typecheck["function"] "action",
usage = typecheck.string "usage", usage = typecheck.string "usage",
help = typecheck.string "help", help = typecheck.string "help"
add_help = noop
}) })
local Argument = add_setters(class { local Argument = add_setters(class {
@@ -303,51 +298,69 @@ end
function Parser:option(...) function Parser:option(...)
local option = Option:new(...) local option = Option:new(...)
table.insert(self._options, option)
if self._has_help then
table.insert(self._options, #self._options, option)
else
table.insert(self._options, option)
end
return option return option
end end
function Parser:flag(...) function Parser:flag(...)
local flag = Option:new():args(0)(...) return self:option():args(0)(...)
table.insert(self._options, flag)
return flag
end end
function Parser:command(...) function Parser:command(...)
local command = Command:new(...) local command = Command:new():add_help(true)(...)
command._parent = self
table.insert(self._commands, command) table.insert(self._commands, command)
return command return command
end end
function Parser:prepare() function Parser:add_help(param)
self._fullname = self._fullname or self._name if self._has_help then
table.remove(self._options)
if self._add_help and not self._help_option then self._has_help = false
self._help_option = self:flag() end
if param then
local help = self:flag()
:description "Show this help message and exit. " :description "Show this help message and exit. "
:action(function() :action(function()
io.stdout:write(self:get_help() .. "\r\n") io.stdout:write(self:get_help() .. "\r\n")
os.exit(0) os.exit(0)
end) end)
(self._add_help) (param)
if not self._help_option._name then if not help._name then
self._help_option "-h" "--help" help "-h" "--help"
end end
end
for _, command in ipairs(self._commands) do self._has_help = true
command._fullname = self._fullname .. " " .. command._name
end end
return self return self
end end
function Parser:update_charset(charset) function Parser:_get_fullname()
local parent = self._parent
local buf = {self._name}
while parent do
table.insert(buf, 1, parent._name)
parent = parent._parent
end
return table.concat(buf, " ")
end
function Parser:_update_charset(charset)
charset = charset or {} charset = charset or {}
for _, command in ipairs(self._commands) do for _, command in ipairs(self._commands) do
command:update_charset(charset) command:_update_charset(charset)
end end
for _, option in ipairs(self._options) do for _, option in ipairs(self._options) do
@@ -367,7 +380,7 @@ function Parser:get_usage()
return self._usage return self._usage
end end
local lines = {usage_welcome .. self._fullname} local lines = {usage_welcome .. self:_get_fullname()}
local function add(s) local function add(s)
if #lines[#lines]+1+#s <= max_usage_width then if #lines[#lines]+1+#s <= max_usage_width then
@@ -553,7 +566,12 @@ end
function Parser:_parse(args, errhandler) function Parser:_parse(args, errhandler)
args = args or arg args = args or arg
self._name = self._name or args[0] local noname
if not self._name then
noname = true
self._name = args[0]
end
local parser local parser
local charset local charset
@@ -682,7 +700,7 @@ function Parser:_parse(args, errhandler)
end end
local function switch(p) local function switch(p)
parser = p:prepare() parser = p
for _, option in ipairs(parser._options) do for _, option in ipairs(parser._options) do
table.insert(options, option) table.insert(options, option)
@@ -817,7 +835,7 @@ function Parser:_parse(args, errhandler)
end end
switch(self) switch(self)
charset = parser:update_charset() charset = parser:_update_charset()
mainloop() mainloop()
if cur_option then if cur_option then
@@ -857,6 +875,10 @@ function Parser:_parse(args, errhandler)
end end
end end
if noname then
self._name = nil
end
return result return result
end end
@@ -890,4 +912,6 @@ function Parser:pparse(args)
end end
end end
return Parser return function(...)
return Parser():add_help(true)(...)
end