From fc556c9e5d68903e373aedd09b886c2d84430a04 Mon Sep 17 00:00:00 2001 From: myk002 Date: Sat, 25 Sep 2021 12:25:02 -0700 Subject: [PATCH] implement non-alias long form params now long form parameters can exist by themselves without being an alias for a required equivalent short form param --- library/lua/argparse.lua | 24 ++++++++++++++++++------ test/library/argparse.lua | 21 ++++++++++++++++++--- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/library/lua/argparse.lua b/library/lua/argparse.lua index 70b9c528e..708f601f4 100644 --- a/library/lua/argparse.lua +++ b/library/lua/argparse.lua @@ -80,6 +80,7 @@ end -- it will be passed to the handler function. -- longOptionAlias is optional. -- hasArg defaults to false. +-- to have an option that has only a long form, pass '' as the shortOptionName. -- -- example usage: -- @@ -100,17 +101,28 @@ function processArgsGetopt(args, optionActions) local handlers = {} for _,optionAction in ipairs(optionActions) do local sh_opt,long_opt = optionAction[1], optionAction[2] - if not sh_opt or type(sh_opt) ~= 'string' or #sh_opt ~= 1 then - error('optionAction missing option letter at index 1') + -- sh_opt can be zero-length if long_opt is specified + if not sh_opt or type(sh_opt) ~= 'string' or + (#sh_opt ~= 1 and not (#sh_opt == 0 and long_opt)) then + error('option letter not found') + end + if long_opt and (type(long_opt) ~= 'string' or #long_opt == 0) then + error('long option name must be a string with length >0') end if not optionAction.handler then error(string.format('handler missing for option "%s"', sh_opt)) end - sh_opts = sh_opts .. sh_opt - if optionAction.hasArg then sh_opts = sh_opts .. ':' end - handlers[sh_opt] = optionAction.handler + if #sh_opt > 0 then + sh_opts = sh_opts .. sh_opt + if optionAction.hasArg then sh_opts = sh_opts .. ':' end + handlers[sh_opt] = optionAction.handler + end if long_opt then - long_opts[long_opt] = sh_opt + if #sh_opt > 0 then + long_opts[long_opt] = sh_opt + else + long_opts[long_opt] = optionAction.hasArg and 1 or 0 + end handlers[long_opt] = optionAction.handler end end diff --git a/test/library/argparse.lua b/test/library/argparse.lua index b83e7aa0c..6f48c7f0c 100644 --- a/test/library/argparse.lua +++ b/test/library/argparse.lua @@ -58,17 +58,23 @@ function test.processArgsGetopt_happy_path() end function test.processArgsGetopt_action_errors() - expect.error_match('missing option letter', + expect.error_match('option letter not found', function() argparse.processArgsGetopt({}, {{handler=function() end}}) end) - expect.error_match('missing option letter', + expect.error_match('option letter not found', function() argparse.processArgsGetopt({}, {{'notoneletter'}}) end) - expect.error_match('missing option letter', + expect.error_match('option letter not found', function() argparse.processArgsGetopt({}, {{function() end}}) end) + expect.error_match('long option name', + function() argparse.processArgsGetopt({}, {{'', ''}}) end) + + expect.error_match('long option name', + function() argparse.processArgsGetopt({}, {{'a', ''}}) end) + expect.error_match('handler missing', function() argparse.processArgsGetopt({}, {{'r'}}) end) end @@ -107,6 +113,15 @@ function test.processArgsGetopt_parsing_errors() 'fail to pass value to long param that requires one') end +function test.processArgsGetopt_long_opt_without_short_opt() + local var = false + local nonoptions = argparse.processArgsGetopt( + {'--long'}, + {{'', 'long', handler=function() var = true end}}) + expect.true_(var) + expect.table_eq({}, nonoptions) +end + function test.stringList() expect.table_eq({'happy', 'path'}, argparse.stringList(' happy , path'), 'ensure elements are trimmed')