lunarmodules / lua_cliargs Goto Github PK
View Code? Open in Web Editor NEWA command-line argument parsing module for Lua.
License: MIT License
A command-line argument parsing module for Lua.
License: MIT License
What is the deal with a numeric limit on splat()
arguments? Why not just specify unlimited
by default? If anyone wants to limit it to 1 he could always optionally pass that integer. But a limit between 1 and 999 seems quite arbitrary to me.
For maximum platform compatibility (especially Windows), change the use of \n
to a platform-specific value
Please to submit cliargs to luarocks
having something like this:
local cli = require "cliargs"
cli:add_option("start", "start the thing", false, function(...)
print(...)
os.exit(0)
end)
local args = cli:parse({ ... or '--help' })
I getting such error:
vagrant@vagrant:/vagrant/data/proj$ lua ./mng.lua start
migrate.lua: error: bad number of arguments: 0 argument(s) must be specified, not 1; re-run with --help for usage.
I agree with docs, but such kind of invacation is very common for cli.
It would be great if you will support it...
If a command or subcommand doesn't exist, it would be really cool if there were suggestions. Today I read about http://blog.notdot.net/2010/07/Damn-Cool-Algorithms-Levenshtein-Automata which seems like a workable solution to integrate here.
It's been a while since cliargs
got any tender loving care. This message is not to blame the maintainer. As a frequent FOSS contributor with many projects on my plate I know exactly how things go. Even if argparse
has some more of the momentum for Lua CLI argument parsing, I am personally a fan of how this library works and have gotten a lot of millage out of it. I would rather not have to migrate most of my existing projects.
That being said the issues are starting to pile up. I see almost 1/3 of the open issues here are things I've raised over the years and have frequently had to monkey-patch my way around. I'd like to offer to help maintain the project so those fixes get upstreamed and I can keep using it as is.
I offer this as the maintainer of Luacheck, LDoc, a contributor to Busted, Penlight, and others. This isn't my first Lua rodeo. I've also picked up the maintainer reigns on a host of Vim plugins at @preservim and other projects as well. You are welcome to review the history of those projects and how smoothly the handovers have gone.
I would like to propose this project join the umbrella of @lunarmodules. You can still be listed as a project owner, but the team there would also have admin rights, and I could help shepherd the process of getting PRs handled, issues triaged, CI brought up to speed, and eventually a new release series going. If that sounds agreeable by all means have a look round at how we've handled other projects in similar boats. I'll check with the rest of the team and if nobody objects we'll get you an invite so you can transfer the repo to that namespace. That way all the old links will have redirects and no existing use connections are broken.
I see @Tieske your are previous contributor to this project as well, does this scan by you?
cli:add_option("-o FILE", "path to output file", nil, "/dev/stdout")
Passing --o=/dev/stdin
works while it shouldn't. Only -o /dev/stdin
should work.
Even with #63 applied, reading from .ini files can fail:
Minimum working example:
test.ini
[database]
verbose=true
port=5432
test.lua
1 cli = require 'cliargs';
2 tbl = cli:read_defaults('test.ini', 'ini', 'database', false);
Running test.lua
result in this error:
attempt to index a boolean value (local 'str')
stack traceback:
./cliargs/utils/trim.lua:3: in function 'cliargs.utils.trim'
./cliargs/config_loader.lua:99: in function 'cliargs.config_loader.from_ini'
(...tail calls...)
./test.lua:2: in main chunk
[C]: in ?
Notes:
read_defaults
to true
(line 2)Currently there's no way to override a flag option set to true by default.
luarocks install lua_cliargs
`Installing https://luarocks.org/lua_cliargs-3.0-2.src.rock
lua_cliargs 3.0-2 depends on lua >= 5.1 (5.1-1 provided by VM)
Error: Failed producing checksum: no MD5 checker tool available, please install md5sum, openssl or md5 in your system`
I have confirmed md5.exe is present in tools folder.
verbose here:
`os.execute: C: & cd "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" & "C:\Program Files (x86)\LuaRocks/tools/cp.exe" "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724\lua_cliargs-3.0-2.rockspec" "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2\lua_cliargs-3.0-2.rockspec"
Results: 1
1 (number): 0
fs.find("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.is_dir("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.absolute_name("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.current_dir()
fs.absolute_name("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724", "C:\Users\wordp")
fs.quiet_stderr(""C:\Program Files (x86)\LuaRocks/tools/find.exe"")
fs.command_at("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2", ""C:\Program Files (x86)\LuaRocks/tools/find.exe" 2> NUL", true)
fs.Q("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
io.popen: c: & cd "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" && "C:\Program Files (x86)\LuaRocks/tools/find.exe" 2> NUL
fs.is_file("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2/doc")
fs.absolute_name("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2/doc")
fs.current_dir()
fs.absolute_name("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724", "C:\Users\wordp")
fs.is_file("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2/doc/package.json")
fs.absolute_name("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2/doc/package.json")
fs.current_dir()
fs.absolute_name("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724", "C:\Users\wordp")
fs.get_md5("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2/doc/package.json")
fs.which_tool("md5checker")
fs.is_tool_available(""C:\Program Files (x86)\LuaRocks/tools/md5sum.exe"", "md5sum")
fs.search_in_path(""C:\Program Files (x86)\LuaRocks/tools/md5sum.exe"")
fs.is_tool_available("openssl", "openssl")
fs.search_in_path("openssl")
fs.is_tool_available("md5", "md5")
fs.search_in_path("md5")
fs.pop_dir()
Error: Failed producing checksum: no MD5 checker tool available, please install md5sum, openssl or md5 in your system
fs.change_dir_to_root()
fs.current_dir()
fs.is_dir("C:\Users\wordp")
fs.absolute_name("C:\Users\wordp")
fs.current_dir()
fs.delete("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.Q("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2\")
fs.Q("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.Q("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs/3.0-2")
fs.execute_quiet("if exist "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2\" ( RMDIR /S /Q "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" ) else ( DEL /Q /F "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" )")
fs.execute_string("if exist "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2\" ( RMDIR /S /Q "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" ) else ( DEL /Q /F "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" )")
fs.current_dir()
fs.absolute_name("/", "C:\Users\wordp")
fs.command_at("/", "if exist "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2\" ( RMDIR /S /Q "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" ) else ( DEL /Q /F "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" )")
fs.Q("/")
os.execute: cd \ & if exist "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2*" ( RMDIR /S /Q "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" ) else ( DEL /Q /F "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs\3.0-2" )
Results: 1
1 (number): 0
fs.remove_dir_if_empty("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs")
fs.execute_quiet("rmdir", "c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs")
fs.Q("c:\lua\/lib/luarocks/rocks-5.1/lua_cliargs")
fs.execute_string("rmdir "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs"")
fs.current_dir()
fs.absolute_name("/", "C:\Users\wordp")
fs.command_at("/", "rmdir "c:\lua\\lib\luarocks\rocks-5.1\lua_cliargs"")
fs.Q("/")
os.execute: cd \ & rmdir "c:\lua\lib\luarocks\rocks-5.1\lua_cliargs"
Results: 1
1 (number): 0
fs.delete("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724\")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_lua_cliargs-3.0-2-4724")
fs.execute_quiet("if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" )")
fs.execute_string("if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" )")
fs.current_dir()
fs.absolute_name("/", "C:\Users\wordp")
fs.command_at("/", "if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" )")
fs.Q("/")
os.execute: cd \ & if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724*" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_lua_cliargs-3.0-2-4724" )
Results: 1
1 (number): 0
fs.delete("C:\Users\wordp\AppData\Local\Temp/luarocks_luarocks-rock-lua_cliargs-3.0-2-8901")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_luarocks-rock-lua_cliargs-3.0-2-8901\")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_luarocks-rock-lua_cliargs-3.0-2-8901")
fs.Q("C:\Users\wordp\AppData\Local\Temp/luarocks_luarocks-rock-lua_cliargs-3.0-2-8901")
fs.execute_quiet("if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" )")
fs.execute_string("if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" )")
fs.current_dir()
fs.absolute_name("/", "C:\Users\wordp")
fs.command_at("/", "if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901\" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" )")
fs.Q("/")
os.execute: cd \ & if exist "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901*" ( RMDIR /S /Q "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" ) else ( DEL /Q /F "C:\Users\wordp\AppData\Local\Temp\luarocks_luarocks-rock-lua_cliargs-3.0-2-8901" )
Results: 1
1 (number): 0`
It would be nice to update the project to its latest version on https://rocks.moonscript.org/
Right now the most recent version available is 2.1-2
, while the latest version is 2.2-0
.
The way the --help
text is parsed the message is returned in the same field as an actual parsing error, and the return code is the same as if it was a failure case. However a user actually passing --help
explicitly should be considered a success.
The only way I came up with to work around this was to test the error string for :match("^Usage:")
and switch gears from error handling to closing with a success status after the message. There really should be a more ergonomic way to do this. As it is most lua apps that implement CLIs with this library return a failure code when they should not.
c.f. orhun/halp#20
c.f. https://github.com/sile-typesetter/sile/pull/1737/files
c.f. lunarmodules/busted#732
c.f. lunarmodules/busted#733 (comment)
In most *nix tooling, -
can be used as an alias for either /dev/stdin
or /dev/stdout
(depending on what is expected in the context). I can't figure out how to pars thet using this library. It looks like it is parsable as an argument after a --
separator, but in all other circumstances (where it might be expected)
Sample expected usage:
$ my_cmd -f -
Example of what should be done:
./prog.lua build
and
./prog.lua install
but if i make install and build both options i get the following error:
mpm: bad number of arguments: 0 argument(s) must be specified, not 1; re-run with help for usage
I can set build or install as arguments, but that makes both options REQUIRED, which is not what is wanted.
cli:add_opt("-Wno-unsigned", ...)
results in the key becoming Wno-
although the label used for printing help is preserved as-is. The expected behavior is to allow -
to appear inside the key.
Just noticed the version went bad.
The new release 3.0-2
did include code changes, but only the rockspec version was updated (pervious version was 3.0-1
).
Rockspec versions are to be increased only when the rockspec changes, but no code changes have been made.
In this case there were backward compatible changes (refactor) without new features, so it should have been version 3.0.1-1
(under the assumption we're on SemVer right?)
calling with --input=
returns an error; unknown option '--input='
cli:add_flag("-v, --version", "prints the program's version and exits")
Invoking a script with --version
will not set the v
key to true, but nil
instead.
See this comment
Can we add an option to the api that takes a list of filenames and loads options from that, which can then be overridden by the commandline provided.
example API; function setconfigfiles(filenames)
Provide a list of filenames as;
.\my_app_name.settings
--> project settings, overrides user settings%USERNAME%\my_app_name\user_config.settings
--> user overrides system%ALLUSERS%\my_app_name\system_config.settings
--> system wide configHighest level priority would be the options on the commandline
the entry table is checked for empty string values "" for key/expanded-key if they weren't provided. The current implementation has them set to nil
.
probably a result of the merge.
The function set_colsz
is in effective, because it creates a new reference and assigns it to colsz
after colsz
has been passed to create_printer
. Instead, assign the new column sizes to the fields of colsz
. Alternatively, we could consider making colsz
a public field along with options
allowing easy expansion for downstream users.
When I have options which take an argument where no default is appropriate or expected, it is a bit silly to have the (default: )
in the output. Can you add a way to disable it?
If you don't care about what others do, could you add an explicit license? In the end the current open remark will give more legal hassle than a proper liberal license like MIT for example.
While debugging an error we had in neovim/neovim#320 I found out that the busted shell script has a problem with parsing long arguments on systems with dash. On OS X I didn't get this error.
Long arguments which include an l in them get parsed as -l argument and this sets the next argument as lua executable.
For more info, see this comment: neovim/neovim#320 (comment)
Related to issue #116.
I'm going to investigate this over the next day or two on busted, but I'm pretty confident it's a lua_cliargs issue, as all we do is read the output.
my changes so far are not backward compatible, so here's another proposal that is not backward compatible (if the chain is broken, better do it all at once)
I would like to drop the reference
parameter from add_arg()
and add_opt()
in my opinion they have limited use as an expanded-key could serve the same purpose.
Instead replace it with a numberof
parameter that applies only to the last argument in the required list;
return value for this argument would always be a table
Usecase: Busted
requires 1 argument, the root drirectory containing the tests. Eventhough the Busted code contains a default value 'spec' for this argument, it cannot be used because cliarg will error out if there is nothing on the commandline. So this force the use of busted spec
. Now if the last argument would be set to a numberof
value of 0, then just the command busted
would do. Additionally if I have multiple root directories with tests I could specify busted spec_private spec_io
to run the tests from 2 different root directories.
Currently there's no way to pass a maximum line width other than manually setting both columns
In the 2.x series of releases it was possible to setup an option that had no value if not set, a default value if just the flag was added but no value given, and additionally a custom value if a value was passed. In 3.x this does not seem to be possible. Flags cannot take values and options always require a value. The default for options is only parsed in the event the option flag is not even passed.
As an example, I would like the value of a --foo=[VALUE]
option to be optional with a default value if set, but allow the user to set (or not set) foo. If this is optopt.lua
:
#!/usr/bin/env lua
local cli = require("cliargs")
cli:set_name("optopt")
cli:set_description("optional arg test")
cli:option("-f, --foo=[VALUE]", "foo val default to fiz", "fiz")
cli:flag("-h, --help", "display this help, then exit")
local opts, err = cli:parse(_G.arg)
if not opts and err then
print(err)
os.exit(1)
end
print("foo is", opts.foo)
What I get vs. what I expect:
# as expected
$ ./optopt.lua -f buz
foo is buz
# unexpected, no option should mean no value
$ ./optopt.lua
foo is fiz
# unexpected, setting the option should enable the default value if no value passed
$ ./optopt.lua -f
option -f requires a value to be set
I'm trying to run the example.lua
file provided in the repo, like: lua example.lua -v
But it seems like the parsing for -v
doesn't work, and the version information are never been displayed.
Setting the "default" value for an option to an empty table seems to enable that option to be specified multiple times and return a table instead of a string, but this does not seem to be documented:
cli:option("-f, --foo=VALUE", "set foo", {})
I'm experimenting with the new command features and not having much luck getting the command description to display with --help when using the command():file() function.
Is this a known issue or am I using it wrong? I've tried a couple different things, and haven't gotten it to work.
For what it's worth, I'm seeing the same behavior with the examples/04_commands--git.lua sample.
Currently there are some optional dependencies including on yaml that are not Lua 5.4 compatible. These should be made easier to swap out for a loader of choice including a YAML reader that works in Lua 5.4, or works with pure Lua, or whatever.
the cli module returns itself as an object. New instances can be created, though only one commandline at program launch needs to be parsed. So why the object setup?
I would like to drop it, so the module can delete itself after parsing to free resources.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.