diff options
author | Paul Ouellette <oue.paul18@gmail.com> | 2019-06-12 16:03:43 -0400 |
---|---|---|
committer | Paul Ouellette <oue.paul18@gmail.com> | 2019-07-29 17:07:39 -0400 |
commit | e92c37b6e3b30268033eaf2ad634998340c0fa3e (patch) | |
tree | f4762179e74c286dd03d5f8298ff735eed879e8d | |
parent | 1d3bb56b309ce0463249852f901147157f34adfa (diff) | |
download | luarocks-e92c37b6e3b30268033eaf2ad634998340c0fa3e.tar.gz luarocks-e92c37b6e3b30268033eaf2ad634998340c0fa3e.tar.bz2 luarocks-e92c37b6e3b30268033eaf2ad634998340c0fa3e.zip |
Use argparse for command line argument parsing
Supports main options and init and lint commands
-rwxr-xr-x | src/bin/luarocks | 2 | ||||
-rwxr-xr-x | src/bin/luarocks-admin | 2 | ||||
-rw-r--r-- | src/luarocks/cmd.lua | 250 | ||||
-rw-r--r-- | src/luarocks/cmd/help.lua | 139 | ||||
-rw-r--r-- | src/luarocks/cmd/init.lua | 52 | ||||
-rw-r--r-- | src/luarocks/cmd/lint.lua | 32 | ||||
-rw-r--r-- | src/luarocks/util.lua | 164 |
7 files changed, 209 insertions, 432 deletions
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 = { | |||
33 | test = "luarocks.cmd.test", | 33 | test = "luarocks.cmd.test", |
34 | } | 34 | } |
35 | 35 | ||
36 | cmd.run_command(description, commands, "luarocks.cmd.external", ...) | 36 | 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 = { | |||
16 | refresh_cache = "luarocks.admin.cmd.refresh_cache", | 16 | refresh_cache = "luarocks.admin.cmd.refresh_cache", |
17 | } | 17 | } |
18 | 18 | ||
19 | cmd.run_command(description, commands, "luarocks.admin.cmd.external", ...) | 19 | 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 @@ | |||
2 | --- Functions for command-line scripts. | 2 | --- Functions for command-line scripts. |
3 | local cmd = {} | 3 | local cmd = {} |
4 | 4 | ||
5 | local unpack = unpack or table.unpack | ||
6 | |||
7 | local loader = require("luarocks.loader") | 5 | local loader = require("luarocks.loader") |
8 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
9 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
10 | local deps = require("luarocks.deps") | ||
11 | local cfg = require("luarocks.core.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
12 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
13 | local fun = require("luarocks.fun") | 10 | local fun = require("luarocks.fun") |
14 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
12 | local argparse = require("argparse") | ||
15 | 13 | ||
16 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") | 14 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") |
17 | if not hc_ok then | 15 | if not hc_ok then |
@@ -91,8 +89,8 @@ do | |||
91 | else | 89 | else |
92 | replace_tree(flags, cfg.home_tree) | 90 | replace_tree(flags, cfg.home_tree) |
93 | end | 91 | end |
94 | elseif flags["project-tree"] then | 92 | elseif flags["project_tree"] then |
95 | local tree = flags["project-tree"] | 93 | local tree = flags["project_tree"] |
96 | table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) | 94 | table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) |
97 | loader.load_rocks_trees() | 95 | loader.load_rocks_trees() |
98 | path.use_tree(tree) | 96 | path.use_tree(tree) |
@@ -131,14 +129,14 @@ local function process_server_flags(flags) | |||
131 | cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) | 129 | cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) |
132 | end | 130 | end |
133 | 131 | ||
134 | if flags["only-server"] then | 132 | if flags["only_server"] then |
135 | if flags["dev"] then | 133 | if flags["dev"] then |
136 | return nil, "--only-server cannot be used with --dev" | 134 | return nil, "--only-server cannot be used with --dev" |
137 | end | 135 | end |
138 | if flags["server"] then | 136 | if flags["server"] then |
139 | return nil, "--only-server cannot be used with --server" | 137 | return nil, "--only-server cannot be used with --server" |
140 | end | 138 | end |
141 | cfg.rocks_servers = { flags["only-server"] } | 139 | cfg.rocks_servers = { flags["only_server"] } |
142 | end | 140 | end |
143 | 141 | ||
144 | return true | 142 | return true |
@@ -231,12 +229,12 @@ do | |||
231 | end | 229 | end |
232 | 230 | ||
233 | local function detect_lua_via_flags(flags, project_dir) | 231 | local function detect_lua_via_flags(flags, project_dir) |
234 | local lua_version = flags["lua-version"] | 232 | local lua_version = flags["lua_version"] |
235 | or find_default_lua_version(flags, project_dir) | 233 | or find_default_lua_version(flags, project_dir) |
236 | or (project_dir and find_version_from_config(project_dir)) | 234 | or (project_dir and find_version_from_config(project_dir)) |
237 | 235 | ||
238 | if flags["lua-dir"] then | 236 | if flags["lua_dir"] then |
239 | local detected, err = util.find_lua(flags["lua-dir"], lua_version) | 237 | local detected, err = util.find_lua(flags["lua_dir"], lua_version) |
240 | if not detected then | 238 | if not detected then |
241 | die(err) | 239 | die(err) |
242 | end | 240 | end |
@@ -265,13 +263,13 @@ do | |||
265 | end | 263 | end |
266 | 264 | ||
267 | detect_config_via_flags = function(flags) | 265 | detect_config_via_flags = function(flags) |
268 | local project_dir, given = find_project_dir(flags["project-tree"]) | 266 | local project_dir, given = find_project_dir(flags["project_tree"]) |
269 | local detected = detect_lua_via_flags(flags, project_dir) | 267 | local detected = detect_lua_via_flags(flags, project_dir) |
270 | if flags["lua-version"] then | 268 | if flags["lua_version"] then |
271 | detected.given_lua_version = flags["lua-version"] | 269 | detected.given_lua_version = flags["lua_version"] |
272 | end | 270 | end |
273 | if flags["lua-dir"] then | 271 | if flags["lua_dir"] then |
274 | detected.given_lua_dir = flags["lua-dir"] | 272 | detected.given_lua_dir = flags["lua_dir"] |
275 | end | 273 | end |
276 | if given then | 274 | if given then |
277 | detected.given_project_dir = project_dir | 275 | detected.given_project_dir = project_dir |
@@ -306,6 +304,103 @@ do | |||
306 | end | 304 | end |
307 | end | 305 | end |
308 | 306 | ||
307 | local function get_status(status) | ||
308 | return status and "ok" or "not found" | ||
309 | end | ||
310 | |||
311 | local function get_config_text() | ||
312 | local buf = "Configuration:\n Lua version: "..cfg.lua_version.."\n" | ||
313 | if cfg.luajit_version then | ||
314 | buf = buf.." LuaJIT version: "..cfg.luajit_version.."\n" | ||
315 | end | ||
316 | buf = buf.."\n Configuration files:\n" | ||
317 | local conf = cfg.config_files | ||
318 | buf = buf.." System : "..fs.absolute_name(conf.system.file).." ("..get_status(conf.system.found)..")\n" | ||
319 | if conf.user.file then | ||
320 | buf = buf.." User : "..fs.absolute_name(conf.user.file).." ("..get_status(conf.user.found)..")\n" | ||
321 | else | ||
322 | buf = buf.." User : disabled in this LuaRocks installation.\n" | ||
323 | end | ||
324 | if conf.project then | ||
325 | buf = buf.." Project : "..fs.absolute_name(conf.project.file).." ("..get_status(conf.project.found)..")\n" | ||
326 | end | ||
327 | buf = buf.."\n Rocks trees in use: \n" | ||
328 | for _, tree in ipairs(cfg.rocks_trees) do | ||
329 | if type(tree) == "string" then | ||
330 | buf = buf.." "..fs.absolute_name(tree) | ||
331 | else | ||
332 | local name = tree.name and " (\""..tree.name.."\")" or "" | ||
333 | buf = buf.." "..fs.absolute_name(tree.root)..name | ||
334 | end | ||
335 | end | ||
336 | |||
337 | return buf.."\n" | ||
338 | end | ||
339 | |||
340 | local function get_parser(program_name, description, cmd_modules) | ||
341 | local epilog = [[ | ||
342 | Variables: | ||
343 | Variables from the "variables" table of the configuration file can be | ||
344 | overridden with VAR=VALUE assignments. | ||
345 | |||
346 | ]]..get_config_text() | ||
347 | |||
348 | local parser = argparse( | ||
349 | program_name, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. | ||
350 | program.." - "..description, epilog) | ||
351 | :help_max_width(80) | ||
352 | :add_help("--help") | ||
353 | :add_help_command({add_help = false}) | ||
354 | :command_target("command") | ||
355 | :require_command(false) | ||
356 | |||
357 | parser:flag("--version", "Show version info and exit.") | ||
358 | :action(function() | ||
359 | util.printout(program.." "..cfg.program_version) | ||
360 | util.printout(description) | ||
361 | util.printout() | ||
362 | os.exit(cmd.errorcodes.OK) | ||
363 | end) | ||
364 | parser:flag("--dev", "Enable the sub-repositories in rocks servers for ".. | ||
365 | "rockspecs of in-development versions.") | ||
366 | parser:option("--server", "Fetch rocks/rockspecs from this server ".. | ||
367 | "(takes priority over config file).") | ||
368 | parser:option("--only-server", "Fetch rocks/rockspecs from this server only ".. | ||
369 | "(overrides any entries in the config file).") | ||
370 | :argname("<server>") | ||
371 | parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") | ||
372 | :argname("<url>") | ||
373 | parser:option("--lua-dir", "Which Lua installation to use.") | ||
374 | :argname("<prefix>") | ||
375 | parser:option("--lua-version", "Which Lua version to use.") | ||
376 | :argname("<ver>") | ||
377 | parser:option("--tree", "Which tree to operate on.") | ||
378 | parser:option("--project-tree"):hidden(true) -- TODO: Description? | ||
379 | parser:flag("--local", "Use the tree in the user's home directory.\n".. | ||
380 | "To enable it, see '"..program.." help path'.") | ||
381 | parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") | ||
382 | parser:flag("--verbose", "Display verbose output of commands executed.") | ||
383 | parser:option("--timeout", "Timeout on network operations, in seconds.\n".. | ||
384 | "0 means no timeout (wait forever). Default is ".. | ||
385 | tostring(cfg.connection_timeout)..".") | ||
386 | :argname("<seconds>") | ||
387 | :convert(tonumber) | ||
388 | |||
389 | -- Compatibility for old names of some options | ||
390 | parser:option("--to"):target("tree"):hidden(true) | ||
391 | parser:option("--from"):target("server"):hidden(true) | ||
392 | parser:option("--only-from"):target("only_server"):hidden(true) | ||
393 | parser:option("--only-sources-from"):target("only_sources"):hidden(true) | ||
394 | |||
395 | for _, module in util.sortedpairs(cmd_modules) do | ||
396 | if module.add_to_parser then -- TODO: Remove this check. | ||
397 | module.add_to_parser(parser) | ||
398 | end | ||
399 | end | ||
400 | |||
401 | return parser | ||
402 | end | ||
403 | |||
309 | --- Main command-line processor. | 404 | --- Main command-line processor. |
310 | -- Parses input arguments and calls the appropriate driver function | 405 | -- Parses input arguments and calls the appropriate driver function |
311 | -- to execute the action requested on the command-line, forwarding | 406 | -- to execute the action requested on the command-line, forwarding |
@@ -314,11 +409,24 @@ end | |||
314 | -- @param commands table: contains the loaded modules representing commands. | 409 | -- @param commands table: contains the loaded modules representing commands. |
315 | -- @param external_namespace string: where to look for external commands. | 410 | -- @param external_namespace string: where to look for external commands. |
316 | -- @param ... string: Arguments given on the command-line. | 411 | -- @param ... string: Arguments given on the command-line. |
317 | function cmd.run_command(description, commands, external_namespace, ...) | 412 | function cmd.run_command(program_name, description, commands, external_namespace, ...) |
318 | 413 | ||
319 | check_popen() | 414 | check_popen() |
320 | 415 | ||
321 | local function process_arguments(...) | 416 | fs.init() |
417 | |||
418 | for _, module_name in ipairs(fs.modules(external_namespace)) do | ||
419 | if not commands[module_name] then | ||
420 | commands[module_name] = external_namespace.."."..module_name | ||
421 | end | ||
422 | end | ||
423 | |||
424 | local cmd_modules = {} | ||
425 | for name, module in pairs(commands) do | ||
426 | cmd_modules[name] = require(module) | ||
427 | end | ||
428 | |||
429 | local function process_cmdline_vars(...) | ||
322 | local args = {...} | 430 | local args = {...} |
323 | local cmdline_vars = {} | 431 | local cmdline_vars = {} |
324 | local last = #args | 432 | local last = #args |
@@ -340,69 +448,38 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
340 | end | 448 | end |
341 | end | 449 | end |
342 | end | 450 | end |
343 | local nonflags = { util.parse_flags(unpack(args)) } | ||
344 | local flags = table.remove(nonflags, 1) | ||
345 | if flags.ERROR then | ||
346 | die(flags.ERROR.." See --help.") | ||
347 | end | ||
348 | 451 | ||
349 | -- Compatibility for old names of some flags | 452 | return args, cmdline_vars |
350 | if flags["to"] then flags["tree"] = flags["to"] end | ||
351 | if flags["from"] then flags["server"] = flags["from"] end | ||
352 | if flags["nodeps"] then flags["deps-mode"] = "none" end | ||
353 | if flags["only-from"] then flags["only-server"] = flags["only-from"] end | ||
354 | if flags["only-sources-from"] then flags["only-sources"] = flags["only-sources-from"] end | ||
355 | |||
356 | return flags, nonflags, cmdline_vars | ||
357 | end | 453 | end |
358 | 454 | ||
359 | local flags, nonflags, cmdline_vars = process_arguments(...) | 455 | local args, cmdline_vars = process_cmdline_vars(...) |
456 | local parser = get_parser(program_name, description, cmd_modules) | ||
457 | args = parser:parse(args) | ||
360 | 458 | ||
361 | if flags["timeout"] then -- setting it in the config file will kick-in earlier in the process | 459 | if not args.command then |
362 | local timeout = tonumber(flags["timeout"]) | 460 | util.printout(parser:get_help()) |
363 | if timeout then | 461 | os.exit(cmd.errorcodes.OK) |
364 | cfg.connection_timeout = timeout | ||
365 | else | ||
366 | die "Argument error: --timeout expects a numeric argument." | ||
367 | end | ||
368 | end | 462 | end |
369 | 463 | ||
370 | local command | 464 | if args.timeout then -- setting it in the config file will kick-in earlier in the process |
371 | if flags["help"] or #nonflags == 0 then | 465 | cfg.connection_timeout = args.timeout |
372 | command = "help" | ||
373 | else | ||
374 | command = table.remove(nonflags, 1) | ||
375 | end | 466 | end |
376 | command = command:gsub("-", "_") | ||
377 | 467 | ||
378 | if command == "config" then | 468 | if args.command == "config" then |
379 | if nonflags[1] == "lua_version" and nonflags[2] then | 469 | if args.key == "lua_version" and args.value then |
380 | flags["lua-version"] = nonflags[2] | 470 | args.lua_version = args.value |
381 | elseif nonflags[1] == "lua_dir" and nonflags[2] then | 471 | elseif args.key == "lua_dir" and args.value then |
382 | flags["lua-dir"] = nonflags[2] | 472 | args.lua_dir = args.value |
383 | end | 473 | end |
384 | end | 474 | end |
385 | |||
386 | if flags["deps-mode"] and not deps.check_deps_mode_flag(flags["deps-mode"]) then | ||
387 | die("Invalid entry for --deps-mode.") | ||
388 | end | ||
389 | 475 | ||
390 | ----------------------------------------------------------------------------- | 476 | ----------------------------------------------------------------------------- |
391 | local lua_found, err = init_config(flags) | 477 | local lua_found, err = init_config(args) |
392 | if err then | 478 | if err then |
393 | die(err) | 479 | die(err) |
394 | end | 480 | end |
395 | ----------------------------------------------------------------------------- | 481 | ----------------------------------------------------------------------------- |
396 | 482 | ||
397 | if flags["version"] then | ||
398 | util.printout(program.." "..cfg.program_version) | ||
399 | util.printout(description) | ||
400 | util.printout() | ||
401 | os.exit(cmd.errorcodes.OK) | ||
402 | end | ||
403 | |||
404 | fs.init() | ||
405 | |||
406 | -- if the Lua interpreter wasn't explicitly found before cfg.init, | 483 | -- if the Lua interpreter wasn't explicitly found before cfg.init, |
407 | -- try again now. | 484 | -- try again now. |
408 | if not lua_found then | 485 | if not lua_found then |
@@ -423,13 +500,7 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
423 | cfg.project_dir = fs.absolute_name(cfg.project_dir) | 500 | cfg.project_dir = fs.absolute_name(cfg.project_dir) |
424 | end | 501 | end |
425 | 502 | ||
426 | for _, module_name in ipairs(fs.modules(external_namespace)) do | 503 | if args.verbose then |
427 | if not commands[module_name] then | ||
428 | commands[module_name] = external_namespace.."."..module_name | ||
429 | end | ||
430 | end | ||
431 | |||
432 | if flags["verbose"] then | ||
433 | cfg.verbose = true | 504 | cfg.verbose = true |
434 | fs.verbose() | 505 | fs.verbose() |
435 | end | 506 | end |
@@ -438,24 +509,22 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
438 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | 509 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") |
439 | end | 510 | end |
440 | 511 | ||
441 | ok, err = process_tree_flags(flags, cfg.project_dir) | 512 | local ok, err = process_tree_flags(args, cfg.project_dir) |
442 | if not ok then | 513 | if not ok then |
443 | die(err) | 514 | die(err) |
444 | end | 515 | end |
445 | 516 | ||
446 | ok, err = process_server_flags(flags) | 517 | ok, err = process_server_flags(args) |
447 | if not ok then | 518 | if not ok then |
448 | die(err) | 519 | die(err) |
449 | end | 520 | end |
450 | 521 | ||
451 | if flags["only-sources"] then | 522 | if args.only_sources then |
452 | cfg.only_sources_from = flags["only-sources"] | 523 | cfg.only_sources_from = args.only_sources |
453 | end | 524 | end |
454 | 525 | ||
455 | if command ~= "help" then | 526 | for k, v in pairs(cmdline_vars) do |
456 | for k, v in pairs(cmdline_vars) do | 527 | cfg.variables[k] = v |
457 | cfg.variables[k] = v | ||
458 | end | ||
459 | end | 528 | end |
460 | 529 | ||
461 | -- if running as superuser, use system cache dir | 530 | -- if running as superuser, use system cache dir |
@@ -463,22 +532,15 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
463 | cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") | 532 | cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") |
464 | end | 533 | end |
465 | 534 | ||
466 | if commands[command] then | 535 | local cmd_mod = cmd_modules[args.command] |
467 | local cmd_mod = require(commands[command]) | 536 | local call_ok, ok, err, exitcode = xpcall(function() |
468 | local call_ok, ok, err, exitcode = xpcall(function() | 537 | return cmd_mod.command(args) |
469 | if command == "help" then | 538 | end, error_handler) |
470 | return cmd_mod.command(description, commands, unpack(nonflags)) | 539 | |
471 | else | 540 | if not call_ok then |
472 | return cmd_mod.command(flags, unpack(nonflags)) | 541 | die(ok, cmd.errorcodes.CRASH) |
473 | end | 542 | elseif not ok then |
474 | end, error_handler) | 543 | die(err, exitcode) |
475 | if not call_ok then | ||
476 | die(ok, cmd.errorcodes.CRASH) | ||
477 | elseif not ok then | ||
478 | die(err, exitcode) | ||
479 | end | ||
480 | else | ||
481 | die("Unknown command: "..command) | ||
482 | end | 544 | end |
483 | util.run_scheduled_functions() | 545 | util.run_scheduled_functions() |
484 | end | 546 | 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 @@ | |||
1 | |||
2 | --- Module implementing the LuaRocks "help" command. | ||
3 | -- This is a generic help display module, which | ||
4 | -- uses a global table called "commands" to find commands | ||
5 | -- to show help for; each command should be represented by a | ||
6 | -- table containing "help" and "help_summary" fields. | ||
7 | local help = {} | ||
8 | |||
9 | local util = require("luarocks.util") | ||
10 | local cfg = require("luarocks.core.cfg") | ||
11 | local dir = require("luarocks.dir") | ||
12 | local fs = require("luarocks.fs") | ||
13 | |||
14 | local program = util.this_program("luarocks") | ||
15 | |||
16 | help.help_summary = "Help on commands. Type '"..program.." help <command>' for more." | ||
17 | |||
18 | help.help_arguments = "[<command>]" | ||
19 | help.help = [[ | ||
20 | <command> is the command to show help for. | ||
21 | ]] | ||
22 | |||
23 | local function print_banner() | ||
24 | util.printout("\nLuaRocks "..cfg.program_version..", the Lua package manager") | ||
25 | end | ||
26 | |||
27 | local function print_section(section) | ||
28 | util.printout("\n"..section) | ||
29 | end | ||
30 | |||
31 | local function get_status(status) | ||
32 | if status then | ||
33 | return "ok" | ||
34 | else | ||
35 | return "not found" | ||
36 | end | ||
37 | end | ||
38 | |||
39 | --- Driver function for the "help" command. | ||
40 | -- @param command string or nil: command to show help for; if not | ||
41 | -- given, help summaries for all commands are shown. | ||
42 | -- @return boolean or (nil, string): true if there were no errors | ||
43 | -- or nil and an error message if an invalid command was requested. | ||
44 | function help.command(description, commands, command) | ||
45 | assert(type(description) == "string") | ||
46 | assert(type(commands) == "table") | ||
47 | |||
48 | if not command then | ||
49 | print_banner() | ||
50 | print_section("NAME") | ||
51 | util.printout("\t"..program..[[ - ]]..description) | ||
52 | print_section("SYNOPSIS") | ||
53 | util.printout("\t"..program..[[ [<flags...>] [VAR=VALUE]... <command> [<argument>] ]]) | ||
54 | print_section("GENERAL OPTIONS") | ||
55 | util.printout([[ | ||
56 | These apply to all commands, as appropriate: | ||
57 | |||
58 | --dev Enable the sub-repositories in rocks servers | ||
59 | for rockspecs of in-development versions | ||
60 | --server=<server> Fetch rocks/rockspecs from this server | ||
61 | (takes priority over config file) | ||
62 | --only-server=<server> Fetch rocks/rockspecs from this server only | ||
63 | (overrides any entries in the config file) | ||
64 | --only-sources=<url> Restrict downloads to paths matching the | ||
65 | given URL. | ||
66 | --lua-dir=<prefix> Which Lua installation to use. | ||
67 | --lua-version=<ver> Which Lua version to use. | ||
68 | --tree=<tree> Which tree to operate on. | ||
69 | --local Use the tree in the user's home directory. | ||
70 | To enable it, see ']]..program..[[ help path'. | ||
71 | --global Use the system tree when `local_by_default` is `true`. | ||
72 | --verbose Display verbose output of commands executed. | ||
73 | --timeout=<seconds> Timeout on network operations, in seconds. | ||
74 | 0 means no timeout (wait forever). | ||
75 | Default is ]]..tostring(cfg.connection_timeout)..[[.]]) | ||
76 | print_section("VARIABLES") | ||
77 | util.printout([[ | ||
78 | Variables from the "variables" table of the configuration file | ||
79 | can be overridden with VAR=VALUE assignments.]]) | ||
80 | print_section("COMMANDS") | ||
81 | for name, modname in util.sortedpairs(commands) do | ||
82 | local cmd = require(modname) | ||
83 | util.printout("", name) | ||
84 | util.printout("\t", cmd.help_summary) | ||
85 | end | ||
86 | print_section("CONFIGURATION") | ||
87 | util.printout("\tLua version: " .. cfg.lua_version) | ||
88 | local ljv = util.get_luajit_version() | ||
89 | if ljv then | ||
90 | util.printout("\tLuaJIT version: " .. ljv) | ||
91 | end | ||
92 | util.printout() | ||
93 | util.printout("\tConfiguration files:") | ||
94 | local conf = cfg.config_files | ||
95 | util.printout("\t\tSystem : ".. fs.absolute_name(conf.system.file) .. " (" .. get_status(conf.system.found) ..")") | ||
96 | if conf.user.file then | ||
97 | util.printout("\t\tUser : ".. fs.absolute_name(conf.user.file) .. " (" .. get_status(conf.user.found) ..")") | ||
98 | else | ||
99 | util.printout("\t\tUser : disabled in this LuaRocks installation.") | ||
100 | end | ||
101 | if conf.project then | ||
102 | util.printout("\t\tProject : ".. fs.absolute_name(conf.project.file) .. " (" .. get_status(conf.project.found) ..")") | ||
103 | end | ||
104 | util.printout() | ||
105 | util.printout("\tRocks trees in use: ") | ||
106 | for _, tree in ipairs(cfg.rocks_trees) do | ||
107 | if type(tree) == "string" then | ||
108 | util.printout("\t\t"..fs.absolute_name(tree)) | ||
109 | else | ||
110 | local name = tree.name and " (\""..tree.name.."\")" or "" | ||
111 | util.printout("\t\t"..fs.absolute_name(tree.root)..name) | ||
112 | end | ||
113 | end | ||
114 | util.printout() | ||
115 | else | ||
116 | command = command:gsub("-", "_") | ||
117 | local cmd = commands[command] and require(commands[command]) | ||
118 | if cmd then | ||
119 | local arguments = cmd.help_arguments or "<argument>" | ||
120 | print_banner() | ||
121 | print_section("NAME") | ||
122 | util.printout("\t"..program.." "..command.." - "..cmd.help_summary) | ||
123 | print_section("SYNOPSIS") | ||
124 | util.printout("\t"..program.." "..command.." "..arguments) | ||
125 | print_section("DESCRIPTION") | ||
126 | util.printout("",(cmd.help:gsub("\n","\n\t"):gsub("\n\t$",""))) | ||
127 | print_section("SEE ALSO") | ||
128 | if cmd.help_see_also then | ||
129 | util.printout(cmd.help_see_also) | ||
130 | end | ||
131 | util.printout("","'"..program.." help' for general options and configuration.\n") | ||
132 | else | ||
133 | return nil, "Unknown command: "..command | ||
134 | end | ||
135 | end | ||
136 | return true | ||
137 | end | ||
138 | |||
139 | 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") | |||
10 | local persist = require("luarocks.persist") | 10 | local persist = require("luarocks.persist") |
11 | local write_rockspec = require("luarocks.cmd.write_rockspec") | 11 | local write_rockspec = require("luarocks.cmd.write_rockspec") |
12 | 12 | ||
13 | init.help_summary = "Initialize a directory for a Lua project using LuaRocks." | 13 | function init.add_to_parser(parser) |
14 | init.help_arguments = "[<name> [<version>]]" | 14 | local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also()) |
15 | init.help = [[ | 15 | :add_help(false) |
16 | <name> is the project name. | 16 | |
17 | <version> is an optional project version. | 17 | cmd:argument("name", "The project name."):args("?") |
18 | 18 | cmd:argument("version", "An optional project version."):args("?") | |
19 | --reset Delete .luarocks/config-5.x.lua and ./lua | 19 | cmd:flag("--reset", "Delete .luarocks/config-5.x.lua and ./lua and generate new ones.") |
20 | and generate new ones. | 20 | |
21 | 21 | cmd:group("Options for specifying rockspec data", | |
22 | Options for specifying rockspec data: | 22 | cmd:option("--license", 'A license string, such as "MIT/X11" or "GNU GPL v3".') |
23 | 23 | :argname("<string>"), | |
24 | --license="<string>" A license string, such as "MIT/X11" or "GNU GPL v3". | 24 | cmd:option("--summary", "A short one-line description summary.") |
25 | --summary="<txt>" A short one-line description summary. | 25 | :argname("<txt>"), |
26 | --detailed="<txt>" A longer description string. | 26 | cmd:option("--detailed", "A longer description string.") |
27 | --homepage=<url> Project homepage. | 27 | :argname("<txt>"), |
28 | --lua-versions=<ver> Supported Lua versions. Accepted values are "5.1", "5.2", | 28 | cmd:option("--homepage", "Project homepage.") |
29 | "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3". | 29 | :argname("<url>"), |
30 | --rockspec-format=<ver> Rockspec format version, such as "1.0" or "1.1". | 30 | cmd:option("--lua-versions", "Supported Lua versions. Accepted values are ".. |
31 | --lib=<lib>[,<lib>] A comma-separated list of libraries that C files need to | 31 | '"5.1", "5.2", "5.3", "5.1,5.2", "5.2,5.3", or "5.1,5.2,5.3".'), |
32 | link to. | 32 | cmd:option("--rockspec-format", 'Rockspec format version, such as "1.0" or "1.1".') |
33 | ]] | 33 | :argname("<ver>"), |
34 | cmd:option("--lib", "A comma-separated list of libraries that C files need to link to.") | ||
35 | :argname("<libs>")) | ||
36 | end | ||
34 | 37 | ||
35 | local function write_gitignore(entries) | 38 | local function write_gitignore(entries) |
36 | local gitignore = "" | 39 | local gitignore = "" |
@@ -53,10 +56,11 @@ end | |||
53 | 56 | ||
54 | --- Driver function for "init" command. | 57 | --- Driver function for "init" command. |
55 | -- @return boolean: True if succeeded, nil on errors. | 58 | -- @return boolean: True if succeeded, nil on errors. |
56 | function init.command(flags, name, version) | 59 | function init.command(args) |
57 | 60 | ||
58 | local pwd = fs.current_dir() | 61 | local pwd = fs.current_dir() |
59 | 62 | ||
63 | local name = args.name | ||
60 | if not name then | 64 | if not name then |
61 | name = dir.base_name(pwd) | 65 | name = dir.base_name(pwd) |
62 | if name == "/" then | 66 | if name == "/" then |
@@ -84,7 +88,7 @@ function init.command(flags, name, version) | |||
84 | end | 88 | end |
85 | 89 | ||
86 | if not has_rockspec then | 90 | if not has_rockspec then |
87 | local ok, err = write_rockspec.command(flags, name, version or "dev", pwd) | 91 | local ok, err = write_rockspec.command(args, name, args.version or "dev", pwd) |
88 | if not ok then | 92 | if not ok then |
89 | util.printerr(err) | 93 | util.printerr(err) |
90 | end | 94 | end |
@@ -101,7 +105,7 @@ function init.command(flags, name, version) | |||
101 | fs.make_dir(".luarocks") | 105 | fs.make_dir(".luarocks") |
102 | local config_file = ".luarocks/config-" .. cfg.lua_version .. ".lua" | 106 | local config_file = ".luarocks/config-" .. cfg.lua_version .. ".lua" |
103 | 107 | ||
104 | if flags["reset"] then | 108 | if args.reset then |
105 | fs.delete(lua_wrapper) | 109 | fs.delete(lua_wrapper) |
106 | fs.delete(config_file) | 110 | fs.delete(config_file) |
107 | end | 111 | 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") | |||
7 | local download = require("luarocks.download") | 7 | local download = require("luarocks.download") |
8 | local fetch = require("luarocks.fetch") | 8 | local fetch = require("luarocks.fetch") |
9 | 9 | ||
10 | lint.help_summary = "Check syntax of a rockspec." | 10 | function lint.add_to_parser(parser) |
11 | lint.help_arguments = "<rockspec>" | 11 | local cmd = parser:command("lint", "Check syntax of a rockspec.\n\n".. |
12 | lint.help = [[ | 12 | "Returns success if the text of the rockspec is syntactically correct, else failure.", |
13 | This is a utility function that checks the syntax of a rockspec. | 13 | util.see_also()) |
14 | 14 | :summary("Check syntax of a rockspec.") | |
15 | It returns success or failure if the text of a rockspec is | 15 | :add_help(false) |
16 | syntactically correct. | 16 | |
17 | ]] | 17 | cmd:argument("rockspec", "The rockspec to check.") |
18 | 18 | end | |
19 | function lint.command(flags, input) | 19 | |
20 | if not input then | 20 | function lint.command(args) |
21 | return nil, "Argument missing. "..util.see_help("lint") | 21 | |
22 | end | 22 | local filename = args.rockspec |
23 | 23 | if not filename:match(".rockspec$") then | |
24 | local filename = input | ||
25 | if not input:match(".rockspec$") then | ||
26 | local err | 24 | local err |
27 | filename, err = download.download("rockspec", input:lower()) | 25 | filename, err = download.download("rockspec", filename:lower()) |
28 | if not filename then | 26 | if not filename then |
29 | return nil, err | 27 | return nil, err |
30 | end | 28 | 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) | |||
77 | return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) | 77 | return (s:gsub("[?%-+*%[%].%%()$^]","%%%1")) |
78 | end | 78 | end |
79 | 79 | ||
80 | --- List of supported arguments. | ||
81 | -- Arguments that take no parameters are marked with the boolean true. | ||
82 | -- Arguments that take a parameter are marked with a descriptive string. | ||
83 | -- Arguments that may take an empty string are described in quotes, | ||
84 | -- (as in the value for --detailed="<text>"). | ||
85 | -- For all other string values, it means the parameter is mandatory. | ||
86 | local supported_flags = { | ||
87 | ["all"] = true, | ||
88 | ["api-key"] = "<key>", | ||
89 | ["append"] = true, | ||
90 | ["arch"] = "<arch>", | ||
91 | ["bin"] = true, | ||
92 | ["binary"] = true, | ||
93 | ["branch"] = "<branch-name>", | ||
94 | ["build-deps"] = true, | ||
95 | ["debug"] = true, | ||
96 | ["deps"] = true, | ||
97 | ["deps-mode"] = "<mode>", | ||
98 | ["detailed"] = "\"<text>\"", | ||
99 | ["dev"] = true, | ||
100 | ["dir"] = "<path>", | ||
101 | ["force"] = true, | ||
102 | ["force-fast"] = true, | ||
103 | ["from"] = "<server>", | ||
104 | ["global"] = true, | ||
105 | ["help"] = true, | ||
106 | ["home"] = true, | ||
107 | ["homepage"] = "\"<url>\"", | ||
108 | ["index"] = true, | ||
109 | ["issues"] = true, | ||
110 | ["json"] = true, | ||
111 | ["keep"] = true, | ||
112 | ["labels"] = true, | ||
113 | ["lib"] = "<library>", | ||
114 | ["license"] = "\"<text>\"", | ||
115 | ["list"] = true, | ||
116 | ["local"] = true, | ||
117 | ["local-tree"] = true, | ||
118 | ["lr-bin"] = true, | ||
119 | ["lr-cpath"] = true, | ||
120 | ["lr-path"] = true, | ||
121 | ["lua-dir"] = "<path>", | ||
122 | ["lua-version"] = "<vers>", | ||
123 | ["lua-versions"] = "<versions>", | ||
124 | ["lua-ver"] = true, | ||
125 | ["lua-incdir"] = true, | ||
126 | ["lua-libdir"] = true, | ||
127 | ["modules"] = true, | ||
128 | ["mversion"] = true, | ||
129 | ["namespace"] = "<namespace>", | ||
130 | ["no-bin"] = true, | ||
131 | ["no-doc"] = true, | ||
132 | ["no-refresh"] = true, | ||
133 | ["nodeps"] = true, | ||
134 | ["old-versions"] = true, | ||
135 | ["only-deps"] = true, | ||
136 | ["only-from"] = "<server>", | ||
137 | ["only-server"] = "<server>", | ||
138 | ["only-sources"] = "<url>", | ||
139 | ["only-sources-from"] = "<url>", | ||
140 | ["outdated"] = true, | ||
141 | ["output"] = "<file>", | ||
142 | ["pack-binary-rock"] = true, | ||
143 | ["porcelain"] = true, | ||
144 | ["project-tree"] = "<tree>", | ||
145 | ["quick"] = true, | ||
146 | ["reset"] = true, | ||
147 | ["rock-dir"] = true, | ||
148 | ["rock-license"] = true, | ||
149 | ["rock-namespace"] = true, | ||
150 | ["rock-tree"] = true, | ||
151 | ["rock-trees"] = true, | ||
152 | ["rockspec"] = true, | ||
153 | ["rockspec-format"] = "<ver>", | ||
154 | ["scope"] = "<system|user|project>", | ||
155 | ["server"] = "<server>", | ||
156 | ["sign"] = true, | ||
157 | ["skip-pack"] = true, | ||
158 | ["source"] = true, | ||
159 | ["summary"] = "\"<text>\"", | ||
160 | ["system-config"] = true, | ||
161 | ["tag"] = "<tag>", | ||
162 | ["test-type"] = "<type>", | ||
163 | ["temp-key"] = "<key>", | ||
164 | ["timeout"] = "<seconds>", | ||
165 | ["to"] = "<path>", | ||
166 | ["tree"] = "<path>", | ||
167 | ["unset"] = true, | ||
168 | ["user-config"] = true, | ||
169 | ["verbose"] = true, | ||
170 | ["verify"] = true, | ||
171 | ["version"] = true, | ||
172 | } | ||
173 | |||
174 | --- Extract flags from an arguments list. | ||
175 | -- Given string arguments, extract flag arguments into a flags set. | ||
176 | -- For example, given "foo", "--tux=beep", "--bla", "bar", "--baz", | ||
177 | -- it would return the following: | ||
178 | -- {["bla"] = true, ["tux"] = "beep", ["baz"] = true}, "foo", "bar". | ||
179 | function util.parse_flags(...) | ||
180 | local args = {...} | ||
181 | local flags = {} | ||
182 | local i = 1 | ||
183 | local out = {} | ||
184 | local state = "initial" | ||
185 | while i <= #args do | ||
186 | local flag = args[i]:match("^%-%-(.*)") | ||
187 | if state == "initial" and flag == "" then | ||
188 | state = "ignore_flags" | ||
189 | elseif state == "initial" and flag then | ||
190 | local var,val = flag:match("([a-z_%-]*)=(.*)") | ||
191 | if val then | ||
192 | local vartype = supported_flags[var] | ||
193 | if type(vartype) == "string" then | ||
194 | if val == "" and vartype:sub(1,1) ~= '"' then | ||
195 | return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } | ||
196 | end | ||
197 | flags[var] = val | ||
198 | else | ||
199 | if vartype then | ||
200 | return { ERROR = "Invalid argument: flag --"..var.." does not take an parameter." } | ||
201 | else | ||
202 | return { ERROR = "Invalid argument: unknown flag --"..var.."." } | ||
203 | end | ||
204 | end | ||
205 | else | ||
206 | local var = flag | ||
207 | local vartype = supported_flags[var] | ||
208 | if type(vartype) == "string" then | ||
209 | i = i + 1 | ||
210 | local val = args[i] | ||
211 | if not val then | ||
212 | return { ERROR = "Invalid argument: flag --"..var.."="..vartype.." expects a parameter." } | ||
213 | end | ||
214 | if val:match("^%-%-.*") then | ||
215 | 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..")." } | ||
216 | else | ||
217 | if val == "" and vartype:sub(1,1) ~= '"' then | ||
218 | return { ERROR = "Invalid argument: parameter to flag --"..var.."="..vartype.." cannot be empty." } | ||
219 | end | ||
220 | flags[var] = val | ||
221 | end | ||
222 | elseif vartype == true then | ||
223 | flags[var] = true | ||
224 | else | ||
225 | return { ERROR = "Invalid argument: unknown flag --"..var.."." } | ||
226 | end | ||
227 | end | ||
228 | elseif state == "ignore_flags" or (state == "initial" and not flag) then | ||
229 | table.insert(out, args[i]) | ||
230 | end | ||
231 | i = i + 1 | ||
232 | end | ||
233 | return flags, unpack(out) | ||
234 | end | ||
235 | |||
236 | local var_format_pattern = "%$%((%a[%a%d_]+)%)" | 80 | local var_format_pattern = "%$%((%a[%a%d_]+)%)" |
237 | 81 | ||
238 | -- Check if a set of needed variables are referenced | 82 | -- Check if a set of needed variables are referenced |
@@ -394,6 +238,14 @@ function util.see_help(command, program) | |||
394 | return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." | 238 | return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." |
395 | end | 239 | end |
396 | 240 | ||
241 | function util.see_also(text) | ||
242 | local see_also = "See also:\n" | ||
243 | if text then | ||
244 | see_also = see_also..text.."\n" | ||
245 | end | ||
246 | return see_also.." '"..util.this_program("luarocks").." help' for general options and configuration." | ||
247 | end | ||
248 | |||
397 | function util.announce_install(rockspec) | 249 | function util.announce_install(rockspec) |
398 | local cfg = require("luarocks.core.cfg") | 250 | local cfg = require("luarocks.core.cfg") |
399 | local path = require("luarocks.path") | 251 | local path = require("luarocks.path") |