From 20c14453fdfc2a177b5ece95762ccd69f27f48df Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 13 Dec 2019 21:46:43 -0500 Subject: [PATCH] Add hidden command and option aliases Also auto-add an alias with dashes in place of underscores if an alias has an underscore. --- docsrc/messages.rst | 35 +++++++++++++++++++++++++++++++++++ docsrc/misc.rst | 2 ++ spec/help_spec.lua | 18 ++++++++++++++++++ spec/options_spec.lua | 16 ++++++++++++---- src/argparse.lua | 36 +++++++++++++++++++++++++++++------- 5 files changed, 96 insertions(+), 11 deletions(-) diff --git a/docsrc/messages.rst b/docsrc/messages.rst index b829c69..d221426 100644 --- a/docsrc/messages.rst +++ b/docsrc/messages.rst @@ -39,6 +39,41 @@ it is not included into help and usage messages, but otherwise works normally. deprecated_option = "value" } +Hiding option and command aliases +--------------------------------- + +Hidden aliases can be added to an option or command by setting the +``hidden_name`` property. Its value is interpreted in the same way as the +``name`` property. + +.. code-block:: lua + :linenos: + + parser:option "--server" + :hidden_name "--from" + +.. code-block:: none + + $ lua script.lua --help + +.. code-block:: none + + Usage: script.lua [-h] [--server ] + + Options: + -h, --help Show this help message and exit. + --server + +.. code-block:: none + + $ lua script.lua --server foo + $ lua script.lua --from foo + +.. code-block:: lua + + { + server = "foo" + } Setting argument placeholder ---------------------------- diff --git a/docsrc/misc.rst b/docsrc/misc.rst index d77b25d..94d462e 100644 --- a/docsrc/misc.rst +++ b/docsrc/misc.rst @@ -200,6 +200,7 @@ Other properties: =========================== ========================== Property Type =========================== ========================== +``hidden_name`` String ``summary`` String ``target`` String ``usage`` String @@ -269,6 +270,7 @@ Other properties: =================== ================== Property Type =================== ================== +``hidden_name`` String ``target`` String ``defmode`` String ``show_default`` Boolean diff --git a/spec/help_spec.lua b/spec/help_spec.lua index 3c9c7a1..566b014 100644 --- a/spec/help_spec.lua +++ b/spec/help_spec.lua @@ -311,6 +311,24 @@ Commands: Usage: foo]], parser:get_help()) end) + it("does not mention hidden option and command aliases", function() + local parser = Parser "foo" + parser:option "--server" + :hidden_name "--from" + parser:command "newname" + :hidden_name "oldname" + + assert.equal([[ +Usage: foo [-h] [--server ] ... + +Options: + -h, --help Show this help message and exit. + --server + +Commands: + newname]], parser:get_help()) + end) + it("supports grouping options", function() local parser = Parser "foo" :add_help(false) diff --git a/spec/options_spec.lua b/spec/options_spec.lua index 4fdffe8..b4df9a6 100644 --- a/spec/options_spec.lua +++ b/spec/options_spec.lua @@ -57,14 +57,14 @@ describe("tests related to options", function() assert.same({server = {"foo", "bar"}}, args) end) - it("handles short option correclty", function() + it("handles short option correctly", function() local parser = Parser() parser:option "-s" "--server" local args = parser:parse({"-s", "foo"}) assert.same({server = "foo"}, args) end) - it("handles flag correclty", function() + it("handles flag correctly", function() local parser = Parser() parser:flag "-q" "--quiet" local args = parser:parse({"--quiet"}) @@ -73,7 +73,7 @@ describe("tests related to options", function() assert.same({}, args) end) - it("handles combined flags correclty", function() + it("handles combined flags correctly", function() local parser = Parser() parser:flag "-q" "--quiet" parser:flag "-f" "--fast" @@ -88,7 +88,7 @@ describe("tests related to options", function() assert.same({server = "foo"}, args) end) - it("handles flags combined with short option correclty", function() + it("handles flags combined with short option correctly", function() local parser = Parser() parser:flag "-q" "--quiet" parser:option "-s" "--server" @@ -146,6 +146,14 @@ describe("tests related to options", function() assert.same({tail = {"foo", "--unrelated", "bar"}}, args) end) + it("handles hidden option aliases", function() + local parser = Parser() + parser:option "--server" + :hidden_name "--from" + local args = parser:parse{"--from", "foo"} + assert.same({server = "foo"}, args) + end) + describe("Special chars set", function() it("handles windows-style options", function() local parser = Parser() diff --git a/src/argparse.lua b/src/argparse.lua index dc6cdb0..f440308 100644 --- a/src/argparse.lua +++ b/src/argparse.lua @@ -130,12 +130,30 @@ local multiname = {"name", function(self, value) for alias in value:gmatch("%S+") do self._name = self._name or alias table.insert(self._aliases, alias) + table.insert(self._public_aliases, alias) + -- If alias contains '_', accept '-' also. + if alias:find("_", 1, true) then + table.insert(self._aliases, (alias:gsub("_", "-"))) + end end -- Do not set _name as with other properties. return true end} +local multiname_hidden = {"hidden_name", function(self, value) + typecheck("hidden_name", {"string"}, value) + + for alias in value:gmatch("%S+") do + table.insert(self._aliases, alias) + if alias:find("_", 1, true) then + table.insert(self._aliases, (alias:gsub("_", "-"))) + end + end + + return true +end} + local function parse_boundaries(str) if tonumber(str) then return tonumber(str), tonumber(str) @@ -257,12 +275,14 @@ local Parser = class({ }) local Command = class({ - _aliases = {} + _aliases = {}, + _public_aliases = {} }, { args = 3, multiname, typechecked("description", "string"), typechecked("epilog", "string"), + multiname_hidden, typechecked("summary", "string"), typechecked("target", "string"), typechecked("usage", "string"), @@ -307,6 +327,7 @@ local Argument = class({ local Option = class({ _aliases = {}, + _public_aliases = {}, _mincount = 0, _overwrite = true }, { @@ -317,6 +338,7 @@ local Option = class({ typechecked("convert", "function", "table"), boundaries("args"), boundaries("count"), + multiname_hidden, typechecked("target", "string"), typechecked("defmode", "string"), typechecked("show_default", "boolean"), @@ -505,22 +527,22 @@ function Option:_get_label_lines() if #argument_list == 0 then -- Don't put aliases for simple flags like `-h` on different lines. - return {table.concat(self._aliases, ", ")} + return {table.concat(self._public_aliases, ", ")} end local longest_alias_length = -1 - for _, alias in ipairs(self._aliases) do + for _, alias in ipairs(self._public_aliases) do longest_alias_length = math.max(longest_alias_length, #alias) end local argument_list_repr = table.concat(argument_list, " ") local lines = {} - for i, alias in ipairs(self._aliases) do + for i, alias in ipairs(self._public_aliases) do local line = (" "):rep(longest_alias_length - #alias) .. alias .. " " .. argument_list_repr - if i ~= #self._aliases then + if i ~= #self._public_aliases then line = line .. "," end @@ -531,7 +553,7 @@ function Option:_get_label_lines() end function Command:_get_label_lines() - return {table.concat(self._aliases, ", ")} + return {table.concat(self._public_aliases, ", ")} end function Argument:_get_description() @@ -569,7 +591,7 @@ end function Option:_get_default_target() local res - for _, alias in ipairs(self._aliases) do + for _, alias in ipairs(self._public_aliases) do if alias:sub(1, 1) == alias:sub(2, 2) then res = alias:sub(3) break