aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Ouellette <oue.paul18@gmail.com>2019-06-12 16:03:43 -0400
committerPaul Ouellette <oue.paul18@gmail.com>2019-07-29 17:07:39 -0400
commite92c37b6e3b30268033eaf2ad634998340c0fa3e (patch)
treef4762179e74c286dd03d5f8298ff735eed879e8d
parent1d3bb56b309ce0463249852f901147157f34adfa (diff)
downloadluarocks-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-xsrc/bin/luarocks2
-rwxr-xr-xsrc/bin/luarocks-admin2
-rw-r--r--src/luarocks/cmd.lua250
-rw-r--r--src/luarocks/cmd/help.lua139
-rw-r--r--src/luarocks/cmd/init.lua52
-rw-r--r--src/luarocks/cmd/lint.lua32
-rw-r--r--src/luarocks/util.lua164
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
36cmd.run_command(description, commands, "luarocks.cmd.external", ...) 36cmd.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
19cmd.run_command(description, commands, "luarocks.admin.cmd.external", ...) 19cmd.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.
3local cmd = {} 3local cmd = {}
4 4
5local unpack = unpack or table.unpack
6
7local loader = require("luarocks.loader") 5local loader = require("luarocks.loader")
8local util = require("luarocks.util") 6local util = require("luarocks.util")
9local path = require("luarocks.path") 7local path = require("luarocks.path")
10local deps = require("luarocks.deps")
11local cfg = require("luarocks.core.cfg") 8local cfg = require("luarocks.core.cfg")
12local dir = require("luarocks.dir") 9local dir = require("luarocks.dir")
13local fun = require("luarocks.fun") 10local fun = require("luarocks.fun")
14local fs = require("luarocks.fs") 11local fs = require("luarocks.fs")
12local argparse = require("argparse")
15 13
16local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") 14local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded")
17if not hc_ok then 15if 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
307end 305end
308 306
307local function get_status(status)
308 return status and "ok" or "not found"
309end
310
311local 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"
338end
339
340local function get_parser(program_name, description, cmd_modules)
341 local epilog = [[
342Variables:
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
402end
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.
317function cmd.run_command(description, commands, external_namespace, ...) 412function 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()
484end 546end
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.
7local help = {}
8
9local util = require("luarocks.util")
10local cfg = require("luarocks.core.cfg")
11local dir = require("luarocks.dir")
12local fs = require("luarocks.fs")
13
14local program = util.this_program("luarocks")
15
16help.help_summary = "Help on commands. Type '"..program.." help <command>' for more."
17
18help.help_arguments = "[<command>]"
19help.help = [[
20<command> is the command to show help for.
21]]
22
23local function print_banner()
24 util.printout("\nLuaRocks "..cfg.program_version..", the Lua package manager")
25end
26
27local function print_section(section)
28 util.printout("\n"..section)
29end
30
31local function get_status(status)
32 if status then
33 return "ok"
34 else
35 return "not found"
36 end
37end
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.
44function 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
137end
138
139return 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")
10local persist = require("luarocks.persist") 10local persist = require("luarocks.persist")
11local write_rockspec = require("luarocks.cmd.write_rockspec") 11local write_rockspec = require("luarocks.cmd.write_rockspec")
12 12
13init.help_summary = "Initialize a directory for a Lua project using LuaRocks." 13function init.add_to_parser(parser)
14init.help_arguments = "[<name> [<version>]]" 14 local cmd = parser:command("init", "Initialize a directory for a Lua project using LuaRocks.", util.see_also())
15init.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",
22Options 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>"))
36end
34 37
35local function write_gitignore(entries) 38local 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.
56function init.command(flags, name, version) 59function 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")
7local download = require("luarocks.download") 7local download = require("luarocks.download")
8local fetch = require("luarocks.fetch") 8local fetch = require("luarocks.fetch")
9 9
10lint.help_summary = "Check syntax of a rockspec." 10function lint.add_to_parser(parser)
11lint.help_arguments = "<rockspec>" 11 local cmd = parser:command("lint", "Check syntax of a rockspec.\n\n"..
12lint.help = [[ 12 "Returns success if the text of the rockspec is syntactically correct, else failure.",
13This is a utility function that checks the syntax of a rockspec. 13 util.see_also())
14 14 :summary("Check syntax of a rockspec.")
15It returns success or failure if the text of a rockspec is 15 :add_help(false)
16syntactically correct. 16
17]] 17 cmd:argument("rockspec", "The rockspec to check.")
18 18end
19function lint.command(flags, input) 19
20 if not input then 20function 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"))
78end 78end
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.
86local 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".
179function 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)
234end
235
236local var_format_pattern = "%$%((%a[%a%d_]+)%)" 80local 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 "").."'."
395end 239end
396 240
241function 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."
247end
248
397function util.announce_install(rockspec) 249function 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")