From e92c37b6e3b30268033eaf2ad634998340c0fa3e Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 12 Jun 2019 16:03:43 -0400 Subject: Use argparse for command line argument parsing Supports main options and init and lint commands --- src/bin/luarocks | 2 +- src/bin/luarocks-admin | 2 +- src/luarocks/cmd.lua | 250 +++++++++++++++++++++++++++++----------------- src/luarocks/cmd/help.lua | 139 -------------------------- src/luarocks/cmd/init.lua | 52 +++++----- src/luarocks/cmd/lint.lua | 32 +++--- src/luarocks/util.lua | 164 ++---------------------------- 7 files changed, 209 insertions(+), 432 deletions(-) delete mode 100644 src/luarocks/cmd/help.lua diff --git a/src/bin/luarocks b/src/bin/luarocks index d982530c..f277b348 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks @@ -33,4 +33,4 @@ local commands = { test = "luarocks.cmd.test", } -cmd.run_command(description, commands, "luarocks.cmd.external", ...) +cmd.run_command("luarocks", description, commands, "luarocks.cmd.external", ...) diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index 71e17b55..ddbe0f48 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin @@ -16,4 +16,4 @@ local commands = { refresh_cache = "luarocks.admin.cmd.refresh_cache", } -cmd.run_command(description, commands, "luarocks.admin.cmd.external", ...) +cmd.run_command("luarocks-admin", description, commands, "luarocks.admin.cmd.external", ...) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 1ead6c4b..23ca023a 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -2,16 +2,14 @@ --- Functions for command-line scripts. local cmd = {} -local unpack = unpack or table.unpack - local loader = require("luarocks.loader") local util = require("luarocks.util") local path = require("luarocks.path") -local deps = require("luarocks.deps") local cfg = require("luarocks.core.cfg") local dir = require("luarocks.dir") local fun = require("luarocks.fun") local fs = require("luarocks.fs") +local argparse = require("argparse") local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") if not hc_ok then @@ -91,8 +89,8 @@ do else replace_tree(flags, cfg.home_tree) end - elseif flags["project-tree"] then - local tree = flags["project-tree"] + elseif flags["project_tree"] then + local tree = flags["project_tree"] table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) loader.load_rocks_trees() path.use_tree(tree) @@ -131,14 +129,14 @@ local function process_server_flags(flags) cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) end - if flags["only-server"] then + if flags["only_server"] then if flags["dev"] then return nil, "--only-server cannot be used with --dev" end if flags["server"] then return nil, "--only-server cannot be used with --server" end - cfg.rocks_servers = { flags["only-server"] } + cfg.rocks_servers = { flags["only_server"] } end return true @@ -231,12 +229,12 @@ do end local function detect_lua_via_flags(flags, project_dir) - local lua_version = flags["lua-version"] + local lua_version = flags["lua_version"] or find_default_lua_version(flags, project_dir) or (project_dir and find_version_from_config(project_dir)) - if flags["lua-dir"] then - local detected, err = util.find_lua(flags["lua-dir"], lua_version) + if flags["lua_dir"] then + local detected, err = util.find_lua(flags["lua_dir"], lua_version) if not detected then die(err) end @@ -265,13 +263,13 @@ do end detect_config_via_flags = function(flags) - local project_dir, given = find_project_dir(flags["project-tree"]) + local project_dir, given = find_project_dir(flags["project_tree"]) local detected = detect_lua_via_flags(flags, project_dir) - if flags["lua-version"] then - detected.given_lua_version = flags["lua-version"] + if flags["lua_version"] then + detected.given_lua_version = flags["lua_version"] end - if flags["lua-dir"] then - detected.given_lua_dir = flags["lua-dir"] + if flags["lua_dir"] then + detected.given_lua_dir = flags["lua_dir"] end if given then detected.given_project_dir = project_dir @@ -306,6 +304,103 @@ do end end +local function get_status(status) + return status and "ok" or "not found" +end + +local function get_config_text() + local buf = "Configuration:\n Lua version: "..cfg.lua_version.."\n" + if cfg.luajit_version then + buf = buf.." LuaJIT version: "..cfg.luajit_version.."\n" + end + buf = buf.."\n Configuration files:\n" + local conf = cfg.config_files + buf = buf.." System : "..fs.absolute_name(conf.system.file).." ("..get_status(conf.system.found)..")\n" + if conf.user.file then + buf = buf.." User : "..fs.absolute_name(conf.user.file).." ("..get_status(conf.user.found)..")\n" + else + buf = buf.." User : disabled in this LuaRocks installation.\n" + end + if conf.project then + buf = buf.." Project : "..fs.absolute_name(conf.project.file).." ("..get_status(conf.project.found)..")\n" + end + buf = buf.."\n Rocks trees in use: \n" + for _, tree in ipairs(cfg.rocks_trees) do + if type(tree) == "string" then + buf = buf.." "..fs.absolute_name(tree) + else + local name = tree.name and " (\""..tree.name.."\")" or "" + buf = buf.." "..fs.absolute_name(tree.root)..name + end + end + + return buf.."\n" +end + +local function get_parser(program_name, description, cmd_modules) + local epilog = [[ +Variables: + Variables from the "variables" table of the configuration file can be + overridden with VAR=VALUE assignments. + +]]..get_config_text() + + local parser = argparse( + program_name, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. + program.." - "..description, epilog) + :help_max_width(80) + :add_help("--help") + :add_help_command({add_help = false}) + :command_target("command") + :require_command(false) + + parser:flag("--version", "Show version info and exit.") + :action(function() + util.printout(program.." "..cfg.program_version) + util.printout(description) + util.printout() + os.exit(cmd.errorcodes.OK) + end) + parser:flag("--dev", "Enable the sub-repositories in rocks servers for ".. + "rockspecs of in-development versions.") + parser:option("--server", "Fetch rocks/rockspecs from this server ".. + "(takes priority over config file).") + parser:option("--only-server", "Fetch rocks/rockspecs from this server only ".. + "(overrides any entries in the config file).") + :argname("") + parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") + :argname("") + parser:option("--lua-dir", "Which Lua installation to use.") + :argname("") + parser:option("--lua-version", "Which Lua version to use.") + :argname("") + parser:option("--tree", "Which tree to operate on.") + parser:option("--project-tree"):hidden(true) -- TODO: Description? + parser:flag("--local", "Use the tree in the user's home directory.\n".. + "To enable it, see '"..program.." help path'.") + parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") + parser:flag("--verbose", "Display verbose output of commands executed.") + parser:option("--timeout", "Timeout on network operations, in seconds.\n".. + "0 means no timeout (wait forever). Default is ".. + tostring(cfg.connection_timeout)..".") + :argname("") + :convert(tonumber) + + -- Compatibility for old names of some options + parser:option("--to"):target("tree"):hidden(true) + parser:option("--from"):target("server"):hidden(true) + parser:option("--only-from"):target("only_server"):hidden(true) + parser:option("--only-sources-from"):target("only_sources"):hidden(true) + + for _, module in util.sortedpairs(cmd_modules) do + if module.add_to_parser then -- TODO: Remove this check. + module.add_to_parser(parser) + end + end + + return parser +end + --- Main command-line processor. -- Parses input arguments and calls the appropriate driver function -- to execute the action requested on the command-line, forwarding @@ -314,11 +409,24 @@ end -- @param commands table: contains the loaded modules representing commands. -- @param external_namespace string: where to look for external commands. -- @param ... string: Arguments given on the command-line. -function cmd.run_command(description, commands, external_namespace, ...) +function cmd.run_command(program_name, description, commands, external_namespace, ...) check_popen() - local function process_arguments(...) + fs.init() + + for _, module_name in ipairs(fs.modules(external_namespace)) do + if not commands[module_name] then + commands[module_name] = external_namespace.."."..module_name + end + end + + local cmd_modules = {} + for name, module in pairs(commands) do + cmd_modules[name] = require(module) + end + + local function process_cmdline_vars(...) local args = {...} local cmdline_vars = {} local last = #args @@ -340,69 +448,38 @@ function cmd.run_command(description, commands, external_namespace, ...) end end end - local nonflags = { util.parse_flags(unpack(args)) } - local flags = table.remove(nonflags, 1) - if flags.ERROR then - die(flags.ERROR.." See --help.") - end - -- Compatibility for old names of some flags - if flags["to"] then flags["tree"] = flags["to"] end - if flags["from"] then flags["server"] = flags["from"] end - if flags["nodeps"] then flags["deps-mode"] = "none" end - if flags["only-from"] then flags["only-server"] = flags["only-from"] end - if flags["only-sources-from"] then flags["only-sources"] = flags["only-sources-from"] end - - return flags, nonflags, cmdline_vars + return args, cmdline_vars end - local flags, nonflags, cmdline_vars = process_arguments(...) + local args, cmdline_vars = process_cmdline_vars(...) + local parser = get_parser(program_name, description, cmd_modules) + args = parser:parse(args) - if flags["timeout"] then -- setting it in the config file will kick-in earlier in the process - local timeout = tonumber(flags["timeout"]) - if timeout then - cfg.connection_timeout = timeout - else - die "Argument error: --timeout expects a numeric argument." - end + if not args.command then + util.printout(parser:get_help()) + os.exit(cmd.errorcodes.OK) end - local command - if flags["help"] or #nonflags == 0 then - command = "help" - else - command = table.remove(nonflags, 1) + if args.timeout then -- setting it in the config file will kick-in earlier in the process + cfg.connection_timeout = args.timeout end - command = command:gsub("-", "_") - if command == "config" then - if nonflags[1] == "lua_version" and nonflags[2] then - flags["lua-version"] = nonflags[2] - elseif nonflags[1] == "lua_dir" and nonflags[2] then - flags["lua-dir"] = nonflags[2] + if args.command == "config" then + if args.key == "lua_version" and args.value then + args.lua_version = args.value + elseif args.key == "lua_dir" and args.value then + args.lua_dir = args.value end end - - if flags["deps-mode"] and not deps.check_deps_mode_flag(flags["deps-mode"]) then - die("Invalid entry for --deps-mode.") - end ----------------------------------------------------------------------------- - local lua_found, err = init_config(flags) + local lua_found, err = init_config(args) if err then die(err) end ----------------------------------------------------------------------------- - if flags["version"] then - util.printout(program.." "..cfg.program_version) - util.printout(description) - util.printout() - os.exit(cmd.errorcodes.OK) - end - - fs.init() - -- if the Lua interpreter wasn't explicitly found before cfg.init, -- try again now. if not lua_found then @@ -423,13 +500,7 @@ function cmd.run_command(description, commands, external_namespace, ...) cfg.project_dir = fs.absolute_name(cfg.project_dir) end - for _, module_name in ipairs(fs.modules(external_namespace)) do - if not commands[module_name] then - commands[module_name] = external_namespace.."."..module_name - end - end - - if flags["verbose"] then + if args.verbose then cfg.verbose = true fs.verbose() end @@ -438,24 +509,22 @@ function cmd.run_command(description, commands, external_namespace, ...) die("Current directory does not exist. Please run LuaRocks from an existing directory.") end - ok, err = process_tree_flags(flags, cfg.project_dir) + local ok, err = process_tree_flags(args, cfg.project_dir) if not ok then die(err) end - ok, err = process_server_flags(flags) + ok, err = process_server_flags(args) if not ok then die(err) end - if flags["only-sources"] then - cfg.only_sources_from = flags["only-sources"] + if args.only_sources then + cfg.only_sources_from = args.only_sources end - if command ~= "help" then - for k, v in pairs(cmdline_vars) do - cfg.variables[k] = v - end + for k, v in pairs(cmdline_vars) do + cfg.variables[k] = v end -- if running as superuser, use system cache dir @@ -463,22 +532,15 @@ function cmd.run_command(description, commands, external_namespace, ...) cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") end - if commands[command] then - local cmd_mod = require(commands[command]) - local call_ok, ok, err, exitcode = xpcall(function() - if command == "help" then - return cmd_mod.command(description, commands, unpack(nonflags)) - else - return cmd_mod.command(flags, unpack(nonflags)) - end - end, error_handler) - if not call_ok then - die(ok, cmd.errorcodes.CRASH) - elseif not ok then - die(err, exitcode) - end - else - die("Unknown command: "..command) + local cmd_mod = cmd_modules[args.command] + local call_ok, ok, err, exitcode = xpcall(function() + return cmd_mod.command(args) + end, error_handler) + + if not call_ok then + die(ok, cmd.errorcodes.CRASH) + elseif not ok then + die(err, exitcode) end util.run_scheduled_functions() end diff --git a/src/luarocks/cmd/help.lua b/src/luarocks/cmd/help.lua deleted file mode 100644 index b3d937e1..00000000 --- a/src/luarocks/cmd/help.lua +++ /dev/null @@ -1,139 +0,0 @@ - ---- Module implementing the LuaRocks "help" command. --- This is a generic help display module, which --- uses a global table called "commands" to find commands --- to show help for; each command should be represented by a --- table containing "help" and "help_summary" fields. -local help = {} - -local util = require("luarocks.util") -local cfg = require("luarocks.core.cfg") -local dir = require("luarocks.dir") -local fs = require("luarocks.fs") - -local program = util.this_program("luarocks") - -help.help_summary = "Help on commands. Type '"..program.." help ' for more." - -help.help_arguments = "[]" -help.help = [[ - is the command to show help for. -]] - -local function print_banner() - util.printout("\nLuaRocks "..cfg.program_version..", the Lua package manager") -end - -local function print_section(section) - util.printout("\n"..section) -end - -local function get_status(status) - if status then - return "ok" - else - return "not found" - end -end - ---- Driver function for the "help" command. --- @param command string or nil: command to show help for; if not --- given, help summaries for all commands are shown. --- @return boolean or (nil, string): true if there were no errors --- or nil and an error message if an invalid command was requested. -function help.command(description, commands, command) - assert(type(description) == "string") - assert(type(commands) == "table") - - if not command then - print_banner() - print_section("NAME") - util.printout("\t"..program..[[ - ]]..description) - print_section("SYNOPSIS") - util.printout("\t"..program..[[ [] [VAR=VALUE]... [] ]]) - print_section("GENERAL OPTIONS") - util.printout([[ - These apply to all commands, as appropriate: - - --dev Enable the sub-repositories in rocks servers - for rockspecs of in-development versions - --server= Fetch rocks/rockspecs from this server - (takes priority over config file) - --only-server= Fetch rocks/rockspecs from this server only - (overrides any entries in the config file) - --only-sources= Restrict downloads to paths matching the - given URL. - --lua-dir= Which Lua installation to use. - --lua-version= Which Lua version to use. - --tree= Which tree to operate on. - --local Use the tree in the user's home directory. - To enable it, see ']]..program..[[ help path'. - --global Use the system tree when `local_by_default` is `true`. - --verbose Display verbose output of commands executed. - --timeout= Timeout on network operations, in seconds. - 0 means no timeout (wait forever). - Default is ]]..tostring(cfg.connection_timeout)..[[.]]) - print_section("VARIABLES") - util.printout([[ - Variables from the "variables" table of the configuration file - can be overridden with VAR=VALUE assignments.]]) - print_section("COMMANDS") - for name, modname in util.sortedpairs(commands) do - local cmd = require(modname) - util.printout("", name) - util.printout("\t", cmd.help_summary) - end - print_section("CONFIGURATION") - util.printout("\tLua version: " .. cfg.lua_version) - local ljv = util.get_luajit_version() - if ljv then - util.printout("\tLuaJIT version: " .. ljv) - end - util.printout() - util.printout("\tConfiguration files:") - local conf = cfg.config_files - util.printout("\t\tSystem : ".. fs.absolute_name(conf.system.file) .. " (" .. get_status(conf.system.found) ..")") - if conf.user.file then - util.printout("\t\tUser : ".. fs.absolute_name(conf.user.file) .. " (" .. get_status(conf.user.found) ..")") - else - util.printout("\t\tUser : disabled in this LuaRocks installation.") - end - if conf.project then - util.printout("\t\tProject : ".. fs.absolute_name(conf.project.file) .. " (" .. get_status(conf.project.found) ..")") - end - util.printout() - util.printout("\tRocks trees in use: ") - for _, tree in ipairs(cfg.rocks_trees) do - if type(tree) == "string" then - util.printout("\t\t"..fs.absolute_name(tree)) - else - local name = tree.name and " (\""..tree.name.."\")" or "" - util.printout("\t\t"..fs.absolute_name(tree.root)..name) - end - end - util.printout() - else - command = command:gsub("-", "_") - local cmd = commands[command] and require(commands[command]) - if cmd then - local arguments = cmd.help_arguments or "" - print_banner() - print_section("NAME") - util.printout("\t"..program.." "..command.." - "..cmd.help_summary) - print_section("SYNOPSIS") - util.printout("\t"..program.." "..command.." "..arguments) - print_section("DESCRIPTION") - util.printout("",(cmd.help:gsub("\n","\n\t"):gsub("\n\t$",""))) - print_section("SEE ALSO") - if cmd.help_see_also then - util.printout(cmd.help_see_also) - end - util.printout("","'"..program.." help' for general options and configuration.\n") - else - return nil, "Unknown command: "..command - end - end - return true -end - -return help diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index 60aa4f82..fc14baf6 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -10,27 +10,30 @@ local util = require("luarocks.util") local persist = require("luarocks.persist") local write_rockspec = require("luarocks.cmd.write_rockspec") -init.help_summary = "Initialize a directory for a Lua project using LuaRocks." -init.help_arguments = "[ []]" -init.help = [[ - is the project name. - is an optional project version. - ---reset Delete .luarocks/config-5.x.lua and ./lua - and generate new ones. - -Options for specifying rockspec data: - ---license="" A license string, such as "MIT/X11" or "GNU GPL v3". ---summary="" A short one-line description summary. ---detailed="" A longer description string. ---homepage= Project homepage. ---lua-versions= Supported Lua versions. Accepted values are "5.1", "5.2", - "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". ---rockspec-format= Rockspec format version, such as "1.0" or "1.1". ---lib=[,] A comma-separated list of libraries that C files need to - link to. -]] +function init.add_to_parser(parser) + local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) + :add_help(false) + + cmd:argument("name", "The project name."):args("?") + cmd:argument("version", "An optional project version."):args("?") + cmd:flag("--reset", "Delete .luarocks/config-5.x.lua and ./lua and generate new ones.") + + cmd:group("Options for specifying rockspec data", + cmd:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') + :argname(""), + cmd:option("--summary", "A short one-line description summary.") + :argname(""), + cmd:option("--detailed", "A longer description string.") + :argname(""), + cmd:option("--homepage", "Project homepage.") + :argname(""), + cmd:option("--lua-versions", "Supported Lua versions. Accepted values are ".. + '"5.1", "5.2", "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3".'), + cmd:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') + :argname(""), + cmd:option("--lib", "A comma-separated list of libraries that C files need to link to.") + :argname("")) +end local function write_gitignore(entries) local gitignore = "" @@ -53,10 +56,11 @@ end --- Driver function for "init" command. -- @return boolean: True if succeeded, nil on errors. -function init.command(flags, name, version) +function init.command(args) local pwd = fs.current_dir() + local name = args.name if not name then name = dir.base_name(pwd) if name == "/" then @@ -84,7 +88,7 @@ function init.command(flags, name, version) end if not has_rockspec then - local ok, err = write_rockspec.command(flags, name, version or "dev", pwd) + local ok, err = write_rockspec.command(args, name, args.version or "dev", pwd) if not ok then util.printerr(err) end @@ -101,7 +105,7 @@ function init.command(flags, name, version) fs.make_dir(".luarocks") local config_file = ".luarocks/config-" .. cfg.lua_version .. ".lua" - if flags["reset"] then + if args.reset then fs.delete(lua_wrapper) fs.delete(config_file) end diff --git a/src/luarocks/cmd/lint.lua b/src/luarocks/cmd/lint.lua index c9ea45ea..433eed84 100644 --- a/src/luarocks/cmd/lint.lua +++ b/src/luarocks/cmd/lint.lua @@ -7,24 +7,22 @@ local util = require("luarocks.util") local download = require("luarocks.download") local fetch = require("luarocks.fetch") -lint.help_summary = "Check syntax of a rockspec." -lint.help_arguments = "" -lint.help = [[ -This is a utility function that checks the syntax of a rockspec. - -It returns success or failure if the text of a rockspec is -syntactically correct. -]] - -function lint.command(flags, input) - if not input then - return nil, "Argument missing. "..util.see_help("lint") - end - - local filename = input - if not input:match(".rockspec$") then +function lint.add_to_parser(parser) + local cmd = parser:command("lint", "Check syntax of a rockspec.\n\n".. + "Returns success if the text of the rockspec is syntactically correct, else failure.", + util.see_also()) + :summary("Check syntax of a rockspec.") + :add_help(false) + + cmd:argument("rockspec", "The rockspec to check.") +end + +function lint.command(args) + + local filename = args.rockspec + if not filename:match(".rockspec$") then local err - filename, err = download.download("rockspec", input:lower()) + filename, err = download.download("rockspec", filename:lower()) if not filename then return nil, err end diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 6caba8cd..60cfb3d8 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -77,162 +77,6 @@ function util.matchquote(s) return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) end ---- List of supported arguments. --- Arguments that take no parameters are marked with the boolean true. --- Arguments that take a parameter are marked with a descriptive string. --- Arguments that may take an empty string are described in quotes, --- (as in the value for --detailed=""). --- For all other string values, it means the parameter is mandatory. -local supported_flags = { - ["all"] = true, - ["api-key"] = "", - ["append"] = true, - ["arch"] = "", - ["bin"] = true, - ["binary"] = true, - ["branch"] = "", - ["build-deps"] = true, - ["debug"] = true, - ["deps"] = true, - ["deps-mode"] = "", - ["detailed"] = "\"\"", - ["dev"] = true, - ["dir"] = "", - ["force"] = true, - ["force-fast"] = true, - ["from"] = "", - ["global"] = true, - ["help"] = true, - ["home"] = true, - ["homepage"] = "\"\"", - ["index"] = true, - ["issues"] = true, - ["json"] = true, - ["keep"] = true, - ["labels"] = true, - ["lib"] = "", - ["license"] = "\"\"", - ["list"] = true, - ["local"] = true, - ["local-tree"] = true, - ["lr-bin"] = true, - ["lr-cpath"] = true, - ["lr-path"] = true, - ["lua-dir"] = "", - ["lua-version"] = "", - ["lua-versions"] = "", - ["lua-ver"] = true, - ["lua-incdir"] = true, - ["lua-libdir"] = true, - ["modules"] = true, - ["mversion"] = true, - ["namespace"] = "", - ["no-bin"] = true, - ["no-doc"] = true, - ["no-refresh"] = true, - ["nodeps"] = true, - ["old-versions"] = true, - ["only-deps"] = true, - ["only-from"] = "", - ["only-server"] = "", - ["only-sources"] = "", - ["only-sources-from"] = "", - ["outdated"] = true, - ["output"] = "", - ["pack-binary-rock"] = true, - ["porcelain"] = true, - ["project-tree"] = "", - ["quick"] = true, - ["reset"] = true, - ["rock-dir"] = true, - ["rock-license"] = true, - ["rock-namespace"] = true, - ["rock-tree"] = true, - ["rock-trees"] = true, - ["rockspec"] = true, - ["rockspec-format"] = "", - ["scope"] = "", - ["server"] = "", - ["sign"] = true, - ["skip-pack"] = true, - ["source"] = true, - ["summary"] = "\"\"", - ["system-config"] = true, - ["tag"] = "", - ["test-type"] = "", - ["temp-key"] = "", - ["timeout"] = "", - ["to"] = "", - ["tree"] = "", - ["unset"] = true, - ["user-config"] = true, - ["verbose"] = true, - ["verify"] = true, - ["version"] = true, -} - ---- Extract flags from an arguments list. --- Given string arguments, extract flag arguments into a flags set. --- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz", --- it would return the following: --- {["bla"] = true, ["tux"] = "beep", ["baz"] = true}, "foo", "bar". -function util.parse_flags(...) - local args = {...} - local flags = {} - local i = 1 - local out = {} - local state = "initial" - while i <= #args do - local flag = args[i]:match("^%-%-(.*)") - if state == "initial" and flag == "" then - state = "ignore_flags" - elseif state == "initial" and flag then - local var,val = flag:match("([a-z_%-]*)=(.*)") - if val then - local vartype = supported_flags[var] - if type(vartype) == "string" then - if val == "" and vartype:sub(1,1) ~= '"' then - return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } - end - flags[var] = val - else - if vartype then - return { ERROR = "Invalid argument: flag --"..var.." does not take an parameter." } - else - return { ERROR = "Invalid argument: unknown flag --"..var.."." } - end - end - else - local var = flag - local vartype = supported_flags[var] - if type(vartype) == "string" then - i = i + 1 - local val = args[i] - if not val then - return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter." } - end - if val:match("^%-%-.*") then - return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter (if you really want to pass "..val.." as an argument to --"..var..", use --"..var.."="..val..")." } - else - if val == "" and vartype:sub(1,1) ~= '"' then - return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } - end - flags[var] = val - end - elseif vartype == true then - flags[var] = true - else - return { ERROR = "Invalid argument: unknown flag --"..var.."." } - end - end - elseif state == "ignore_flags" or (state == "initial" and not flag) then - table.insert(out, args[i]) - end - i = i + 1 - end - return flags, unpack(out) -end - local var_format_pattern = "%$%((%a[%a%d_]+)%)" -- Check if a set of needed variables are referenced @@ -394,6 +238,14 @@ function util.see_help(command, program) return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." end +function util.see_also(text) + local see_also = "See also:\n" + if text then + see_also = see_also..text.."\n" + end + return see_also.." '"..util.this_program("luarocks").." help' for general options and configuration." +end + function util.announce_install(rockspec) local cfg = require("luarocks.core.cfg") local path = require("luarocks.path") -- cgit v1.2.3-55-g6feb From 3afab9d46de3889241c0f882cb312b8ec4a385ed Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 12 Jun 2019 18:57:06 -0400 Subject: Move build command to argparse --- src/luarocks/cmd.lua | 8 ++- src/luarocks/cmd/build.lua | 115 ++++++++++++++++++++----------------------- src/luarocks/cmd/install.lua | 2 +- src/luarocks/cmd/remove.lua | 2 +- src/luarocks/cmd/test.lua | 2 +- src/luarocks/deps.lua | 15 +----- src/luarocks/util.lua | 31 ++++++------ 7 files changed, 81 insertions(+), 94 deletions(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 23ca023a..4929b326 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -370,6 +370,7 @@ Variables: :argname("") parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") :argname("") + parser:option("--namespace"):hidden(true) -- TODO: Description parser:option("--lua-dir", "Which Lua installation to use.") :argname("") parser:option("--lua-version", "Which Lua version to use.") @@ -461,6 +462,11 @@ function cmd.run_command(program_name, description, commands, external_namespace os.exit(cmd.errorcodes.OK) end + -- Compatibility for old flag + if args.nodeps then + args.deps_mode = "none" + end + if args.timeout then -- setting it in the config file will kick-in earlier in the process cfg.connection_timeout = args.timeout end @@ -472,7 +478,7 @@ function cmd.run_command(program_name, description, commands, external_namespace args.lua_dir = args.value end end - + ----------------------------------------------------------------------------- local lua_found, err = init_config(args) if err then diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 23a94fa7..2b9f4dd6 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -18,40 +18,37 @@ local search = require("luarocks.search") local make = require("luarocks.cmd.make") local cmd = require("luarocks.cmd") -cmd_build.help_summary = "build/compile a rock." -cmd_build.help_arguments = "[] {|| []}" -cmd_build.help = [[ -Build and install a rock, compiling its C parts if any. -Argument may be a rockspec file, a source rock file -or the name of a rock to be fetched from a repository. - ---pack-binary-rock Do not install rock. Instead, produce a .rock file - with the contents of compilation in the current - directory. - ---keep Do not remove previously installed versions of the - rock after building a new one. This behavior can - be made permanent by setting keep_other_versions=true - in the configuration file. - ---branch= Override the `source.branch` field in the loaded - rockspec. Allows to specify a different branch to - fetch. Particularly for "dev" rocks. - ---only-deps Installs only the dependencies of the rock. - ---verify Verify signature of the rockspec or src.rock being - built. If the rockspec or src.rock is being downloaded, - LuaRocks will attempt to download the signature as well. - Otherwise, the signature file should be already - available locally in the same directory. - You need the signer’s public key in your local - keyring for this option to work properly. - ---sign To be used with --pack-binary-rock. Also produce - a signature file for the generated .rock file. - -]]..util.deps_mode_help() +function cmd_build.add_to_parser(parser) + local cmd = parser:command("build", "Build and install a rock, compiling ".. + "its C parts if any.", util.see_also()) + :summary("Build/compile a rock.") + :add_help(false) + + cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. + "a rock to be fetched from a repository.") + cmd:argument("version", "Rock version.") + :args("?") + + cmd:flag("--pack-binary-rock", "Do not install rock. Instead, produce a ".. + ".rock file with the contents of compilation in the current directory.") + cmd:flag("--keep", "Do not remove previously installed versions of the ".. + "rock after building a new one. This behavior can be made permanent by ".. + "setting keep_other_versions=true in the configuration file.") + cmd:option("--branch", "Override the `source.branch` field in the loaded ".. + "rockspec. Allows to specify a different branch to fetch. Particularly ".. + 'for "dev" rocks.') + :argname("") + cmd:flag("--only-deps", "Installs only the dependencies of the rock.") + cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. + "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. + "attempt to download the signature as well. Otherwise, the signature ".. + "file should be already available locally in the same directory.\n".. + "You need the signer’s public key in your local keyring for this ".. + "option to work properly.") + cmd:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. + "signature file for the generated .rock file.") + util.deps_mode_option(cmd) +end --- Build and install a rock. -- @param rock_filename string: local or remote filename of a rock. @@ -132,58 +129,54 @@ local function remove_doc_dir(name, version) end --- Driver function for "build" command. --- @param name string: A local or remote rockspec or rock file. -- If a package name is given, forwards the request to "search" and, -- if returned a result, installs the matching rock. --- @param version string: When passing a package name, a version number may --- also be given. +-- When passing a package name, a version number may also be given. -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an -- error message otherwise. exitcode is optionally returned. -function cmd_build.command(flags, name, version) - assert(type(name) == "string" or not name) - assert(type(version) == "string" or not version) - - if not name then - return make.command(flags) +function cmd_build.command(args) + if not args.rock then + return make.command(args) end - name = util.adjust_name_and_namespace(name, flags) + local name = util.adjust_name_and_namespace(args.rock, args) local opts = build.opts({ need_to_fetch = true, minimal_mode = false, - deps_mode = deps.get_deps_mode(flags), - build_only_deps = not not flags["only-deps"], - namespace = flags["namespace"], - branch = not not flags["branch"], - verify = not not flags["verify"], + deps_mode = deps.get_deps_mode(args), + build_only_deps = not not args.only_deps, + namespace = args.namespace, + branch = not not args.branch, + verify = not not args.verify, }) - if flags["sign"] and not flags["pack-binary-rock"] then + if args.sign and not args.pack_binary_rock then return nil, "In the build command, --sign is meant to be used only with --pack-binary-rock" end - if flags["pack-binary-rock"] then - return pack.pack_binary_rock(name, version, flags["sign"], function() + if args.pack_binary_rock then + return pack.pack_binary_rock(name, args.version, args.sign, function() opts.build_only_deps = false - local status, err, errcode = do_build(name, version, opts) - if status and flags["no-doc"] then - remove_doc_dir(name, version) + local status, err, errcode = do_build(name, args.version, opts) + if status and args.no_doc then + remove_doc_dir(name, args.version) end return status, err, errcode end) end - local ok, err = fs.check_command_permissions(flags) + local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end - ok, err = do_build(name, version, opts) + ok, err = do_build(name, args.version, opts) if not ok then return nil, err end + local version name, version = ok, err - if flags["no-doc"] then + if args.no_doc then remove_doc_dir(name, version) end @@ -191,15 +184,15 @@ function cmd_build.command(flags, name, version) util.printout("Stopping after installing dependencies for " ..name.." "..version) util.printout() else - if (not flags["keep"]) and not cfg.keep_other_versions then - local ok, err = remove.remove_other_versions(name, version, flags["force"], flags["force-fast"]) + if (not args.keep) and not cfg.keep_other_versions then + local ok, err = remove.remove_other_versions(name, version, args.force, args.force_fast) if not ok then util.printerr(err) end end end - writer.check_dependencies(nil, deps.get_deps_mode(flags)) + writer.check_dependencies(nil, deps.get_deps_mode(args)) return name, version end diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index d1d7bf6c..ec6da14f 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -41,7 +41,7 @@ or a filename of a locally available rock. You need the signer’s public key in your local keyring for this option to work properly. -]]..util.deps_mode_help() +]]--..util.deps_mode_help() install.opts = util.opts_table("install.opts", { namespace = "string?", diff --git a/src/luarocks/cmd/remove.lua b/src/luarocks/cmd/remove.lua index 5ddf7477..f9345670 100644 --- a/src/luarocks/cmd/remove.lua +++ b/src/luarocks/cmd/remove.lua @@ -24,7 +24,7 @@ To override this check and force the removal, use --force. To perform a forced removal without reporting dependency issues, use --force-fast. -]]..util.deps_mode_help() +]]--..util.deps_mode_help() --- Driver function for the "remove" command. -- @param name string: name of a rock. If a version is given, refer to diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index 413a029c..06ac0068 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -23,7 +23,7 @@ test suite arguments. specified in the rockspec and it could not be auto-detected. -]]..util.deps_mode_help() +]]--..util.deps_mode_help() function cmd_test.command(flags, argument, ...) assert(type(argument) == "string" or not argument) diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 9ee21772..af05ed05 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -569,20 +569,9 @@ function deps.check_lua_libdir(vars) return nil, "Failed finding Lua library. You may need to configure LUA_LIBDIR.", "dependency" end -local valid_deps_modes = { - one = true, - order = true, - all = true, - none = true, -} - -function deps.check_deps_mode_flag(flag) - return valid_deps_modes[flag] -end - function deps.get_deps_mode(flags) - if flags["deps-mode"] then - return flags["deps-mode"] + if flags["deps_mode"] then + return flags["deps_mode"] else return cfg.deps_mode end diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 60cfb3d8..635d3a97 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -215,23 +215,22 @@ function util.this_program(default) return prog end -function util.deps_mode_help(program) +function util.deps_mode_option(parser) local cfg = require("luarocks.core.cfg") - return [[ ---deps-mode= How to handle dependencies. Four modes are supported: - * all - use all trees from the rocks_trees list - for finding dependencies - * one - use only the current tree (possibly set - with --tree) - * order - use trees based on order (use the current - tree and all trees below it on the rocks_trees list) - * none - ignore dependencies altogether. - The default mode may be set with the deps_mode entry - in the configuration file. - The current default is "]]..cfg.deps_mode..[[". - Type ']]..util.this_program(program or "luarocks")..[[' with no arguments to see - your list of rocks trees. -]] + + parser:option("--deps-mode", "How to handle dependencies. Four modes are supported:\n".. + "* all - use all trees from the rocks_trees list for finding dependencies\n".. + "* one - use only the current tree (possibly set with --tree)\n".. + "* order - use trees based on order (use the current tree and all ".. + "trees below it on the rocks_trees list)\n".. + "* none - ignore dependencies altogether.\n".. + "The default mode may be set with the deps_mode entry in the configuration file.\n".. + 'The current default is "'..cfg.deps_mode..'".\n'.. + "Type '"..util.this_program(program or "luarocks").."' with no ".. + "arguments to see your list of rocks trees.") + :argname("") + :choices({"all", "one", "order", "none"}) + parser:flag("--nodeps"):hidden(true) end function util.see_help(command, program) -- cgit v1.2.3-55-g6feb From d6f296e108972982cf071d42cee37ac0cb122174 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 12 Jun 2019 23:49:46 -0400 Subject: Move config command to argparse --- src/luarocks/cmd/config.lua | 121 +++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 62 deletions(-) diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index b3cb5e07..6ec0efdf 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -9,9 +9,10 @@ local deps = require("luarocks.deps") local dir = require("luarocks.dir") local fs = require("luarocks.fs") -config_cmd.help_summary = "Query information about the LuaRocks configuration." -config_cmd.help_arguments = "( | --scope= | --unset --scope= | )" -config_cmd.help = [[ +function config_cmd.add_to_parser(parser) + local cmd = parser:command("config", [[ +Query information about the LuaRocks configuration. + * When given a configuration key, it prints the value of that key according to the currently active configuration (taking into account all config files and any command-line flags passed) @@ -45,23 +46,35 @@ config_cmd.help = [[ configuration, resulting from reading the config files from all scopes. - Example: luarocks config - -OPTIONS ---scope= The scope indicates which config file should be rewritten. - Accepted values are "system", "user" or "project". - * Using a wrapper created with `luarocks init`, - the default is "project". - * Using --local (or when `local_by_default` is `true`), - the default is "user". - * Otherwise, the default is "system". - ---json Output as JSON -]] -config_cmd.help_see_also = [[ - https://github.com/luarocks/luarocks/wiki/Config-file-format - for detailed information on the LuaRocks config file format. -]] + Example: luarocks config]], util.see_also([[ + https://github.com/luarocks/luarocks/wiki/Config-file-format + for detailed information on the LuaRocks config file format. +]])) + :summary("Query information about the LuaRocks configuration.") + :add_help(false) + + cmd:argument("key", "The configuration key.") + :args("?") + cmd:argument("value", "The configuration value.") + :args("?") + + cmd:option("--scope", "The scope indicates which config file should be rewritten.\n".. + 'Accepted values are "system", "user" or "project".\n'.. + '* Using a wrapper created with `luarocks init`, the default is "project".\n'.. + '* Using --local (or when `local_by_default` is `true`), the default is "user".\n'.. + '* Otherwise, the default is "system".') + :choices({"system", "user", "project"}) + cmd:flag("--unset", "Delete the key from the configuration file.") + cmd:flag("--json", "Output as JSON.") + + -- Deprecated flags + cmd:flag("--lua-incdir"):hidden(true) + cmd:flag("--lua-libdir"):hidden(true) + cmd:flag("--lua-ver"):hidden(true) + cmd:flag("--system-config"):hidden(true) + cmd:flag("--user-config"):hidden(true) + cmd:flag("--rock-trees"):hidden(true) +end local function config_file(conf) print(dir.normalize(conf.file)) @@ -218,45 +231,40 @@ local function write_entries(keys, scope, do_unset) end end -local function check_scope(flags) - local scope = flags["scope"] - or (flags["local"] and "user") - or (flags["project-tree"] and "project") - or (cfg.local_by_default and "user") - or "system" - if scope ~= "system" and scope ~= "user" and scope ~= "project" then - return nil, "Valid values for scope are: system, user, project" - end - - return scope +local function get_scope(flags) + return flags["scope"] + or (flags["local"] and "user") + or (flags["project_tree"] and "project") + or (cfg.local_by_default and "user") + or "system" end --- Driver function for "config" command. -- @return boolean: True if succeeded, nil on errors. -function config_cmd.command(flags, var, val) +function config_cmd.command(args) deps.check_lua_incdir(cfg.variables) deps.check_lua_libdir(cfg.variables) -- deprecated flags - if flags["lua-incdir"] then + if args["lua_incdir"] then print(cfg.variables.LUA_INCDIR) return true end - if flags["lua-libdir"] then + if args["lua_libdir"] then print(cfg.variables.LUA_LIBDIR) return true end - if flags["lua-ver"] then + if args["lua_ver"] then print(cfg.lua_version) return true end - if flags["system-config"] then + if args["system_config"] then return config_file(cfg.config_files.system) end - if flags["user-config"] then + if args["user_config"] then return config_file(cfg.config_files.user) end - if flags["rock-trees"] then + if args["rock_trees"] then for _, tree in ipairs(cfg.rocks_trees) do if type(tree) == "string" then util.printout(dir.normalize(tree)) @@ -268,29 +276,22 @@ function config_cmd.command(flags, var, val) return true end - if var == "lua_version" and val then - local scope, err = check_scope(flags) - if not scope then - return nil, err - end - + if args.key == "lua_version" and args.value then + local scope = get_scope(args) if scope == "project" and not cfg.config_files.project then return nil, "Current directory is not part of a project. You may want to run `luarocks init`." end local prefix = dir.dir_name(cfg.config_files[scope].file) - local ok, err = persist.save_default_lua_version(prefix, val) + local ok, err = persist.save_default_lua_version(prefix, args.value) if not ok then return nil, "could not set default Lua version: " .. err end - print("Lua version will default to " .. val .. " in " .. prefix) + print("Lua version will default to " .. args.value .. " in " .. prefix) end - if var == "lua_dir" and val then - local scope, err = check_scope(flags) - if not scope then - return nil, err - end + if args.key == "lua_dir" and args.value then + local scope = get_scope(args) local keys = { ["variables.LUA_DIR"] = cfg.variables.LUA_DIR, ["variables.LUA_BINDIR"] = cfg.variables.LUA_BINDIR, @@ -298,25 +299,21 @@ function config_cmd.command(flags, var, val) ["variables.LUA_LIBDIR"] = cfg.variables.LUA_LIBDIR, ["lua_interpreter"] = cfg.lua_interpreter, } - return write_entries(keys, scope, flags["unset"]) + return write_entries(keys, scope, args["unset"]) end - if var then - if val or flags["unset"] then - local scope, err = check_scope(flags) - if not scope then - return nil, err - end - - return write_entries({ [var] = val }, scope, flags["unset"]) + if args.key then + if args.value or args["unset"] then + local scope = get_scope(args) + return write_entries({ [args.key] = args.value }, scope, args["unset"]) else - return print_entry(var, cfg, flags["json"]) + return print_entry(args.key, cfg, args["json"]) end end local cleancfg = cleanup(cfg) - if flags["json"] then + if args["json"] then return print_json(cleancfg) else print(persist.save_from_table_to_string(cleancfg)) -- cgit v1.2.3-55-g6feb From 0823c4dd62e15515ad1e77cd20681b720485c564 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Thu, 13 Jun 2019 20:41:14 -0400 Subject: Move remaining commands to argparse --- src/bin/luarocks | 1 - src/bin/luarocks-admin | 1 - src/luarocks/admin/cmd/add.lua | 39 +++++---- src/luarocks/admin/cmd/make_manifest.lua | 31 +++---- src/luarocks/admin/cmd/refresh_cache.lua | 21 ++--- src/luarocks/admin/cmd/remove.lua | 33 ++++---- src/luarocks/cmd.lua | 4 +- src/luarocks/cmd/doc.lua | 51 ++++++------ src/luarocks/cmd/download.lua | 44 +++++----- src/luarocks/cmd/init.lua | 19 +++-- src/luarocks/cmd/install.lua | 97 ++++++++++------------ src/luarocks/cmd/list.lua | 39 ++++----- src/luarocks/cmd/make.lua | 96 +++++++++++----------- src/luarocks/cmd/new_version.lua | 55 ++++++++----- src/luarocks/cmd/pack.lua | 42 ++++------ src/luarocks/cmd/path.lua | 52 ++++++------ src/luarocks/cmd/purge.lua | 34 ++++---- src/luarocks/cmd/remove.lua | 45 ++++++----- src/luarocks/cmd/search.lua | 50 ++++++------ src/luarocks/cmd/show.lua | 83 ++++++++++--------- src/luarocks/cmd/test.lua | 52 ++++++------ src/luarocks/cmd/unpack.lua | 35 ++++---- src/luarocks/cmd/upload.lua | 67 ++++++++------- src/luarocks/cmd/which.lua | 31 +++---- src/luarocks/cmd/write_rockspec.lua | 135 +++++++++++++++++++------------ src/luarocks/deps.lua | 5 +- src/luarocks/upload/api.lua | 4 +- 27 files changed, 598 insertions(+), 568 deletions(-) diff --git a/src/bin/luarocks b/src/bin/luarocks index f277b348..18c8fac6 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks @@ -9,7 +9,6 @@ local cmd = require("luarocks.cmd") local description = "LuaRocks main command-line interface" local commands = { - help = "luarocks.cmd.help", init = "luarocks.cmd.init", pack = "luarocks.cmd.pack", unpack = "luarocks.cmd.unpack", diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index ddbe0f48..db746bea 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin @@ -9,7 +9,6 @@ local cmd = require("luarocks.cmd") local description = "LuaRocks repository administration interface" local commands = { - help = "luarocks.cmd.help", make_manifest = "luarocks.admin.cmd.make_manifest", add = "luarocks.admin.cmd.add", remove = "luarocks.admin.cmd.remove", diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index 19990b3c..fa198baf 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -11,20 +11,21 @@ local fs = require("luarocks.fs") local cache = require("luarocks.admin.cache") local index = require("luarocks.admin.index") -add.help_summary = "Add a rock or rockspec to a rocks server." -add.help_arguments = "[--server=] [--no-refresh] {|...}" -add.help = [[ -Arguments are local files, which may be rockspecs or rocks. -The flag --server indicates which server to use. -If not given, the default server set in the upload_server variable -from the configuration file is used instead. - ---no-refresh The local cache should not be refreshed - prior to generation of the updated manifest. ---index Produce an index.html file for the manifest. - This flag is automatically set if an index.html - file already exists. -]] +function add.add_to_parser(parser) + local cmd = parser:command("add", "Add a rock or rockspec to a rocks server.", + util.see_also()) + :add_help(false) + + cmd:argument("rock", "A local rockspec or rock file.") + :args("+") + + cmd:option("--server", "The server to use. If not given, the default server ".. + "set in the upload_server variable from the configuration file is used instead.") + cmd:flag("--no-refresh", "Do not refresh the local cache prior to ".. + "generation of the updated manifest.") + cmd:flag("--index", "Produce an index.html file for the manifest. This ".. + "flag is automatically set if an index.html file already exists.") +end local function zip_manifests() for ver in util.lua_versions() do @@ -124,14 +125,10 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server, do return fs.execute(cmd) end -function add.command(flags, ...) - local files = {...} - if #files < 1 then - return nil, "Argument missing. "..util.see_help("add", "luarocks-admin") - end - local server, server_table = cache.get_upload_server(flags["server"]) +function add.command(args) + local server, server_table = cache.get_upload_server(args["server"]) if not server then return nil, server_table end - return add_files_to_server(not flags["no-refresh"], files, server, server_table, flags["index"]) + return add_files_to_server(not args["no_refresh"], files, server, server_table, args["index"]) end diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index f0b64135..dba7ccf8 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -11,36 +11,37 @@ local deps = require("luarocks.deps") local fs = require("luarocks.fs") local dir = require("luarocks.dir") -make_manifest.help_summary = "Compile a manifest file for a repository." +function make_manifest.add_to_parser(parser) + local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", + util.see_also()) + :add_help(false) -make_manifest.help = [[ -, if given, is a local repository pathname. + cmd:argument("repository", "Local repository pathname.") + :args("?") ---local-tree If given, do not write versioned versions of the manifest file. - Use this when rebuilding the manifest of a local rocks tree. -]] + cmd:flag("--local-tree", "If given, do not write versioned versions of the manifest file.\n".. + "Use this when rebuilding the manifest of a local rocks tree.") + cmd:option("--deps-mode"):hidden(true) -- TODO: Description? +end --- Driver function for "make_manifest" command. --- @param repo string or nil: Pathname of a local repository. If not given, --- the default local repository configured as cfg.rocks_dir is used. -- @return boolean or (nil, string): True if manifest was generated, -- or nil and an error message. -function make_manifest.command(flags, repo) - assert(type(repo) == "string" or not repo) - repo = repo or cfg.rocks_dir +function make_manifest.command(args) + local repo = args.repository or cfg.rocks_dir util.printout("Making manifest for "..repo) - if repo:match("/lib/luarocks") and not flags["local-tree"] then + if repo:match("/lib/luarocks") and not args["local_tree"] then util.warning("This looks like a local rocks tree, but you did not pass --local-tree.") end - local ok, err = writer.make_manifest(repo, deps.get_deps_mode(flags), not flags["local-tree"]) - if ok and not flags["local-tree"] then + local ok, err = writer.make_manifest(repo, deps.get_deps_mode(args), not args["local_tree"]) + if ok and not args["local_tree"] then util.printout("Generating index.html for "..repo) index.make_index(repo) end - if flags["local-tree"] then + if args["local_tree"] then for luaver in util.lua_versions() do fs.delete(dir.path(repo, "manifest-"..luaver)) end diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index 3ffe56d9..0b2574b8 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -3,18 +3,21 @@ local refresh_cache = {} local cfg = require("luarocks.core.cfg") +local util = require("luarocks.util") local cache = require("luarocks.admin.cache") -refresh_cache.help_summary = "Refresh local cache of a remote rocks server." -refresh_cache.help_arguments = "[--from=]" -refresh_cache.help = [[ -The flag --from indicates which server to use. -If not given, the default server set in the upload_server variable -from the configuration file is used instead. -]] +function refresh_cache.add_to_parser(parser) + local cmd = parser:command( + "refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) + :add_help(false) -function refresh_cache.command(flags) - local server, upload_server = cache.get_upload_server(flags["server"]) + cmd:option("--from", "The server to use. If not given, the default server ".. + "set in the upload_server variable from the configuration file is used instead.") + :argname("") +end + +function refresh_cache.command(args) + local server, upload_server = cache.get_upload_server(args["server"]) if not server then return nil, upload_server end local download_url = cache.get_server_urls(server, upload_server) diff --git a/src/luarocks/admin/cmd/remove.lua b/src/luarocks/admin/cmd/remove.lua index f005c83c..4c0125a9 100644 --- a/src/luarocks/admin/cmd/remove.lua +++ b/src/luarocks/admin/cmd/remove.lua @@ -11,16 +11,19 @@ local fs = require("luarocks.fs") local cache = require("luarocks.admin.cache") local index = require("luarocks.admin.index") -admin_remove.help_summary = "Remove a rock or rockspec from a rocks server." -admin_remove.help_arguments = "[--server=] [--no-refresh] {|...}" -admin_remove.help = [[ -Arguments are local files, which may be rockspecs or rocks. -The flag --server indicates which server to use. -If not given, the default server set in the upload_server variable -from the configuration file is used instead. -The flag --no-refresh indicates the local cache should not be refreshed -prior to generation of the updated manifest. -]] +function admin_remove.add_to_parser(parser) + local cmd = parser:command( + "remove", "Remove a rock or rockspec from a rocks server.", util.see_also()) + :add_help(false) + + cmd:argument("rock", "A local rockspec or rock file.") + :args("+") + + cmd:option("--server", "The server to use. If not given, the default server ".. + "set in the upload_server variable from the configuration file is used instead.") + cmd:flag("--no-refresh", "Do not refresh the local cache prior to ".. + "generation of the updated manifest.") +end local function remove_files_from_server(refresh, rockfiles, server, upload_server) assert(type(refresh) == "boolean" or not refresh) @@ -76,14 +79,10 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve return true end -function admin_remove.command(flags, ...) - local files = {...} - if #files < 1 then - return nil, "Argument missing. "..util.see_help("remove", "luarocks-admin") - end - local server, server_table = cache.get_upload_server(flags["server"]) +function admin_remove.command(args) + local server, server_table = cache.get_upload_server(args["server"]) if not server then return nil, server_table end - return remove_files_from_server(not flags["no-refresh"], files, server, server_table) + return remove_files_from_server(not args["no_refresh"], files, server, server_table) end diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 4929b326..34dc75d8 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -394,9 +394,7 @@ Variables: parser:option("--only-sources-from"):target("only_sources"):hidden(true) for _, module in util.sortedpairs(cmd_modules) do - if module.add_to_parser then -- TODO: Remove this check. - module.add_to_parser(parser) - end + module.add_to_parser(parser) end return parser diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index a2472be4..74508fab 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -12,19 +12,23 @@ local fetch = require("luarocks.fetch") local fs = require("luarocks.fs") local download = require("luarocks.download") -doc.help_summary = "Show documentation for an installed rock." - -doc.help = [[ - is an existing package name. -Without any flags, tries to load the documentation -using a series of heuristics. -With these flags, return only the desired information: - ---home Open the home page of project. ---list List documentation files only. - -For more information about a rock, see the 'show' command. -]] +function doc.add_to_parser(parser) + local cmd = parser:command("doc", "Show documentation for an installed rock.\n\n".. + "Without any flags, tries to load the documentation using a series of heuristics.\n".. + "With flags, return only the desired information.", util.see_also([[ + For more information about a rock, see the 'show' command. +]])) + :summary("Show documentation for an installed rock.") + :add_help(false) + + cmd:argument("rock", "Name of the rock.") + cmd:argument("version", "Version of the rock.") + :args("?") + + cmd:flag("--home", "Open the home page of project.") + cmd:flag("--list", "List documentation files only.") + cmd:flag("--porcelain"):hidden(true) -- TODO: Description? +end local function show_homepage(homepage, name, version) if not homepage then @@ -54,17 +58,12 @@ local function try_to_open_homepage(name, version) end --- Driver function for "doc" command. --- @param name or nil: an existing package name. --- @param version string or nil: a version may also be passed. -- @return boolean: True if succeeded, nil on errors. -function doc.command(flags, name, version) - if not name then - return nil, "Argument missing. "..util.see_help("doc") - end - - name = util.adjust_name_and_namespace(name, flags) +function doc.command(args) + local name = util.adjust_name_and_namespace(args.rock, args) + local version = args.version local query = queries.new(name, version) - local iname, iversion, repo = search.pick_installed_rock(query, flags["tree"]) + local iname, iversion, repo = search.pick_installed_rock(query, args["tree"]) if not iname then util.printout(name..(version and " "..version or "").." is not installed. Looking for it in the rocks servers...") return try_to_open_homepage(name, version) @@ -75,7 +74,7 @@ function doc.command(flags, name, version) if not rockspec then return nil,err end local descript = rockspec.description or {} - if flags["home"] then + if args["home"] then return show_homepage(descript.homepage, name, version) end @@ -91,7 +90,7 @@ function doc.command(flags, name, version) end end if not docdir then - if descript.homepage and not flags["list"] then + if descript.homepage and not args["list"] then util.printout("Local documentation directory not found -- opening "..descript.homepage.." ...") fs.browser(descript.homepage) return true @@ -105,7 +104,7 @@ function doc.command(flags, name, version) local extensions = { htmlpatt, "%.md$", "%.txt$", "%.textile$", "" } local basenames = { "index", "readme", "manual" } - local porcelain = flags["porcelain"] + local porcelain = args["porcelain"] if #files > 0 then util.title("Documentation files for "..name.." "..version, porcelain) if porcelain then @@ -120,7 +119,7 @@ function doc.command(flags, name, version) end end - if flags["list"] then + if args["list"] then return true end diff --git a/src/luarocks/cmd/download.lua b/src/luarocks/cmd/download.lua index 50c10c0c..80897d5a 100644 --- a/src/luarocks/cmd/download.lua +++ b/src/luarocks/cmd/download.lua @@ -6,42 +6,46 @@ local cmd_download = {} local util = require("luarocks.util") local download = require("luarocks.download") -cmd_download.help_summary = "Download a specific rock file from a rocks server." -cmd_download.help_arguments = "[--all] [--arch= | --source | --rockspec] [ []]" -cmd_download.help = [[ ---all Download all files if there are multiple matches. ---source Download .src.rock if available. ---rockspec Download .rockspec if available. ---arch= Download rock for a specific architecture. -]] +function cmd_download.add_to_parser(parser) + local cmd = parser:command( + "download", "Download a specific rock file from a rocks server.", util.see_also()) + :add_help(false) + + cmd:argument("name", "Name of the rock.") + :args("?") + cmd:argument("version", "Version of the rock.") + :args("?") + + cmd:flag("--all", "Download all files if there are multiple matches.") + cmd:mutex( + cmd:flag("--source", "Download .src.rock if available."), + cmd:flag("--rockspec", "Download .rockspec if available."), + cmd:option("--arch", "Download rock for a specific architecture.")) +end --- Driver function for the "download" command. --- @param name string: a rock name. --- @param version string or nil: if the name of a package is given, a --- version may also be passed. -- @return boolean or (nil, string): true if successful or nil followed -- by an error message. -function cmd_download.command(flags, name, version) - assert(type(version) == "string" or not version) - if type(name) ~= "string" and not flags["all"] then +function cmd_download.command(args) + if not args.name and not args["all"] then return nil, "Argument missing. "..util.see_help("download") end - name = util.adjust_name_and_namespace(name, flags) + local name = util.adjust_name_and_namespace(args.name, args) if not name then name, version = "", "" end local arch - if flags["source"] then + if args["source"] then arch = "src" - elseif flags["rockspec"] then + elseif args["rockspec"] then arch = "rockspec" - elseif flags["arch"] then - arch = flags["arch"] + elseif args["arch"] then + arch = args["arch"] end - local dl, err = download.download(arch, name:lower(), version, flags["all"]) + local dl, err = download.download(arch, name:lower(), version, args["all"]) return dl and true, err end diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index fc14baf6..1053850d 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -14,8 +14,10 @@ function init.add_to_parser(parser) local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) :add_help(false) - cmd:argument("name", "The project name."):args("?") - cmd:argument("version", "An optional project version."):args("?") + cmd:argument("name", "The project name.") + :args("?") + cmd:argument("version", "An optional project version.") + :args("?") cmd:flag("--reset", "Delete .luarocks/config-5.x.lua and ./lua and generate new ones.") cmd:group("Options for specifying rockspec data", @@ -60,15 +62,14 @@ function init.command(args) local pwd = fs.current_dir() - local name = args.name - if not name then - name = dir.base_name(pwd) - if name == "/" then + if not args.name then + args.name = dir.base_name(pwd) + if args.name == "/" then return nil, "When running from the root directory, please specify the argument" end end - util.title("Initializing project '" .. name .. "' for Lua " .. cfg.lua_version .. " ...") + util.title("Initializing project '" .. args.name .. "' for Lua " .. cfg.lua_version .. " ...") util.printout("Checking your Lua installation ...") if not cfg.lua_found then @@ -88,7 +89,9 @@ function init.command(args) end if not has_rockspec then - local ok, err = write_rockspec.command(args, name, args.version or "dev", pwd) + args.version = args.version or "dev" + args.location = pwd + local ok, err = write_rockspec.command(args) if not ok then util.printerr(err) end diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index ec6da14f..3d3f0fe2 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -16,32 +16,28 @@ local cfg = require("luarocks.core.cfg") local cmd = require("luarocks.cmd") local dir = require("luarocks.dir") -install.help_summary = "Install a rock." - -install.help_arguments = "{| []}" - -install.help = [[ -Argument may be the name of a rock to be fetched from a repository -or a filename of a locally available rock. - ---keep Do not remove previously installed versions of the - rock after installing a new one. This behavior can - be made permanent by setting keep_other_versions=true - in the configuration file. - ---only-deps Installs only the dependencies of the rock. - ---no-doc Installs the rock without its documentation. - ---verify Verify signature of the rock being installed. - If rock is being downloaded, LuaRocks will attempt - to download the signature as well. If the rock is - local, the signature file should be in the same - directory. - You need the signer’s public key in your local - keyring for this option to work properly. - -]]--..util.deps_mode_help() +function install.add_to_parser(parser) + local cmd = parser:command("install", "Install a rock.", util.see_also()) + :add_help(false) + + cmd:argument("rock", "The name of a rock to be fetched from a repository ".. + "or a filename of a locally available rock.") + cmd:argument("version", "Version of the rock.") + :args("?") + + cmd:flag("--keep", "Do not remove previously installed versions of the ".. + "rock after building a new one. This behavior can be made permanent by ".. + "setting keep_other_versions=true in the configuration file.") + cmd:flag("--only-deps", "Installs only the dependencies of the rock.") + cmd:flag("--no-doc", "Installs the rock without its documentation.") + cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. + "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. + "attempt to download the signature as well. Otherwise, the signature ".. + "file should be already available locally in the same directory.\n".. + "You need the signer’s public key in your local keyring for this ".. + "option to work properly.") + util.deps_mode_option(cmd) +end install.opts = util.opts_table("install.opts", { namespace = "string?", @@ -208,51 +204,46 @@ local function install_rock_file(filename, opts) end --- Driver function for the "install" command. --- @param name string: name of a binary rock. If an URL or pathname --- to a binary rock is given, fetches and installs it. If a rockspec or a --- source rock is given, forwards the request to the "build" command. +-- If an URL or pathname to a binary rock is given, fetches and installs it. +-- If a rockspec or a source rock is given, forwards the request to the "build" +-- command. -- If a package name is given, forwards the request to "search" and, -- if returned a result, installs the matching rock. --- @param version string: When passing a package name, a version number --- may also be given. -- @return boolean or (nil, string, exitcode): True if installation was -- successful, nil and an error message otherwise. exitcode is optionally returned. -function install.command(flags, name, version) - if type(name) ~= "string" then - return nil, "Argument missing. "..util.see_help("install") - end - - name = util.adjust_name_and_namespace(name, flags) +function install.command(args) + args.rock = util.adjust_name_and_namespace(args.rock, args) - local ok, err = fs.check_command_permissions(flags) + local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end - if name:match("%.rockspec$") or name:match("%.src%.rock$") then + if args.rock:match("%.rockspec$") or args.rock:match("%.src%.rock$") then local build = require("luarocks.cmd.build") - return build.command(flags, name) - elseif name:match("%.rock$") then - local deps_mode = deps.get_deps_mode(flags) + return build.command(args) + elseif args.rock:match("%.rock$") then + local deps_mode = deps.get_deps_mode(args) local opts = install.opts({ - namespace = flags["namespace"], - keep = not not flags["keep"], - force = not not flags["force"], - force_fast = not not flags["force-fast"], - no_doc = not not flags["no-doc"], + namespace = args["namespace"], + keep = not not args["keep"], + force = not not args["force"], + force_fast = not not args["force_fast"], + no_doc = not not args["no_doc"], deps_mode = deps_mode, - verify = not not flags["verify"], + verify = not not args["verify"], }) - if flags["only-deps"] then - return install_rock_file_deps(name, opts) + if args["only_deps"] then + return install_rock_file_deps(args.rock, opts) else - return install_rock_file(name, opts) + return install_rock_file(args.rock, opts) end else - local url, err = search.find_suitable_rock(queries.new(name:lower(), version), true) + local url, err = search.find_suitable_rock(queries.new(args.rock:lower(), args.version), true) if not url then return nil, err end util.printout("Installing "..url) - return install.command(flags, url) + args.rock = url + return install.command(args) end end diff --git a/src/luarocks/cmd/list.lua b/src/luarocks/cmd/list.lua index 5e5cfac8..2bb7660f 100644 --- a/src/luarocks/cmd/list.lua +++ b/src/luarocks/cmd/list.lua @@ -10,16 +10,19 @@ local cfg = require("luarocks.core.cfg") local util = require("luarocks.util") local path = require("luarocks.path") -list.help_summary = "List currently installed rocks." -list.help_arguments = "[--porcelain] " -list.help = [[ - is a substring of a rock name to filter by. +function list.add_to_parser(parser) + local cmd = parser:command("list", "List currently installed rocks.", util.see_also()) + :add_help(false) ---outdated List only rocks for which there is a - higher version available in the rocks server. + cmd:argument("filter", "A substring of a rock name to filter by.") + :args("?") + cmd:argument("version", "Rock version to filter by.") + :args("?") ---porcelain Produce machine-friendly output. -]] + cmd:flag("--outdated", "List only rocks for which there is a higher ".. + "version available in the rocks server.") + cmd:flag("--porcelain", "Produce machine-friendly output.") +end local function check_outdated(trees, query) local results_installed = {} @@ -65,20 +68,18 @@ local function list_outdated(trees, query, porcelain) end --- Driver function for "list" command. --- @param filter string or nil: A substring of a rock name to filter by. --- @param version string or nil: a version may also be passed. -- @return boolean: True if succeeded, nil on errors. -function list.command(flags, filter, version) - local query = queries.new(filter and filter:lower() or "", version, true) +function list.command(args) + local query = queries.new(args.filter and args.filter:lower() or "", args.version, true) local trees = cfg.rocks_trees local title = "Rocks installed for Lua "..cfg.lua_version - if flags["tree"] then - trees = { flags["tree"] } - title = title .. " in " .. flags["tree"] + if args["tree"] then + trees = { args["tree"] } + title = title .. " in " .. args["tree"] end - if flags["outdated"] then - return list_outdated(trees, query, flags["porcelain"]) + if args["outdated"] then + return list_outdated(trees, query, args["porcelain"]) end local results = {} @@ -88,8 +89,8 @@ function list.command(flags, filter, version) util.warning(err) end end - util.title(title, flags["porcelain"]) - search.print_result_tree(results, flags["porcelain"]) + util.title(title, args["porcelain"]) + search.print_result_tree(results, args["porcelain"]) return true end diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index 4d813864..a8084293 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -16,9 +16,8 @@ local deps = require("luarocks.deps") local writer = require("luarocks.manif.writer") local cmd = require("luarocks.cmd") -make.help_summary = "Compile package in current directory using a rockspec." -make.help_arguments = "[--pack-binary-rock] []" -make.help = [[ +function make.add_to_parser(parser) + local cmd = parser:command("make", [[ Builds sources in the current directory, but unlike "build", it does not fetch sources, etc., assuming everything is available in the current directory. If no argument is given, @@ -34,89 +33,86 @@ To install rocks, you'll normally want to use the "install" and NB: Use `luarocks install` with the `--only-deps` flag if you want to install only dependencies of the rockspec (see `luarocks help install`). - ---pack-binary-rock Do not install rock. Instead, produce a .rock file - with the contents of compilation in the current - directory. - ---keep Do not remove previously installed versions of the - rock after installing a new one. This behavior can - be made permanent by setting keep_other_versions=true - in the configuration file. - ---branch= Override the `source.branch` field in the loaded - rockspec. Allows to specify a different branch to - fetch. Particularly for "dev" rocks. - ---verify Verify signature of the rockspec or src.rock being - built. If the rockspec or src.rock is being downloaded, - LuaRocks will attempt to download the signature as well. - Otherwise, the signature file should be already - available locally in the same directory. - You need the signer’s public key in your local - keyring for this option to work properly. - ---sign To be used with --pack-binary-rock. Also produce - a signature file for the generated .rock file. - -]] +]], util.see_also()) + :summary("Compile package in current directory using a rockspec.") + :add_help(false) + + cmd:argument("rockspec", "Rockspec for the rock to build.") + :args("?") + + cmd:flag("--pack-binary-rock", "Do not install rock. Instead, produce a ".. + ".rock file with the contents of compilation in the current directory.") + cmd:flag("--keep", "Do not remove previously installed versions of the ".. + "rock after building a new one. This behavior can be made permanent by ".. + "setting keep_other_versions=true in the configuration file.") + cmd:option("--branch", "Override the `source.branch` field in the loaded ".. + "rockspec. Allows to specify a different branch to fetch. Particularly ".. + 'for "dev" rocks.') + :argname("") + cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. + "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. + "attempt to download the signature as well. Otherwise, the signature ".. + "file should be already available locally in the same directory.\n".. + "You need the signer’s public key in your local keyring for this ".. + "option to work properly.") + cmd:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. + "signature file for the generated .rock file.") +end --- Driver function for "make" command. --- @param name string: A local rockspec. -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an -- error message otherwise. exitcode is optionally returned. -function make.command(flags, rockspec_filename) - assert(type(rockspec_filename) == "string" or not rockspec_filename) - - if not rockspec_filename then +function make.command(args) + local rockspec + if not args.rockspec then local err - rockspec_filename, err = util.get_default_rockspec() - if not rockspec_filename then + rockspec, err = util.get_default_rockspec() + if not rockspec then return nil, err end end - if not rockspec_filename:match("rockspec$") then + if not rockspec:match("rockspec$") then return nil, "Invalid argument: 'make' takes a rockspec as a parameter. "..util.see_help("make") end - local rockspec, err, errcode = fetch.load_rockspec(rockspec_filename) + local rockspec, err, errcode = fetch.load_rockspec(rockspec) if not rockspec then return nil, err end - local name = util.adjust_name_and_namespace(rockspec.name, flags) + local name = util.adjust_name_and_namespace(rockspec.name, args) local opts = build.opts({ need_to_fetch = false, minimal_mode = true, - deps_mode = deps.get_deps_mode(flags), + deps_mode = deps.get_deps_mode(args), build_only_deps = false, - namespace = flags["namespace"], - branch = not not flags["branch"], - verify = not not flags["verify"], + namespace = args["namespace"], + branch = not not args["branch"], + verify = not not args["verify"], }) - if flags["sign"] and not flags["pack-binary-rock"] then + if args["sign"] and not args["pack_binary_rock"] then return nil, "In the make command, --sign is meant to be used only with --pack-binary-rock" end - if flags["pack-binary-rock"] then - return pack.pack_binary_rock(name, rockspec.version, flags["sign"], function() + if args["pack_binary_rock"] then + return pack.pack_binary_rock(name, rockspec.version, args["sign"], function() return build.build_rockspec(rockspec, opts) end) else - local ok, err = fs.check_command_permissions(flags) + local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end ok, err = build.build_rockspec(rockspec, opts) if not ok then return nil, err end local name, version = ok, err - if (not flags["keep"]) and not cfg.keep_other_versions then - local ok, err = remove.remove_other_versions(name, version, flags["force"], flags["force-fast"]) + if (not args["keep"]) and not cfg.keep_other_versions then + local ok, err = remove.remove_other_versions(name, version, args["force"], args["force_fast"]) if not ok then util.printerr(err) end end - writer.check_dependencies(nil, deps.get_deps_mode(flags)) + writer.check_dependencies(nil, deps.get_deps_mode(args)) return name, version end end diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 19b5fa1e..37d4206e 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -11,9 +11,8 @@ local fs = require("luarocks.fs") local dir = require("luarocks.dir") local type_rockspec = require("luarocks.type.rockspec") -new_version.help_summary = "Auto-write a rockspec for a new version of a rock." -new_version.help_arguments = "[--tag=] [--dir=] [|] [] []" -new_version.help = [[ +function new_version.add_to_parser(parser) + local cmd = parser:command("new_version", [[ This is a utility function that writes a new rockspec, updating data from a previous one. @@ -22,7 +21,7 @@ default server. If a rockspec is given, it uses it instead. If no argument is given, it looks for a rockspec same way 'luarocks make' does. If the version number is not given and tag is passed using --tag, -it is used as the version, with 'v' removed from beginning. +it is used as the version, with 'v' removed from beginnnumbering. Otherwise, it only increments the revision number of the given (or downloaded) rockspec. @@ -38,8 +37,21 @@ an old tag but no new one passed, it is guessed in the same way URL is. If a directory is not given, it defaults to the current directory. WARNING: it writes the new rockspec to the given directory, -overwriting the file if it already exists. -]] +overwriting the file if it already exists.]], util.see_also()) + :summary("Auto-write a rockspec for a new version of a rock.") + :add_help(false) + + cmd:argument("rock", "Package name or rockspec.") + :args("?") + cmd:argument("new_version", "New version of the rock.") + :args("?") + cmd:argument("new_url", "New URL of the rock.") + :args("?") + + cmd:option("--dir", "Output directory for the new rockspec.") + cmd:option("--tag", "New SCM tag.") +end + local function try_replace(tbl, field, old, new) if not tbl[field] then @@ -126,24 +138,23 @@ local function update_source_section(out_rs, url, tag, old_ver, new_ver) return true end -function new_version.command(flags, input, version, url) - if not input then +function new_version.command(args) + if not args.input then local err - input, err = util.get_default_rockspec() - if not input then + args.input, err = util.get_default_rockspec() + if not args.input then return nil, err end end - assert(type(input) == "string") local filename, err - if input:match("rockspec$") then - filename, err = fetch.fetch_url(input) + if args.input:match("rockspec$") then + filename, err = fetch.fetch_url(args.input) if not filename then return nil, err end else - filename, err = download.download("rockspec", input:lower()) + filename, err = download.download("rockspec", args.input:lower()) if not filename then return nil, err end @@ -157,20 +168,20 @@ function new_version.command(flags, input, version, url) local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") local new_ver, new_rev - if flags.tag and not version then - version = flags.tag:gsub("^v", "") + if args.tag and not args.new_version then + args.new_version = args.tag:gsub("^v", "") end local out_dir - if flags.dir then - out_dir = dir.normalize(flags.dir) + if args.dir then + out_dir = dir.normalize(args.dir) end - if version then - new_ver, new_rev = version:match("(.*)%-(%d+)$") + if args.new_version then + new_ver, new_rev = args.new_version:match("(.*)%-(%d+)$") new_rev = tonumber(new_rev) if not new_rev then - new_ver = version + new_ver = args.new_version new_rev = 1 end else @@ -183,7 +194,7 @@ function new_version.command(flags, input, version, url) local out_name = out_rs.package:lower() out_rs.version = new_rockver.."-"..new_rev - local ok, err = update_source_section(out_rs, url, flags.tag, old_ver, new_ver) + local ok, err = update_source_section(out_rs, args.new_url, args.tag, old_ver, new_ver) if not ok then return nil, err end if out_rs.build and out_rs.build.type == "module" then diff --git a/src/luarocks/cmd/pack.lua b/src/luarocks/cmd/pack.lua index 7781a3bd..e5e7f525 100644 --- a/src/luarocks/cmd/pack.lua +++ b/src/luarocks/cmd/pack.lua @@ -8,39 +8,31 @@ local pack = require("luarocks.pack") local signing = require("luarocks.signing") local queries = require("luarocks.queries") -cmd_pack.help_summary = "Create a rock, packing sources or binaries." -cmd_pack.help_arguments = "{| []}" -cmd_pack.help = [[ ---sign Produce a signature file as well. +function cmd_pack.add_to_parser(parser) + local cmd = parser:command("pack", "Create a rock, packing sources or binaries.", util.see_also()) + :add_help(false) -Argument may be a rockspec file, for creating a source rock, -or the name of an installed package, for creating a binary rock. -In the latter case, the app version may be given as a second -argument. -]] + cmd:argument("rock", "A rockspec file, for creating a source rock, or the ".. + "name of an installed package, for creating a binary rock.") + cmd:argument("version", "A version may be given if the first argument is a rock name.") + :args("?") + + cmd:flag("--sign", "Produce a signature file as well.") +end --- Driver function for the "pack" command. --- @param arg string: may be a rockspec file, for creating a source rock, --- or the name of an installed package, for creating a binary rock. --- @param version string or nil: if the name of a package is given, a --- version may also be passed. -- @return boolean or (nil, string): true if successful or nil followed -- by an error message. -function cmd_pack.command(flags, arg, version) - assert(type(version) == "string" or not version) - if type(arg) ~= "string" then - return nil, "Argument missing. "..util.see_help("pack") - end - +function cmd_pack.command(args) local file, err - if arg:match(".*%.rockspec") then - file, err = pack.pack_source_rock(arg) + if args.rock:match(".*%.rockspec") then + file, err = pack.pack_source_rock(args.rock) else - local name = util.adjust_name_and_namespace(arg, flags) - local query = queries.new(name, version) - file, err = pack.pack_installed_rock(query, flags["tree"]) + local name = util.adjust_name_and_namespace(args.rock, args) + local query = queries.new(name, args.version) + file, err = pack.pack_installed_rock(query, args["tree"]) end - return pack.report_and_sign_local_file(file, err, flags["sign"]) + return pack.report_and_sign_local_file(file, err, args["sign"]) end return cmd_pack diff --git a/src/luarocks/cmd/path.lua b/src/luarocks/cmd/path.lua index bb383ad9..8921d2a5 100644 --- a/src/luarocks/cmd/path.lua +++ b/src/luarocks/cmd/path.lua @@ -7,48 +7,46 @@ local util = require("luarocks.util") local cfg = require("luarocks.core.cfg") local fs = require("luarocks.fs") -path_cmd.help_summary = "Return the currently configured package path." -path_cmd.help_arguments = "" -path_cmd.help = [[ +function path_cmd.add_to_parser(parser) + local cmd = parser:command("path", [[ Returns the package path currently configured for this installation of LuaRocks, formatted as shell commands to update LUA_PATH and LUA_CPATH. ---no-bin Do not export the PATH variable - ---append Appends the paths to the existing paths. Default is to prefix - the LR paths to the existing paths. - ---lr-path Exports the Lua path (not formatted as shell command) - ---lr-cpath Exports the Lua cpath (not formatted as shell command) - ---lr-bin Exports the system path (not formatted as shell command) - - On Unix systems, you may run: eval `luarocks path` And on Windows: - luarocks path > "%temp%\_lrp.bat" && call "%temp%\_lrp.bat" && del "%temp%\_lrp.bat" -]] + luarocks path > "%temp%\_lrp.bat" && call "%temp%\_lrp.bat" && del "%temp%\_lrp.bat"]], + util.see_also()) + :summary("Return the currently configured package path.") + :add_help(false) + + cmd:flag("--no-bin", "Do not export the PATH variable.") + cmd:flag("--append", "Appends the paths to the existing paths. Default is ".. + "to prefix the LR paths to the existing paths.") + cmd:flag("--lr-path", "Exports the Lua path (not formatted as shell command).") + cmd:flag("--lr-cpath", "Exports the Lua cpath (not formatted as shell command).") + cmd:flag("--lr-bin", "Exports the system path (not formatted as shell command).") + cmd:flag("--bin"):hidden(true) +end --- Driver function for "path" command. -- @return boolean This function always succeeds. -function path_cmd.command(flags) - local lr_path, lr_cpath, lr_bin = cfg.package_paths(flags["tree"]) +function path_cmd.command(args) + local lr_path, lr_cpath, lr_bin = cfg.package_paths(args["tree"]) local path_sep = cfg.export_path_separator - if flags["lr-path"] then + if args["lr_path"] then util.printout(util.cleanup_path(lr_path, ';', cfg.lua_version)) return true - elseif flags["lr-cpath"] then + elseif args["lr_cpath"] then util.printout(util.cleanup_path(lr_cpath, ';', cfg.lua_version)) return true - elseif flags["lr-bin"] then + elseif args["lr_bin"] then util.printout(util.cleanup_path(lr_bin, path_sep)) return true end - if flags["append"] then + if args["append"] then lr_path = package.path .. ";" .. lr_path lr_cpath = package.cpath .. ";" .. lr_cpath lr_bin = os.getenv("PATH") .. path_sep .. lr_bin @@ -60,10 +58,10 @@ function path_cmd.command(flags) local lpath_var, lcpath_var = util.lua_path_variables() - util.printout(fs.export_cmd(lpath_var, util.cleanup_path(lr_path, ';', cfg.lua_version, flags["append"]))) - util.printout(fs.export_cmd(lcpath_var, util.cleanup_path(lr_cpath, ';', cfg.lua_version, flags["append"]))) - if not flags["no-bin"] then - util.printout(fs.export_cmd("PATH", util.cleanup_path(lr_bin, path_sep, nil, flags["append"]))) + util.printout(fs.export_cmd(lpath_var, util.cleanup_path(lr_path, ';', cfg.lua_version))) + util.printout(fs.export_cmd(lcpath_var, util.cleanup_path(lr_cpath, ';', cfg.lua_version))) + if not args["no_bin"] then + util.printout(fs.export_cmd("PATH", util.cleanup_path(lr_bin, path_sep))) end return true end diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index 98b76a0f..9b1e2ae9 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua @@ -15,24 +15,24 @@ local remove = require("luarocks.remove") local queries = require("luarocks.queries") local cmd = require("luarocks.cmd") -purge.help_summary = "Remove all installed rocks from a tree." -purge.help_arguments = "--tree= [--old-versions]" -purge.help = [[ +function purge.add_to_parser(parser) + local cmd = parser:command("purge", [[ This command removes rocks en masse from a given tree. By default, it removes all rocks from a tree. -The --tree argument is mandatory: luarocks purge does not -assume a default tree. +The --tree option is mandatory: luarocks purge does not assume a default tree.]], + util.see_also()) + :summary("Remove all installed rocks from a tree.") + :add_help(false) ---old-versions Keep the highest-numbered version of each - rock and remove the other ones. By default - it only removes old versions if they are - not needed as dependencies. This can be - overridden with the flag --force. -]] + cmd:flag("--old-versions", "Keep the highest-numbered version of each ".. + "rock and remove the other ones. By default it only removes old ".. + "versions if they are not needed as dependencies. This can be ".. + "overridden with the flag --force.") +end -function purge.command(flags) - local tree = flags["tree"] +function purge.command(args) + local tree = args["tree"] if type(tree) ~= "string" then return nil, "The --tree argument is mandatory. "..util.see_help("purge") @@ -43,21 +43,21 @@ function purge.command(flags) return nil, "Directory not found: "..tree end - local ok, err = fs.check_command_permissions(flags) + local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end search.local_manifest_search(results, path.rocks_dir(tree), queries.all()) local sort = function(a,b) return vers.compare_versions(b,a) end - if flags["old-versions"] then + if args["old_versions"] then sort = vers.compare_versions end for package, versions in util.sortedpairs(results) do for version, _ in util.sortedpairs(versions, sort) do - if flags["old-versions"] then + if args["old_versions"] then util.printout("Keeping "..package.." "..version.."...") - local ok, err = remove.remove_other_versions(package, version, flags["force"], flags["force-fast"]) + local ok, err = remove.remove_other_versions(package, version, args["force"], args["force_fast"]) if not ok then util.printerr(err) end diff --git a/src/luarocks/cmd/remove.lua b/src/luarocks/cmd/remove.lua index f9345670..e311f399 100644 --- a/src/luarocks/cmd/remove.lua +++ b/src/luarocks/cmd/remove.lua @@ -14,38 +14,39 @@ local writer = require("luarocks.manif.writer") local queries = require("luarocks.queries") local cmd = require("luarocks.cmd") -cmd_remove.help_summary = "Uninstall a rock." -cmd_remove.help_arguments = "[--force|--force-fast] []" -cmd_remove.help = [[ -Argument is the name of a rock to be uninstalled. +function cmd_remove.add_to_parser(parser) + local cmd = parser:command("remove", [[ +Uninstall a rock. + If a version is not given, try to remove all versions at once. Will only perform the removal if it does not break dependencies. -To override this check and force the removal, use --force. -To perform a forced removal without reporting dependency issues, -use --force-fast. +To override this check and force the removal, use --force or --force-fast.]], + util.see_also()) + :summary("Uninstall a rock.") + :add_help(false) + + cmd:argument("rock", "Name of the rock to be uninstalled.") + cmd:argument("version", "Version of the rock to uninstall.") + :args("?") -]]--..util.deps_mode_help() + cmd:flag("--force", "Force removal if it would break dependencies.") + cmd:flag("--force-fast", "Perform a forced removal without reporting dependency issues.") + util.deps_mode_option(cmd) +end --- Driver function for the "remove" command. --- @param name string: name of a rock. If a version is given, refer to --- a specific version; otherwise, try to remove all versions. --- @param version string: When passing a package name, a version number --- may also be given. -- @return boolean or (nil, string, exitcode): True if removal was -- successful, nil and an error message otherwise. exitcode is optionally returned. -function cmd_remove.command(flags, name, version) - if type(name) ~= "string" then - return nil, "Argument missing. "..util.see_help("remove") - end - - name = util.adjust_name_and_namespace(name, flags) +function cmd_remove.command(args) + local name = util.adjust_name_and_namespace(args.rock, args) - local deps_mode = flags["deps-mode"] or cfg.deps_mode + local deps_mode = args["deps_mode"] or cfg.deps_mode - local ok, err = fs.check_command_permissions(flags) + local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end local rock_type = name:match("%.(rock)$") or name:match("%.(rockspec)$") + local version = args.version local filename = name if rock_type then name, version = path.parse_name(filename) @@ -59,12 +60,12 @@ function cmd_remove.command(flags, name, version) return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..path.rocks_tree_to_string(cfg.root_dir) end - local ok, err = remove.remove_search_results(results, name, deps_mode, flags["force"], flags["force-fast"]) + local ok, err = remove.remove_search_results(results, name, deps_mode, args["force"], args["force_fast"]) if not ok then return nil, err end - writer.check_dependencies(nil, deps.get_deps_mode(flags)) + writer.check_dependencies(nil, deps.get_deps_mode(args)) return true end diff --git a/src/luarocks/cmd/search.lua b/src/luarocks/cmd/search.lua index 8f4d014e..d1546e80 100644 --- a/src/luarocks/cmd/search.lua +++ b/src/luarocks/cmd/search.lua @@ -9,17 +9,23 @@ local search = require("luarocks.search") local queries = require("luarocks.queries") local results = require("luarocks.results") -cmd_search.help_summary = "Query the LuaRocks servers." -cmd_search.help_arguments = "[--source] [--binary] { [] | --all }" -cmd_search.help = [[ ---source Return only rockspecs and source rocks, - to be used with the "build" command. ---binary Return only pure Lua and binary rocks (rocks that can be used - with the "install" command without requiring a C toolchain). ---all List all contents of the server that are suitable to - this platform, do not filter by name. ---porcelain Return a machine readable format. -]] +function cmd_search.add_to_parser(parser) + local cmd = parser:command("search", "Query the LuaRocks servers.", util.see_also()) + :add_help(false) + + cmd:argument("name", "Name of the rock to search for.") + :args("?") + cmd:argument("version", "Rock version to search for.") + :args("?") + + cmd:flag("--source", "Return only rockspecs and source rocks, to be used ".. + 'with the "build" command.') + cmd:flag("--binary", "Return only pure Lua and binary rocks (rocks that ".. + 'can be used with the "install" command without requiring a C toolchain).') + cmd:flag("--all", "List all contents of the server that are suitable to ".. + "this platform, do not filter by name.") + cmd:flag("--porcelain", "Return a machine readable format.") +end --- Splits a list of search results into two lists, one for "source" results -- to be used with the "build" command, and one for "binary" results to be @@ -45,33 +51,31 @@ local function split_source_and_binary_results(result_tree) end --- Driver function for "search" command. --- @param name string: A substring of a rock name to search. --- @param version string or nil: a version may also be passed. -- @return boolean or (nil, string): True if build was successful; nil and an -- error message otherwise. -function cmd_search.command(flags, name, version) +function cmd_search.command(args) - name = util.adjust_name_and_namespace(name, flags) + local name = util.adjust_name_and_namespace(args.name, args) - if flags["all"] then - name, version = "", nil + if args["all"] then + name, args.version = "", nil end - if type(name) ~= "string" and not flags["all"] then + if not args.name and not args["all"] then return nil, "Enter name and version or use --all. "..util.see_help("search") end - local query = queries.new(name:lower(), version, true) + local query = queries.new(name:lower(), args.version, true) local result_tree, err = search.search_repos(query) - local porcelain = flags["porcelain"] - local full_name = name .. (version and " " .. version or "") + local porcelain = args["porcelain"] + local full_name = name .. (args.version and " " .. args.version or "") util.title(full_name .. " - Search results for Lua "..cfg.lua_version..":", porcelain, "=") local sources, binaries = split_source_and_binary_results(result_tree) - if next(sources) and not flags["binary"] then + if next(sources) and not args["binary"] then util.title("Rockspecs and source rocks:", porcelain) search.print_result_tree(sources, porcelain) end - if next(binaries) and not flags["source"] then + if next(binaries) and not args["source"] then util.title("Binary and pure-Lua rocks:", porcelain) search.print_result_tree(binaries, porcelain) end diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index 37c2c55e..9bfedd20 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -13,24 +13,34 @@ local fetch = require("luarocks.fetch") local manif = require("luarocks.manif") local repos = require("luarocks.repos") -show.help_summary = "Show information about an installed rock." +function show.add_to_parser(parser) + local cmd = parser:command("show", [[ +Show information about an installed rock. -show.help = [[ - is an existing package name. Without any flags, show all module information. -With these flags, return only the desired information: +With flags, return only the desired information.]], util.see_also()) + :summary("Show information about an installed rock.") + :add_help(false) ---home home page of project ---modules all modules provided by this package as used by require() ---deps packages this package depends on ---build-deps build-only dependencies for this package ---test-deps dependencies for testing this package ---rockspec the full path of the rockspec file ---mversion the package version ---rock-tree local tree where rock is installed ---rock-dir data directory of the installed rock -]] + cmd:argument("rock", "Name of an installed rock.") + cmd:argument("version", "Rock version.") + :args("?") + cmd:flag("--home", "Show home page of project.") + cmd:flag("--modules", "Show all modules provided by the package as used by require().") + cmd:flag("--deps", "Show packages the package depends on.") + cmd:flag("--build-deps", "Show build-only dependencies for the package.") + cmd:flag("--test-deps", "Show dependencies for testing the package.") + cmd:flag("--rockspec", "Show the full path of the rockspec file.") + cmd:flag("--mversion", "Show the package version.") + cmd:flag("--rock-tree", "Show local tree where rock is installed.") + cmd:flag("--rock-namespace", "Show rock namespace.") + cmd:flag("--rock-dir", "Show data directory of the installed rock.") + cmd:flag("--rock-license", "Show rock license.") + cmd:flag("--issues", "Show URL for project's issue tracker.") + cmd:flag("--labels", "List the labels of the rock.") + cmd:flag("--porcelain", "Produce machine-friendly output.") +end local friendly_template = [[ : @@ -249,19 +259,14 @@ local function show_rock(template, namespace, name, version, rockspec, repo, min end --- Driver function for "show" command. --- @param name or nil: an existing package name. --- @param version string or nil: a version may also be passed. -- @return boolean: True if succeeded, nil on errors. -function show.command(flags, name, version) - if not name then - return nil, "Argument missing. "..util.see_help("show") - end - - name = util.adjust_name_and_namespace(name, flags) +function show.command(args) + local name = util.adjust_name_and_namespace(args.rock, args) + local version = args.verson local query = queries.new(name, version) local repo, repo_url - name, version, repo, repo_url = search.pick_installed_rock(query, flags["tree"]) + name, version, repo, repo_url = search.pick_installed_rock(query, args["tree"]) if not name then return nil, version end @@ -277,32 +282,32 @@ function show.command(flags, name, version) if not manifest then return nil,err end local minfo = manifest.repository[name][version][1] - if flags["rock-tree"] then util.printout(tree) - elseif flags["rock-namespace"] then util.printout(namespace) - elseif flags["rock-dir"] then util.printout(directory) - elseif flags["home"] then util.printout(descript.homepage) - elseif flags["rock-license"] then util.printout(descript.license) - elseif flags["issues"] then util.printout(descript.issues_url) - elseif flags["labels"] then util.printout(descript.labels and table.concat(descript.labels, "\n")) - elseif flags["modules"] then util.printout(keys_as_string(minfo.modules, "\n")) - elseif flags["deps"] then + if args["rock_tree"] then util.printout(tree) + elseif args["rock_namespace"] then util.printout(namespace) + elseif args["rock_dir"] then util.printout(directory) + elseif args["home"] then util.printout(descript.homepage) + elseif args["rock_license"] then util.printout(descript.license) + elseif args["issues"] then util.printout(descript.issues_url) + elseif args["labels"] then util.printout(descript.labels and table.concat(descript.labels, "\n")) + elseif args["modules"] then util.printout(keys_as_string(minfo.modules, "\n")) + elseif args["deps"] then for _, dep in ipairs(rockspec.dependencies) do util.printout(tostring(dep)) end - elseif flags["build-deps"] then + elseif args["build_deps"] then for _, dep in ipairs(rockspec.build_dependencies) do util.printout(tostring(dep)) end - elseif flags["test-deps"] then + elseif args["test_deps"] then for _, dep in ipairs(rockspec.test_dependencies) do util.printout(tostring(dep)) end - elseif flags["rockspec"] then util.printout(rockspec_file) - elseif flags["mversion"] then util.printout(version) - elseif flags["porcelain"] then - show_rock(porcelain_template, namespace, name, version, rockspec, repo, minfo, flags["tree"]) + elseif args["rockspec"] then util.printout(rockspec_file) + elseif args["mversion"] then util.printout(version) + elseif args["porcelain"] then + show_rock(porcelain_template, namespace, name, version, rockspec, repo, minfo, args["tree"]) else - show_rock(friendly_template, namespace, name, version, rockspec, repo, minfo, flags["tree"]) + show_rock(friendly_template, namespace, name, version, rockspec, repo, minfo, args["tree"]) end return true end diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index 06ac0068..baf7515e 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -6,42 +6,44 @@ local cmd_test = {} local util = require("luarocks.util") local test = require("luarocks.test") -cmd_test.help_summary = "Run the test suite in the current directory." -cmd_test.help_arguments = "[--test-type=] [] [-- ]" -cmd_test.help = [[ +function cmd_test.add_to_parser(parser) + local cmd = parser:command("test", [[ Run the test suite for the Lua project in the current directory. -If the first argument is a rockspec, it will use it to determine -the parameters for running tests; otherwise, it will attempt to -detect the rockspec. -Any additional arguments are forwarded to the test suite. -To make sure that any flags passed in are not interpreted -as LuaRocks flags, use -- to separate LuaRocks arguments from -test suite arguments. - ---test-type= Specify the test suite type manually if it was not - specified in the rockspec and it could not be - auto-detected. - -]]--..util.deps_mode_help() - -function cmd_test.command(flags, argument, ...) - assert(type(argument) == "string" or not argument) - - local arguments = { ... } +If the first argument is a rockspec, it will use it to determine the parameters +for running tests; otherwise, it will attempt to detect the rockspec. + +Any additional arguments are forwarded to the test suite. +To make sure that test suite flags are not interpreted as LuaRocks flags, use -- +to separate LuaRocks arguments from test suite arguments.]], + util.see_also()) + :summary("Run the test suite in the current directory.") + :add_help(false) + + cmd:argument("rockspec", "Project rockspec.") + :args("?") + cmd:argument("args", "Test suite arguments.") + :args("*") + + cmd:option("--test-type", "Specify the test suite type manually if it was ".. + "not specified in the rockspec and it could not be auto-detected.") + :argname("") + util.deps_mode_option(cmd) +end - if argument and argument:match("rockspec$") then - return test.run_test_suite(argument, flags["test-type"], arguments) +function cmd_test.command(args) + if args.rockspec and args.rockspec:match("rockspec$") then + return test.run_test_suite(args.rockspec, args["test_type"], args.args) end - table.insert(arguments, 1, argument) + table.insert(args.args, 1, args.rockspec) local rockspec, err = util.get_default_rockspec() if not rockspec then return nil, err end - return test.run_test_suite(rockspec, flags["test-type"], arguments) + return test.run_test_suite(rockspec, args["test_type"], args.args) end return cmd_test diff --git a/src/luarocks/cmd/unpack.lua b/src/luarocks/cmd/unpack.lua index 99263f49..65ce5c7c 100644 --- a/src/luarocks/cmd/unpack.lua +++ b/src/luarocks/cmd/unpack.lua @@ -10,15 +10,21 @@ local build = require("luarocks.build") local dir = require("luarocks.dir") local search = require("luarocks.search") -unpack.help_summary = "Unpack the contents of a rock." -unpack.help_arguments = "[--force] {| []}" -unpack.help = [[ +function unpack.add_to_parser(parser) + local cmd = parser:command("unpack", [[ Unpacks the contents of a rock in a newly created directory. Argument may be a rock file, or the name of a rock in a rocks server. -In the latter case, the app version may be given as a second argument. +In the latter case, the rock version may be given as a second argument.]], + util.see_also()) + :summary("Unpack the contents of a rock.") + :add_help(false) ---force Unpack files even if the output directory already exists. -]] + cmd:argument("rock", "A rock file or the name of a rock.") + cmd:argument("version", "Rock version.") + :args("?") + + cmd:flag("--force", "Unpack files even if the output directory already exists.") +end --- Load a rockspec file to the given directory, fetches the source -- files specified in the rockspec, and unpack them inside the directory. @@ -141,31 +147,22 @@ local function run_unpacker(file, force) end --- Driver function for the "unpack" command. --- @param ns_name string: may be a rock filename, for unpacking a --- rock file or the name of a rock to be fetched and unpacked. --- @param version string or nil: if the name of a package is given, a --- version may also be passed. -- @return boolean or (nil, string): true if successful or nil followed -- by an error message. -function unpack.command(flags, ns_name, version) - assert(type(version) == "string" or not version) - if type(ns_name) ~= "string" then - return nil, "Argument missing. "..util.see_help("unpack") - end - - ns_name = util.adjust_name_and_namespace(ns_name, flags) +function unpack.command(args) + local ns_name = util.adjust_name_and_namespace(args.rock, args) local url, err if ns_name:match(".*%.rock") or ns_name:match(".*%.rockspec") then url = ns_name else - url, err = search.find_src_or_rockspec(ns_name, version, true) + url, err = search.find_src_or_rockspec(ns_name, args.version, true) if not url then return nil, err end end - return run_unpacker(url, flags["force"]) + return run_unpacker(url, args["force"]) end return unpack diff --git a/src/luarocks/cmd/upload.lua b/src/luarocks/cmd/upload.lua index b052500e..64bf18ad 100644 --- a/src/luarocks/cmd/upload.lua +++ b/src/luarocks/cmd/upload.lua @@ -8,37 +8,34 @@ local pack = require("luarocks.pack") local cfg = require("luarocks.core.cfg") local Api = require("luarocks.upload.api") -upload.help_summary = "Upload a rockspec to the public rocks repository." -upload.help_arguments = "[--skip-pack] [--api-key=] [--force] " -upload.help = [[ - Pack a source rock file (.src.rock extension), - upload rockspec and source rock to server. - ---skip-pack Do not pack and send source rock. - ---api-key= Give it an API key. It will be stored for subsequent uses. - ---temp-key= Use the given a temporary API key in this invocation only. - It will not be stored. - ---force Replace existing rockspec if the same revision of - a module already exists. This should be used only - in case of upload mistakes: when updating a rockspec, - increment the revision number instead. - ---sign Upload a signature file alongside each file as well. -]] +function upload.add_to_parser(parser) + local cmd = parser:command("upload", "Pack a source rock file (.src.rock extension) ".. + "and upload it and the rockspec to the public rocks repository.", util.see_also()) + :summary("Upload a rockspec to the public rocks repository.") + :add_help(false) + + cmd:argument("rockspec", "Rockspec for the rock to upload.") + + cmd:flag("--skip-pack", "Do not pack and send source rock.") + cmd:option("--api-key", "Pass an API key. It will be stored for subsequent uses.") + :argname("") + cmd:option("--temp-key", "Use the given a temporary API key in this ".. + "invocation only. It will not be stored.") + :argname("") + cmd:flag("--force", "Replace existing rockspec if the same revision of a ".. + "module already exists. This should be used only in case of upload ".. + "mistakes: when updating a rockspec, increment the revision number ".. + "instead.") + cmd:flag("--sign", "Upload a signature file alongside each file as well.") + cmd:flag("--debug"):hidden(true) +end local function is_dev_version(version) return version:match("^dev") or version:match("^scm") end -function upload.command(flags, fname) - if not fname then - return nil, "Missing rockspec. "..util.see_help("upload") - end - - local api, err = Api.new(flags) +function upload.command(args) + local api, err = Api.new(args) if not api then return nil, err end @@ -46,12 +43,12 @@ function upload.command(flags, fname) api.debug = true end - local rockspec, err, errcode = fetch.load_rockspec(fname) + local rockspec, err, errcode = fetch.load_rockspec(args.rockspec) if err then return nil, err, errcode end - util.printout("Sending " .. tostring(fname) .. " ...") + util.printout("Sending " .. tostring(args.rockspec) .. " ...") local res, err = api:method("check_rockspec", { package = rockspec.package, version = rockspec.version @@ -61,15 +58,15 @@ function upload.command(flags, fname) if not res.module then util.printout("Will create new module (" .. tostring(rockspec.package) .. ")") end - if res.version and not flags["force"] then + if res.version and not args["force"] then return nil, "Revision "..rockspec.version.." already exists on the server. "..util.see_help("upload") end local sigfname local rock_sigfname - if flags["sign"] then - sigfname, err = signing.sign_file(fname) + if args["sign"] then + sigfname, err = signing.sign_file(args.rockspec) if err then return nil, "Failed signing rockspec: " .. err end @@ -77,13 +74,13 @@ function upload.command(flags, fname) end local rock_fname - if not flags["skip-pack"] and not is_dev_version(rockspec.version) then + if not args["skip_pack"] and not is_dev_version(rockspec.version) then util.printout("Packing " .. tostring(rockspec.package)) - rock_fname, err = pack.pack_source_rock(fname) + rock_fname, err = pack.pack_source_rock(args.rockspec) if not rock_fname then return nil, err end - if flags["sign"] then + if args["sign"] then rock_sigfname, err = signing.sign_file(rock_fname) if err then return nil, "Failed signing rock: " .. err @@ -95,7 +92,7 @@ function upload.command(flags, fname) local multipart = require("luarocks.upload.multipart") res, err = api:method("upload", nil, { - rockspec_file = multipart.new_file(fname), + rockspec_file = multipart.new_file(args.rockspec), rockspec_sig = sigfname and multipart.new_file(sigfname), }) if not res then return nil, err end diff --git a/src/luarocks/cmd/which.lua b/src/luarocks/cmd/which.lua index 56db5254..571d2638 100644 --- a/src/luarocks/cmd/which.lua +++ b/src/luarocks/cmd/which.lua @@ -8,20 +8,21 @@ local cfg = require("luarocks.core.cfg") local util = require("luarocks.util") local fs = require("luarocks.fs") -which_cmd.help_summary = "Tell which file corresponds to a given module name." -which_cmd.help_arguments = "" -which_cmd.help = [[ -Given a module name like "foo.bar", output which file would be loaded to resolve -that module by luarocks.loader, like "/usr/local/lua/]]..cfg.lua_version..[[/foo/bar.lua". -]] - ---- Driver function for "lua" command. +function which_cmd.add_to_parser(parser) + local cmd = parser:command("which", 'Given a module name like "foo.bar", '.. + "output which file would be loaded to resolve that module by ".. + 'luarocks.loader, like "/usr/local/lua/'..cfg.lua_version..'/foo/bar.lua".', + util.see_also()) + :summary("Tell which file corresponds to a given module name.") + :add_help(false) + + cmd:argument("modname", "Module name.") +end + +--- Driver function for "which" command. -- @return boolean This function terminates the interpreter. -function which_cmd.command(_, modname) - if modname == nil then - return nil, "Missing module name. " .. util.see_help("which") - end - local pathname, rock_name, rock_version = loader.which(modname) +function which_cmd.command(args) + local pathname, rock_name, rock_version = loader.which(args.modname) if pathname then util.printout(pathname) @@ -29,7 +30,7 @@ function which_cmd.command(_, modname) return true end - local modpath = modname:gsub("%.", "/") + local modpath = args.modname:gsub("%.", "/") for _, v in ipairs({"path", "cpath"}) do for p in package[v]:gmatch("([^;]+)") do local pathname = p:gsub("%?", modpath) @@ -41,7 +42,7 @@ function which_cmd.command(_, modname) end end - return nil, "Module '" .. modname .. "' not found." + return nil, "Module '" .. args.modname .. "' not found." end return which_cmd diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index aad91910..4b16c0b7 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -11,36 +11,65 @@ local rockspecs = require("luarocks.rockspecs") local type_rockspec = require("luarocks.type.rockspec") local util = require("luarocks.util") -write_rockspec.help_summary = "Write a template for a rockspec file." -write_rockspec.help_arguments = "[--output= ...] [] [] [|]" -write_rockspec.help = [[ +local lua_versions = { + "5.1", + "5.2", + "5.3", + "5.4", + "5.1,5.2", + "5.2,5.3", + "5.3,5.4", + "5.1,5.2,5.3", + "5.2,5.3,5.4", + "5.1,5.2,5.3,5.4" +} + +function write_rockspec.add_to_parser(parser) + local cmd = parser:command("write_rockspec", [[ This command writes an initial version of a rockspec file, based on a name, a version, and a location (an URL or a local path). If only two arguments are given, the first one is considered the name and the second one is the location. + If only one argument is given, it must be the location. -If no arguments are given, current directory is used as location. +If no arguments are given, current directory is used as the location. LuaRocks will attempt to infer name and version if not given, using 'dev' as a fallback default version. Note that the generated file is a _starting point_ for writing a -rockspec, and is not guaranteed to be complete or correct. - ---output= Write the rockspec with the given filename. - If not given, a file is written in the current - directory with a filename based on given name and version. ---license="" A license string, such as "MIT/X11" or "GNU GPL v3". ---summary="" A short one-line description summary. ---detailed="" A longer description string. ---homepage= Project homepage. ---lua-versions= Supported Lua versions. Accepted values are: "5.1", "5.2", - "5.3", "5.4", "5.1,5.2", "5.2,5.3", "5.3,5.4", "5.1,5.2,5.3", - "5.2,5.3,5.4", or "5.1,5.2,5.3,5.4" ---rockspec-format= Rockspec format version, such as "1.0" or "1.1". ---tag= Tag to use. Will attempt to extract version number from it. ---lib=[,] A comma-separated list of libraries that C files need to - link to. -]] +rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) + :summary("Write a template for a rockspec file.") + :add_help(false) + + cmd:argument("name", "Name of the rock.") + :args("?") + cmd:argument("version", "Rock version.") + :args("?") + cmd:argument("location", "URL or path to the rock sources.") + :args("?") + + cmd:option("--output", "Write the rockspec with the given filename.\n".. + "If not given, a file is written in the current directory with a ".. + "filename based on given name and version.") + :argname("") + cmd:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') + :argname("") + cmd:option("--summary", "A short one-line description summary.") + :argname("") + cmd:option("--detailed", "A longer description string.") + :argname("") + cmd:option("--homepage", "Project homepage.") + :argname("") + cmd:option("--lua-versions", 'Supported Lua versions. Accepted values are: "'.. + table.concat(lua_versions, '", "')..'".') + :argname("") + :choices(lua_versions) + cmd:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') + :argname("") + cmd:option("--tag", "Tag to use. Will attempt to extract version number from it.") + cmd:option("--lib", "A comma-separated list of libraries that C files need to link to.") + :argname("") +end local function open_file(name) return io.open(dir.path(fs.current_dir(), name), "r") @@ -229,40 +258,42 @@ local function rockspec_cleanup(rockspec) end end -function write_rockspec.command(flags, name, version, url_or_dir) +function write_rockspec.command(args) - name = util.adjust_name_and_namespace(name, flags) + local name = util.adjust_name_and_namespace(args.name, args) + local version = args.version + local location = args.location if not name then - url_or_dir = "." + location = "." elseif not version then - url_or_dir = name + location = name name = nil - elseif not url_or_dir then - url_or_dir = version + elseif not location then + location = version version = nil end - if flags["tag"] then + if args["tag"] then if not version then - version = flags["tag"]:gsub("^v", "") + version = args["tag"]:gsub("^v", "") end end - local protocol, pathname = dir.split_url(url_or_dir) + local protocol, pathname = dir.split_url(location) if protocol == "file" then if pathname == "." then name = name or dir.base_name(fs.current_dir()) end elseif dir.is_basic_protocol(protocol) then - local filename = dir.base_name(url_or_dir) + local filename = dir.base_name(location) local newname, newversion = filename:match("(.*)-([^-]+)") if newname then name = name or newname version = version or newversion:gsub("%.[a-z]+$", ""):gsub("%.tar$", "") end else - name = name or dir.base_name(url_or_dir):gsub("%.[^.]+$", "") + name = name or dir.base_name(location):gsub("%.[^.]+$", "") end if not name then @@ -270,27 +301,27 @@ function write_rockspec.command(flags, name, version, url_or_dir) end version = version or "dev" - local filename = flags["output"] or dir.path(fs.current_dir(), name:lower().."-"..version.."-1.rockspec") + local filename = args["output"] or dir.path(fs.current_dir(), name:lower().."-"..version.."-1.rockspec") - local url = detect_url(url_or_dir) - local homepage = detect_homepage(url, flags["homepage"]) + local url = detect_url(location) + local homepage = detect_homepage(url, args["homepage"]) local rockspec, err = rockspecs.from_persisted_table(filename, { - rockspec_format = flags["rockspec-format"], + rockspec_format = args["rockspec_format"], package = name, version = version.."-1", source = { url = url, - tag = flags["tag"], + tag = args["tag"], }, description = { - summary = flags["summary"] or "*** please specify description summary ***", - detailed = flags["detailed"] or "*** please enter a detailed description ***", + summary = args["summary"] or "*** please specify description summary ***", + detailed = args["detailed"] or "*** please enter a detailed description ***", homepage = homepage, - license = flags["license"] or "*** please specify a license ***", + license = args["license"] or "*** please specify a license ***", }, dependencies = { - lua_version_dep[flags["lua-versions"]], + lua_version_dep[args["lua_versions"]], }, build = {}, }) @@ -301,19 +332,19 @@ function write_rockspec.command(flags, name, version, url_or_dir) util.warning("Please specify supported Lua versions with --lua-versions=. "..util.see_help("write_rockspec")) end - local local_dir = url_or_dir + local local_dir = location - if url_or_dir:match("://") then - rockspec.source.file = dir.base_name(url_or_dir) + if location:match("://") then + rockspec.source.file = dir.base_name(location) if not dir.is_basic_protocol(rockspec.source.protocol) then if version ~= "dev" then - rockspec.source.tag = flags["tag"] or "v" .. version + rockspec.source.tag = args["tag"] or "v" .. version end end rockspec.source.dir = nil local ok, base_dir, temp_dir = fetch_url(rockspec) if ok then - if base_dir ~= dir.base_name(url_or_dir) then + if base_dir ~= dir.base_name(location) then rockspec.source.dir = base_dir end end @@ -329,10 +360,10 @@ function write_rockspec.command(flags, name, version, url_or_dir) end local libs = nil - if flags["lib"] then + if args["lib"] then libs = {} rockspec.external_dependencies = {} - for lib in flags["lib"]:gmatch("([^,]+)") do + for lib in args["lib"]:gmatch("([^,]+)") do table.insert(libs, lib) rockspec.external_dependencies[lib:upper()] = { library = lib @@ -343,13 +374,13 @@ function write_rockspec.command(flags, name, version, url_or_dir) local ok, err = fs.change_dir(local_dir) if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end - if not (flags["summary"] and flags["detailed"]) then + if not (args["summary"] and args["detailed"]) then local summary, detailed = detect_description() - rockspec.description.summary = flags["summary"] or summary - rockspec.description.detailed = flags["detailed"] or detailed + rockspec.description.summary = args["summary"] or summary + rockspec.description.detailed = args["detailed"] or detailed end - if not flags["license"] then + if not args["license"] then local license, fulltext = check_license() if license then rockspec.description.license = license diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index af05ed05..93148de3 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -170,12 +170,13 @@ function deps.fulfill_dependency(dep, deps_mode, name, version, rocks_provided, return nil, "Could not satisfy dependency "..tostring(dep)..": "..search_err end util.printout("Installing "..url) - local install_flags = { + local install_args = { + rock = url, deps_mode = deps_mode, namespace = dep.namespace, verify = verify, } - local ok, install_err, errcode = install.command(install_flags, url) + local ok, install_err, errcode = install.command(install_args) if not ok then return nil, "Failed installing dependency: "..url.." - "..install_err, errcode end diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index 0e71432f..bd584d1a 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua @@ -251,14 +251,14 @@ function api.new(flags) self.config = self:load_config() or {} self.config.server = flags["server"] or self.config.server or cfg.upload.server self.config.version = self.config.version or cfg.upload.version - self.config.key = flags["temp-key"] or flags["api-key"] or self.config.key + self.config.key = flags["temp_key"] or flags["api_key"] or self.config.key self.debug = flags["debug"] if not self.config.key then return nil, "You need an API key to upload rocks.\n" .. "Navigate to "..self.config.server.."/settings to get a key\n" .. "and then pass it through the --api-key= flag." end - if flags["api-key"] then + if flags["api_key"] then self:save_config() end return self -- cgit v1.2.3-55-g6feb From 3cf0c501f2ab62a73f25c6b244b8b019d4b1a36a Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 12:30:17 -0400 Subject: Remove program_name cmd.run_command argument --- src/bin/luarocks | 2 +- src/bin/luarocks-admin | 2 +- src/luarocks/cmd.lua | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bin/luarocks b/src/bin/luarocks index 18c8fac6..56caaa60 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks @@ -32,4 +32,4 @@ local commands = { test = "luarocks.cmd.test", } -cmd.run_command("luarocks", description, commands, "luarocks.cmd.external", ...) +cmd.run_command(description, commands, "luarocks.cmd.external", ...) diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index db746bea..4a85e45b 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin @@ -15,4 +15,4 @@ local commands = { refresh_cache = "luarocks.admin.cmd.refresh_cache", } -cmd.run_command("luarocks-admin", description, commands, "luarocks.admin.cmd.external", ...) +cmd.run_command(description, commands, "luarocks.admin.cmd.external", ...) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 34dc75d8..1c8f0946 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -337,7 +337,7 @@ local function get_config_text() return buf.."\n" end -local function get_parser(program_name, description, cmd_modules) +local function get_parser(description, cmd_modules) local epilog = [[ Variables: Variables from the "variables" table of the configuration file can be @@ -346,7 +346,7 @@ Variables: ]]..get_config_text() local parser = argparse( - program_name, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. + dir.base_name(program), "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. program.." - "..description, epilog) :help_max_width(80) :add_help("--help") @@ -408,7 +408,7 @@ end -- @param commands table: contains the loaded modules representing commands. -- @param external_namespace string: where to look for external commands. -- @param ... string: Arguments given on the command-line. -function cmd.run_command(program_name, description, commands, external_namespace, ...) +function cmd.run_command(description, commands, external_namespace, ...) check_popen() @@ -452,7 +452,7 @@ function cmd.run_command(program_name, description, commands, external_namespace end local args, cmdline_vars = process_cmdline_vars(...) - local parser = get_parser(program_name, description, cmd_modules) + local parser = get_parser(description, cmd_modules) args = parser:parse(args) if not args.command then -- cgit v1.2.3-55-g6feb From c6a7d4c4656fbf0d9026741e4749d44a9446040c Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 18:38:09 -0400 Subject: Add help option to subcommands --- src/luarocks/admin/cmd/add.lua | 2 +- src/luarocks/admin/cmd/make_manifest.lua | 2 +- src/luarocks/admin/cmd/refresh_cache.lua | 2 +- src/luarocks/admin/cmd/remove.lua | 2 +- src/luarocks/cmd.lua | 2 +- src/luarocks/cmd/build.lua | 2 +- src/luarocks/cmd/config.lua | 2 +- src/luarocks/cmd/doc.lua | 2 +- src/luarocks/cmd/download.lua | 2 +- src/luarocks/cmd/init.lua | 2 +- src/luarocks/cmd/install.lua | 2 +- src/luarocks/cmd/lint.lua | 2 +- src/luarocks/cmd/list.lua | 2 +- src/luarocks/cmd/make.lua | 2 +- src/luarocks/cmd/new_version.lua | 2 +- src/luarocks/cmd/pack.lua | 2 +- src/luarocks/cmd/path.lua | 2 +- src/luarocks/cmd/purge.lua | 2 +- src/luarocks/cmd/remove.lua | 2 +- src/luarocks/cmd/search.lua | 2 +- src/luarocks/cmd/show.lua | 2 +- src/luarocks/cmd/test.lua | 2 +- src/luarocks/cmd/unpack.lua | 2 +- src/luarocks/cmd/upload.lua | 2 +- src/luarocks/cmd/which.lua | 2 +- src/luarocks/cmd/write_rockspec.lua | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index fa198baf..0682d89b 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -14,7 +14,7 @@ local index = require("luarocks.admin.index") function add.add_to_parser(parser) local cmd = parser:command("add", "Add a rock or rockspec to a rocks server.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") :args("+") diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index dba7ccf8..c7614ab5 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -14,7 +14,7 @@ local dir = require("luarocks.dir") function make_manifest.add_to_parser(parser) local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("repository", "Local repository pathname.") :args("?") diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index 0b2574b8..ab0708ec 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -9,7 +9,7 @@ local cache = require("luarocks.admin.cache") function refresh_cache.add_to_parser(parser) local cmd = parser:command( "refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:option("--from", "The server to use. If not given, the default server ".. "set in the upload_server variable from the configuration file is used instead.") diff --git a/src/luarocks/admin/cmd/remove.lua b/src/luarocks/admin/cmd/remove.lua index 4c0125a9..3fe70da6 100644 --- a/src/luarocks/admin/cmd/remove.lua +++ b/src/luarocks/admin/cmd/remove.lua @@ -14,7 +14,7 @@ local index = require("luarocks.admin.index") function admin_remove.add_to_parser(parser) local cmd = parser:command( "remove", "Remove a rock or rockspec from a rocks server.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") :args("+") diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 1c8f0946..ab8d22c6 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -350,7 +350,7 @@ Variables: program.." - "..description, epilog) :help_max_width(80) :add_help("--help") - :add_help_command({add_help = false}) + :add_help_command() :command_target("command") :require_command(false) diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 2b9f4dd6..ea75fa3d 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -22,7 +22,7 @@ function cmd_build.add_to_parser(parser) local cmd = parser:command("build", "Build and install a rock, compiling ".. "its C parts if any.", util.see_also()) :summary("Build/compile a rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. "a rock to be fetched from a repository.") diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index 6ec0efdf..fa954b3c 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -51,7 +51,7 @@ Query information about the LuaRocks configuration. for detailed information on the LuaRocks config file format. ]])) :summary("Query information about the LuaRocks configuration.") - :add_help(false) + :add_help("--help") cmd:argument("key", "The configuration key.") :args("?") diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index 74508fab..94a1b548 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -19,7 +19,7 @@ function doc.add_to_parser(parser) For more information about a rock, see the 'show' command. ]])) :summary("Show documentation for an installed rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "Name of the rock.") cmd:argument("version", "Version of the rock.") diff --git a/src/luarocks/cmd/download.lua b/src/luarocks/cmd/download.lua index 80897d5a..2b09e764 100644 --- a/src/luarocks/cmd/download.lua +++ b/src/luarocks/cmd/download.lua @@ -9,7 +9,7 @@ local download = require("luarocks.download") function cmd_download.add_to_parser(parser) local cmd = parser:command( "download", "Download a specific rock file from a rocks server.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("name", "Name of the rock.") :args("?") diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index 1053850d..bb10eb79 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -12,7 +12,7 @@ local write_rockspec = require("luarocks.cmd.write_rockspec") function init.add_to_parser(parser) local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("name", "The project name.") :args("?") diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index 3d3f0fe2..343bcfbe 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -18,7 +18,7 @@ local dir = require("luarocks.dir") function install.add_to_parser(parser) local cmd = parser:command("install", "Install a rock.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("rock", "The name of a rock to be fetched from a repository ".. "or a filename of a locally available rock.") diff --git a/src/luarocks/cmd/lint.lua b/src/luarocks/cmd/lint.lua index 433eed84..2af19392 100644 --- a/src/luarocks/cmd/lint.lua +++ b/src/luarocks/cmd/lint.lua @@ -12,7 +12,7 @@ function lint.add_to_parser(parser) "Returns success if the text of the rockspec is syntactically correct, else failure.", util.see_also()) :summary("Check syntax of a rockspec.") - :add_help(false) + :add_help("--help") cmd:argument("rockspec", "The rockspec to check.") end diff --git a/src/luarocks/cmd/list.lua b/src/luarocks/cmd/list.lua index 2bb7660f..01555e89 100644 --- a/src/luarocks/cmd/list.lua +++ b/src/luarocks/cmd/list.lua @@ -12,7 +12,7 @@ local path = require("luarocks.path") function list.add_to_parser(parser) local cmd = parser:command("list", "List currently installed rocks.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("filter", "A substring of a rock name to filter by.") :args("?") diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index a8084293..7ac9978a 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -35,7 +35,7 @@ NB: Use `luarocks install` with the `--only-deps` flag if you want to install only dependencies of the rockspec (see `luarocks help install`). ]], util.see_also()) :summary("Compile package in current directory using a rockspec.") - :add_help(false) + :add_help("--help") cmd:argument("rockspec", "Rockspec for the rock to build.") :args("?") diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 37d4206e..7c3e9329 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -39,7 +39,7 @@ If a directory is not given, it defaults to the current directory. WARNING: it writes the new rockspec to the given directory, overwriting the file if it already exists.]], util.see_also()) :summary("Auto-write a rockspec for a new version of a rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "Package name or rockspec.") :args("?") diff --git a/src/luarocks/cmd/pack.lua b/src/luarocks/cmd/pack.lua index e5e7f525..28c39687 100644 --- a/src/luarocks/cmd/pack.lua +++ b/src/luarocks/cmd/pack.lua @@ -10,7 +10,7 @@ local queries = require("luarocks.queries") function cmd_pack.add_to_parser(parser) local cmd = parser:command("pack", "Create a rock, packing sources or binaries.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("rock", "A rockspec file, for creating a source rock, or the ".. "name of an installed package, for creating a binary rock.") diff --git a/src/luarocks/cmd/path.lua b/src/luarocks/cmd/path.lua index 8921d2a5..c65aca01 100644 --- a/src/luarocks/cmd/path.lua +++ b/src/luarocks/cmd/path.lua @@ -18,7 +18,7 @@ And on Windows: luarocks path > "%temp%\_lrp.bat" && call "%temp%\_lrp.bat" && del "%temp%\_lrp.bat"]], util.see_also()) :summary("Return the currently configured package path.") - :add_help(false) + :add_help("--help") cmd:flag("--no-bin", "Do not export the PATH variable.") cmd:flag("--append", "Appends the paths to the existing paths. Default is ".. diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index 9b1e2ae9..7bb6b4ec 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua @@ -23,7 +23,7 @@ By default, it removes all rocks from a tree. The --tree option is mandatory: luarocks purge does not assume a default tree.]], util.see_also()) :summary("Remove all installed rocks from a tree.") - :add_help(false) + :add_help("--help") cmd:flag("--old-versions", "Keep the highest-numbered version of each ".. "rock and remove the other ones. By default it only removes old ".. diff --git a/src/luarocks/cmd/remove.lua b/src/luarocks/cmd/remove.lua index e311f399..b78d61bd 100644 --- a/src/luarocks/cmd/remove.lua +++ b/src/luarocks/cmd/remove.lua @@ -23,7 +23,7 @@ Will only perform the removal if it does not break dependencies. To override this check and force the removal, use --force or --force-fast.]], util.see_also()) :summary("Uninstall a rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "Name of the rock to be uninstalled.") cmd:argument("version", "Version of the rock to uninstall.") diff --git a/src/luarocks/cmd/search.lua b/src/luarocks/cmd/search.lua index d1546e80..8c735b22 100644 --- a/src/luarocks/cmd/search.lua +++ b/src/luarocks/cmd/search.lua @@ -11,7 +11,7 @@ local results = require("luarocks.results") function cmd_search.add_to_parser(parser) local cmd = parser:command("search", "Query the LuaRocks servers.", util.see_also()) - :add_help(false) + :add_help("--help") cmd:argument("name", "Name of the rock to search for.") :args("?") diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index 9bfedd20..3a7d86e0 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -20,7 +20,7 @@ Show information about an installed rock. Without any flags, show all module information. With flags, return only the desired information.]], util.see_also()) :summary("Show information about an installed rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "Name of an installed rock.") cmd:argument("version", "Rock version.") diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index baf7515e..cef17f53 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -18,7 +18,7 @@ To make sure that test suite flags are not interpreted as LuaRocks flags, use -- to separate LuaRocks arguments from test suite arguments.]], util.see_also()) :summary("Run the test suite in the current directory.") - :add_help(false) + :add_help("--help") cmd:argument("rockspec", "Project rockspec.") :args("?") diff --git a/src/luarocks/cmd/unpack.lua b/src/luarocks/cmd/unpack.lua index 65ce5c7c..b84b4166 100644 --- a/src/luarocks/cmd/unpack.lua +++ b/src/luarocks/cmd/unpack.lua @@ -17,7 +17,7 @@ Argument may be a rock file, or the name of a rock in a rocks server. In the latter case, the rock version may be given as a second argument.]], util.see_also()) :summary("Unpack the contents of a rock.") - :add_help(false) + :add_help("--help") cmd:argument("rock", "A rock file or the name of a rock.") cmd:argument("version", "Rock version.") diff --git a/src/luarocks/cmd/upload.lua b/src/luarocks/cmd/upload.lua index 64bf18ad..44e2a830 100644 --- a/src/luarocks/cmd/upload.lua +++ b/src/luarocks/cmd/upload.lua @@ -12,7 +12,7 @@ function upload.add_to_parser(parser) local cmd = parser:command("upload", "Pack a source rock file (.src.rock extension) ".. "and upload it and the rockspec to the public rocks repository.", util.see_also()) :summary("Upload a rockspec to the public rocks repository.") - :add_help(false) + :add_help("--help") cmd:argument("rockspec", "Rockspec for the rock to upload.") diff --git a/src/luarocks/cmd/which.lua b/src/luarocks/cmd/which.lua index 571d2638..7fdc5228 100644 --- a/src/luarocks/cmd/which.lua +++ b/src/luarocks/cmd/which.lua @@ -14,7 +14,7 @@ function which_cmd.add_to_parser(parser) 'luarocks.loader, like "/usr/local/lua/'..cfg.lua_version..'/foo/bar.lua".', util.see_also()) :summary("Tell which file corresponds to a given module name.") - :add_help(false) + :add_help("--help") cmd:argument("modname", "Module name.") end diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 4b16c0b7..846aebd4 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -39,7 +39,7 @@ using 'dev' as a fallback default version. Note that the generated file is a _starting point_ for writing a rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) :summary("Write a template for a rockspec file.") - :add_help(false) + :add_help("--help") cmd:argument("name", "Name of the rock.") :args("?") -- cgit v1.2.3-55-g6feb From d1d7fda791c7134af48e06f09a742b4727a6893f Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 21:14:31 -0400 Subject: Remove duplication between write_rockspec and init --- src/luarocks/cmd/init.lua | 16 +------------ src/luarocks/cmd/write_rockspec.lua | 46 ++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index bb10eb79..fe74751b 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -20,21 +20,7 @@ function init.add_to_parser(parser) :args("?") cmd:flag("--reset", "Delete .luarocks/config-5.x.lua and ./lua and generate new ones.") - cmd:group("Options for specifying rockspec data", - cmd:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') - :argname(""), - cmd:option("--summary", "A short one-line description summary.") - :argname(""), - cmd:option("--detailed", "A longer description string.") - :argname(""), - cmd:option("--homepage", "Project homepage.") - :argname(""), - cmd:option("--lua-versions", "Supported Lua versions. Accepted values are ".. - '"5.1", "5.2", "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3".'), - cmd:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') - :argname(""), - cmd:option("--lib", "A comma-separated list of libraries that C files need to link to.") - :argname("")) + cmd:group("Options for specifying rockspec data", write_rockspec.cmd_options(cmd)) end local function write_gitignore(entries) diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 846aebd4..dbf71a14 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -24,6 +24,30 @@ local lua_versions = { "5.1,5.2,5.3,5.4" } +function write_rockspec.cmd_options(parser) + return parser:option("--output", "Write the rockspec with the given filename.\n".. + "If not given, a file is written in the current directory with a ".. + "filename based on given name and version.") + :argname(""), + parser:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') + :argname(""), + parser:option("--summary", "A short one-line description summary.") + :argname(""), + parser:option("--detailed", "A longer description string.") + :argname(""), + parser:option("--homepage", "Project homepage.") + :argname(""), + parser:option("--lua-versions", 'Supported Lua versions. Accepted values are: "'.. + table.concat(lua_versions, '", "')..'".') + :argname("") + :choices(lua_versions), + parser:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') + :argname(""), + parser:option("--tag", "Tag to use. Will attempt to extract version number from it."), + parser:option("--lib", "A comma-separated list of libraries that C files need to link to.") + :argname("") +end + function write_rockspec.add_to_parser(parser) local cmd = parser:command("write_rockspec", [[ This command writes an initial version of a rockspec file, @@ -48,27 +72,7 @@ rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) cmd:argument("location", "URL or path to the rock sources.") :args("?") - cmd:option("--output", "Write the rockspec with the given filename.\n".. - "If not given, a file is written in the current directory with a ".. - "filename based on given name and version.") - :argname("") - cmd:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') - :argname("") - cmd:option("--summary", "A short one-line description summary.") - :argname("") - cmd:option("--detailed", "A longer description string.") - :argname("") - cmd:option("--homepage", "Project homepage.") - :argname("") - cmd:option("--lua-versions", 'Supported Lua versions. Accepted values are: "'.. - table.concat(lua_versions, '", "')..'".') - :argname("") - :choices(lua_versions) - cmd:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') - :argname("") - cmd:option("--tag", "Tag to use. Will attempt to extract version number from it.") - cmd:option("--lib", "A comma-separated list of libraries that C files need to link to.") - :argname("") + write_rockspec.cmd_options(cmd) end local function open_file(name) -- cgit v1.2.3-55-g6feb From 6fc92e343d6ea1db91bcb6c8e471b2442a8b5f43 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 21:28:10 -0400 Subject: Misc. fixes --- src/luarocks/admin/cmd/add.lua | 3 +-- src/luarocks/cmd.lua | 4 ++-- src/luarocks/cmd/config.lua | 1 - src/luarocks/cmd/new_version.lua | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index 0682d89b..ad16c232 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -12,8 +12,7 @@ local cache = require("luarocks.admin.cache") local index = require("luarocks.admin.index") function add.add_to_parser(parser) - local cmd = parser:command("add", "Add a rock or rockspec to a rocks server.", - util.see_also()) + local cmd = parser:command("add", "Add a rock or rockspec to a rocks server.", util.see_also()) :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index ab8d22c6..d85661d8 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -308,7 +308,7 @@ local function get_status(status) return status and "ok" or "not found" end -local function get_config_text() +local function get_config_text(cfg) local buf = "Configuration:\n Lua version: "..cfg.lua_version.."\n" if cfg.luajit_version then buf = buf.." LuaJIT version: "..cfg.luajit_version.."\n" @@ -343,7 +343,7 @@ Variables: Variables from the "variables" table of the configuration file can be overridden with VAR=VALUE assignments. -]]..get_config_text() +]]..get_config_text(cfg) local parser = argparse( dir.base_name(program), "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index fa954b3c..4f688a65 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -59,7 +59,6 @@ Query information about the LuaRocks configuration. :args("?") cmd:option("--scope", "The scope indicates which config file should be rewritten.\n".. - 'Accepted values are "system", "user" or "project".\n'.. '* Using a wrapper created with `luarocks init`, the default is "project".\n'.. '* Using --local (or when `local_by_default` is `true`), the default is "user".\n'.. '* Otherwise, the default is "system".') diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 7c3e9329..95d762be 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -21,7 +21,7 @@ default server. If a rockspec is given, it uses it instead. If no argument is given, it looks for a rockspec same way 'luarocks make' does. If the version number is not given and tag is passed using --tag, -it is used as the version, with 'v' removed from beginnnumbering. +it is used as the version, with 'v' removed from beginning. Otherwise, it only increments the revision number of the given (or downloaded) rockspec. -- cgit v1.2.3-55-g6feb From 84270767f50a51c0b00a22a32a9843b6e6c1f2d6 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 22:10:48 -0400 Subject: args["foo"] --> args.foo, flags --> args --- src/luarocks/admin/cmd/add.lua | 4 +- src/luarocks/admin/cmd/make_manifest.lua | 8 +-- src/luarocks/admin/cmd/refresh_cache.lua | 2 +- src/luarocks/admin/cmd/remove.lua | 4 +- src/luarocks/cmd.lua | 84 ++++++++++++++++---------------- src/luarocks/cmd/config.lua | 30 ++++++------ src/luarocks/cmd/doc.lua | 10 ++-- src/luarocks/cmd/download.lua | 12 ++--- src/luarocks/cmd/install.lua | 14 +++--- src/luarocks/cmd/list.lua | 14 +++--- src/luarocks/cmd/make.lua | 16 +++--- src/luarocks/cmd/pack.lua | 4 +- src/luarocks/cmd/path.lua | 12 ++--- src/luarocks/cmd/purge.lua | 8 +-- src/luarocks/cmd/remove.lua | 4 +- src/luarocks/cmd/search.lua | 10 ++-- src/luarocks/cmd/show.lua | 34 ++++++------- src/luarocks/cmd/test.lua | 4 +- src/luarocks/cmd/unpack.lua | 2 +- src/luarocks/cmd/upload.lua | 8 +-- src/luarocks/cmd/write_rockspec.lua | 34 ++++++------- src/luarocks/deps.lua | 6 +-- src/luarocks/fs/lua.lua | 6 +-- src/luarocks/upload/api.lua | 10 ++-- src/luarocks/util.lua | 16 +++--- 25 files changed, 178 insertions(+), 178 deletions(-) diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index ad16c232..f07b9fae 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -125,9 +125,9 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server, do end function add.command(args) - local server, server_table = cache.get_upload_server(args["server"]) + local server, server_table = cache.get_upload_server(args.server) if not server then return nil, server_table end - return add_files_to_server(not args["no_refresh"], files, server, server_table, args["index"]) + return add_files_to_server(not args.no_refresh, files, server, server_table, args.index) end diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index c7614ab5..840501ba 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -32,16 +32,16 @@ function make_manifest.command(args) util.printout("Making manifest for "..repo) - if repo:match("/lib/luarocks") and not args["local_tree"] then + if repo:match("/lib/luarocks") and not args.local_tree then util.warning("This looks like a local rocks tree, but you did not pass --local-tree.") end - local ok, err = writer.make_manifest(repo, deps.get_deps_mode(args), not args["local_tree"]) - if ok and not args["local_tree"] then + local ok, err = writer.make_manifest(repo, deps.get_deps_mode(args), not args.local_tree) + if ok and not args.local_tree then util.printout("Generating index.html for "..repo) index.make_index(repo) end - if args["local_tree"] then + if args.local_tree then for luaver in util.lua_versions() do fs.delete(dir.path(repo, "manifest-"..luaver)) end diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index ab0708ec..a5bdecb4 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -17,7 +17,7 @@ function refresh_cache.add_to_parser(parser) end function refresh_cache.command(args) - local server, upload_server = cache.get_upload_server(args["server"]) + local server, upload_server = cache.get_upload_server(args.server) if not server then return nil, upload_server end local download_url = cache.get_server_urls(server, upload_server) diff --git a/src/luarocks/admin/cmd/remove.lua b/src/luarocks/admin/cmd/remove.lua index 3fe70da6..b730ca51 100644 --- a/src/luarocks/admin/cmd/remove.lua +++ b/src/luarocks/admin/cmd/remove.lua @@ -80,9 +80,9 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve end function admin_remove.command(args) - local server, server_table = cache.get_upload_server(args["server"]) + local server, server_table = cache.get_upload_server(args.server) if not server then return nil, server_table end - return remove_files_from_server(not args["no_refresh"], files, server, server_table) + return remove_files_from_server(not args.no_refresh, files, server, server_table) end diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index d85661d8..f000e59e 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -39,11 +39,11 @@ local function check_popen() end end -local process_tree_flags +local process_tree_args do - local function replace_tree(flags, root, tree) + local function replace_tree(args, root, tree) root = dir.normalize(root) - flags["tree"] = root + args.tree = root path.use_tree(tree or root) end @@ -59,44 +59,44 @@ do cfg.deploy_lib_dir = cfg.deploy_lib_dir:gsub("/+$", "") end - process_tree_flags = function(flags, project_dir) + process_tree_args = function(args, project_dir) - if flags["global"] then + if args.global then cfg.local_by_default = false end - if flags["tree"] then + if args.tree then local named = false for _, tree in ipairs(cfg.rocks_trees) do - if type(tree) == "table" and flags["tree"] == tree.name then + if type(tree) == "table" and args.tree == tree.name then if not tree.root then return nil, "Configuration error: tree '"..tree.name.."' has no 'root' field." end - replace_tree(flags, tree.root, tree) + replace_tree(args, tree.root, tree) named = true break end end if not named then - local root_dir = fs.absolute_name(flags["tree"]) - replace_tree(flags, root_dir) + local root_dir = fs.absolute_name(args.tree) + replace_tree(args, root_dir) end - elseif flags["local"] then + elseif args["local"] then if not cfg.home_tree then return nil, "The --local flag is meant for operating in a user's home directory.\n".. "You are running as a superuser, which is intended for system-wide operation.\n".. "To force using the superuser's home, use --tree explicitly." else - replace_tree(flags, cfg.home_tree) + replace_tree(args, cfg.home_tree) end - elseif flags["project_tree"] then - local tree = flags["project_tree"] + elseif args.project_tree then + local tree = args.project_tree table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) loader.load_rocks_trees() path.use_tree(tree) elseif cfg.local_by_default then if cfg.home_tree then - replace_tree(flags, cfg.home_tree) + replace_tree(args, cfg.home_tree) end elseif project_dir then local project_tree = project_dir .. "/lua_modules" @@ -117,26 +117,26 @@ do end end -local function process_server_flags(flags) - if flags["server"] then - local protocol, pathname = dir.split_url(flags["server"]) +local function process_server_args(args) + if args.server then + local protocol, pathname = dir.split_url(args.server) table.insert(cfg.rocks_servers, 1, protocol.."://"..pathname) end - if flags["dev"] then + if args.dev then local append_dev = function(s) return dir.path(s, "dev") end local dev_servers = fun.traverse(cfg.rocks_servers, append_dev) cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) end - if flags["only_server"] then - if flags["dev"] then + if args.only_server then + if args.dev then return nil, "--only-server cannot be used with --dev" end - if flags["server"] then + if args.server then return nil, "--only-server cannot be used with --server" end - cfg.rocks_servers = { flags["only_server"] } + cfg.rocks_servers = { args.only_server } end return true @@ -172,7 +172,7 @@ end local init_config do - local detect_config_via_flags + local detect_config_via_args do local function find_project_dir(project_tree) if project_tree then @@ -191,7 +191,7 @@ do return nil end - local function find_default_lua_version(flags, project_dir) + local function find_default_lua_version(args, project_dir) if hardcoded.FORCE_CONFIG then return nil end @@ -210,7 +210,7 @@ do if mod then local pok, ver = pcall(mod) if pok and type(ver) == "string" and ver:match("%d+.%d+") then - if flags["verbose"] then + if args.verbose then util.printout("Defaulting to Lua " .. ver .. " based on " .. f .. " ...") end return ver @@ -228,13 +228,13 @@ do end) end - local function detect_lua_via_flags(flags, project_dir) - local lua_version = flags["lua_version"] - or find_default_lua_version(flags, project_dir) + local function detect_lua_via_args(args, project_dir) + local lua_version = args.lua_version + or find_default_lua_version(args, project_dir) or (project_dir and find_version_from_config(project_dir)) - if flags["lua_dir"] then - local detected, err = util.find_lua(flags["lua_dir"], lua_version) + if args.lua_dir then + local detected, err = util.find_lua(args.lua_dir, lua_version) if not detected then die(err) end @@ -262,14 +262,14 @@ do return {} end - detect_config_via_flags = function(flags) - local project_dir, given = find_project_dir(flags["project_tree"]) - local detected = detect_lua_via_flags(flags, project_dir) - if flags["lua_version"] then - detected.given_lua_version = flags["lua_version"] + detect_config_via_args = function(args) + local project_dir, given = find_project_dir(args.project_tree) + local detected = detect_lua_via_args(args, project_dir) + if args.lua_version then + detected.given_lua_version = args.lua_version end - if flags["lua_dir"] then - detected.given_lua_dir = flags["lua_dir"] + if args.lua_dir then + detected.given_lua_dir = args.lua_dir end if given then detected.given_project_dir = project_dir @@ -279,8 +279,8 @@ do end end - init_config = function(flags) - local detected = detect_config_via_flags(flags) + init_config = function(args) + local detected = detect_config_via_args(args) -- FIXME A quick hack for the experimental Windows build if os.getenv("LUAROCKS_CROSS_COMPILING") then @@ -513,12 +513,12 @@ function cmd.run_command(description, commands, external_namespace, ...) die("Current directory does not exist. Please run LuaRocks from an existing directory.") end - local ok, err = process_tree_flags(args, cfg.project_dir) + local ok, err = process_tree_args(args, cfg.project_dir) if not ok then die(err) end - ok, err = process_server_flags(args) + ok, err = process_server_args(args) if not ok then die(err) end diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index 4f688a65..9177c50d 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -230,10 +230,10 @@ local function write_entries(keys, scope, do_unset) end end -local function get_scope(flags) - return flags["scope"] - or (flags["local"] and "user") - or (flags["project_tree"] and "project") +local function get_scope(args) + return args.scope + or (args["local"] and "user") + or (args.project_tree and "project") or (cfg.local_by_default and "user") or "system" end @@ -245,25 +245,25 @@ function config_cmd.command(args) deps.check_lua_libdir(cfg.variables) -- deprecated flags - if args["lua_incdir"] then + if args.lua_incdir then print(cfg.variables.LUA_INCDIR) return true end - if args["lua_libdir"] then + if args.lua_libdir then print(cfg.variables.LUA_LIBDIR) return true end - if args["lua_ver"] then + if args.lua_ver then print(cfg.lua_version) return true end - if args["system_config"] then + if args.system_config then return config_file(cfg.config_files.system) end - if args["user_config"] then + if args.user_config then return config_file(cfg.config_files.user) end - if args["rock_trees"] then + if args.rock_trees then for _, tree in ipairs(cfg.rocks_trees) do if type(tree) == "string" then util.printout(dir.normalize(tree)) @@ -298,21 +298,21 @@ function config_cmd.command(args) ["variables.LUA_LIBDIR"] = cfg.variables.LUA_LIBDIR, ["lua_interpreter"] = cfg.lua_interpreter, } - return write_entries(keys, scope, args["unset"]) + return write_entries(keys, scope, args.unset) end if args.key then - if args.value or args["unset"] then + if args.value or args.unset then local scope = get_scope(args) - return write_entries({ [args.key] = args.value }, scope, args["unset"]) + return write_entries({ [args.key] = args.value }, scope, args.unset) else - return print_entry(args.key, cfg, args["json"]) + return print_entry(args.key, cfg, args.json) end end local cleancfg = cleanup(cfg) - if args["json"] then + if args.json then return print_json(cleancfg) else print(persist.save_from_table_to_string(cleancfg)) diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index 94a1b548..a732795d 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -63,7 +63,7 @@ function doc.command(args) local name = util.adjust_name_and_namespace(args.rock, args) local version = args.version local query = queries.new(name, version) - local iname, iversion, repo = search.pick_installed_rock(query, args["tree"]) + local iname, iversion, repo = search.pick_installed_rock(query, args.tree) if not iname then util.printout(name..(version and " "..version or "").." is not installed. Looking for it in the rocks servers...") return try_to_open_homepage(name, version) @@ -74,7 +74,7 @@ function doc.command(args) if not rockspec then return nil,err end local descript = rockspec.description or {} - if args["home"] then + if args.home then return show_homepage(descript.homepage, name, version) end @@ -90,7 +90,7 @@ function doc.command(args) end end if not docdir then - if descript.homepage and not args["list"] then + if descript.homepage and not args.list then util.printout("Local documentation directory not found -- opening "..descript.homepage.." ...") fs.browser(descript.homepage) return true @@ -104,7 +104,7 @@ function doc.command(args) local extensions = { htmlpatt, "%.md$", "%.txt$", "%.textile$", "" } local basenames = { "index", "readme", "manual" } - local porcelain = args["porcelain"] + local porcelain = args.porcelain if #files > 0 then util.title("Documentation files for "..name.." "..version, porcelain) if porcelain then @@ -119,7 +119,7 @@ function doc.command(args) end end - if args["list"] then + if args.list then return true end diff --git a/src/luarocks/cmd/download.lua b/src/luarocks/cmd/download.lua index 2b09e764..76acc9a5 100644 --- a/src/luarocks/cmd/download.lua +++ b/src/luarocks/cmd/download.lua @@ -27,7 +27,7 @@ end -- @return boolean or (nil, string): true if successful or nil followed -- by an error message. function cmd_download.command(args) - if not args.name and not args["all"] then + if not args.name and not args.all then return nil, "Argument missing. "..util.see_help("download") end @@ -37,15 +37,15 @@ function cmd_download.command(args) local arch - if args["source"] then + if args.source then arch = "src" - elseif args["rockspec"] then + elseif args.rockspec then arch = "rockspec" - elseif args["arch"] then - arch = args["arch"] + elseif args.arch then + arch = args.arch end - local dl, err = download.download(arch, name:lower(), version, args["all"]) + local dl, err = download.download(arch, name:lower(), version, args.all) return dl and true, err end diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index 343bcfbe..9085b3b7 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -223,15 +223,15 @@ function install.command(args) elseif args.rock:match("%.rock$") then local deps_mode = deps.get_deps_mode(args) local opts = install.opts({ - namespace = args["namespace"], - keep = not not args["keep"], - force = not not args["force"], - force_fast = not not args["force_fast"], - no_doc = not not args["no_doc"], + namespace = args.namespace, + keep = not not args.keep, + force = not not args.force, + force_fast = not not args.force_fast, + no_doc = not not args.no_doc, deps_mode = deps_mode, - verify = not not args["verify"], + verify = not not args.verify, }) - if args["only_deps"] then + if args.only_deps then return install_rock_file_deps(args.rock, opts) else return install_rock_file(args.rock, opts) diff --git a/src/luarocks/cmd/list.lua b/src/luarocks/cmd/list.lua index 01555e89..3e275a0d 100644 --- a/src/luarocks/cmd/list.lua +++ b/src/luarocks/cmd/list.lua @@ -73,13 +73,13 @@ function list.command(args) local query = queries.new(args.filter and args.filter:lower() or "", args.version, true) local trees = cfg.rocks_trees local title = "Rocks installed for Lua "..cfg.lua_version - if args["tree"] then - trees = { args["tree"] } - title = title .. " in " .. args["tree"] + if args.tree then + trees = { args.tree } + title = title .. " in " .. args.tree end - if args["outdated"] then - return list_outdated(trees, query, args["porcelain"]) + if args.outdated then + return list_outdated(trees, query, args.porcelain) end local results = {} @@ -89,8 +89,8 @@ function list.command(args) util.warning(err) end end - util.title(title, args["porcelain"]) - search.print_result_tree(results, args["porcelain"]) + util.title(title, args.porcelain) + search.print_result_tree(results, args.porcelain) return true end diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index 7ac9978a..512a3d74 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -87,17 +87,17 @@ function make.command(args) minimal_mode = true, deps_mode = deps.get_deps_mode(args), build_only_deps = false, - namespace = args["namespace"], - branch = not not args["branch"], - verify = not not args["verify"], + namespace = args.namespace, + branch = not not args.branch, + verify = not not args.verify, }) - if args["sign"] and not args["pack_binary_rock"] then + if args.sign and not args.pack_binary_rock then return nil, "In the make command, --sign is meant to be used only with --pack-binary-rock" end - if args["pack_binary_rock"] then - return pack.pack_binary_rock(name, rockspec.version, args["sign"], function() + if args.pack_binary_rock then + return pack.pack_binary_rock(name, rockspec.version, args.sign, function() return build.build_rockspec(rockspec, opts) end) else @@ -107,8 +107,8 @@ function make.command(args) if not ok then return nil, err end local name, version = ok, err - if (not args["keep"]) and not cfg.keep_other_versions then - local ok, err = remove.remove_other_versions(name, version, args["force"], args["force_fast"]) + if (not args.keep) and not cfg.keep_other_versions then + local ok, err = remove.remove_other_versions(name, version, args.force, args.force_fast) if not ok then util.printerr(err) end end diff --git a/src/luarocks/cmd/pack.lua b/src/luarocks/cmd/pack.lua index 28c39687..1f428546 100644 --- a/src/luarocks/cmd/pack.lua +++ b/src/luarocks/cmd/pack.lua @@ -30,9 +30,9 @@ function cmd_pack.command(args) else local name = util.adjust_name_and_namespace(args.rock, args) local query = queries.new(name, args.version) - file, err = pack.pack_installed_rock(query, args["tree"]) + file, err = pack.pack_installed_rock(query, args.tree) end - return pack.report_and_sign_local_file(file, err, args["sign"]) + return pack.report_and_sign_local_file(file, err, args.sign) end return cmd_pack diff --git a/src/luarocks/cmd/path.lua b/src/luarocks/cmd/path.lua index c65aca01..bdb1d2bc 100644 --- a/src/luarocks/cmd/path.lua +++ b/src/luarocks/cmd/path.lua @@ -32,21 +32,21 @@ end --- Driver function for "path" command. -- @return boolean This function always succeeds. function path_cmd.command(args) - local lr_path, lr_cpath, lr_bin = cfg.package_paths(args["tree"]) + local lr_path, lr_cpath, lr_bin = cfg.package_paths(args.tree) local path_sep = cfg.export_path_separator - if args["lr_path"] then + if args.lr_path then util.printout(util.cleanup_path(lr_path, ';', cfg.lua_version)) return true - elseif args["lr_cpath"] then + elseif args.lr_cpath then util.printout(util.cleanup_path(lr_cpath, ';', cfg.lua_version)) return true - elseif args["lr_bin"] then + elseif args.lr_bin then util.printout(util.cleanup_path(lr_bin, path_sep)) return true end - if args["append"] then + if args.append then lr_path = package.path .. ";" .. lr_path lr_cpath = package.cpath .. ";" .. lr_cpath lr_bin = os.getenv("PATH") .. path_sep .. lr_bin @@ -60,7 +60,7 @@ function path_cmd.command(args) util.printout(fs.export_cmd(lpath_var, util.cleanup_path(lr_path, ';', cfg.lua_version))) util.printout(fs.export_cmd(lcpath_var, util.cleanup_path(lr_cpath, ';', cfg.lua_version))) - if not args["no_bin"] then + if not args.no_bin then util.printout(fs.export_cmd("PATH", util.cleanup_path(lr_bin, path_sep))) end return true diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index 7bb6b4ec..bf037678 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua @@ -32,7 +32,7 @@ The --tree option is mandatory: luarocks purge does not assume a default tree.]] end function purge.command(args) - local tree = args["tree"] + local tree = args.tree if type(tree) ~= "string" then return nil, "The --tree argument is mandatory. "..util.see_help("purge") @@ -49,15 +49,15 @@ function purge.command(args) search.local_manifest_search(results, path.rocks_dir(tree), queries.all()) local sort = function(a,b) return vers.compare_versions(b,a) end - if args["old_versions"] then + if args.old_versions then sort = vers.compare_versions end for package, versions in util.sortedpairs(results) do for version, _ in util.sortedpairs(versions, sort) do - if args["old_versions"] then + if args.old_versions then util.printout("Keeping "..package.." "..version.."...") - local ok, err = remove.remove_other_versions(package, version, args["force"], args["force_fast"]) + local ok, err = remove.remove_other_versions(package, version, args.force, args.force_fast) if not ok then util.printerr(err) end diff --git a/src/luarocks/cmd/remove.lua b/src/luarocks/cmd/remove.lua index b78d61bd..492ea5bb 100644 --- a/src/luarocks/cmd/remove.lua +++ b/src/luarocks/cmd/remove.lua @@ -40,7 +40,7 @@ end function cmd_remove.command(args) local name = util.adjust_name_and_namespace(args.rock, args) - local deps_mode = args["deps_mode"] or cfg.deps_mode + local deps_mode = args.deps_mode or cfg.deps_mode local ok, err = fs.check_command_permissions(args) if not ok then return nil, err, cmd.errorcodes.PERMISSIONDENIED end @@ -60,7 +60,7 @@ function cmd_remove.command(args) return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..path.rocks_tree_to_string(cfg.root_dir) end - local ok, err = remove.remove_search_results(results, name, deps_mode, args["force"], args["force_fast"]) + local ok, err = remove.remove_search_results(results, name, deps_mode, args.force, args.force_fast) if not ok then return nil, err end diff --git a/src/luarocks/cmd/search.lua b/src/luarocks/cmd/search.lua index 8c735b22..37ec5272 100644 --- a/src/luarocks/cmd/search.lua +++ b/src/luarocks/cmd/search.lua @@ -57,25 +57,25 @@ function cmd_search.command(args) local name = util.adjust_name_and_namespace(args.name, args) - if args["all"] then + if args.all then name, args.version = "", nil end - if not args.name and not args["all"] then + if not args.name and not args.all then return nil, "Enter name and version or use --all. "..util.see_help("search") end local query = queries.new(name:lower(), args.version, true) local result_tree, err = search.search_repos(query) - local porcelain = args["porcelain"] + local porcelain = args.porcelain local full_name = name .. (args.version and " " .. args.version or "") util.title(full_name .. " - Search results for Lua "..cfg.lua_version..":", porcelain, "=") local sources, binaries = split_source_and_binary_results(result_tree) - if next(sources) and not args["binary"] then + if next(sources) and not args.binary then util.title("Rockspecs and source rocks:", porcelain) search.print_result_tree(sources, porcelain) end - if next(binaries) and not args["source"] then + if next(binaries) and not args.source then util.title("Binary and pure-Lua rocks:", porcelain) search.print_result_tree(binaries, porcelain) end diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index 3a7d86e0..f599f443 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -266,7 +266,7 @@ function show.command(args) local query = queries.new(name, version) local repo, repo_url - name, version, repo, repo_url = search.pick_installed_rock(query, args["tree"]) + name, version, repo, repo_url = search.pick_installed_rock(query, args.tree) if not name then return nil, version end @@ -282,32 +282,32 @@ function show.command(args) if not manifest then return nil,err end local minfo = manifest.repository[name][version][1] - if args["rock_tree"] then util.printout(tree) - elseif args["rock_namespace"] then util.printout(namespace) - elseif args["rock_dir"] then util.printout(directory) - elseif args["home"] then util.printout(descript.homepage) - elseif args["rock_license"] then util.printout(descript.license) - elseif args["issues"] then util.printout(descript.issues_url) - elseif args["labels"] then util.printout(descript.labels and table.concat(descript.labels, "\n")) - elseif args["modules"] then util.printout(keys_as_string(minfo.modules, "\n")) - elseif args["deps"] then + if args.rock_tree then util.printout(tree) + elseif args.rock_namespace then util.printout(namespace) + elseif args.rock_dir then util.printout(directory) + elseif args.home then util.printout(descript.homepage) + elseif args.rock_license then util.printout(descript.license) + elseif args.issues then util.printout(descript.issues_url) + elseif args.labels then util.printout(descript.labels and table.concat(descript.labels, "\n")) + elseif args.modules then util.printout(keys_as_string(minfo.modules, "\n")) + elseif args.deps then for _, dep in ipairs(rockspec.dependencies) do util.printout(tostring(dep)) end - elseif args["build_deps"] then + elseif args.build_deps then for _, dep in ipairs(rockspec.build_dependencies) do util.printout(tostring(dep)) end - elseif args["test_deps"] then + elseif args.test_deps then for _, dep in ipairs(rockspec.test_dependencies) do util.printout(tostring(dep)) end - elseif args["rockspec"] then util.printout(rockspec_file) - elseif args["mversion"] then util.printout(version) - elseif args["porcelain"] then - show_rock(porcelain_template, namespace, name, version, rockspec, repo, minfo, args["tree"]) + elseif args.rockspec then util.printout(rockspec_file) + elseif args.mversion then util.printout(version) + elseif args.porcelain then + show_rock(porcelain_template, namespace, name, version, rockspec, repo, minfo, args.tree) else - show_rock(friendly_template, namespace, name, version, rockspec, repo, minfo, args["tree"]) + show_rock(friendly_template, namespace, name, version, rockspec, repo, minfo, args.tree) end return true end diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index cef17f53..99be7f40 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -33,7 +33,7 @@ end function cmd_test.command(args) if args.rockspec and args.rockspec:match("rockspec$") then - return test.run_test_suite(args.rockspec, args["test_type"], args.args) + return test.run_test_suite(args.rockspec, args.test_type, args.args) end table.insert(args.args, 1, args.rockspec) @@ -43,7 +43,7 @@ function cmd_test.command(args) return nil, err end - return test.run_test_suite(rockspec, args["test_type"], args.args) + return test.run_test_suite(rockspec, args.test_type, args.args) end return cmd_test diff --git a/src/luarocks/cmd/unpack.lua b/src/luarocks/cmd/unpack.lua index b84b4166..46a438ba 100644 --- a/src/luarocks/cmd/unpack.lua +++ b/src/luarocks/cmd/unpack.lua @@ -162,7 +162,7 @@ function unpack.command(args) end end - return run_unpacker(url, args["force"]) + return run_unpacker(url, args.force) end return unpack diff --git a/src/luarocks/cmd/upload.lua b/src/luarocks/cmd/upload.lua index 44e2a830..f19f1e93 100644 --- a/src/luarocks/cmd/upload.lua +++ b/src/luarocks/cmd/upload.lua @@ -58,14 +58,14 @@ function upload.command(args) if not res.module then util.printout("Will create new module (" .. tostring(rockspec.package) .. ")") end - if res.version and not args["force"] then + if res.version and not args.force then return nil, "Revision "..rockspec.version.." already exists on the server. "..util.see_help("upload") end local sigfname local rock_sigfname - if args["sign"] then + if args.sign then sigfname, err = signing.sign_file(args.rockspec) if err then return nil, "Failed signing rockspec: " .. err @@ -74,13 +74,13 @@ function upload.command(args) end local rock_fname - if not args["skip_pack"] and not is_dev_version(rockspec.version) then + if not args.skip_pack and not is_dev_version(rockspec.version) then util.printout("Packing " .. tostring(rockspec.package)) rock_fname, err = pack.pack_source_rock(args.rockspec) if not rock_fname then return nil, err end - if args["sign"] then + if args.sign then rock_sigfname, err = signing.sign_file(rock_fname) if err then return nil, "Failed signing rock: " .. err diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index dbf71a14..3895a7f8 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -278,9 +278,9 @@ function write_rockspec.command(args) version = nil end - if args["tag"] then + if args.tag then if not version then - version = args["tag"]:gsub("^v", "") + version = args.tag:gsub("^v", "") end end @@ -305,27 +305,27 @@ function write_rockspec.command(args) end version = version or "dev" - local filename = args["output"] or dir.path(fs.current_dir(), name:lower().."-"..version.."-1.rockspec") + local filename = args.output or dir.path(fs.current_dir(), name:lower().."-"..version.."-1.rockspec") local url = detect_url(location) - local homepage = detect_homepage(url, args["homepage"]) + local homepage = detect_homepage(url, args.homepage) local rockspec, err = rockspecs.from_persisted_table(filename, { - rockspec_format = args["rockspec_format"], + rockspec_format = args.rockspec_format, package = name, version = version.."-1", source = { url = url, - tag = args["tag"], + tag = args.tag, }, description = { - summary = args["summary"] or "*** please specify description summary ***", - detailed = args["detailed"] or "*** please enter a detailed description ***", + summary = args.summary or "*** please specify description summary ***", + detailed = args.detailed or "*** please enter a detailed description ***", homepage = homepage, - license = args["license"] or "*** please specify a license ***", + license = args.license or "*** please specify a license ***", }, dependencies = { - lua_version_dep[args["lua_versions"]], + lua_version_dep[args.lua_versions], }, build = {}, }) @@ -342,7 +342,7 @@ function write_rockspec.command(args) rockspec.source.file = dir.base_name(location) if not dir.is_basic_protocol(rockspec.source.protocol) then if version ~= "dev" then - rockspec.source.tag = args["tag"] or "v" .. version + rockspec.source.tag = args.tag or "v" .. version end end rockspec.source.dir = nil @@ -364,10 +364,10 @@ function write_rockspec.command(args) end local libs = nil - if args["lib"] then + if args.lib then libs = {} rockspec.external_dependencies = {} - for lib in args["lib"]:gmatch("([^,]+)") do + for lib in args.lib:gmatch("([^,]+)") do table.insert(libs, lib) rockspec.external_dependencies[lib:upper()] = { library = lib @@ -378,13 +378,13 @@ function write_rockspec.command(args) local ok, err = fs.change_dir(local_dir) if not ok then return nil, "Failed reaching files from project - error entering directory "..local_dir end - if not (args["summary"] and args["detailed"]) then + if not (args.summary and args.detailed) then local summary, detailed = detect_description() - rockspec.description.summary = args["summary"] or summary - rockspec.description.detailed = args["detailed"] or detailed + rockspec.description.summary = args.summary or summary + rockspec.description.detailed = args.detailed or detailed end - if not args["license"] then + if not args.license then local license, fulltext = check_license() if license then rockspec.description.license = license diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 93148de3..7bce3dec 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -570,9 +570,9 @@ function deps.check_lua_libdir(vars) return nil, "Failed finding Lua library. You may need to configure LUA_LIBDIR.", "dependency" end -function deps.get_deps_mode(flags) - if flags["deps_mode"] then - return flags["deps_mode"] +function deps.get_deps_mode(args) + if args.deps_mode then + return args.deps_mode else return cfg.deps_mode end diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 56583676..6028a925 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -1092,10 +1092,10 @@ end --- Check if user has write permissions for the command. -- Assumes the configuration variables under cfg have been previously set up. --- @param flags table: the flags table passed to run() drivers. +-- @param args table: the args table passed to run() drivers. -- @return boolean or (boolean, string): true on success, false on failure, -- plus an error message. -function fs_lua.check_command_permissions(flags) +function fs_lua.check_command_permissions(args) local ok = true local err = "" for _, directory in ipairs { cfg.rocks_dir, cfg.deploy_lua_dir, cfg.deploy_bin_dir, cfg.deploy_lua_dir } do @@ -1124,7 +1124,7 @@ function fs_lua.check_command_permissions(flags) if ok then return true else - if flags["local"] or cfg.local_by_default then + if args["local"] or cfg.local_by_default then err = err .. " \n-- please check your permissions." else err = err .. " \n-- you may want to run as a privileged user or use your local tree with --local." diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index bd584d1a..a28b517a 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua @@ -245,20 +245,20 @@ end end -function api.new(flags) +function api.new(args) local self = {} setmetatable(self, { __index = Api }) self.config = self:load_config() or {} - self.config.server = flags["server"] or self.config.server or cfg.upload.server + self.config.server = args.server or self.config.server or cfg.upload.server self.config.version = self.config.version or cfg.upload.version - self.config.key = flags["temp_key"] or flags["api_key"] or self.config.key - self.debug = flags["debug"] + self.config.key = args.temp_key or args.api_key or self.config.key + self.debug = args.debug if not self.config.key then return nil, "You need an API key to upload rocks.\n" .. "Navigate to "..self.config.server.."/settings to get a key\n" .. "and then pass it through the --api-key= flag." end - if flags["api_key"] then + if args.api_key then self:save_config() end return self diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 635d3a97..5df2df51 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -338,13 +338,13 @@ function util.LQ(s) return ("%q"):format(s) end ---- Normalize the --namespace flag and the user/rock syntax for namespaces. --- If a namespace is given in user/rock syntax, update the --namespace flag; --- If a namespace is given in --namespace flag, update the user/rock syntax. +--- Normalize the --namespace option and the user/rock syntax for namespaces. +-- If a namespace is given in user/rock syntax, update the --namespace option; +-- If a namespace is given in --namespace option, update the user/rock syntax. -- In case of conflicts, the user/rock syntax takes precedence. -function util.adjust_name_and_namespace(ns_name, flags) +function util.adjust_name_and_namespace(ns_name, args) assert(type(ns_name) == "string" or not ns_name) - assert(type(flags) == "table") + assert(type(args) == "table") if not ns_name then return @@ -354,10 +354,10 @@ function util.adjust_name_and_namespace(ns_name, flags) local name, namespace = util.split_namespace(ns_name) if namespace then - flags["namespace"] = namespace + args.namespace = namespace end - if flags["namespace"] then - name = flags["namespace"] .. "/" .. name + if args.namespace then + name = args.namespace .. "/" .. name end return name:lower() end -- cgit v1.2.3-55-g6feb From 0d0c705f6b808b9ab819c19c4d8bbb5a850e9e13 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 19 Jun 2019 23:36:29 -0400 Subject: Rewrap some lines and fix some bugs --- src/luarocks/admin/cmd/add.lua | 2 +- src/luarocks/admin/cmd/make_manifest.lua | 3 +-- src/luarocks/admin/cmd/refresh_cache.lua | 3 +-- src/luarocks/admin/cmd/remove.lua | 5 ++--- src/luarocks/cmd/build.lua | 3 +-- src/luarocks/cmd/config.lua | 23 +++++++++++------------ src/luarocks/cmd/download.lua | 7 +++---- src/luarocks/cmd/write_rockspec.lua | 1 - src/luarocks/util.lua | 2 +- 9 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index f07b9fae..75f9386d 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -127,7 +127,7 @@ end function add.command(args) local server, server_table = cache.get_upload_server(args.server) if not server then return nil, server_table end - return add_files_to_server(not args.no_refresh, files, server, server_table, args.index) + return add_files_to_server(not args.no_refresh, args.rock, server, server_table, args.index) end diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index 840501ba..8eb673f5 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -12,8 +12,7 @@ local fs = require("luarocks.fs") local dir = require("luarocks.dir") function make_manifest.add_to_parser(parser) - local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", - util.see_also()) + local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", util.see_also()) :add_help("--help") cmd:argument("repository", "Local repository pathname.") diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index a5bdecb4..042a07a7 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -7,8 +7,7 @@ local util = require("luarocks.util") local cache = require("luarocks.admin.cache") function refresh_cache.add_to_parser(parser) - local cmd = parser:command( - "refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) + local cmd = parser:command("refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) :add_help("--help") cmd:option("--from", "The server to use. If not given, the default server ".. diff --git a/src/luarocks/admin/cmd/remove.lua b/src/luarocks/admin/cmd/remove.lua index b730ca51..74432ce9 100644 --- a/src/luarocks/admin/cmd/remove.lua +++ b/src/luarocks/admin/cmd/remove.lua @@ -12,8 +12,7 @@ local cache = require("luarocks.admin.cache") local index = require("luarocks.admin.index") function admin_remove.add_to_parser(parser) - local cmd = parser:command( - "remove", "Remove a rock or rockspec from a rocks server.", util.see_also()) + local cmd = parser:command("remove", "Remove a rock or rockspec from a rocks server.", util.see_also()) :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") @@ -82,7 +81,7 @@ end function admin_remove.command(args) local server, server_table = cache.get_upload_server(args.server) if not server then return nil, server_table end - return remove_files_from_server(not args.no_refresh, files, server, server_table) + return remove_files_from_server(not args.no_refresh, args.rock, server, server_table) end diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index ea75fa3d..09e0abc7 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -19,8 +19,7 @@ local make = require("luarocks.cmd.make") local cmd = require("luarocks.cmd") function cmd_build.add_to_parser(parser) - local cmd = parser:command("build", "Build and install a rock, compiling ".. - "its C parts if any.", util.see_also()) + local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.", util.see_also()) :summary("Build/compile a rock.") :add_help("--help") diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index 9177c50d..0af9e247 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -13,18 +13,18 @@ function config_cmd.add_to_parser(parser) local cmd = parser:command("config", [[ Query information about the LuaRocks configuration. -* When given a configuration key, it prints the value of that key - according to the currently active configuration (taking into account - all config files and any command-line flags passed) +* When given a configuration key, it prints the value of that key according to + the currently active configuration (taking into account all config files and + any command-line flags passed) Examples: luarocks config lua_interpreter luarocks config variables.LUA_INCDIR luarocks config lua_version -* When given a configuration key and a value, - it overwrites the config file (see the --scope option below to determine which) - and replaces the value of the given key with the given value. +* When given a configuration key and a value, it overwrites the config file (see + the --scope option below to determine which) and replaces the value of the + given key with the given value. * `lua_dir` is a special key as it checks for a valid Lua installation (equivalent to --lua-dir) and sets several keys at once. @@ -36,15 +36,14 @@ Query information about the LuaRocks configuration. luarocks config lua_dir /usr/local luarocks config lua_version 5.3 -* When given a configuration key and --unset, - it overwrites the config file (see the --scope option below to determine which) - and deletes that key from the file. +* When given a configuration key and --unset, it overwrites the config file (see + the --scope option below to determine which) and deletes that key from the + file. Example: luarocks config variables.OPENSSL_DIR --unset -* When given no arguments, it prints the entire currently active - configuration, resulting from reading the config files from - all scopes. +* When given no arguments, it prints the entire currently active configuration, + resulting from reading the config files from all scopes. Example: luarocks config]], util.see_also([[ https://github.com/luarocks/luarocks/wiki/Config-file-format diff --git a/src/luarocks/cmd/download.lua b/src/luarocks/cmd/download.lua index 76acc9a5..7f12a35f 100644 --- a/src/luarocks/cmd/download.lua +++ b/src/luarocks/cmd/download.lua @@ -7,8 +7,7 @@ local util = require("luarocks.util") local download = require("luarocks.download") function cmd_download.add_to_parser(parser) - local cmd = parser:command( - "download", "Download a specific rock file from a rocks server.", util.see_also()) + local cmd = parser:command("download", "Download a specific rock file from a rocks server.", util.see_also()) :add_help("--help") cmd:argument("name", "Name of the rock.") @@ -33,7 +32,7 @@ function cmd_download.command(args) local name = util.adjust_name_and_namespace(args.name, args) - if not name then name, version = "", "" end + if not name then name, args.version = "", "" end local arch @@ -45,7 +44,7 @@ function cmd_download.command(args) arch = args.arch end - local dl, err = download.download(arch, name:lower(), version, args.all) + local dl, err = download.download(arch, name:lower(), args.version, args.all) return dl and true, err end diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 3895a7f8..3fdc8091 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -54,7 +54,6 @@ This command writes an initial version of a rockspec file, based on a name, a version, and a location (an URL or a local path). If only two arguments are given, the first one is considered the name and the second one is the location. - If only one argument is given, it must be the location. If no arguments are given, current directory is used as the location. LuaRocks will attempt to infer name and version if not given, diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 5df2df51..42523c3c 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -215,7 +215,7 @@ function util.this_program(default) return prog end -function util.deps_mode_option(parser) +function util.deps_mode_option(parser, program) local cfg = require("luarocks.core.cfg") parser:option("--deps-mode", "How to handle dependencies. Four modes are supported:\n".. -- cgit v1.2.3-55-g6feb From 9ca43ac0e8864ac3098c95b56b9e45bc10a4709d Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Tue, 2 Jul 2019 00:25:13 -0400 Subject: Add argparse --- src/luarocks/argparse.lua | 2013 +++++++++++++++++++++++++++++++++++++++++++++ src/luarocks/cmd.lua | 2 +- 2 files changed, 2014 insertions(+), 1 deletion(-) create mode 100644 src/luarocks/argparse.lua diff --git a/src/luarocks/argparse.lua b/src/luarocks/argparse.lua new file mode 100644 index 00000000..a91da957 --- /dev/null +++ b/src/luarocks/argparse.lua @@ -0,0 +1,2013 @@ +-- The MIT License (MIT) + +-- Copyright (c) 2013 - 2018 Peter Melnichenko +-- 2019 Paul Ouellette + +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +-- the Software, and to permit persons to whom the Software is furnished to do so, +-- subject to the following conditions: + +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. + +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +-- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +-- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +-- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +-- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +local function deep_update(t1, t2) + for k, v in pairs(t2) do + if type(v) == "table" then + v = deep_update({}, v) + end + + t1[k] = v + end + + return t1 +end + +-- A property is a tuple {name, callback}. +-- properties.args is number of properties that can be set as arguments +-- when calling an object. +local function class(prototype, properties, parent) + -- Class is the metatable of its instances. + local cl = {} + cl.__index = cl + + if parent then + cl.__prototype = deep_update(deep_update({}, parent.__prototype), prototype) + else + cl.__prototype = prototype + end + + if properties then + local names = {} + + -- Create setter methods and fill set of property names. + for _, property in ipairs(properties) do + local name, callback = property[1], property[2] + + cl[name] = function(self, value) + if not callback(self, value) then + self["_" .. name] = value + end + + return self + end + + names[name] = true + end + + function cl.__call(self, ...) + -- When calling an object, if the first argument is a table, + -- interpret keys as property names, else delegate arguments + -- to corresponding setters in order. + if type((...)) == "table" then + for name, value in pairs((...)) do + if names[name] then + self[name](self, value) + end + end + else + local nargs = select("#", ...) + + for i, property in ipairs(properties) do + if i > nargs or i > properties.args then + break + end + + local arg = select(i, ...) + + if arg ~= nil then + self[property[1]](self, arg) + end + end + end + + return self + end + end + + -- If indexing class fails, fallback to its parent. + local class_metatable = {} + class_metatable.__index = parent + + function class_metatable.__call(self, ...) + -- Calling a class returns its instance. + -- Arguments are delegated to the instance. + local object = deep_update({}, self.__prototype) + setmetatable(object, self) + return object(...) + end + + return setmetatable(cl, class_metatable) +end + +local function typecheck(name, types, value) + for _, type_ in ipairs(types) do + if type(value) == type_ then + return true + end + end + + error(("bad property '%s' (%s expected, got %s)"):format(name, table.concat(types, " or "), type(value))) +end + +local function typechecked(name, ...) + local types = {...} + return {name, function(_, value) typecheck(name, types, value) end} +end + +local multiname = {"name", function(self, value) + typecheck("name", {"string"}, value) + + for alias in value:gmatch("%S+") do + self._name = self._name or alias + table.insert(self._aliases, alias) + end + + -- Do not set _name as with other properties. + return true +end} + +local function parse_boundaries(str) + if tonumber(str) then + return tonumber(str), tonumber(str) + end + + if str == "*" then + return 0, math.huge + end + + if str == "+" then + return 1, math.huge + end + + if str == "?" then + return 0, 1 + end + + if str:match "^%d+%-%d+$" then + local min, max = str:match "^(%d+)%-(%d+)$" + return tonumber(min), tonumber(max) + end + + if str:match "^%d+%+$" then + local min = str:match "^(%d+)%+$" + return tonumber(min), math.huge + end +end + +local function boundaries(name) + return {name, function(self, value) + typecheck(name, {"number", "string"}, value) + + local min, max = parse_boundaries(value) + + if not min then + error(("bad property '%s'"):format(name)) + end + + self["_min" .. name], self["_max" .. name] = min, max + end} +end + +local actions = {} + +local option_action = {"action", function(_, value) + typecheck("action", {"function", "string"}, value) + + if type(value) == "string" and not actions[value] then + error(("unknown action '%s'"):format(value)) + end +end} + +local option_init = {"init", function(self) + self._has_init = true +end} + +local option_default = {"default", function(self, value) + if type(value) ~= "string" then + self._init = value + self._has_init = true + return true + end +end} + +local add_help = {"add_help", function(self, value) + typecheck("add_help", {"boolean", "string", "table"}, value) + + if self._help_option_idx then + table.remove(self._options, self._help_option_idx) + self._help_option_idx = nil + end + + if value then + local help = self:flag() + :description "Show this help message and exit." + :action(function() + print(self:get_help()) + os.exit(0) + end) + + if value ~= true then + help = help(value) + end + + if not help._name then + help "-h" "--help" + end + + self._help_option_idx = #self._options + end +end} + +local Parser = class({ + _arguments = {}, + _options = {}, + _commands = {}, + _mutexes = {}, + _groups = {}, + _require_command = true, + _handle_options = true +}, { + args = 3, + typechecked("name", "string"), + typechecked("description", "string"), + typechecked("epilog", "string"), + typechecked("usage", "string"), + typechecked("help", "string"), + typechecked("require_command", "boolean"), + typechecked("handle_options", "boolean"), + typechecked("action", "function"), + typechecked("command_target", "string"), + typechecked("help_vertical_space", "number"), + typechecked("usage_margin", "number"), + typechecked("usage_max_width", "number"), + typechecked("help_usage_margin", "number"), + typechecked("help_description_margin", "number"), + typechecked("help_max_width", "number"), + add_help +}) + +local Command = class({ + _aliases = {} +}, { + args = 3, + multiname, + typechecked("description", "string"), + typechecked("epilog", "string"), + typechecked("summary", "string"), + typechecked("target", "string"), + typechecked("usage", "string"), + typechecked("help", "string"), + typechecked("require_command", "boolean"), + typechecked("handle_options", "boolean"), + typechecked("action", "function"), + typechecked("command_target", "string"), + typechecked("help_vertical_space", "number"), + typechecked("usage_margin", "number"), + typechecked("usage_max_width", "number"), + typechecked("help_usage_margin", "number"), + typechecked("help_description_margin", "number"), + typechecked("help_max_width", "number"), + typechecked("hidden", "boolean"), + add_help +}, Parser) + +local Argument = class({ + _minargs = 1, + _maxargs = 1, + _mincount = 1, + _maxcount = 1, + _defmode = "unused", + _show_default = true +}, { + args = 5, + typechecked("name", "string"), + typechecked("description", "string"), + option_default, + typechecked("convert", "function", "table"), + boundaries("args"), + typechecked("target", "string"), + typechecked("defmode", "string"), + typechecked("show_default", "boolean"), + typechecked("argname", "string", "table"), + typechecked("choices", "table"), + typechecked("hidden", "boolean"), + option_action, + option_init +}) + +local Option = class({ + _aliases = {}, + _mincount = 0, + _overwrite = true +}, { + args = 6, + multiname, + typechecked("description", "string"), + option_default, + typechecked("convert", "function", "table"), + boundaries("args"), + boundaries("count"), + typechecked("target", "string"), + typechecked("defmode", "string"), + typechecked("show_default", "boolean"), + typechecked("overwrite", "boolean"), + typechecked("argname", "string", "table"), + typechecked("choices", "table"), + typechecked("hidden", "boolean"), + option_action, + option_init +}, Argument) + +function Parser:_inherit_property(name, default) + local element = self + + while true do + local value = element["_" .. name] + + if value ~= nil then + return value + end + + if not element._parent then + return default + end + + element = element._parent + end +end + +function Argument:_get_argument_list() + local buf = {} + local i = 1 + + while i <= math.min(self._minargs, 3) do + local argname = self:_get_argname(i) + + if self._default and self._defmode:find "a" then + argname = "[" .. argname .. "]" + end + + table.insert(buf, argname) + i = i+1 + end + + while i <= math.min(self._maxargs, 3) do + table.insert(buf, "[" .. self:_get_argname(i) .. "]") + i = i+1 + + if self._maxargs == math.huge then + break + end + end + + if i < self._maxargs then + table.insert(buf, "...") + end + + return buf +end + +function Argument:_get_usage() + local usage = table.concat(self:_get_argument_list(), " ") + + if self._default and self._defmode:find "u" then + if self._maxargs > 1 or (self._minargs == 1 and not self._defmode:find "a") then + usage = "[" .. usage .. "]" + end + end + + return usage +end + +function actions.store_true(result, target) + result[target] = true +end + +function actions.store_false(result, target) + result[target] = false +end + +function actions.store(result, target, argument) + result[target] = argument +end + +function actions.count(result, target, _, overwrite) + if not overwrite then + result[target] = result[target] + 1 + end +end + +function actions.append(result, target, argument, overwrite) + result[target] = result[target] or {} + table.insert(result[target], argument) + + if overwrite then + table.remove(result[target], 1) + end +end + +function actions.concat(result, target, arguments, overwrite) + if overwrite then + error("'concat' action can't handle too many invocations") + end + + result[target] = result[target] or {} + + for _, argument in ipairs(arguments) do + table.insert(result[target], argument) + end +end + +function Argument:_get_action() + local action, init + + if self._maxcount == 1 then + if self._maxargs == 0 then + action, init = "store_true", nil + else + action, init = "store", nil + end + else + if self._maxargs == 0 then + action, init = "count", 0 + else + action, init = "append", {} + end + end + + if self._action then + action = self._action + end + + if self._has_init then + init = self._init + end + + if type(action) == "string" then + action = actions[action] + end + + return action, init +end + +-- Returns placeholder for `narg`-th argument. +function Argument:_get_argname(narg) + local argname = self._argname or self:_get_default_argname() + + if type(argname) == "table" then + return argname[narg] + else + return argname + end +end + +function Argument:_get_choices_list() + return "{" .. table.concat(self._choices, ",") .. "}" +end + +function Argument:_get_default_argname() + if self._choices then + return self:_get_choices_list() + else + return "<" .. self._name .. ">" + end +end + +function Option:_get_default_argname() + if self._choices then + return self:_get_choices_list() + else + return "<" .. self:_get_default_target() .. ">" + end +end + +-- Returns labels to be shown in the help message. +function Argument:_get_label_lines() + if self._choices then + return {self:_get_choices_list()} + else + return {self._name} + end +end + +function Option:_get_label_lines() + local argument_list = self:_get_argument_list() + + if #argument_list == 0 then + -- Don't put aliases for simple flags like `-h` on different lines. + return {table.concat(self._aliases, ", ")} + end + + local longest_alias_length = -1 + + for _, alias in ipairs(self._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 + local line = (" "):rep(longest_alias_length - #alias) .. alias .. " " .. argument_list_repr + + if i ~= #self._aliases then + line = line .. "," + end + + table.insert(lines, line) + end + + return lines +end + +function Command:_get_label_lines() + return {table.concat(self._aliases, ", ")} +end + +function Argument:_get_description() + if self._default and self._show_default then + if self._description then + return ("%s (default: %s)"):format(self._description, self._default) + else + return ("default: %s"):format(self._default) + end + else + return self._description or "" + end +end + +function Command:_get_description() + return self._summary or self._description or "" +end + +function Option:_get_usage() + local usage = self:_get_argument_list() + table.insert(usage, 1, self._name) + usage = table.concat(usage, " ") + + if self._mincount == 0 or self._default then + usage = "[" .. usage .. "]" + end + + return usage +end + +function Argument:_get_default_target() + return self._name +end + +function Option:_get_default_target() + local res + + for _, alias in ipairs(self._aliases) do + if alias:sub(1, 1) == alias:sub(2, 2) then + res = alias:sub(3) + break + end + end + + res = res or self._name:sub(2) + return (res:gsub("-", "_")) +end + +function Option:_is_vararg() + return self._maxargs ~= self._minargs +end + +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 {} + + for _, command in ipairs(self._commands) do + command:_update_charset(charset) + end + + for _, option in ipairs(self._options) do + for _, alias in ipairs(option._aliases) do + charset[alias:sub(1, 1)] = true + end + end + + return charset +end + +function Parser:argument(...) + local argument = Argument(...) + table.insert(self._arguments, argument) + return argument +end + +function Parser:option(...) + local option = Option(...) + table.insert(self._options, option) + return option +end + +function Parser:flag(...) + return self:option():args(0)(...) +end + +function Parser:command(...) + local command = Command():add_help(true)(...) + command._parent = self + table.insert(self._commands, command) + return command +end + +function Parser:mutex(...) + local elements = {...} + + for i, element in ipairs(elements) do + local mt = getmetatable(element) + assert(mt == Option or mt == Argument, ("bad argument #%d to 'mutex' (Option or Argument expected)"):format(i)) + end + + table.insert(self._mutexes, elements) + return self +end + +function Parser:group(name, ...) + assert(type(name) == "string", ("bad argument #1 to 'group' (string expected, got %s)"):format(type(name))) + + local group = {name = name, ...} + + for i, element in ipairs(group) do + local mt = getmetatable(element) + assert(mt == Option or mt == Argument or mt == Command, + ("bad argument #%d to 'group' (Option or Argument or Command expected)"):format(i + 1)) + end + + table.insert(self._groups, group) + return self +end + +local usage_welcome = "Usage: " + +function Parser:get_usage() + if self._usage then + return self._usage + end + + local usage_margin = self:_inherit_property("usage_margin", #usage_welcome) + local max_usage_width = self:_inherit_property("usage_max_width", 70) + local lines = {usage_welcome .. self:_get_fullname()} + + local function add(s) + if #lines[#lines]+1+#s <= max_usage_width then + lines[#lines] = lines[#lines] .. " " .. s + else + lines[#lines+1] = (" "):rep(usage_margin) .. s + end + end + + -- Normally options are before positional arguments in usage messages. + -- However, vararg options should be after, because they can't be reliable used + -- before a positional argument. + -- Mutexes come into play, too, and are shown as soon as possible. + -- Overall, output usages in the following order: + -- 1. Mutexes that don't have positional arguments or vararg options. + -- 2. Options that are not in any mutexes and are not vararg. + -- 3. Positional arguments - on their own or as a part of a mutex. + -- 4. Remaining mutexes. + -- 5. Remaining options. + + local elements_in_mutexes = {} + local added_elements = {} + local added_mutexes = {} + local argument_to_mutexes = {} + + local function add_mutex(mutex, main_argument) + if added_mutexes[mutex] then + return + end + + added_mutexes[mutex] = true + local buf = {} + + for _, element in ipairs(mutex) do + if not element._hidden and not added_elements[element] then + if getmetatable(element) == Option or element == main_argument then + table.insert(buf, element:_get_usage()) + added_elements[element] = true + end + end + end + + if #buf == 1 then + add(buf[1]) + elseif #buf > 1 then + add("(" .. table.concat(buf, " | ") .. ")") + end + end + + local function add_element(element) + if not element._hidden and not added_elements[element] then + add(element:_get_usage()) + added_elements[element] = true + end + end + + for _, mutex in ipairs(self._mutexes) do + local is_vararg = false + local has_argument = false + + for _, element in ipairs(mutex) do + if getmetatable(element) == Option then + if element:_is_vararg() then + is_vararg = true + end + else + has_argument = true + argument_to_mutexes[element] = argument_to_mutexes[element] or {} + table.insert(argument_to_mutexes[element], mutex) + end + + elements_in_mutexes[element] = true + end + + if not is_vararg and not has_argument then + add_mutex(mutex) + end + end + + for _, option in ipairs(self._options) do + if not elements_in_mutexes[option] and not option:_is_vararg() then + add_element(option) + end + end + + -- Add usages for positional arguments, together with one mutex containing them, if they are in a mutex. + for _, argument in ipairs(self._arguments) do + -- Pick a mutex as a part of which to show this argument, take the first one that's still available. + local mutex + + if elements_in_mutexes[argument] then + for _, argument_mutex in ipairs(argument_to_mutexes[argument]) do + if not added_mutexes[argument_mutex] then + mutex = argument_mutex + end + end + end + + if mutex then + add_mutex(mutex, argument) + else + add_element(argument) + end + end + + for _, mutex in ipairs(self._mutexes) do + add_mutex(mutex) + end + + for _, option in ipairs(self._options) do + add_element(option) + end + + if #self._commands > 0 then + if self._require_command then + add("") + else + add("[]") + end + + add("...") + end + + return table.concat(lines, "\n") +end + +local function split_lines(s) + if s == "" then + return {} + end + + local lines = {} + + if s:sub(-1) ~= "\n" then + s = s .. "\n" + end + + for line in s:gmatch("([^\n]*)\n") do + table.insert(lines, line) + end + + return lines +end + +local function autowrap_line(line, max_length) + -- Algorithm for splitting lines is simple and greedy. + local result_lines = {} + + -- Preserve original indentation of the line, put this at the beginning of each result line. + -- If the first word looks like a list marker ('*', '+', or '-'), add spaces so that starts + -- of the second and the following lines vertically align with the start of the second word. + local indentation = line:match("^ *") + + if line:find("^ *[%*%+%-]") then + indentation = indentation .. " " .. line:match("^ *[%*%+%-]( *)") + end + + -- Parts of the last line being assembled. + local line_parts = {} + + -- Length of the current line. + local line_length = 0 + + -- Index of the next character to consider. + local index = 1 + + while true do + local word_start, word_finish, word = line:find("([^ ]+)", index) + + if not word_start then + -- Ignore trailing spaces, if any. + break + end + + local preceding_spaces = line:sub(index, word_start - 1) + index = word_finish + 1 + + if (#line_parts == 0) or (line_length + #preceding_spaces + #word <= max_length) then + -- Either this is the very first word or it fits as an addition to the current line, add it. + table.insert(line_parts, preceding_spaces) -- For the very first word this adds the indentation. + table.insert(line_parts, word) + line_length = line_length + #preceding_spaces + #word + else + -- Does not fit, finish current line and put the word into a new one. + table.insert(result_lines, table.concat(line_parts)) + line_parts = {indentation, word} + line_length = #indentation + #word + end + end + + if #line_parts > 0 then + table.insert(result_lines, table.concat(line_parts)) + end + + if #result_lines == 0 then + -- Preserve empty lines. + result_lines[1] = "" + end + + return result_lines +end + +-- Automatically wraps lines within given array, +-- attempting to limit line length to `max_length`. +-- Existing line splits are preserved. +local function autowrap(lines, max_length) + local result_lines = {} + + for _, line in ipairs(lines) do + local autowrapped_lines = autowrap_line(line, max_length) + + for _, autowrapped_line in ipairs(autowrapped_lines) do + table.insert(result_lines, autowrapped_line) + end + end + + return result_lines +end + +function Parser:_get_element_help(element) + local label_lines = element:_get_label_lines() + local description_lines = split_lines(element:_get_description()) + + local result_lines = {} + + -- All label lines should have the same length (except the last one, it has no comma). + -- If too long, start description after all the label lines. + -- Otherwise, combine label and description lines. + + local usage_margin_len = self:_inherit_property("help_usage_margin", 3) + local usage_margin = (" "):rep(usage_margin_len) + local description_margin_len = self:_inherit_property("help_description_margin", 25) + local description_margin = (" "):rep(description_margin_len) + + local help_max_width = self:_inherit_property("help_max_width") + + if help_max_width then + local description_max_width = math.max(help_max_width - description_margin_len, 10) + description_lines = autowrap(description_lines, description_max_width) + end + + if #label_lines[1] >= (description_margin_len - usage_margin_len) then + for _, label_line in ipairs(label_lines) do + table.insert(result_lines, usage_margin .. label_line) + end + + for _, description_line in ipairs(description_lines) do + table.insert(result_lines, description_margin .. description_line) + end + else + for i = 1, math.max(#label_lines, #description_lines) do + local label_line = label_lines[i] + local description_line = description_lines[i] + + local line = "" + + if label_line then + line = usage_margin .. label_line + end + + if description_line and description_line ~= "" then + line = line .. (" "):rep(description_margin_len - #line) .. description_line + end + + table.insert(result_lines, line) + end + end + + return table.concat(result_lines, "\n") +end + +local function get_group_types(group) + local types = {} + + for _, element in ipairs(group) do + types[getmetatable(element)] = true + end + + return types +end + +function Parser:_add_group_help(blocks, added_elements, label, elements) + local buf = {label} + + for _, element in ipairs(elements) do + if not element._hidden and not added_elements[element] then + added_elements[element] = true + table.insert(buf, self:_get_element_help(element)) + end + end + + if #buf > 1 then + table.insert(blocks, table.concat(buf, ("\n"):rep(self:_inherit_property("help_vertical_space", 0) + 1))) + end +end + +function Parser:get_help() + if self._help then + return self._help + end + + local blocks = {self:get_usage()} + + local help_max_width = self:_inherit_property("help_max_width") + + if self._description then + local description = self._description + + if help_max_width then + description = table.concat(autowrap(split_lines(description), help_max_width), "\n") + end + + table.insert(blocks, description) + end + + -- 1. Put groups containing arguments first, then other arguments. + -- 2. Put remaining groups containing options, then other options. + -- 3. Put remaining groups containing commands, then other commands. + -- Assume that an element can't be in several groups. + local groups_by_type = { + [Argument] = {}, + [Option] = {}, + [Command] = {} + } + + for _, group in ipairs(self._groups) do + local group_types = get_group_types(group) + + for _, mt in ipairs({Argument, Option, Command}) do + if group_types[mt] then + table.insert(groups_by_type[mt], group) + break + end + end + end + + local default_groups = { + {name = "Arguments", type = Argument, elements = self._arguments}, + {name = "Options", type = Option, elements = self._options}, + {name = "Commands", type = Command, elements = self._commands} + } + + local added_elements = {} + + for _, default_group in ipairs(default_groups) do + local type_groups = groups_by_type[default_group.type] + + for _, group in ipairs(type_groups) do + self:_add_group_help(blocks, added_elements, group.name .. ":", group) + end + + local default_label = default_group.name .. ":" + + if #type_groups > 0 then + default_label = "Other " .. default_label:gsub("^.", string.lower) + end + + self:_add_group_help(blocks, added_elements, default_label, default_group.elements) + end + + if self._epilog then + local epilog = self._epilog + + if help_max_width then + epilog = table.concat(autowrap(split_lines(epilog), help_max_width), "\n") + end + + table.insert(blocks, epilog) + end + + return table.concat(blocks, "\n\n") +end + +function Parser:add_help_command(value) + if value then + assert(type(value) == "string" or type(value) == "table", + ("bad argument #1 to 'add_help_command' (string or table expected, got %s)"):format(type(value))) + end + + local help = self:command() + :description "Show help for commands." + help:argument "command" + :description "The command to show help for." + :args "?" + :action(function(_, _, cmd) + if not cmd then + print(self:get_help()) + os.exit(0) + else + for _, command in ipairs(self._commands) do + for _, alias in ipairs(command._aliases) do + if alias == cmd then + print(command:get_help()) + os.exit(0) + end + end + end + end + help:error(("unknown command '%s'"):format(cmd)) + end) + + if value then + help = help(value) + end + + if not help._name then + help "help" + end + + help._is_help_command = true + return self +end + +function Parser:_is_shell_safe() + if self._basename then + if self._basename:find("[^%w_%-%+%.]") then + return false + end + else + for _, alias in ipairs(self._aliases) do + if alias:find("[^%w_%-%+%.]") then + return false + end + end + end + for _, option in ipairs(self._options) do + for _, alias in ipairs(option._aliases) do + if alias:find("[^%w_%-%+%.]") then + return false + end + end + if option._choices then + for _, choice in ipairs(option._choices) do + if choice:find("[%s'\"]") then + return false + end + end + end + end + for _, argument in ipairs(self._arguments) do + if argument._choices then + for _, choice in ipairs(argument._choices) do + if choice:find("[%s'\"]") then + return false + end + end + end + end + for _, command in ipairs(self._commands) do + if not command:_is_shell_safe() then + return false + end + end + return true +end + +function Parser:add_complete(value) + if value then + assert(type(value) == "string" or type(value) == "table", + ("bad argument #1 to 'add_complete' (string or table expected, got %s)"):format(type(value))) + end + + local complete = self:option() + :description "Output a shell completion script for the specified shell." + :args(1) + :choices {"bash", "zsh", "fish"} + :action(function(_, _, shell) + io.write(self["get_" .. shell .. "_complete"](self)) + os.exit(0) + end) + + if value then + complete = complete(value) + end + + if not complete._name then + complete "--completion" + end + + return self +end + +function Parser:add_complete_command(value) + if value then + assert(type(value) == "string" or type(value) == "table", + ("bad argument #1 to 'add_complete_command' (string or table expected, got %s)"):format(type(value))) + end + + local complete = self:command() + :description "Output a shell completion script." + complete:argument "shell" + :description "The shell to output a completion script for." + :choices {"bash", "zsh", "fish"} + :action(function(_, _, shell) + io.write(self["get_" .. shell .. "_complete"](self)) + os.exit(0) + end) + + if value then + complete = complete(value) + end + + if not complete._name then + complete "completion" + end + + return self +end + +local function base_name(pathname) + return pathname:gsub("[/\\]*$", ""):match(".*[/\\]([^/\\]*)") or pathname +end + +local function get_short_description(element) + local short = element:_get_description():match("^(.-)%.%s") + return short or element:_get_description():match("^(.-)%.?$") +end + +function Parser:_get_options() + local options = {} + for _, option in ipairs(self._options) do + for _, alias in ipairs(option._aliases) do + table.insert(options, alias) + end + end + return table.concat(options, " ") +end + +function Parser:_get_commands() + local commands = {} + for _, command in ipairs(self._commands) do + for _, alias in ipairs(command._aliases) do + table.insert(commands, alias) + end + end + return table.concat(commands, " ") +end + +function Parser:_bash_option_args(buf, indent) + local opts = {} + for _, option in ipairs(self._options) do + if option._choices or option._minargs > 0 then + local compreply + if option._choices then + compreply = 'COMPREPLY=($(compgen -W "' .. table.concat(option._choices, " ") .. '" -- "$cur"))' + else + compreply = 'COMPREPLY=($(compgen -f -- "$cur"))' + end + table.insert(opts, (" "):rep(indent + 4) .. table.concat(option._aliases, "|") .. ")") + table.insert(opts, (" "):rep(indent + 8) .. compreply) + table.insert(opts, (" "):rep(indent + 8) .. "return 0") + table.insert(opts, (" "):rep(indent + 8) .. ";;") + end + end + + if #opts > 0 then + table.insert(buf, (" "):rep(indent) .. 'case "$prev" in') + table.insert(buf, table.concat(opts, "\n")) + table.insert(buf, (" "):rep(indent) .. "esac\n") + end +end + +function Parser:_bash_get_cmd(buf) + local cmds = {} + for _, command in ipairs(self._commands) do + if not command._is_help_command then + table.insert(cmds, (" "):rep(12) .. table.concat(command._aliases, "|") .. ")") + table.insert(cmds, (" "):rep(16) .. 'cmd="' .. command._name .. '"') + table.insert(cmds, (" "):rep(16) .. "break") + table.insert(cmds, (" "):rep(16) .. ";;") + end + end + + if #cmds > 0 then + table.insert(buf, (" "):rep(4) .. "for arg in ${COMP_WORDS[@]:1}; do") + table.insert(buf, (" "):rep(8) .. 'case "$arg" in') + table.insert(buf, table.concat(cmds, "\n")) + table.insert(buf, (" "):rep(8) .. "esac") + table.insert(buf, (" "):rep(4) .. "done\n") + end +end + +function Parser:_bash_cmd_completions(buf) + local subcmds = {} + for _, command in ipairs(self._commands) do + if #command._options > 0 and not command._is_help_command then + table.insert(subcmds, (" "):rep(8) .. command._name .. ")") + command:_bash_option_args(subcmds, 12) + table.insert(subcmds, (" "):rep(12) .. 'opts="$opts ' .. command:_get_options() .. '"') + table.insert(subcmds, (" "):rep(12) .. ";;") + end + end + + table.insert(buf, (" "):rep(4) .. 'case "$cmd" in') + table.insert(buf, (" "):rep(8) .. self._basename .. ")") + table.insert(buf, (" "):rep(12) .. 'COMPREPLY=($(compgen -W "' .. self:_get_commands() .. '" -- "$cur"))') + table.insert(buf, (" "):rep(12) .. ";;") + if #subcmds > 0 then + table.insert(buf, table.concat(subcmds, "\n")) + end + table.insert(buf, (" "):rep(4) .. "esac\n") +end + +function Parser:get_bash_complete() + self._basename = base_name(self._name) + assert(self:_is_shell_safe()) + local buf = {([[ +_%s() { + local IFS=$' \t\n' + local cur prev cmd opts arg + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="%s" + opts="%s" +]]):format(self._basename, self._basename, self:_get_options())} + + self:_bash_option_args(buf, 4) + self:_bash_get_cmd(buf) + if #self._commands > 0 then + self:_bash_cmd_completions(buf) + end + + table.insert(buf, ([=[ + if [[ "$cur" = -* ]]; then + COMPREPLY=($(compgen -W "$opts" -- "$cur")) + fi +} + +complete -F _%s -o bashdefault -o default %s +]=]):format(self._basename, self._basename)) + + return table.concat(buf, "\n") +end + +function Parser:_zsh_arguments(buf, cmd_name, indent) + if self._parent then + table.insert(buf, (" "):rep(indent) .. "options=(") + table.insert(buf, (" "):rep(indent + 2) .. "$options") + else + table.insert(buf, (" "):rep(indent) .. "local -a options=(") + end + + for _, option in ipairs(self._options) do + local line = {} + if #option._aliases > 1 then + if option._maxcount > 1 then + table.insert(line, '"*"') + end + table.insert(line, "{" .. table.concat(option._aliases, ",") .. '}"') + else + table.insert(line, '"') + if option._maxcount > 1 then + table.insert(line, "*") + end + table.insert(line, option._name) + end + if option._description then + local description = get_short_description(option):gsub('["%]:`$]', "\\%0") + table.insert(line, "[" .. description .. "]") + end + if option._maxargs == math.huge then + table.insert(line, ":*") + end + if option._choices then + table.insert(line, ": :(" .. table.concat(option._choices, " ") .. ")") + elseif option._maxargs > 0 then + table.insert(line, ": :_files") + end + table.insert(line, '"') + table.insert(buf, (" "):rep(indent + 2) .. table.concat(line)) + end + + table.insert(buf, (" "):rep(indent) .. ")") + table.insert(buf, (" "):rep(indent) .. "_arguments -s -S \\") + table.insert(buf, (" "):rep(indent + 2) .. "$options \\") + + if self._is_help_command then + table.insert(buf, (" "):rep(indent + 2) .. '": :(' .. self._parent:_get_commands() .. ')" \\') + else + for _, argument in ipairs(self._arguments) do + local spec + if argument._choices then + spec = ": :(" .. table.concat(argument._choices, " ") .. ")" + else + spec = ": :_files" + end + if argument._maxargs == math.huge then + table.insert(buf, (" "):rep(indent + 2) .. '"*' .. spec .. '" \\') + break + end + for _ = 1, argument._maxargs do + table.insert(buf, (" "):rep(indent + 2) .. '"' .. spec .. '" \\') + end + end + + if #self._commands > 0 then + table.insert(buf, (" "):rep(indent + 2) .. '": :_' .. cmd_name .. '_cmds" \\') + table.insert(buf, (" "):rep(indent + 2) .. '"*:: :->args" \\') + end + end + + table.insert(buf, (" "):rep(indent + 2) .. "&& return 0") +end + +function Parser:_zsh_cmds(buf, cmd_name) + table.insert(buf, "\n_" .. cmd_name .. "_cmds() {") + table.insert(buf, " local -a commands=(") + + for _, command in ipairs(self._commands) do + local line = {} + if #command._aliases > 1 then + table.insert(line, "{" .. table.concat(command._aliases, ",") .. '}"') + else + table.insert(line, '"' .. command._name) + end + if command._description then + table.insert(line, ":" .. get_short_description(command):gsub('["`$]', "\\%0")) + end + table.insert(buf, " " .. table.concat(line) .. '"') + end + + table.insert(buf, ' )\n _describe "command" commands\n}') +end + +function Parser:_zsh_complete_help(buf, cmds_buf, cmd_name, indent) + if #self._commands == 0 then + return + end + + self:_zsh_cmds(cmds_buf, cmd_name) + table.insert(buf, "\n" .. (" "):rep(indent) .. "case $words[1] in") + + for _, command in ipairs(self._commands) do + local name = cmd_name .. "_" .. command._name + table.insert(buf, (" "):rep(indent + 2) .. table.concat(command._aliases, "|") .. ")") + command:_zsh_arguments(buf, name, indent + 4) + command:_zsh_complete_help(buf, cmds_buf, name, indent + 4) + table.insert(buf, (" "):rep(indent + 4) .. ";;\n") + end + + table.insert(buf, (" "):rep(indent) .. "esac") +end + +function Parser:get_zsh_complete() + self._basename = base_name(self._name) + assert(self:_is_shell_safe()) + local buf = {("#compdef %s\n"):format(self._basename)} + local cmds_buf = {} + table.insert(buf, "_" .. self._basename .. "() {") + if #self._commands > 0 then + table.insert(buf, " local context state state_descr line") + table.insert(buf, " typeset -A opt_args\n") + end + self:_zsh_arguments(buf, self._basename, 2) + self:_zsh_complete_help(buf, cmds_buf, self._basename, 2) + table.insert(buf, "\n return 1") + table.insert(buf, "}") + + local result = table.concat(buf, "\n") + if #cmds_buf > 0 then + result = result .. "\n" .. table.concat(cmds_buf, "\n") + end + return result .. "\n\n_" .. self._basename .. "\n" +end + +local function fish_escape(string) + return string:gsub("[\\']", "\\%0") +end + +function Parser:_fish_complete_help(buf, prefix) + table.insert(buf, "") + + for _, command in ipairs(self._commands) do + for _, alias in ipairs(command._aliases) do + local line = ("%s -n '__fish_use_subcommand' -xa '%s'"):format(prefix, alias) + if command._description then + line = ("%s -d '%s'"):format(line, fish_escape(get_short_description(command))) + end + table.insert(buf, line) + end + + end + + if self._is_help_command then + local line = ("%s -n '__fish_seen_subcommand_from %s' -xa '%s'") + :format(prefix, table.concat(self._aliases, " "), self._parent:_get_commands()) + table.insert(buf, line) + end + + for _, option in ipairs(self._options) do + local parts = {prefix} + + if self._parent then + table.insert(parts, "-n '__fish_seen_subcommand_from " .. table.concat(self._aliases, " ") .. "'") + end + + for _, alias in ipairs(option._aliases) do + if alias:match("^%-.$") then + table.insert(parts, "-s " .. alias:sub(2)) + elseif alias:match("^%-%-.+") then + table.insert(parts, "-l " .. alias:sub(3)) + end + end + + if option._choices then + table.insert(parts, "-xa '" .. table.concat(option._choices, " ") .. "'") + elseif option._minargs > 0 then + table.insert(parts, "-r") + end + + if option._description then + table.insert(parts, "-d '" .. fish_escape(get_short_description(option)) .. "'") + end + + table.insert(buf, table.concat(parts, " ")) + end + + for _, command in ipairs(self._commands) do + command:_fish_complete_help(buf, prefix) + end +end + +function Parser:get_fish_complete() + self._basename = base_name(self._name) + assert(self:_is_shell_safe()) + local buf = {} + local prefix = "complete -c " .. self._basename + self:_fish_complete_help(buf, prefix) + return table.concat(buf, "\n") .. "\n" +end + +local function get_tip(context, wrong_name) + local context_pool = {} + local possible_name + local possible_names = {} + + for name in pairs(context) do + if type(name) == "string" then + for i = 1, #name do + possible_name = name:sub(1, i - 1) .. name:sub(i + 1) + + if not context_pool[possible_name] then + context_pool[possible_name] = {} + end + + table.insert(context_pool[possible_name], name) + end + end + end + + for i = 1, #wrong_name + 1 do + possible_name = wrong_name:sub(1, i - 1) .. wrong_name:sub(i + 1) + + if context[possible_name] then + possible_names[possible_name] = true + elseif context_pool[possible_name] then + for _, name in ipairs(context_pool[possible_name]) do + possible_names[name] = true + end + end + end + + local first = next(possible_names) + + if first then + if next(possible_names, first) then + local possible_names_arr = {} + + for name in pairs(possible_names) do + table.insert(possible_names_arr, "'" .. name .. "'") + end + + table.sort(possible_names_arr) + return "\nDid you mean one of these: " .. table.concat(possible_names_arr, " ") .. "?" + else + return "\nDid you mean '" .. first .. "'?" + end + else + return "" + end +end + +local ElementState = class({ + invocations = 0 +}) + +function ElementState:__call(state, element) + self.state = state + self.result = state.result + self.element = element + self.target = element._target or element:_get_default_target() + self.action, self.result[self.target] = element:_get_action() + return self +end + +function ElementState:error(fmt, ...) + self.state:error(fmt, ...) +end + +function ElementState:convert(argument, index) + local converter = self.element._convert + + if converter then + local ok, err + + if type(converter) == "function" then + ok, err = converter(argument) + elseif type(converter[index]) == "function" then + ok, err = converter[index](argument) + else + ok = converter[argument] + end + + if ok == nil then + self:error(err and "%s" or "malformed argument '%s'", err or argument) + end + + argument = ok + end + + return argument +end + +function ElementState:default(mode) + return self.element._defmode:find(mode) and self.element._default +end + +local function bound(noun, min, max, is_max) + local res = "" + + if min ~= max then + res = "at " .. (is_max and "most" or "least") .. " " + end + + local number = is_max and max or min + return res .. tostring(number) .. " " .. noun .. (number == 1 and "" or "s") +end + +function ElementState:set_name(alias) + self.name = ("%s '%s'"):format(alias and "option" or "argument", alias or self.element._name) +end + +function ElementState:invoke() + self.open = true + self.overwrite = false + + if self.invocations >= self.element._maxcount then + if self.element._overwrite then + self.overwrite = true + else + local num_times_repr = bound("time", self.element._mincount, self.element._maxcount, true) + self:error("%s must be used %s", self.name, num_times_repr) + end + else + self.invocations = self.invocations + 1 + end + + self.args = {} + + if self.element._maxargs <= 0 then + self:close() + end + + return self.open +end + +function ElementState:check_choices(argument) + if self.element._choices then + for _, choice in ipairs(self.element._choices) do + if argument == choice then + return + end + end + local choices_list = "'" .. table.concat(self.element._choices, "', '") .. "'" + local is_option = getmetatable(self.element) == Option + self:error("%s%s must be one of %s", is_option and "argument for " or "", self.name, choices_list) + end +end + +function ElementState:pass(argument) + self:check_choices(argument) + argument = self:convert(argument, #self.args + 1) + table.insert(self.args, argument) + + if #self.args >= self.element._maxargs then + self:close() + end + + return self.open +end + +function ElementState:complete_invocation() + while #self.args < self.element._minargs do + self:pass(self.element._default) + end +end + +function ElementState:close() + if self.open then + self.open = false + + if #self.args < self.element._minargs then + if self:default("a") then + self:complete_invocation() + else + if #self.args == 0 then + if getmetatable(self.element) == Argument then + self:error("missing %s", self.name) + elseif self.element._maxargs == 1 then + self:error("%s requires an argument", self.name) + end + end + + self:error("%s requires %s", self.name, bound("argument", self.element._minargs, self.element._maxargs)) + end + end + + local args + + if self.element._maxargs == 0 then + args = self.args[1] + elseif self.element._maxargs == 1 then + if self.element._minargs == 0 and self.element._mincount ~= self.element._maxcount then + args = self.args + else + args = self.args[1] + end + else + args = self.args + end + + self.action(self.result, self.target, args, self.overwrite) + end +end + +local ParseState = class({ + result = {}, + options = {}, + arguments = {}, + argument_i = 1, + element_to_mutexes = {}, + mutex_to_element_state = {}, + command_actions = {} +}) + +function ParseState:__call(parser, error_handler) + self.parser = parser + self.error_handler = error_handler + self.charset = parser:_update_charset() + self:switch(parser) + return self +end + +function ParseState:error(fmt, ...) + self.error_handler(self.parser, fmt:format(...)) +end + +function ParseState:switch(parser) + self.parser = parser + + if parser._action then + table.insert(self.command_actions, {action = parser._action, name = parser._name}) + end + + for _, option in ipairs(parser._options) do + option = ElementState(self, option) + table.insert(self.options, option) + + for _, alias in ipairs(option.element._aliases) do + self.options[alias] = option + end + end + + for _, mutex in ipairs(parser._mutexes) do + for _, element in ipairs(mutex) do + if not self.element_to_mutexes[element] then + self.element_to_mutexes[element] = {} + end + + table.insert(self.element_to_mutexes[element], mutex) + end + end + + for _, argument in ipairs(parser._arguments) do + argument = ElementState(self, argument) + table.insert(self.arguments, argument) + argument:set_name() + argument:invoke() + end + + self.handle_options = parser._handle_options + self.argument = self.arguments[self.argument_i] + self.commands = parser._commands + + for _, command in ipairs(self.commands) do + for _, alias in ipairs(command._aliases) do + self.commands[alias] = command + end + end +end + +function ParseState:get_option(name) + local option = self.options[name] + + if not option then + self:error("unknown option '%s'%s", name, get_tip(self.options, name)) + else + return option + end +end + +function ParseState:get_command(name) + local command = self.commands[name] + + if not command then + if #self.commands > 0 then + self:error("unknown command '%s'%s", name, get_tip(self.commands, name)) + else + self:error("too many arguments") + end + else + return command + end +end + +function ParseState:check_mutexes(element_state) + if self.element_to_mutexes[element_state.element] then + for _, mutex in ipairs(self.element_to_mutexes[element_state.element]) do + local used_element_state = self.mutex_to_element_state[mutex] + + if used_element_state and used_element_state ~= element_state then + self:error("%s can not be used together with %s", element_state.name, used_element_state.name) + else + self.mutex_to_element_state[mutex] = element_state + end + end + end +end + +function ParseState:invoke(option, name) + self:close() + option:set_name(name) + self:check_mutexes(option, name) + + if option:invoke() then + self.option = option + end +end + +function ParseState:pass(arg) + if self.option then + if not self.option:pass(arg) then + self.option = nil + end + elseif self.argument then + self:check_mutexes(self.argument) + + if not self.argument:pass(arg) then + self.argument_i = self.argument_i + 1 + self.argument = self.arguments[self.argument_i] + end + else + local command = self:get_command(arg) + self.result[command._target or command._name] = true + + if self.parser._command_target then + self.result[self.parser._command_target] = command._name + end + + self:switch(command) + end +end + +function ParseState:close() + if self.option then + self.option:close() + self.option = nil + end +end + +function ParseState:finalize() + self:close() + + for i = self.argument_i, #self.arguments do + local argument = self.arguments[i] + if #argument.args == 0 and argument:default("u") then + argument:complete_invocation() + else + argument:close() + end + end + + if self.parser._require_command and #self.commands > 0 then + self:error("a command is required") + end + + for _, option in ipairs(self.options) do + option.name = option.name or ("option '%s'"):format(option.element._name) + + if option.invocations == 0 then + if option:default("u") then + option:invoke() + option:complete_invocation() + option:close() + end + end + + local mincount = option.element._mincount + + if option.invocations < mincount then + if option:default("a") then + while option.invocations < mincount do + option:invoke() + option:close() + end + elseif option.invocations == 0 then + self:error("missing %s", option.name) + else + self:error("%s must be used %s", option.name, bound("time", mincount, option.element._maxcount)) + end + end + end + + for i = #self.command_actions, 1, -1 do + self.command_actions[i].action(self.result, self.command_actions[i].name) + end +end + +function ParseState:parse(args) + for _, arg in ipairs(args) do + local plain = true + + if self.handle_options then + local first = arg:sub(1, 1) + + if self.charset[first] then + if #arg > 1 then + plain = false + + if arg:sub(2, 2) == first then + if #arg == 2 then + if self.options[arg] then + local option = self:get_option(arg) + self:invoke(option, arg) + else + self:close() + end + + self.handle_options = false + else + local equals = arg:find "=" + if equals then + local name = arg:sub(1, equals - 1) + local option = self:get_option(name) + + if option.element._maxargs <= 0 then + self:error("option '%s' does not take arguments", name) + end + + self:invoke(option, name) + self:pass(arg:sub(equals + 1)) + else + local option = self:get_option(arg) + self:invoke(option, arg) + end + end + else + for i = 2, #arg do + local name = first .. arg:sub(i, i) + local option = self:get_option(name) + self:invoke(option, name) + + if i ~= #arg and option.element._maxargs > 0 then + self:pass(arg:sub(i + 1)) + break + end + end + end + end + end + end + + if plain then + self:pass(arg) + end + end + + self:finalize() + return self.result +end + +function Parser:error(msg) + io.stderr:write(("%s\n\nError: %s\n"):format(self:get_usage(), msg)) + os.exit(1) +end + +-- Compatibility with strict.lua and other checkers: +local default_cmdline = rawget(_G, "arg") or {} + +function Parser:_parse(args, error_handler) + return ParseState(self, error_handler):parse(args or default_cmdline) +end + +function Parser:parse(args) + return self:_parse(args, self.error) +end + +local function xpcall_error_handler(err) + return tostring(err) .. "\noriginal " .. debug.traceback("", 2):sub(2) +end + +function Parser:pparse(args) + local parse_error + + local ok, result = xpcall(function() + return self:_parse(args, function(_, err) + parse_error = err + error(err, 0) + end) + end, xpcall_error_handler) + + if ok then + return true, result + elseif not parse_error then + error(result, 0) + else + return false, parse_error + end +end + +local argparse = {} + +argparse.version = "0.6.0" + +setmetatable(argparse, {__call = function(_, ...) + return Parser(default_cmdline[0]):add_help(true)(...) +end}) + +return argparse diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index f000e59e..60aa633c 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -9,7 +9,7 @@ local cfg = require("luarocks.core.cfg") local dir = require("luarocks.dir") local fun = require("luarocks.fun") local fs = require("luarocks.fs") -local argparse = require("argparse") +local argparse = require("luarocks.argparse") local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") if not hc_ok then -- cgit v1.2.3-55-g6feb From fe3885908acb53b1bb63803d029f704c76195b8b Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Mon, 29 Jul 2019 17:52:52 -0400 Subject: Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 23f76e8a..cf1c1a40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /config.* /src/luarocks/core/hardcoded.lua /testrun/* +/lua_install # Stuff that pops up during development but shouldn't be in the repo (helps clean up `git status`) /build /build-binary @@ -15,4 +16,5 @@ /lua /lua_modules /luarocks +/luarocks-admin /.luarocks -- cgit v1.2.3-55-g6feb From b4d7742508105244053ebea15cac5cc570e4337f Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Mon, 29 Jul 2019 17:53:07 -0400 Subject: Add completion command --- src/luarocks/cmd.lua | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 60aa633c..174da616 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -345,12 +345,44 @@ Variables: ]]..get_config_text(cfg) + local basename = dir.base_name(program) local parser = argparse( - dir.base_name(program), "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. + basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. program.." - "..description, epilog) :help_max_width(80) :add_help("--help") :add_help_command() + :add_complete_command({ + help_max_width = 120, + summary = "Output a shell completion script.", + description = [[ +Output a shell completion script. + +Enabling completions for Bash: + + Add the following line to your ~/.bashrc: + source <(]]..basename..[[ completion bash) + or save the completion script to the local completion directory: + ]]..basename..[[ completion bash > ~/.local/share/bash-completion/completions/]]..basename..[[ + + +Enabling completions for Zsh: + + Save the completion script to a file in your $fpath. + You can add a new directory to your $fpath by adding e.g. + fpath=(~/.zfunc $fpath) + to your ~/.zshrc. + Then run: + ]]..basename..[[ completion zsh > ~/.zfunc/_]]..basename..[[ + + +Enabling completion for Fish: + + Add the following line to your ~/.config/fish/config.fish: + ]]..basename..[[ completion fish | source + or save the completion script to the local completion directory: + ]]..basename..[[ completion fish > ~/.config/fish/completions/]]..basename..[[.fish +]]}) :command_target("command") :require_command(false) -- cgit v1.2.3-55-g6feb From f52deeed485897511ecf80555e12a52c3e69d674 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Tue, 30 Jul 2019 16:08:48 -0400 Subject: Fix some failing tests --- spec/which_spec.lua | 2 +- src/luarocks/admin/cmd/add.lua | 3 ++- src/luarocks/cmd.lua | 30 ++++++++++++++++-------------- src/luarocks/cmd/build.lua | 5 +++++ src/luarocks/cmd/install.lua | 4 ++++ src/luarocks/cmd/make.lua | 9 +++++++-- src/luarocks/cmd/new_version.lua | 12 ++++++------ src/luarocks/cmd/purge.lua | 4 ++++ src/luarocks/cmd/show.lua | 2 +- 9 files changed, 46 insertions(+), 25 deletions(-) diff --git a/spec/which_spec.lua b/spec/which_spec.lua index d5bcfab9..79b9ef7e 100644 --- a/spec/which_spec.lua +++ b/spec/which_spec.lua @@ -22,7 +22,7 @@ describe("LuaRocks which tests #integration", function() it("fails on missing arguments", function() local output = run.luarocks("which") - assert.match("Missing module name", output, 1, true) + assert.match("missing argument 'modname'", output, 1, true) end) it("finds modules found in package.path", function() diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index 75f9386d..10e6bf09 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -20,6 +20,7 @@ function add.add_to_parser(parser) cmd:option("--server", "The server to use. If not given, the default server ".. "set in the upload_server variable from the configuration file is used instead.") + :target("add_server") cmd:flag("--no-refresh", "Do not refresh the local cache prior to ".. "generation of the updated manifest.") cmd:flag("--index", "Produce an index.html file for the manifest. This ".. @@ -125,7 +126,7 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server, do end function add.command(args) - local server, server_table = cache.get_upload_server(args.server) + local server, server_table = cache.get_upload_server(args.add_server or args.server) if not server then return nil, server_table end return add_files_to_server(not args.no_refresh, args.rock, server, server_table, args.index) end diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 174da616..0d249421 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -338,17 +338,10 @@ local function get_config_text(cfg) end local function get_parser(description, cmd_modules) - local epilog = [[ -Variables: - Variables from the "variables" table of the configuration file can be - overridden with VAR=VALUE assignments. - -]]..get_config_text(cfg) - local basename = dir.base_name(program) local parser = argparse( basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. - program.." - "..description, epilog) + program.." - "..description) :help_max_width(80) :add_help("--help") :add_help_command() @@ -487,11 +480,6 @@ function cmd.run_command(description, commands, external_namespace, ...) local parser = get_parser(description, cmd_modules) args = parser:parse(args) - if not args.command then - util.printout(parser:get_help()) - os.exit(cmd.errorcodes.OK) - end - -- Compatibility for old flag if args.nodeps then args.deps_mode = "none" @@ -527,7 +515,7 @@ function cmd.run_command(description, commands, external_namespace, ...) if not lua_found then util.warning("Could not find a Lua " .. cfg.lua_version .. " interpreter in your PATH. " .. "Modules may not install with the correct configurations. " .. - "You may want to specify to the path prefix to your build " .. + "You may want to specify the path prefix to your build " .. "of Lua " .. cfg.lua_version .. " using --lua-dir") end cfg.lua_found = lua_found @@ -568,6 +556,20 @@ function cmd.run_command(description, commands, external_namespace, ...) cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") end + parser:epilog([[ +Variables: + Variables from the "variables" table of the configuration file can be + overridden with VAR=VALUE assignments. + +]]..get_config_text(cfg)) + + if not args.command then + util.printout() + util.printout(parser:get_help()) + util.printout() + os.exit(cmd.errorcodes.OK) + end + local cmd_mod = cmd_modules[args.command] local call_ok, ok, err, exitcode = xpcall(function() return cmd_mod.command(args) diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 09e0abc7..0b1864fc 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -25,6 +25,7 @@ function cmd_build.add_to_parser(parser) cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. "a rock to be fetched from a repository.") + :args("?") cmd:argument("version", "Rock version.") :args("?") @@ -33,6 +34,10 @@ function cmd_build.add_to_parser(parser) cmd:flag("--keep", "Do not remove previously installed versions of the ".. "rock after building a new one. This behavior can be made permanent by ".. "setting keep_other_versions=true in the configuration file.") + cmd:flag("--force", "If --keep is not specified, force removal of ".. + "previously installed versions if it would break dependencies.") + cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. + "without reporting dependency issues.") cmd:option("--branch", "Override the `source.branch` field in the loaded ".. "rockspec. Allows to specify a different branch to fetch. Particularly ".. 'for "dev" rocks.') diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index 9085b3b7..6b308e0f 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -28,6 +28,10 @@ function install.add_to_parser(parser) cmd:flag("--keep", "Do not remove previously installed versions of the ".. "rock after building a new one. This behavior can be made permanent by ".. "setting keep_other_versions=true in the configuration file.") + cmd:flag("--force", "If --keep is not specified, force removal of ".. + "previously installed versions if it would break dependencies.") + cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. + "without reporting dependency issues.") cmd:flag("--only-deps", "Installs only the dependencies of the rock.") cmd:flag("--no-doc", "Installs the rock without its documentation.") cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index 512a3d74..da22a446 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -45,6 +45,10 @@ only dependencies of the rockspec (see `luarocks help install`). cmd:flag("--keep", "Do not remove previously installed versions of the ".. "rock after building a new one. This behavior can be made permanent by ".. "setting keep_other_versions=true in the configuration file.") + cmd:flag("--force", "If --keep is not specified, force removal of ".. + "previously installed versions if it would break dependencies.") + cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. + "without reporting dependency issues.") cmd:option("--branch", "Override the `source.branch` field in the loaded ".. "rockspec. Allows to specify a different branch to fetch. Particularly ".. 'for "dev" rocks.') @@ -57,14 +61,15 @@ only dependencies of the rockspec (see `luarocks help install`). "option to work properly.") cmd:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. "signature file for the generated .rock file.") + util.deps_mode_option(cmd) end --- Driver function for "make" command. -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an -- error message otherwise. exitcode is optionally returned. function make.command(args) - local rockspec - if not args.rockspec then + local rockspec = args.rockspec + if not rockspec then local err rockspec, err = util.get_default_rockspec() if not rockspec then diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 95d762be..b6951059 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -139,22 +139,22 @@ local function update_source_section(out_rs, url, tag, old_ver, new_ver) end function new_version.command(args) - if not args.input then + if not args.rock then local err - args.input, err = util.get_default_rockspec() - if not args.input then + args.rock, err = util.get_default_rockspec() + if not args.rock then return nil, err end end local filename, err - if args.input:match("rockspec$") then - filename, err = fetch.fetch_url(args.input) + if args.rock:match("rockspec$") then + filename, err = fetch.fetch_url(args.rock) if not filename then return nil, err end else - filename, err = download.download("rockspec", args.input:lower()) + filename, err = download.download("rockspec", args.rock:lower()) if not filename then return nil, err end diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index bf037678..c9102876 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua @@ -29,6 +29,10 @@ The --tree option is mandatory: luarocks purge does not assume a default tree.]] "rock and remove the other ones. By default it only removes old ".. "versions if they are not needed as dependencies. This can be ".. "overridden with the flag --force.") + cmd:flag("--force", "If --old-versions is specified, force removal of ".. + "previously installed versions if it would break dependencies.") + cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. + "without reporting dependency issues.") end function purge.command(args) diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index f599f443..dd4b33d1 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -262,7 +262,7 @@ end -- @return boolean: True if succeeded, nil on errors. function show.command(args) local name = util.adjust_name_and_namespace(args.rock, args) - local version = args.verson + local version = args.version local query = queries.new(name, version) local repo, repo_url -- cgit v1.2.3-55-g6feb From d394ecba0cb8572b60483e23444ce79a9761a1aa Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Thu, 1 Aug 2019 21:25:59 -0400 Subject: Remove duplication between build and make commands --- src/luarocks/cmd/build.lua | 26 +++---------------------- src/luarocks/cmd/make.lua | 48 +++++++++++++++++++++++++--------------------- 2 files changed, 29 insertions(+), 45 deletions(-) diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 0b1864fc..428ede2a 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -19,7 +19,8 @@ local make = require("luarocks.cmd.make") local cmd = require("luarocks.cmd") function cmd_build.add_to_parser(parser) - local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.", util.see_also()) + local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.\n".. + "If no arguments are given, behaves as luarocks make.", util.see_also()) :summary("Build/compile a rock.") :add_help("--help") @@ -29,29 +30,8 @@ function cmd_build.add_to_parser(parser) cmd:argument("version", "Rock version.") :args("?") - cmd:flag("--pack-binary-rock", "Do not install rock. Instead, produce a ".. - ".rock file with the contents of compilation in the current directory.") - cmd:flag("--keep", "Do not remove previously installed versions of the ".. - "rock after building a new one. This behavior can be made permanent by ".. - "setting keep_other_versions=true in the configuration file.") - cmd:flag("--force", "If --keep is not specified, force removal of ".. - "previously installed versions if it would break dependencies.") - cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. - "without reporting dependency issues.") - cmd:option("--branch", "Override the `source.branch` field in the loaded ".. - "rockspec. Allows to specify a different branch to fetch. Particularly ".. - 'for "dev" rocks.') - :argname("") cmd:flag("--only-deps", "Installs only the dependencies of the rock.") - cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. - "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. - "attempt to download the signature as well. Otherwise, the signature ".. - "file should be already available locally in the same directory.\n".. - "You need the signer’s public key in your local keyring for this ".. - "option to work properly.") - cmd:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. - "signature file for the generated .rock file.") - util.deps_mode_option(cmd) + make.cmd_options(cmd) end --- Build and install a rock. diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index da22a446..bc7c2c60 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -16,6 +16,31 @@ local deps = require("luarocks.deps") local writer = require("luarocks.manif.writer") local cmd = require("luarocks.cmd") +function make.cmd_options(parser) + parser:flag("--pack-binary-rock", "Do not install rock. Instead, produce a ".. + ".rock file with the contents of compilation in the current directory.") + parser:flag("--keep", "Do not remove previously installed versions of the ".. + "rock after building a new one. This behavior can be made permanent by ".. + "setting keep_other_versions=true in the configuration file.") + parser:flag("--force", "If --keep is not specified, force removal of ".. + "previously installed versions if it would break dependencies.") + parser:flag("--force-fast", "Like --force, but performs a forced removal ".. + "without reporting dependency issues.") + parser:option("--branch", "Override the `source.branch` field in the loaded ".. + "rockspec. Allows to specify a different branch to fetch. Particularly ".. + 'for "dev" rocks.') + :argname("") + parser:flag("--verify", "Verify signature of the rockspec or src.rock being ".. + "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. + "attempt to download the signature as well. Otherwise, the signature ".. + "file should be already available locally in the same directory.\n".. + "You need the signer’s public key in your local keyring for this ".. + "option to work properly.") + parser:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. + "signature file for the generated .rock file.") + util.deps_mode_option(parser) +end + function make.add_to_parser(parser) local cmd = parser:command("make", [[ Builds sources in the current directory, but unlike "build", @@ -40,28 +65,7 @@ only dependencies of the rockspec (see `luarocks help install`). cmd:argument("rockspec", "Rockspec for the rock to build.") :args("?") - cmd:flag("--pack-binary-rock", "Do not install rock. Instead, produce a ".. - ".rock file with the contents of compilation in the current directory.") - cmd:flag("--keep", "Do not remove previously installed versions of the ".. - "rock after building a new one. This behavior can be made permanent by ".. - "setting keep_other_versions=true in the configuration file.") - cmd:flag("--force", "If --keep is not specified, force removal of ".. - "previously installed versions if it would break dependencies.") - cmd:flag("--force-fast", "Like --force, but performs a forced removal ".. - "without reporting dependency issues.") - cmd:option("--branch", "Override the `source.branch` field in the loaded ".. - "rockspec. Allows to specify a different branch to fetch. Particularly ".. - 'for "dev" rocks.') - :argname("") - cmd:flag("--verify", "Verify signature of the rockspec or src.rock being ".. - "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. - "attempt to download the signature as well. Otherwise, the signature ".. - "file should be already available locally in the same directory.\n".. - "You need the signer’s public key in your local keyring for this ".. - "option to work properly.") - cmd:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. - "signature file for the generated .rock file.") - util.deps_mode_option(cmd) + make.cmd_options(cmd) end --- Driver function for "make" command. -- cgit v1.2.3-55-g6feb From 0ef0c7086e26a1e656e8409e2c0a041d3584f9c5 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Thu, 1 Aug 2019 22:35:12 -0400 Subject: Remove unused --deps-mode option of test command --- src/luarocks/cmd/test.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index 99be7f40..3f752d66 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -28,7 +28,6 @@ to separate LuaRocks arguments from test suite arguments.]], cmd:option("--test-type", "Specify the test suite type manually if it was ".. "not specified in the rockspec and it could not be auto-detected.") :argname("") - util.deps_mode_option(cmd) end function cmd_test.command(args) -- cgit v1.2.3-55-g6feb From f82f796ef6838336d87e5f544b4fd82fd3117194 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Thu, 1 Aug 2019 23:51:53 -0400 Subject: Add some missing descriptions --- src/luarocks/admin/cmd/make_manifest.lua | 2 +- src/luarocks/cmd.lua | 5 +++-- src/luarocks/cmd/doc.lua | 2 +- src/luarocks/cmd/install.lua | 4 ++++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index 8eb673f5..0233682d 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -20,7 +20,7 @@ function make_manifest.add_to_parser(parser) cmd:flag("--local-tree", "If given, do not write versioned versions of the manifest file.\n".. "Use this when rebuilding the manifest of a local rocks tree.") - cmd:option("--deps-mode"):hidden(true) -- TODO: Description? + util.deps_mode_option(cmd) end --- Driver function for "make_manifest" command. diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 0d249421..26780eed 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -395,13 +395,14 @@ Enabling completion for Fish: :argname("") parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") :argname("") - parser:option("--namespace"):hidden(true) -- TODO: Description + parser:option("--namespace"):description("Specify the rocks server namespace to use.") parser:option("--lua-dir", "Which Lua installation to use.") :argname("") parser:option("--lua-version", "Which Lua version to use.") :argname("") parser:option("--tree", "Which tree to operate on.") - parser:option("--project-tree"):hidden(true) -- TODO: Description? + parser:option("--project-tree"):description("") -- TODO + :argname("") parser:flag("--local", "Use the tree in the user's home directory.\n".. "To enable it, see '"..program.." help path'.") parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index a732795d..3f6b6995 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -27,7 +27,7 @@ function doc.add_to_parser(parser) cmd:flag("--home", "Open the home page of project.") cmd:flag("--list", "List documentation files only.") - cmd:flag("--porcelain"):hidden(true) -- TODO: Description? + cmd:flag("--porcelain"):description("Produce machine-friendly output.") end local function show_homepage(homepage, name, version) diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index 6b308e0f..f2874cb1 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -41,6 +41,10 @@ function install.add_to_parser(parser) "You need the signer’s public key in your local keyring for this ".. "option to work properly.") util.deps_mode_option(cmd) + -- luarocks build options + parser:flag("--pack-binary-rock"):hidden(true) + parser:flag("--branch"):hidden(true) + parser:flag("--sign"):hidden(true) end install.opts = util.opts_table("install.opts", { -- cgit v1.2.3-55-g6feb From cdda7a8b924fd73682183ee8b29215e703bbb52f Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 2 Aug 2019 00:59:52 -0400 Subject: Fix epilog not showing with `luarocks help` Argparse will print the help when we call :parse(), so the epilog has to be set at that time. We also want to show an up to date config text when using `luarocks`, so update the epilog then. --- src/luarocks/cmd.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 26780eed..0bbb9715 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -338,10 +338,17 @@ local function get_config_text(cfg) end local function get_parser(description, cmd_modules) + local epilog = [[ +Variables: + Variables from the "variables" table of the configuration file can be + overridden with VAR=VALUE assignments. + +]]..get_config_text(cfg) + local basename = dir.base_name(program) local parser = argparse( basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. - program.." - "..description) + program.." - "..description, epilog) :help_max_width(80) :add_help("--help") :add_help_command() @@ -557,14 +564,15 @@ function cmd.run_command(description, commands, external_namespace, ...) cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") end - parser:epilog([[ + if not args.command then + -- Update the config text + parser:epilog([[ Variables: Variables from the "variables" table of the configuration file can be overridden with VAR=VALUE assignments. ]]..get_config_text(cfg)) - if not args.command then util.printout() util.printout(parser:get_help()) util.printout() -- cgit v1.2.3-55-g6feb From be10b503b29b3be5ced9607465fb309b1334026c Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Wed, 7 Aug 2019 14:55:58 -0400 Subject: Hide --project-tree option --- src/luarocks/cmd.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 0bbb9715..df52c92e 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -408,8 +408,6 @@ Enabling completion for Fish: parser:option("--lua-version", "Which Lua version to use.") :argname("") parser:option("--tree", "Which tree to operate on.") - parser:option("--project-tree"):description("") -- TODO - :argname("") parser:flag("--local", "Use the tree in the user's home directory.\n".. "To enable it, see '"..program.." help path'.") parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") @@ -420,6 +418,8 @@ Enabling completion for Fish: :argname("") :convert(tonumber) + -- Used internally to force the use of a particular project tree + parser:option("--project-tree"):hidden(true) -- Compatibility for old names of some options parser:option("--to"):target("tree"):hidden(true) parser:option("--from"):target("server"):hidden(true) -- cgit v1.2.3-55-g6feb From 545805531805cd3ed267296460441f321a0e6aba Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 01:01:55 -0400 Subject: Use default -h flag --- src/luarocks/admin/cmd/add.lua | 1 - src/luarocks/admin/cmd/make_manifest.lua | 1 - src/luarocks/admin/cmd/refresh_cache.lua | 1 - src/luarocks/admin/cmd/remove.lua | 1 - src/luarocks/cmd.lua | 1 - src/luarocks/cmd/build.lua | 1 - src/luarocks/cmd/config.lua | 1 - src/luarocks/cmd/doc.lua | 1 - src/luarocks/cmd/download.lua | 1 - src/luarocks/cmd/init.lua | 1 - src/luarocks/cmd/install.lua | 1 - src/luarocks/cmd/lint.lua | 1 - src/luarocks/cmd/list.lua | 1 - src/luarocks/cmd/make.lua | 1 - src/luarocks/cmd/new_version.lua | 1 - src/luarocks/cmd/pack.lua | 1 - src/luarocks/cmd/path.lua | 1 - src/luarocks/cmd/purge.lua | 1 - src/luarocks/cmd/remove.lua | 1 - src/luarocks/cmd/search.lua | 1 - src/luarocks/cmd/show.lua | 1 - src/luarocks/cmd/test.lua | 1 - src/luarocks/cmd/unpack.lua | 1 - src/luarocks/cmd/upload.lua | 1 - src/luarocks/cmd/which.lua | 1 - src/luarocks/cmd/write_rockspec.lua | 1 - 26 files changed, 26 deletions(-) diff --git a/src/luarocks/admin/cmd/add.lua b/src/luarocks/admin/cmd/add.lua index 10e6bf09..5011c680 100644 --- a/src/luarocks/admin/cmd/add.lua +++ b/src/luarocks/admin/cmd/add.lua @@ -13,7 +13,6 @@ local index = require("luarocks.admin.index") function add.add_to_parser(parser) local cmd = parser:command("add", "Add a rock or rockspec to a rocks server.", util.see_also()) - :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") :args("+") diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index 0233682d..b4f2ca5b 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -13,7 +13,6 @@ local dir = require("luarocks.dir") function make_manifest.add_to_parser(parser) local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", util.see_also()) - :add_help("--help") cmd:argument("repository", "Local repository pathname.") :args("?") diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index 042a07a7..81959953 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -8,7 +8,6 @@ local cache = require("luarocks.admin.cache") function refresh_cache.add_to_parser(parser) local cmd = parser:command("refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) - :add_help("--help") cmd:option("--from", "The server to use. If not given, the default server ".. "set in the upload_server variable from the configuration file is used instead.") diff --git a/src/luarocks/admin/cmd/remove.lua b/src/luarocks/admin/cmd/remove.lua index 74432ce9..de58f7a3 100644 --- a/src/luarocks/admin/cmd/remove.lua +++ b/src/luarocks/admin/cmd/remove.lua @@ -13,7 +13,6 @@ local index = require("luarocks.admin.index") function admin_remove.add_to_parser(parser) local cmd = parser:command("remove", "Remove a rock or rockspec from a rocks server.", util.see_also()) - :add_help("--help") cmd:argument("rock", "A local rockspec or rock file.") :args("+") diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index df52c92e..4ded7e5f 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -350,7 +350,6 @@ Variables: basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. program.." - "..description, epilog) :help_max_width(80) - :add_help("--help") :add_help_command() :add_complete_command({ help_max_width = 120, diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 428ede2a..0654b4eb 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua @@ -22,7 +22,6 @@ function cmd_build.add_to_parser(parser) local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.\n".. "If no arguments are given, behaves as luarocks make.", util.see_also()) :summary("Build/compile a rock.") - :add_help("--help") cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. "a rock to be fetched from a repository.") diff --git a/src/luarocks/cmd/config.lua b/src/luarocks/cmd/config.lua index 0af9e247..59dafdb5 100644 --- a/src/luarocks/cmd/config.lua +++ b/src/luarocks/cmd/config.lua @@ -50,7 +50,6 @@ Query information about the LuaRocks configuration. for detailed information on the LuaRocks config file format. ]])) :summary("Query information about the LuaRocks configuration.") - :add_help("--help") cmd:argument("key", "The configuration key.") :args("?") diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index 3f6b6995..cffdebab 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -19,7 +19,6 @@ function doc.add_to_parser(parser) For more information about a rock, see the 'show' command. ]])) :summary("Show documentation for an installed rock.") - :add_help("--help") cmd:argument("rock", "Name of the rock.") cmd:argument("version", "Version of the rock.") diff --git a/src/luarocks/cmd/download.lua b/src/luarocks/cmd/download.lua index 7f12a35f..5032d580 100644 --- a/src/luarocks/cmd/download.lua +++ b/src/luarocks/cmd/download.lua @@ -8,7 +8,6 @@ local download = require("luarocks.download") function cmd_download.add_to_parser(parser) local cmd = parser:command("download", "Download a specific rock file from a rocks server.", util.see_also()) - :add_help("--help") cmd:argument("name", "Name of the rock.") :args("?") diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index fe74751b..5f269e22 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -12,7 +12,6 @@ local write_rockspec = require("luarocks.cmd.write_rockspec") function init.add_to_parser(parser) local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) - :add_help("--help") cmd:argument("name", "The project name.") :args("?") diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index f2874cb1..4020918e 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua @@ -18,7 +18,6 @@ local dir = require("luarocks.dir") function install.add_to_parser(parser) local cmd = parser:command("install", "Install a rock.", util.see_also()) - :add_help("--help") cmd:argument("rock", "The name of a rock to be fetched from a repository ".. "or a filename of a locally available rock.") diff --git a/src/luarocks/cmd/lint.lua b/src/luarocks/cmd/lint.lua index 2af19392..20c842ff 100644 --- a/src/luarocks/cmd/lint.lua +++ b/src/luarocks/cmd/lint.lua @@ -12,7 +12,6 @@ function lint.add_to_parser(parser) "Returns success if the text of the rockspec is syntactically correct, else failure.", util.see_also()) :summary("Check syntax of a rockspec.") - :add_help("--help") cmd:argument("rockspec", "The rockspec to check.") end diff --git a/src/luarocks/cmd/list.lua b/src/luarocks/cmd/list.lua index 3e275a0d..cac5cd8a 100644 --- a/src/luarocks/cmd/list.lua +++ b/src/luarocks/cmd/list.lua @@ -12,7 +12,6 @@ local path = require("luarocks.path") function list.add_to_parser(parser) local cmd = parser:command("list", "List currently installed rocks.", util.see_also()) - :add_help("--help") cmd:argument("filter", "A substring of a rock name to filter by.") :args("?") diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index bc7c2c60..e04bba96 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -60,7 +60,6 @@ NB: Use `luarocks install` with the `--only-deps` flag if you want to install only dependencies of the rockspec (see `luarocks help install`). ]], util.see_also()) :summary("Compile package in current directory using a rockspec.") - :add_help("--help") cmd:argument("rockspec", "Rockspec for the rock to build.") :args("?") diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index b6951059..71d763f8 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -39,7 +39,6 @@ If a directory is not given, it defaults to the current directory. WARNING: it writes the new rockspec to the given directory, overwriting the file if it already exists.]], util.see_also()) :summary("Auto-write a rockspec for a new version of a rock.") - :add_help("--help") cmd:argument("rock", "Package name or rockspec.") :args("?") diff --git a/src/luarocks/cmd/pack.lua b/src/luarocks/cmd/pack.lua index 1f428546..fde8f875 100644 --- a/src/luarocks/cmd/pack.lua +++ b/src/luarocks/cmd/pack.lua @@ -10,7 +10,6 @@ local queries = require("luarocks.queries") function cmd_pack.add_to_parser(parser) local cmd = parser:command("pack", "Create a rock, packing sources or binaries.", util.see_also()) - :add_help("--help") cmd:argument("rock", "A rockspec file, for creating a source rock, or the ".. "name of an installed package, for creating a binary rock.") diff --git a/src/luarocks/cmd/path.lua b/src/luarocks/cmd/path.lua index bdb1d2bc..b1da4c0b 100644 --- a/src/luarocks/cmd/path.lua +++ b/src/luarocks/cmd/path.lua @@ -18,7 +18,6 @@ And on Windows: luarocks path > "%temp%\_lrp.bat" && call "%temp%\_lrp.bat" && del "%temp%\_lrp.bat"]], util.see_also()) :summary("Return the currently configured package path.") - :add_help("--help") cmd:flag("--no-bin", "Do not export the PATH variable.") cmd:flag("--append", "Appends the paths to the existing paths. Default is ".. diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index c9102876..b71baa7c 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua @@ -23,7 +23,6 @@ By default, it removes all rocks from a tree. The --tree option is mandatory: luarocks purge does not assume a default tree.]], util.see_also()) :summary("Remove all installed rocks from a tree.") - :add_help("--help") cmd:flag("--old-versions", "Keep the highest-numbered version of each ".. "rock and remove the other ones. By default it only removes old ".. diff --git a/src/luarocks/cmd/remove.lua b/src/luarocks/cmd/remove.lua index 492ea5bb..f29b0b7d 100644 --- a/src/luarocks/cmd/remove.lua +++ b/src/luarocks/cmd/remove.lua @@ -23,7 +23,6 @@ Will only perform the removal if it does not break dependencies. To override this check and force the removal, use --force or --force-fast.]], util.see_also()) :summary("Uninstall a rock.") - :add_help("--help") cmd:argument("rock", "Name of the rock to be uninstalled.") cmd:argument("version", "Version of the rock to uninstall.") diff --git a/src/luarocks/cmd/search.lua b/src/luarocks/cmd/search.lua index 37ec5272..f34cf7b9 100644 --- a/src/luarocks/cmd/search.lua +++ b/src/luarocks/cmd/search.lua @@ -11,7 +11,6 @@ local results = require("luarocks.results") function cmd_search.add_to_parser(parser) local cmd = parser:command("search", "Query the LuaRocks servers.", util.see_also()) - :add_help("--help") cmd:argument("name", "Name of the rock to search for.") :args("?") diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index dd4b33d1..db7aed54 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -20,7 +20,6 @@ Show information about an installed rock. Without any flags, show all module information. With flags, return only the desired information.]], util.see_also()) :summary("Show information about an installed rock.") - :add_help("--help") cmd:argument("rock", "Name of an installed rock.") cmd:argument("version", "Rock version.") diff --git a/src/luarocks/cmd/test.lua b/src/luarocks/cmd/test.lua index 3f752d66..7a1ffda2 100644 --- a/src/luarocks/cmd/test.lua +++ b/src/luarocks/cmd/test.lua @@ -18,7 +18,6 @@ To make sure that test suite flags are not interpreted as LuaRocks flags, use -- to separate LuaRocks arguments from test suite arguments.]], util.see_also()) :summary("Run the test suite in the current directory.") - :add_help("--help") cmd:argument("rockspec", "Project rockspec.") :args("?") diff --git a/src/luarocks/cmd/unpack.lua b/src/luarocks/cmd/unpack.lua index 46a438ba..fe0535e4 100644 --- a/src/luarocks/cmd/unpack.lua +++ b/src/luarocks/cmd/unpack.lua @@ -17,7 +17,6 @@ Argument may be a rock file, or the name of a rock in a rocks server. In the latter case, the rock version may be given as a second argument.]], util.see_also()) :summary("Unpack the contents of a rock.") - :add_help("--help") cmd:argument("rock", "A rock file or the name of a rock.") cmd:argument("version", "Rock version.") diff --git a/src/luarocks/cmd/upload.lua b/src/luarocks/cmd/upload.lua index f19f1e93..6e3877ba 100644 --- a/src/luarocks/cmd/upload.lua +++ b/src/luarocks/cmd/upload.lua @@ -12,7 +12,6 @@ function upload.add_to_parser(parser) local cmd = parser:command("upload", "Pack a source rock file (.src.rock extension) ".. "and upload it and the rockspec to the public rocks repository.", util.see_also()) :summary("Upload a rockspec to the public rocks repository.") - :add_help("--help") cmd:argument("rockspec", "Rockspec for the rock to upload.") diff --git a/src/luarocks/cmd/which.lua b/src/luarocks/cmd/which.lua index 7fdc5228..9a363e85 100644 --- a/src/luarocks/cmd/which.lua +++ b/src/luarocks/cmd/which.lua @@ -14,7 +14,6 @@ function which_cmd.add_to_parser(parser) 'luarocks.loader, like "/usr/local/lua/'..cfg.lua_version..'/foo/bar.lua".', util.see_also()) :summary("Tell which file corresponds to a given module name.") - :add_help("--help") cmd:argument("modname", "Module name.") end diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 3fdc8091..4ab0e534 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -62,7 +62,6 @@ using 'dev' as a fallback default version. Note that the generated file is a _starting point_ for writing a rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) :summary("Write a template for a rockspec file.") - :add_help("--help") cmd:argument("name", "Name of the rock.") :args("?") -- cgit v1.2.3-55-g6feb From cc559584eac8c0c20037085d2fed6dd8cfb93ae4 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 01:16:57 -0400 Subject: Set option descriptions using argument --- src/luarocks/cmd.lua | 2 +- src/luarocks/cmd/doc.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 4ded7e5f..0cb4135a 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -401,7 +401,7 @@ Enabling completion for Fish: :argname("") parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") :argname("") - parser:option("--namespace"):description("Specify the rocks server namespace to use.") + parser:option("--namespace", "Specify the rocks server namespace to use.") parser:option("--lua-dir", "Which Lua installation to use.") :argname("") parser:option("--lua-version", "Which Lua version to use.") diff --git a/src/luarocks/cmd/doc.lua b/src/luarocks/cmd/doc.lua index cffdebab..4b3335d8 100644 --- a/src/luarocks/cmd/doc.lua +++ b/src/luarocks/cmd/doc.lua @@ -26,7 +26,7 @@ function doc.add_to_parser(parser) cmd:flag("--home", "Open the home page of project.") cmd:flag("--list", "List documentation files only.") - cmd:flag("--porcelain"):description("Produce machine-friendly output.") + cmd:flag("--porcelain", "Produce machine-friendly output.") end local function show_homepage(homepage, name, version) -- cgit v1.2.3-55-g6feb From 6a751c541814534015e4b8b651f71332d293ace1 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 12:43:17 -0400 Subject: Update to argparse 0.7.0 --- src/luarocks/argparse.lua | 165 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 50 deletions(-) diff --git a/src/luarocks/argparse.lua b/src/luarocks/argparse.lua index a91da957..dc6cdb0d 100644 --- a/src/luarocks/argparse.lua +++ b/src/luarocks/argparse.lua @@ -584,12 +584,17 @@ function Option:_is_vararg() return self._maxargs ~= self._minargs end -function Parser:_get_fullname() +function Parser:_get_fullname(exclude_root) local parent = self._parent + if exclude_root and not parent then + return "" + end local buf = {self._name} while parent do - table.insert(buf, 1, parent._name) + if not exclude_root or parent._parent then + table.insert(buf, 1, parent._name) + end parent = parent._parent end @@ -1234,45 +1239,54 @@ function Parser:_bash_option_args(buf, indent) end end -function Parser:_bash_get_cmd(buf) - local cmds = {} +function Parser:_bash_get_cmd(buf, indent) + if #self._commands == 0 then + return + end + + table.insert(buf, (" "):rep(indent) .. 'args=("${args[@]:1}")') + table.insert(buf, (" "):rep(indent) .. 'for arg in "${args[@]}"; do') + table.insert(buf, (" "):rep(indent + 4) .. 'case "$arg" in') + for _, command in ipairs(self._commands) do - if not command._is_help_command then - table.insert(cmds, (" "):rep(12) .. table.concat(command._aliases, "|") .. ")") - table.insert(cmds, (" "):rep(16) .. 'cmd="' .. command._name .. '"') - table.insert(cmds, (" "):rep(16) .. "break") - table.insert(cmds, (" "):rep(16) .. ";;") + table.insert(buf, (" "):rep(indent + 8) .. table.concat(command._aliases, "|") .. ")") + if self._parent then + table.insert(buf, (" "):rep(indent + 12) .. 'cmd="$cmd ' .. command._name .. '"') + else + table.insert(buf, (" "):rep(indent + 12) .. 'cmd="' .. command._name .. '"') end + table.insert(buf, (" "):rep(indent + 12) .. 'opts="$opts ' .. command:_get_options() .. '"') + command:_bash_get_cmd(buf, indent + 12) + table.insert(buf, (" "):rep(indent + 12) .. "break") + table.insert(buf, (" "):rep(indent + 12) .. ";;") end - if #cmds > 0 then - table.insert(buf, (" "):rep(4) .. "for arg in ${COMP_WORDS[@]:1}; do") - table.insert(buf, (" "):rep(8) .. 'case "$arg" in') - table.insert(buf, table.concat(cmds, "\n")) - table.insert(buf, (" "):rep(8) .. "esac") - table.insert(buf, (" "):rep(4) .. "done\n") - end + table.insert(buf, (" "):rep(indent + 4) .. "esac") + table.insert(buf, (" "):rep(indent) .. "done") end function Parser:_bash_cmd_completions(buf) - local subcmds = {} - for _, command in ipairs(self._commands) do - if #command._options > 0 and not command._is_help_command then - table.insert(subcmds, (" "):rep(8) .. command._name .. ")") - command:_bash_option_args(subcmds, 12) - table.insert(subcmds, (" "):rep(12) .. 'opts="$opts ' .. command:_get_options() .. '"') - table.insert(subcmds, (" "):rep(12) .. ";;") - end + local cmd_buf = {} + if self._parent then + self:_bash_option_args(cmd_buf, 12) + end + if #self._commands > 0 then + table.insert(cmd_buf, (" "):rep(12) .. 'COMPREPLY=($(compgen -W "' .. self:_get_commands() .. '" -- "$cur"))') + elseif self._is_help_command then + table.insert(cmd_buf, (" "):rep(12) + .. 'COMPREPLY=($(compgen -W "' + .. self._parent:_get_commands() + .. '" -- "$cur"))') + end + if #cmd_buf > 0 then + table.insert(buf, (" "):rep(8) .. "'" .. self:_get_fullname(true) .. "')") + table.insert(buf, table.concat(cmd_buf, "\n")) + table.insert(buf, (" "):rep(12) .. ";;") end - table.insert(buf, (" "):rep(4) .. 'case "$cmd" in') - table.insert(buf, (" "):rep(8) .. self._basename .. ")") - table.insert(buf, (" "):rep(12) .. 'COMPREPLY=($(compgen -W "' .. self:_get_commands() .. '" -- "$cur"))') - table.insert(buf, (" "):rep(12) .. ";;") - if #subcmds > 0 then - table.insert(buf, table.concat(subcmds, "\n")) + for _, command in ipairs(self._commands) do + command:_bash_cmd_completions(buf) end - table.insert(buf, (" "):rep(4) .. "esac\n") end function Parser:get_bash_complete() @@ -1281,17 +1295,20 @@ function Parser:get_bash_complete() local buf = {([[ _%s() { local IFS=$' \t\n' - local cur prev cmd opts arg + local args cur prev cmd opts arg + args=("${COMP_WORDS[@]}") cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - cmd="%s" opts="%s" -]]):format(self._basename, self._basename, self:_get_options())} +]]):format(self._basename, self:_get_options())} self:_bash_option_args(buf, 4) - self:_bash_get_cmd(buf) + self:_bash_get_cmd(buf, 4) if #self._commands > 0 then + table.insert(buf, "") + table.insert(buf, (" "):rep(4) .. 'case "$cmd" in') self:_bash_cmd_completions(buf) + table.insert(buf, (" "):rep(4) .. "esac\n") end table.insert(buf, ([=[ @@ -1441,23 +1458,48 @@ local function fish_escape(string) return string:gsub("[\\']", "\\%0") end -function Parser:_fish_complete_help(buf, prefix) +function Parser:_fish_get_cmd(buf, indent) + if #self._commands == 0 then + return + end + + table.insert(buf, (" "):rep(indent) .. "set -e cmdline[1]") + table.insert(buf, (" "):rep(indent) .. "for arg in $cmdline") + table.insert(buf, (" "):rep(indent + 4) .. "switch $arg") + + for _, command in ipairs(self._commands) do + table.insert(buf, (" "):rep(indent + 8) .. "case " .. table.concat(command._aliases, " ")) + table.insert(buf, (" "):rep(indent + 12) .. "set cmd $cmd " .. command._name) + command:_fish_get_cmd(buf, indent + 12) + table.insert(buf, (" "):rep(indent + 12) .. "break") + end + + table.insert(buf, (" "):rep(indent + 4) .. "end") + table.insert(buf, (" "):rep(indent) .. "end") +end + +function Parser:_fish_complete_help(buf, basename) + local prefix = "complete -c " .. basename table.insert(buf, "") for _, command in ipairs(self._commands) do - for _, alias in ipairs(command._aliases) do - local line = ("%s -n '__fish_use_subcommand' -xa '%s'"):format(prefix, alias) - if command._description then - line = ("%s -d '%s'"):format(line, fish_escape(get_short_description(command))) - end - table.insert(buf, line) + local aliases = table.concat(command._aliases, " ") + local line + if self._parent then + line = ("%s -n '__fish_%s_using_command %s' -xa '%s'") + :format(prefix, basename, self:_get_fullname(true), aliases) + else + line = ("%s -n '__fish_%s_using_command' -xa '%s'"):format(prefix, basename, aliases) end - + if command._description then + line = ("%s -d '%s'"):format(line, fish_escape(get_short_description(command))) + end + table.insert(buf, line) end if self._is_help_command then - local line = ("%s -n '__fish_seen_subcommand_from %s' -xa '%s'") - :format(prefix, table.concat(self._aliases, " "), self._parent:_get_commands()) + local line = ("%s -n '__fish_%s_using_command %s' -xa '%s'") + :format(prefix, basename, self:_get_fullname(true), self._parent:_get_commands()) table.insert(buf, line) end @@ -1465,7 +1507,7 @@ function Parser:_fish_complete_help(buf, prefix) local parts = {prefix} if self._parent then - table.insert(parts, "-n '__fish_seen_subcommand_from " .. table.concat(self._aliases, " ") .. "'") + table.insert(parts, "-n '__fish_" .. basename .. "_seen_command " .. self:_get_fullname(true) .. "'") end for _, alias in ipairs(option._aliases) do @@ -1490,7 +1532,7 @@ function Parser:_fish_complete_help(buf, prefix) end for _, command in ipairs(self._commands) do - command:_fish_complete_help(buf, prefix) + command:_fish_complete_help(buf, basename) end end @@ -1498,8 +1540,31 @@ function Parser:get_fish_complete() self._basename = base_name(self._name) assert(self:_is_shell_safe()) local buf = {} - local prefix = "complete -c " .. self._basename - self:_fish_complete_help(buf, prefix) + + if #self._commands > 0 then + table.insert(buf, ([[ +function __fish_%s_print_command + set -l cmdline (commandline -poc) + set -l cmd]]):format(self._basename)) + self:_fish_get_cmd(buf, 4) + table.insert(buf, ([[ + echo "$cmd" +end + +function __fish_%s_using_command + test (__fish_%s_print_command) = "$argv" + and return 0 + or return 1 +end + +function __fish_%s_seen_command + string match -q "$argv*" (__fish_%s_print_command) + and return 0 + or return 1 +end]]):format(self._basename, self._basename, self._basename, self._basename)) + end + + self:_fish_complete_help(buf, self._basename) return table.concat(buf, "\n") .. "\n" end @@ -2004,7 +2069,7 @@ end local argparse = {} -argparse.version = "0.6.0" +argparse.version = "0.7.0" setmetatable(argparse, {__call = function(_, ...) return Parser(default_cmdline[0]):add_help(true)(...) -- cgit v1.2.3-55-g6feb From 4a4299763ece819ce306ed2903c5ac90fd7ecc11 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 12:52:13 -0400 Subject: Allow using - or _ in commands --- src/luarocks/admin/cmd/make_manifest.lua | 1 + src/luarocks/admin/cmd/refresh_cache.lua | 1 + src/luarocks/cmd/new_version.lua | 2 ++ src/luarocks/cmd/write_rockspec.lua | 2 ++ 4 files changed, 6 insertions(+) diff --git a/src/luarocks/admin/cmd/make_manifest.lua b/src/luarocks/admin/cmd/make_manifest.lua index b4f2ca5b..ab940f9e 100644 --- a/src/luarocks/admin/cmd/make_manifest.lua +++ b/src/luarocks/admin/cmd/make_manifest.lua @@ -13,6 +13,7 @@ local dir = require("luarocks.dir") function make_manifest.add_to_parser(parser) local cmd = parser:command("make_manifest", "Compile a manifest file for a repository.", util.see_also()) + parser:command("make-manifest"):hidden(true):action(function(args) args.command = "make_manifest" end) cmd:argument("repository", "Local repository pathname.") :args("?") diff --git a/src/luarocks/admin/cmd/refresh_cache.lua b/src/luarocks/admin/cmd/refresh_cache.lua index 81959953..40c9ff09 100644 --- a/src/luarocks/admin/cmd/refresh_cache.lua +++ b/src/luarocks/admin/cmd/refresh_cache.lua @@ -8,6 +8,7 @@ local cache = require("luarocks.admin.cache") function refresh_cache.add_to_parser(parser) local cmd = parser:command("refresh_cache", "Refresh local cache of a remote rocks server.", util.see_also()) + parser:command("refresh-cache"):hidden(true):action(function(args) args.command = "refresh_cache" end) cmd:option("--from", "The server to use. If not given, the default server ".. "set in the upload_server variable from the configuration file is used instead.") diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 71d763f8..1aecec95 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -40,6 +40,8 @@ WARNING: it writes the new rockspec to the given directory, overwriting the file if it already exists.]], util.see_also()) :summary("Auto-write a rockspec for a new version of a rock.") + parser:command("new-version"):hidden(true):action(function(args) args.command = "new_version" end) + cmd:argument("rock", "Package name or rockspec.") :args("?") cmd:argument("new_version", "New version of the rock.") diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 4ab0e534..ee825ce4 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -63,6 +63,8 @@ Note that the generated file is a _starting point_ for writing a rockspec, and is not guaranteed to be complete or correct. ]], util.see_also()) :summary("Write a template for a rockspec file.") + parser:command("write-rockspec"):hidden(true):action(function(args) args.command = "write_rockspec" end) + cmd:argument("name", "Name of the rock.") :args("?") cmd:argument("version", "Rock version.") -- cgit v1.2.3-55-g6feb From 209e95008c4069e51f55790fbc2fc7961fca0426 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 13:08:13 -0400 Subject: Simplify deps.get_deps_mode --- src/luarocks/deps.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 7bce3dec..cb85764e 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -571,11 +571,7 @@ function deps.check_lua_libdir(vars) end function deps.get_deps_mode(args) - if args.deps_mode then - return args.deps_mode - else - return cfg.deps_mode - end + return args.deps_mode or cfg.deps_mode end return deps -- cgit v1.2.3-55-g6feb From 31dbd1d37ed8ccc9a7da706a59ab918833e26917 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 17:44:06 -0400 Subject: Revert variable rename in cmd/make.lua --- src/luarocks/cmd/make.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index e04bba96..ef99218a 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -71,19 +71,19 @@ end -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an -- error message otherwise. exitcode is optionally returned. function make.command(args) - local rockspec = args.rockspec - if not rockspec then + local rockspec_filename = args.rockspec + if not rockspec_filename then local err - rockspec, err = util.get_default_rockspec() - if not rockspec then + rockspec_filename, err = util.get_default_rockspec() + if not rockspec_filename then return nil, err end end - if not rockspec:match("rockspec$") then + if not rockspec_filename:match("rockspec$") then return nil, "Invalid argument: 'make' takes a rockspec as a parameter. "..util.see_help("make") end - local rockspec, err, errcode = fetch.load_rockspec(rockspec) + local rockspec, err, errcode = fetch.load_rockspec(rockspec_filename) if not rockspec then return nil, err end -- cgit v1.2.3-55-g6feb From 9fefe1dd0692e842693d6aea5c06396e0b25ee6f Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Fri, 16 Aug 2019 19:44:28 -0400 Subject: writer.make_namespace_file: name has no namespace --- src/luarocks/manif/writer.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/luarocks/manif/writer.lua b/src/luarocks/manif/writer.lua index 23ba2532..d6b70a5f 100644 --- a/src/luarocks/manif/writer.lua +++ b/src/luarocks/manif/writer.lua @@ -279,7 +279,7 @@ function writer.make_rock_manifest(name, version) end -- Writes a 'rock_namespace' file in a locally installed rock directory. --- @param name string: the rock name (may be in user/rock format) +-- @param name string: the rock name, without a namespace -- @param version string: the rock version -- @param namespace string?: the namespace -- @return true if successful (or unnecessary, if there is no namespace), @@ -288,8 +288,6 @@ function writer.make_namespace_file(name, version, namespace) assert(type(name) == "string" and not name:match("/")) assert(type(version) == "string") assert(type(namespace) == "string" or not namespace) - name = util.adjust_name_and_namespace(name, { namespace = namespace }) - name, namespace = util.split_namespace(name) if not namespace then return true end -- cgit v1.2.3-55-g6feb From 5f35b21824fa4ec4670e5b98020533bedc147a82 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Sat, 17 Aug 2019 01:29:07 -0400 Subject: Show config text only when run with no arguments --- src/luarocks/cmd.lua | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 0cb4135a..f424f488 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua @@ -304,6 +304,13 @@ do end end +local variables_help = [[ +Variables: + Variables from the "variables" table of the configuration file can be + overridden with VAR=VALUE assignments. + +]] + local function get_status(status) return status and "ok" or "not found" end @@ -338,21 +345,15 @@ local function get_config_text(cfg) end local function get_parser(description, cmd_modules) - local epilog = [[ -Variables: - Variables from the "variables" table of the configuration file can be - overridden with VAR=VALUE assignments. - -]]..get_config_text(cfg) - local basename = dir.base_name(program) local parser = argparse( basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. - program.." - "..description, epilog) + program.." - "..description, variables_help.."Run '"..basename.. + "' without any arguments to see the configuration.") :help_max_width(80) :add_help_command() :add_complete_command({ - help_max_width = 120, + help_max_width = 100, summary = "Output a shell completion script.", description = [[ Output a shell completion script. @@ -564,14 +565,7 @@ function cmd.run_command(description, commands, external_namespace, ...) end if not args.command then - -- Update the config text - parser:epilog([[ -Variables: - Variables from the "variables" table of the configuration file can be - overridden with VAR=VALUE assignments. - -]]..get_config_text(cfg)) - + parser:epilog(variables_help..get_config_text(cfg)) util.printout() util.printout(parser:get_help()) util.printout() -- cgit v1.2.3-55-g6feb From 8e602d751e79c97eb664682b5b2441495d9ad974 Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Thu, 22 Aug 2019 14:41:36 -0400 Subject: Rewrap some help messages to 80 cols --- src/luarocks/cmd/make.lua | 17 ++++++++--------- src/luarocks/cmd/new_version.lua | 34 ++++++++++++++++------------------ 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index ef99218a..480ec48d 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua @@ -43,18 +43,17 @@ end function make.add_to_parser(parser) local cmd = parser:command("make", [[ -Builds sources in the current directory, but unlike "build", -it does not fetch sources, etc., assuming everything is -available in the current directory. If no argument is given, -it looks for a rockspec in the current directory and in "rockspec/" -and "rockspecs/" subdirectories, picking the rockspec with newest version -or without version name. If rockspecs for different rocks are found -or there are several rockspecs without version, you must specify which to use, +Builds sources in the current directory, but unlike "build", it does not fetch +sources, etc., assuming everything is available in the current directory. If no +argument is given, it looks for a rockspec in the current directory and in +"rockspec/" and "rockspecs/" subdirectories, picking the rockspec with newest +version or without version name. If rockspecs for different rocks are found or +there are several rockspecs without version, you must specify which to use, through the command-line. This command is useful as a tool for debugging rockspecs. -To install rocks, you'll normally want to use the "install" and -"build" commands. See the help on those for details. +To install rocks, you'll normally want to use the "install" and "build" +commands. See the help on those for details. NB: Use `luarocks install` with the `--only-deps` flag if you want to install only dependencies of the rockspec (see `luarocks help install`). diff --git a/src/luarocks/cmd/new_version.lua b/src/luarocks/cmd/new_version.lua index 1aecec95..62fb08f6 100644 --- a/src/luarocks/cmd/new_version.lua +++ b/src/luarocks/cmd/new_version.lua @@ -13,31 +13,29 @@ local type_rockspec = require("luarocks.type.rockspec") function new_version.add_to_parser(parser) local cmd = parser:command("new_version", [[ -This is a utility function that writes a new rockspec, updating data -from a previous one. +This is a utility function that writes a new rockspec, updating data from a +previous one. -If a package name is given, it downloads the latest rockspec from the -default server. If a rockspec is given, it uses it instead. If no argument -is given, it looks for a rockspec same way 'luarocks make' does. +If a package name is given, it downloads the latest rockspec from the default +server. If a rockspec is given, it uses it instead. If no argument is given, it +looks for a rockspec same way 'luarocks make' does. -If the version number is not given and tag is passed using --tag, -it is used as the version, with 'v' removed from beginning. -Otherwise, it only increments the revision number of the given -(or downloaded) rockspec. +If the version number is not given and tag is passed using --tag, it is used as +the version, with 'v' removed from beginning. Otherwise, it only increments the +revision number of the given (or downloaded) rockspec. -If a URL is given, it replaces the one from the old rockspec with the -given URL. If a URL is not given and a new version is given, it tries -to guess the new URL by replacing occurrences of the version number -in the URL or tag. It also tries to download the new URL to determine -the new MD5 checksum. +If a URL is given, it replaces the one from the old rockspec with the given URL. +If a URL is not given and a new version is given, it tries to guess the new URL +by replacing occurrences of the version number in the URL or tag. It also tries +to download the new URL to determine the new MD5 checksum. -If a tag is given, it replaces the one from the old rockspec. If there is -an old tag but no new one passed, it is guessed in the same way URL is. +If a tag is given, it replaces the one from the old rockspec. If there is an old +tag but no new one passed, it is guessed in the same way URL is. If a directory is not given, it defaults to the current directory. -WARNING: it writes the new rockspec to the given directory, -overwriting the file if it already exists.]], util.see_also()) +WARNING: it writes the new rockspec to the given directory, overwriting the file +if it already exists.]], util.see_also()) :summary("Auto-write a rockspec for a new version of a rock.") parser:command("new-version"):hidden(true):action(function(args) args.command = "new_version" end) -- cgit v1.2.3-55-g6feb