diff options
author | V1K1NGbg <victor@ilchev.com> | 2024-08-19 17:42:28 +0300 |
---|---|---|
committer | V1K1NGbg <victor@ilchev.com> | 2024-08-19 17:42:28 +0300 |
commit | f17c209b891e53cf510e13e31a40dbc4fa918049 (patch) | |
tree | 8416b832c3c28abd8e3d1032df0b7c2793d65478 | |
parent | e46a1edb5b5c75e10b2d199a64817743fc29dbee (diff) | |
download | luarocks-f17c209b891e53cf510e13e31a40dbc4fa918049.tar.gz luarocks-f17c209b891e53cf510e13e31a40dbc4fa918049.tar.bz2 luarocks-f17c209b891e53cf510e13e31a40dbc4fa918049.zip |
cmd build
-rw-r--r-- | src/luarocks/build.tl | 3 | ||||
-rw-r--r-- | src/luarocks/cmd-original.lua | 781 | ||||
-rw-r--r-- | src/luarocks/cmd.lua | 415 | ||||
-rw-r--r-- | src/luarocks/cmd.tl | 10 | ||||
-rw-r--r-- | src/luarocks/cmd/build-original.lua | 199 | ||||
-rw-r--r-- | src/luarocks/cmd/build.lua | 101 | ||||
-rw-r--r-- | src/luarocks/cmd/build.tl | 17 | ||||
-rw-r--r-- | src/luarocks/cmd/install.tl | 2 | ||||
-rw-r--r-- | src/luarocks/cmd/make.tl | 2 | ||||
-rw-r--r-- | src/luarocks/cmd/show.tl | 13 | ||||
-rw-r--r-- | src/luarocks/cmd/upload.tl | 26 | ||||
-rw-r--r-- | src/luarocks/deps.tl | 7 | ||||
-rw-r--r-- | src/luarocks/test/busted.tl | 1 |
13 files changed, 1285 insertions, 292 deletions
diff --git a/src/luarocks/build.tl b/src/luarocks/build.tl index ffbc4f01..b3594225 100644 --- a/src/luarocks/build.tl +++ b/src/luarocks/build.tl | |||
@@ -403,8 +403,7 @@ end | |||
403 | -- @param rockspec rockspec: the rockspec to build | 403 | -- @param rockspec rockspec: the rockspec to build |
404 | -- @param opts table: build options table | 404 | -- @param opts table: build options table |
405 | -- @param cwd string or nil: The current working directory | 405 | -- @param cwd string or nil: The current working directory |
406 | -- @return (string, string) or (nil, string, [string]): Name and version of | 406 | -- @return: Name and version of installed rock if succeeded or nil and an error message. |
407 | -- installed rock if succeeded or nil and an error message followed by an error code. | ||
408 | function build.build_rockspec(rockspec: Rockspec, opts: BOpts, cwd: string): string, string | 407 | function build.build_rockspec(rockspec: Rockspec, opts: BOpts, cwd: string): string, string |
409 | 408 | ||
410 | cwd = cwd or dir.path(".") | 409 | cwd = cwd or dir.path(".") |
diff --git a/src/luarocks/cmd-original.lua b/src/luarocks/cmd-original.lua new file mode 100644 index 00000000..7710dc68 --- /dev/null +++ b/src/luarocks/cmd-original.lua | |||
@@ -0,0 +1,781 @@ | |||
1 | |||
2 | --- Functions for command-line scripts. | ||
3 | local cmd = {} | ||
4 | |||
5 | local manif = require("luarocks.manif") | ||
6 | local config = require("luarocks.config") | ||
7 | local util = require("luarocks.util") | ||
8 | local path = require("luarocks.path") | ||
9 | local cfg = require("luarocks.core.cfg") | ||
10 | local dir = require("luarocks.dir") | ||
11 | local fun = require("luarocks.fun") | ||
12 | local fs = require("luarocks.fs") | ||
13 | local argparse = require("luarocks.vendor.argparse") | ||
14 | |||
15 | local unpack = table.unpack or unpack | ||
16 | local pack = table.pack or function(...) return { n = select("#", ...), ... } end | ||
17 | |||
18 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") | ||
19 | if not hc_ok then | ||
20 | hardcoded = {} | ||
21 | end | ||
22 | |||
23 | local program = util.this_program("luarocks") | ||
24 | |||
25 | cmd.errorcodes = { | ||
26 | OK = 0, | ||
27 | UNSPECIFIED = 1, | ||
28 | PERMISSIONDENIED = 2, | ||
29 | CONFIGFILE = 3, | ||
30 | LOCK = 4, | ||
31 | CRASH = 99 | ||
32 | } | ||
33 | |||
34 | local function check_popen() | ||
35 | local popen_ok, popen_result = pcall(io.popen, "") | ||
36 | if popen_ok then | ||
37 | if popen_result then | ||
38 | popen_result:close() | ||
39 | end | ||
40 | else | ||
41 | io.stderr:write("Your version of Lua does not support io.popen,\n") | ||
42 | io.stderr:write("which is required by LuaRocks. Please check your Lua installation.\n") | ||
43 | os.exit(cmd.errorcodes.UNSPECIFIED) | ||
44 | end | ||
45 | end | ||
46 | |||
47 | local process_tree_args | ||
48 | do | ||
49 | local function replace_tree(args, root, tree) | ||
50 | root = dir.normalize(root) | ||
51 | args.tree = root | ||
52 | path.use_tree(tree or root) | ||
53 | end | ||
54 | |||
55 | local function strip_trailing_slashes() | ||
56 | if type(cfg.root_dir) == "string" then | ||
57 | cfg.root_dir = cfg.root_dir:gsub("/+$", "") | ||
58 | else | ||
59 | cfg.root_dir.root = cfg.root_dir.root:gsub("/+$", "") | ||
60 | end | ||
61 | cfg.rocks_dir = cfg.rocks_dir:gsub("/+$", "") | ||
62 | cfg.deploy_bin_dir = cfg.deploy_bin_dir:gsub("/+$", "") | ||
63 | cfg.deploy_lua_dir = cfg.deploy_lua_dir:gsub("/+$", "") | ||
64 | cfg.deploy_lib_dir = cfg.deploy_lib_dir:gsub("/+$", "") | ||
65 | end | ||
66 | |||
67 | local function set_named_tree(args, name) | ||
68 | for _, tree in ipairs(cfg.rocks_trees) do | ||
69 | if type(tree) == "table" and name == tree.name then | ||
70 | if not tree.root then | ||
71 | return nil, "Configuration error: tree '"..tree.name.."' has no 'root' field." | ||
72 | end | ||
73 | replace_tree(args, tree.root, tree) | ||
74 | return true | ||
75 | end | ||
76 | end | ||
77 | return false | ||
78 | end | ||
79 | |||
80 | process_tree_args = function(args, project_dir) | ||
81 | |||
82 | if args.global then | ||
83 | local ok, err = set_named_tree(args, "system") | ||
84 | if not ok then | ||
85 | return nil, err | ||
86 | end | ||
87 | elseif args.tree then | ||
88 | local named = set_named_tree(args, args.tree) | ||
89 | if not named then | ||
90 | local root_dir = fs.absolute_name(args.tree) | ||
91 | replace_tree(args, root_dir) | ||
92 | if (args.deps_mode or cfg.deps_mode) ~= "order" then | ||
93 | table.insert(cfg.rocks_trees, 1, { name = "arg", root = root_dir } ) | ||
94 | end | ||
95 | end | ||
96 | elseif args["local"] then | ||
97 | if fs.is_superuser() then | ||
98 | return nil, "The --local flag is meant for operating in a user's home directory.\n".. | ||
99 | "You are running as a superuser, which is intended for system-wide operation.\n".. | ||
100 | "To force using the superuser's home, use --tree explicitly." | ||
101 | else | ||
102 | local ok, err = set_named_tree(args, "user") | ||
103 | if not ok then | ||
104 | return nil, err | ||
105 | end | ||
106 | end | ||
107 | elseif args.project_tree then | ||
108 | local tree = args.project_tree | ||
109 | table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) | ||
110 | manif.load_rocks_tree_manifests() | ||
111 | path.use_tree(tree) | ||
112 | elseif project_dir then | ||
113 | local project_tree = project_dir .. "/lua_modules" | ||
114 | table.insert(cfg.rocks_trees, 1, { name = "project", root = project_tree } ) | ||
115 | manif.load_rocks_tree_manifests() | ||
116 | path.use_tree(project_tree) | ||
117 | elseif cfg.local_by_default then | ||
118 | local ok, err = set_named_tree(args, "user") | ||
119 | if not ok then | ||
120 | return nil, err | ||
121 | end | ||
122 | else | ||
123 | local trees = cfg.rocks_trees | ||
124 | path.use_tree(trees[#trees]) | ||
125 | end | ||
126 | |||
127 | strip_trailing_slashes() | ||
128 | |||
129 | cfg.variables.ROCKS_TREE = cfg.rocks_dir | ||
130 | cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir | ||
131 | |||
132 | return true | ||
133 | end | ||
134 | end | ||
135 | |||
136 | local function process_server_args(args) | ||
137 | if args.server then | ||
138 | local protocol, pathname = dir.split_url(args.server) | ||
139 | table.insert(cfg.rocks_servers, 1, protocol.."://"..pathname) | ||
140 | end | ||
141 | |||
142 | if args.dev then | ||
143 | local append_dev = function(s) return dir.path(s, "dev") end | ||
144 | local dev_servers = fun.traverse(cfg.rocks_servers, append_dev) | ||
145 | cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) | ||
146 | end | ||
147 | |||
148 | if args.only_server then | ||
149 | if args.dev then | ||
150 | return nil, "--only-server cannot be used with --dev" | ||
151 | end | ||
152 | if args.server then | ||
153 | return nil, "--only-server cannot be used with --server" | ||
154 | end | ||
155 | cfg.rocks_servers = { args.only_server } | ||
156 | end | ||
157 | |||
158 | return true | ||
159 | end | ||
160 | |||
161 | local function error_handler(err) | ||
162 | if not debug then | ||
163 | return err | ||
164 | end | ||
165 | local mode = "Arch.: " .. (cfg and cfg.arch or "unknown") | ||
166 | if package.config:sub(1, 1) == "\\" then | ||
167 | if cfg and cfg.fs_use_modules then | ||
168 | mode = mode .. " (fs_use_modules = true)" | ||
169 | end | ||
170 | end | ||
171 | if cfg and cfg.is_binary then | ||
172 | mode = mode .. " (binary)" | ||
173 | end | ||
174 | return debug.traceback("LuaRocks "..cfg.program_version.. | ||
175 | " bug (please report at https://github.com/luarocks/luarocks/issues).\n".. | ||
176 | mode.."\n"..err, 2) | ||
177 | end | ||
178 | |||
179 | --- Display an error message and exit. | ||
180 | -- @param message string: The error message. | ||
181 | -- @param exitcode number: the exitcode to use | ||
182 | local function die(message, exitcode) | ||
183 | assert(type(message) == "string", "bad error, expected string, got: " .. type(message)) | ||
184 | assert(exitcode == nil or type(exitcode) == "number", "bad error, expected number, got: " .. type(exitcode) .. " - " .. tostring(exitcode)) | ||
185 | util.printerr("\nError: "..message) | ||
186 | |||
187 | local ok, err = xpcall(util.run_scheduled_functions, error_handler) | ||
188 | if not ok then | ||
189 | util.printerr("\nError: "..err) | ||
190 | exitcode = cmd.errorcodes.CRASH | ||
191 | end | ||
192 | |||
193 | os.exit(exitcode or cmd.errorcodes.UNSPECIFIED) | ||
194 | end | ||
195 | |||
196 | local function search_lua(lua_version, verbose, search_at) | ||
197 | if search_at then | ||
198 | return util.find_lua(search_at, lua_version, verbose) | ||
199 | end | ||
200 | |||
201 | local path_sep = (package.config:sub(1, 1) == "\\" and ";" or ":") | ||
202 | local all_tried = {} | ||
203 | for bindir in (os.getenv("PATH") or ""):gmatch("[^"..path_sep.."]+") do | ||
204 | local searchdir = (bindir:gsub("[\\/]+bin[\\/]?$", "")) | ||
205 | local detected, tried = util.find_lua(searchdir, lua_version) | ||
206 | if detected then | ||
207 | return detected | ||
208 | else | ||
209 | table.insert(all_tried, tried) | ||
210 | end | ||
211 | end | ||
212 | return nil, "Could not find " .. | ||
213 | (lua_version and "Lua " .. lua_version or "Lua") .. | ||
214 | " in PATH." .. | ||
215 | (verbose and " Tried:\n" .. table.concat(all_tried, "\n") or "") | ||
216 | end | ||
217 | |||
218 | local init_config | ||
219 | do | ||
220 | local detect_config_via_args | ||
221 | do | ||
222 | local function find_project_dir(project_tree) | ||
223 | if project_tree then | ||
224 | return project_tree:gsub("[/\\][^/\\]+$", ""), true | ||
225 | else | ||
226 | local try = "." | ||
227 | for _ = 1, 10 do -- FIXME detect when root dir was hit instead | ||
228 | if util.exists(try .. "/.luarocks") and util.exists(try .. "/lua_modules") then | ||
229 | return dir.normalize(try), false | ||
230 | elseif util.exists(try .. "/.luarocks-no-project") then | ||
231 | break | ||
232 | end | ||
233 | try = try .. "/.." | ||
234 | end | ||
235 | end | ||
236 | return nil | ||
237 | end | ||
238 | |||
239 | local function find_default_lua_version(args, project_dir) | ||
240 | if hardcoded.FORCE_CONFIG then | ||
241 | return nil | ||
242 | end | ||
243 | |||
244 | local dirs = {} | ||
245 | if project_dir then | ||
246 | table.insert(dirs, dir.path(project_dir, ".luarocks")) | ||
247 | end | ||
248 | if cfg.homeconfdir then | ||
249 | table.insert(dirs, cfg.homeconfdir) | ||
250 | end | ||
251 | table.insert(dirs, cfg.sysconfdir) | ||
252 | for _, d in ipairs(dirs) do | ||
253 | local f = dir.path(d, "default-lua-version.lua") | ||
254 | local mod, err = loadfile(f, "t") | ||
255 | if mod then | ||
256 | local pok, ver = pcall(mod) | ||
257 | if pok and type(ver) == "string" and ver:match("%d+.%d+") then | ||
258 | if args.verbose then | ||
259 | util.printout("Defaulting to Lua " .. ver .. " based on " .. f .. " ...") | ||
260 | end | ||
261 | return ver | ||
262 | end | ||
263 | end | ||
264 | end | ||
265 | return nil | ||
266 | end | ||
267 | |||
268 | local function find_version_from_config(dirname) | ||
269 | return fun.find(util.lua_versions("descending"), function(v) | ||
270 | if util.exists(dir.path(dirname, ".luarocks", "config-"..v..".lua")) then | ||
271 | return v | ||
272 | end | ||
273 | end) | ||
274 | end | ||
275 | |||
276 | local function detect_lua_via_args(args, project_dir) | ||
277 | local lua_version = args.lua_version | ||
278 | or find_default_lua_version(args, project_dir) | ||
279 | or (project_dir and find_version_from_config(project_dir)) | ||
280 | |||
281 | if args.lua_dir then | ||
282 | local detected, err = util.find_lua(args.lua_dir, lua_version) | ||
283 | if not detected then | ||
284 | local suggestion = (not args.lua_version) | ||
285 | and "\nYou may want to specify a different Lua version with --lua-version\n" | ||
286 | or "" | ||
287 | die(err .. suggestion) | ||
288 | end | ||
289 | return detected | ||
290 | end | ||
291 | |||
292 | if lua_version then | ||
293 | local detected = search_lua(lua_version) | ||
294 | if detected then | ||
295 | return detected | ||
296 | end | ||
297 | return { | ||
298 | lua_version = lua_version, | ||
299 | } | ||
300 | end | ||
301 | |||
302 | return {} | ||
303 | end | ||
304 | |||
305 | detect_config_via_args = function(args) | ||
306 | local project_dir, given | ||
307 | if not args.no_project then | ||
308 | project_dir, given = find_project_dir(args.project_tree) | ||
309 | end | ||
310 | |||
311 | local detected = detect_lua_via_args(args, project_dir) | ||
312 | if args.lua_version then | ||
313 | detected.given_lua_version = args.lua_version | ||
314 | end | ||
315 | if args.lua_dir then | ||
316 | detected.given_lua_dir = args.lua_dir | ||
317 | end | ||
318 | if given then | ||
319 | detected.given_project_dir = project_dir | ||
320 | end | ||
321 | detected.project_dir = project_dir | ||
322 | return detected | ||
323 | end | ||
324 | end | ||
325 | |||
326 | init_config = function(args) | ||
327 | local detected = detect_config_via_args(args) | ||
328 | |||
329 | local ok, err = cfg.init(detected, util.warning) | ||
330 | if not ok then | ||
331 | return nil, err | ||
332 | end | ||
333 | |||
334 | return (detected.lua_dir ~= nil) | ||
335 | end | ||
336 | end | ||
337 | |||
338 | local variables_help = [[ | ||
339 | Variables: | ||
340 | Variables from the "variables" table of the configuration file can be | ||
341 | overridden with VAR=VALUE assignments. | ||
342 | |||
343 | ]] | ||
344 | |||
345 | local lua_example = package.config:sub(1, 1) == "\\" | ||
346 | and "<d:\\path\\lua.exe>" | ||
347 | or "</path/lua>" | ||
348 | |||
349 | local function show_status(file, status, err) | ||
350 | return (file and file .. " " or "") .. (status and "(ok)" or ("(" .. (err or "not found") ..")")) | ||
351 | end | ||
352 | |||
353 | local function use_to_fix_location(key, what) | ||
354 | local buf = " ****************************************\n" | ||
355 | buf = buf .. " Use the command\n\n" | ||
356 | buf = buf .. " luarocks config " .. key .. " " .. (what or "<dir>") .. "\n\n" | ||
357 | buf = buf .. " to fix the location\n" | ||
358 | buf = buf .. " ****************************************\n" | ||
359 | return buf | ||
360 | end | ||
361 | |||
362 | local function get_config_text(cfg) -- luacheck: ignore 431 | ||
363 | local deps = require("luarocks.deps") | ||
364 | |||
365 | local libdir_ok = deps.check_lua_libdir(cfg.variables) | ||
366 | local incdir_ok = deps.check_lua_incdir(cfg.variables) | ||
367 | local lua_ok = cfg.variables.LUA and fs.exists(cfg.variables.LUA) | ||
368 | |||
369 | local buf = "Configuration:\n" | ||
370 | buf = buf.." Lua:\n" | ||
371 | buf = buf.." Version : "..cfg.lua_version.."\n" | ||
372 | if cfg.luajit_version then | ||
373 | buf = buf.." LuaJIT : "..cfg.luajit_version.."\n" | ||
374 | end | ||
375 | buf = buf.." LUA : "..show_status(cfg.variables.LUA, lua_ok, "interpreter not found").."\n" | ||
376 | if not lua_ok then | ||
377 | buf = buf .. use_to_fix_location("variables.LUA", lua_example) | ||
378 | end | ||
379 | buf = buf.." LUA_INCDIR : "..show_status(cfg.variables.LUA_INCDIR, incdir_ok, "lua.h not found").."\n" | ||
380 | if lua_ok and not incdir_ok then | ||
381 | buf = buf .. use_to_fix_location("variables.LUA_INCDIR") | ||
382 | end | ||
383 | buf = buf.." LUA_LIBDIR : "..show_status(cfg.variables.LUA_LIBDIR, libdir_ok, "Lua library itself not found").."\n" | ||
384 | if lua_ok and not libdir_ok then | ||
385 | buf = buf .. use_to_fix_location("variables.LUA_LIBDIR") | ||
386 | end | ||
387 | |||
388 | buf = buf.."\n Configuration files:\n" | ||
389 | local conf = cfg.config_files | ||
390 | buf = buf.." System : "..show_status(fs.absolute_name(conf.system.file), conf.system.found).."\n" | ||
391 | if conf.user.file then | ||
392 | buf = buf.." User : "..show_status(fs.absolute_name(conf.user.file), conf.user.found).."\n" | ||
393 | else | ||
394 | buf = buf.." User : disabled in this LuaRocks installation.\n" | ||
395 | end | ||
396 | if conf.project then | ||
397 | buf = buf.." Project : "..show_status(fs.absolute_name(conf.project.file), conf.project.found).."\n" | ||
398 | end | ||
399 | buf = buf.."\n Rocks trees in use: \n" | ||
400 | for _, tree in ipairs(cfg.rocks_trees) do | ||
401 | if type(tree) == "string" then | ||
402 | buf = buf.." "..fs.absolute_name(tree) | ||
403 | else | ||
404 | local name = tree.name and " (\""..tree.name.."\")" or "" | ||
405 | buf = buf.." "..fs.absolute_name(tree.root)..name | ||
406 | end | ||
407 | buf = buf .. "\n" | ||
408 | end | ||
409 | |||
410 | return buf | ||
411 | end | ||
412 | |||
413 | local function get_parser(description, cmd_modules) | ||
414 | local basename = dir.base_name(program) | ||
415 | local parser = argparse( | ||
416 | basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. | ||
417 | program.." - "..description, variables_help.."Run '"..basename.. | ||
418 | "' without any arguments to see the configuration.") | ||
419 | :help_max_width(80) | ||
420 | :add_help_command() | ||
421 | :add_complete_command({ | ||
422 | help_max_width = 100, | ||
423 | summary = "Output a shell completion script.", | ||
424 | description = [[ | ||
425 | Output a shell completion script. | ||
426 | |||
427 | Enabling completions for Bash: | ||
428 | |||
429 | Add the following line to your ~/.bashrc: | ||
430 | source <(]]..basename..[[ completion bash) | ||
431 | or save the completion script to the local completion directory: | ||
432 | ]]..basename..[[ completion bash > ~/.local/share/bash-completion/completions/]]..basename..[[ | ||
433 | |||
434 | |||
435 | Enabling completions for Zsh: | ||
436 | |||
437 | Save the completion script to a file in your $fpath. | ||
438 | You can add a new directory to your $fpath by adding e.g. | ||
439 | fpath=(~/.zfunc $fpath) | ||
440 | to your ~/.zshrc. | ||
441 | Then run: | ||
442 | ]]..basename..[[ completion zsh > ~/.zfunc/_]]..basename..[[ | ||
443 | |||
444 | |||
445 | Enabling completion for Fish: | ||
446 | |||
447 | Add the following line to your ~/.config/fish/config.fish: | ||
448 | ]]..basename..[[ completion fish | source | ||
449 | or save the completion script to the local completion directory: | ||
450 | ]]..basename..[[ completion fish > ~/.config/fish/completions/]]..basename..[[.fish | ||
451 | ]]}) | ||
452 | :command_target("command") | ||
453 | :require_command(false) | ||
454 | |||
455 | parser:flag("--version", "Show version info and exit.") | ||
456 | :action(function() | ||
457 | util.printout(program.." "..cfg.program_version) | ||
458 | util.printout(description) | ||
459 | util.printout() | ||
460 | os.exit(cmd.errorcodes.OK) | ||
461 | end) | ||
462 | parser:flag("--dev", "Enable the sub-repositories in rocks servers for ".. | ||
463 | "rockspecs of in-development versions.") | ||
464 | parser:option("--server", "Fetch rocks/rockspecs from this server ".. | ||
465 | "(takes priority over config file).") | ||
466 | :hidden_name("--from") | ||
467 | parser:option("--only-server", "Fetch rocks/rockspecs from this server only ".. | ||
468 | "(overrides any entries in the config file).") | ||
469 | :argname("<server>") | ||
470 | :hidden_name("--only-from") | ||
471 | parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") | ||
472 | :argname("<url>") | ||
473 | :hidden_name("--only-sources-from") | ||
474 | parser:option("--namespace", "Specify the rocks server namespace to use.") | ||
475 | :convert(string.lower) | ||
476 | parser:option("--lua-dir", "Which Lua installation to use.") | ||
477 | :argname("<prefix>") | ||
478 | parser:option("--lua-version", "Which Lua version to use.") | ||
479 | :argname("<ver>") | ||
480 | :convert(function(s) return (s:match("^%d+%.%d+$")) end) | ||
481 | parser:option("--tree", "Which tree to operate on.") | ||
482 | :hidden_name("--to") | ||
483 | parser:flag("--local", "Use the tree in the user's home directory.\n".. | ||
484 | "To enable it, see '"..program.." help path'.") | ||
485 | parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") | ||
486 | parser:flag("--no-project", "Do not use project tree even if running from a project folder.") | ||
487 | parser:flag("--force-lock", "Attempt to overwrite the lock for commands " .. | ||
488 | "that require exclusive access, such as 'install'") | ||
489 | parser:flag("--verbose", "Display verbose output of commands executed.") | ||
490 | parser:option("--timeout", "Timeout on network operations, in seconds.\n".. | ||
491 | "0 means no timeout (wait forever). Default is ".. | ||
492 | tostring(cfg.connection_timeout)..".") | ||
493 | :argname("<seconds>") | ||
494 | :convert(tonumber) | ||
495 | |||
496 | -- Used internally to force the use of a particular project tree | ||
497 | parser:option("--project-tree"):hidden(true) | ||
498 | |||
499 | for _, module in util.sortedpairs(cmd_modules) do | ||
500 | module.add_to_parser(parser) | ||
501 | end | ||
502 | |||
503 | return parser | ||
504 | end | ||
505 | |||
506 | local function get_first_arg() | ||
507 | if not arg then | ||
508 | return | ||
509 | end | ||
510 | local first_arg = arg[0] | ||
511 | local i = -1 | ||
512 | while arg[i] do | ||
513 | first_arg = arg[i] | ||
514 | i = i -1 | ||
515 | end | ||
516 | return first_arg | ||
517 | end | ||
518 | |||
519 | --- Main command-line processor. | ||
520 | -- Parses input arguments and calls the appropriate driver function | ||
521 | -- to execute the action requested on the command-line, forwarding | ||
522 | -- to it any additional arguments passed by the user. | ||
523 | -- @param description string: Short summary description of the program. | ||
524 | -- @param commands table: contains the loaded modules representing commands. | ||
525 | -- @param external_namespace string: where to look for external commands. | ||
526 | -- @param ... string: Arguments given on the command-line. | ||
527 | function cmd.run_command(description, commands, external_namespace, ...) | ||
528 | |||
529 | check_popen() | ||
530 | |||
531 | -- Preliminary initialization | ||
532 | cfg.init() | ||
533 | |||
534 | fs.init() | ||
535 | |||
536 | for _, module_name in ipairs(fs.modules(external_namespace)) do | ||
537 | if not commands[module_name] then | ||
538 | commands[module_name] = external_namespace.."."..module_name | ||
539 | end | ||
540 | end | ||
541 | |||
542 | local cmd_modules = {} | ||
543 | for name, module in pairs(commands) do | ||
544 | local pok, mod = pcall(require, module) | ||
545 | if pok and type(mod) == "table" then | ||
546 | local original_command = mod.command | ||
547 | if original_command then | ||
548 | if not mod.add_to_parser then | ||
549 | mod.add_to_parser = function(parser) | ||
550 | parser:command(name, mod.help, util.see_also()) | ||
551 | :summary(mod.help_summary) | ||
552 | :handle_options(false) | ||
553 | :argument("input") | ||
554 | :args("*") | ||
555 | end | ||
556 | |||
557 | mod.command = function(args) | ||
558 | return original_command(args, unpack(args.input)) | ||
559 | end | ||
560 | end | ||
561 | cmd_modules[name] = mod | ||
562 | else | ||
563 | util.warning("command module " .. module .. " does not implement command(), skipping") | ||
564 | end | ||
565 | else | ||
566 | util.warning("failed to load command module " .. module .. ": " .. mod) | ||
567 | end | ||
568 | end | ||
569 | |||
570 | local function process_cmdline_vars(...) | ||
571 | local args = pack(...) | ||
572 | local cmdline_vars = {} | ||
573 | local last = args.n | ||
574 | for i = 1, args.n do | ||
575 | if args[i] == "--" then | ||
576 | last = i - 1 | ||
577 | break | ||
578 | end | ||
579 | end | ||
580 | for i = last, 1, -1 do | ||
581 | local arg = args[i] | ||
582 | if arg:match("^[^-][^=]*=") then | ||
583 | local var, val = arg:match("^([A-Z_][A-Z0-9_]*)=(.*)") | ||
584 | if val then | ||
585 | cmdline_vars[var] = val | ||
586 | table.remove(args, i) | ||
587 | else | ||
588 | die("Invalid assignment: "..arg) | ||
589 | end | ||
590 | end | ||
591 | end | ||
592 | |||
593 | return args, cmdline_vars | ||
594 | end | ||
595 | |||
596 | local args, cmdline_vars = process_cmdline_vars(...) | ||
597 | local parser = get_parser(description, cmd_modules) | ||
598 | args = parser:parse(args) | ||
599 | |||
600 | -- Compatibility for old flag | ||
601 | if args.nodeps then | ||
602 | args.deps_mode = "none" | ||
603 | end | ||
604 | |||
605 | if args.timeout then -- setting it in the config file will kick-in earlier in the process | ||
606 | cfg.connection_timeout = args.timeout | ||
607 | end | ||
608 | |||
609 | if args.command == "config" then | ||
610 | if args.key == "lua_version" and args.value then | ||
611 | args.lua_version = args.value | ||
612 | elseif args.key == "lua_dir" and args.value then | ||
613 | args.lua_dir = args.value | ||
614 | end | ||
615 | end | ||
616 | |||
617 | ----------------------------------------------------------------------------- | ||
618 | local lua_found, err = init_config(args) | ||
619 | if err then | ||
620 | die(err) | ||
621 | end | ||
622 | ----------------------------------------------------------------------------- | ||
623 | |||
624 | -- Now that the config is fully loaded, reinitialize fs using the full | ||
625 | -- feature set. | ||
626 | fs.init() | ||
627 | |||
628 | -- if the Lua interpreter wasn't explicitly found before cfg.init, | ||
629 | -- try again now. | ||
630 | local tried | ||
631 | if not lua_found then | ||
632 | local detected | ||
633 | detected, tried = search_lua(cfg.lua_version, args.verbose, cfg.variables.LUA_DIR) | ||
634 | if detected then | ||
635 | lua_found = true | ||
636 | cfg.variables.LUA = detected.lua | ||
637 | cfg.variables.LUA_DIR = detected.lua_dir | ||
638 | cfg.variables.LUA_BINDIR = detected.lua_bindir | ||
639 | if args.lua_dir then | ||
640 | cfg.variables.LUA_INCDIR = nil | ||
641 | cfg.variables.LUA_LIBDIR = nil | ||
642 | end | ||
643 | else | ||
644 | cfg.variables.LUA = nil | ||
645 | cfg.variables.LUA_DIR = nil | ||
646 | cfg.variables.LUA_BINDIR = nil | ||
647 | cfg.variables.LUA_INCDIR = nil | ||
648 | cfg.variables.LUA_LIBDIR = nil | ||
649 | end | ||
650 | end | ||
651 | |||
652 | if lua_found then | ||
653 | assert(cfg.variables.LUA) | ||
654 | else | ||
655 | -- Fallback producing _some_ Lua configuration based on the running interpreter. | ||
656 | -- Most likely won't produce correct results when running from the standalone binary, | ||
657 | -- so eventually we need to drop this and outright fail if Lua is not found | ||
658 | -- or explictly configured | ||
659 | if not cfg.variables.LUA then | ||
660 | local first_arg = get_first_arg() | ||
661 | local bin_dir = dir.dir_name(fs.absolute_name(first_arg)) | ||
662 | local exe = dir.base_name(first_arg) | ||
663 | exe = exe:match("rocks") and ("lua" .. (cfg.arch:match("win") and ".exe" or "")) or exe | ||
664 | local full_path = dir.path(bin_dir, exe) | ||
665 | if util.check_lua_version(full_path, cfg.lua_version) then | ||
666 | cfg.variables.LUA = dir.path(bin_dir, exe) | ||
667 | cfg.variables.LUA_DIR = bin_dir:gsub("[/\\]bin[/\\]?$", "") | ||
668 | cfg.variables.LUA_BINDIR = bin_dir | ||
669 | cfg.variables.LUA_INCDIR = nil | ||
670 | cfg.variables.LUA_LIBDIR = nil | ||
671 | end | ||
672 | end | ||
673 | end | ||
674 | |||
675 | cfg.lua_found = lua_found | ||
676 | |||
677 | if cfg.project_dir then | ||
678 | cfg.project_dir = fs.absolute_name(cfg.project_dir) | ||
679 | end | ||
680 | |||
681 | if args.verbose then | ||
682 | cfg.verbose = true | ||
683 | print(("-"):rep(79)) | ||
684 | print("Current configuration:") | ||
685 | print(("-"):rep(79)) | ||
686 | print(config.to_string(cfg)) | ||
687 | print(("-"):rep(79)) | ||
688 | fs.verbose() | ||
689 | end | ||
690 | |||
691 | if (not fs.current_dir()) or fs.current_dir() == "" then | ||
692 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | ||
693 | end | ||
694 | |||
695 | local ok, err = process_tree_args(args, cfg.project_dir) | ||
696 | if not ok then | ||
697 | die(err) | ||
698 | end | ||
699 | |||
700 | ok, err = process_server_args(args) | ||
701 | if not ok then | ||
702 | die(err) | ||
703 | end | ||
704 | |||
705 | if args.only_sources then | ||
706 | cfg.only_sources_from = args.only_sources | ||
707 | end | ||
708 | |||
709 | for k, v in pairs(cmdline_vars) do | ||
710 | cfg.variables[k] = v | ||
711 | end | ||
712 | |||
713 | -- if running as superuser, use system cache dir | ||
714 | if fs.is_superuser() then | ||
715 | cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") | ||
716 | end | ||
717 | |||
718 | if args.no_manifest then | ||
719 | cfg.no_manifest = true | ||
720 | end | ||
721 | |||
722 | if not args.command then | ||
723 | parser:epilog(variables_help..get_config_text(cfg)) | ||
724 | util.printout() | ||
725 | util.printout(parser:get_help()) | ||
726 | util.printout() | ||
727 | os.exit(cmd.errorcodes.OK) | ||
728 | end | ||
729 | |||
730 | if not cfg.variables["LUA"] and args.command ~= "config" and args.command ~= "help" then | ||
731 | local flag = (not cfg.project_tree) | ||
732 | and "--local " | ||
733 | or "" | ||
734 | if args.lua_version then | ||
735 | flag = "--lua-version=" .. args.lua_version .. " " .. flag | ||
736 | end | ||
737 | die((tried or "Lua interpreter not found.") .. | ||
738 | "\nPlease set your Lua interpreter with:\n\n" .. | ||
739 | " luarocks " .. flag.. "config variables.LUA " .. lua_example .. "\n") | ||
740 | end | ||
741 | |||
742 | local cmd_mod = cmd_modules[args.command] | ||
743 | |||
744 | local lock | ||
745 | if cmd_mod.needs_lock and cmd_mod.needs_lock(args) then | ||
746 | local ok, err = fs.check_command_permissions(args) | ||
747 | if not ok then | ||
748 | die(err, cmd.errorcodes.PERMISSIONDENIED) | ||
749 | end | ||
750 | |||
751 | lock, err = fs.lock_access(path.root_dir(cfg.root_dir), args.force_lock) | ||
752 | if not lock then | ||
753 | err = args.force_lock | ||
754 | and ("failed to force the lock" .. (err and ": " .. err or "")) | ||
755 | or (err and err ~= "File exists") | ||
756 | and err | ||
757 | or "try --force-lock to overwrite the lock" | ||
758 | |||
759 | die("command '" .. args.command .. "' " .. | ||
760 | "requires exclusive write access to " .. path.root_dir(cfg.root_dir) .. " - " .. | ||
761 | err, cmd.errorcodes.LOCK) | ||
762 | end | ||
763 | end | ||
764 | |||
765 | local call_ok, ok, err, exitcode = xpcall(function() | ||
766 | return cmd_mod.command(args) | ||
767 | end, error_handler) | ||
768 | |||
769 | if lock then | ||
770 | fs.unlock_access(lock) | ||
771 | end | ||
772 | |||
773 | if not call_ok then | ||
774 | die(ok, cmd.errorcodes.CRASH) | ||
775 | elseif not ok then | ||
776 | die(err, exitcode) | ||
777 | end | ||
778 | util.run_scheduled_functions() | ||
779 | end | ||
780 | |||
781 | return cmd | ||
diff --git a/src/luarocks/cmd.lua b/src/luarocks/cmd.lua index 7710dc68..3cf565bf 100644 --- a/src/luarocks/cmd.lua +++ b/src/luarocks/cmd.lua | |||
@@ -1,6 +1,16 @@ | |||
1 | local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local assert = _tl_compat and _tl_compat.assert or assert; local debug = _tl_compat and _tl_compat.debug or debug; local io = _tl_compat and _tl_compat.io or io; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local loadfile = _tl_compat and _tl_compat.loadfile or loadfile; local os = _tl_compat and _tl_compat.os or os; local package = _tl_compat and _tl_compat.package or package; local pairs = _tl_compat and _tl_compat.pairs or pairs; local pcall = _tl_compat and _tl_compat.pcall or pcall; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table; local _tl_table_unpack = unpack or table.unpack; local xpcall = _tl_compat and _tl_compat.xpcall or xpcall | ||
2 | |||
3 | local cmd = {Module = {}, } | ||
4 | |||
5 | |||
6 | |||
7 | |||
8 | |||
9 | |||
10 | |||
11 | |||
12 | |||
1 | 13 | ||
2 | --- Functions for command-line scripts. | ||
3 | local cmd = {} | ||
4 | 14 | ||
5 | local manif = require("luarocks.manif") | 15 | local manif = require("luarocks.manif") |
6 | local config = require("luarocks.config") | 16 | local config = require("luarocks.config") |
@@ -12,8 +22,22 @@ local fun = require("luarocks.fun") | |||
12 | local fs = require("luarocks.fs") | 22 | local fs = require("luarocks.fs") |
13 | local argparse = require("luarocks.vendor.argparse") | 23 | local argparse = require("luarocks.vendor.argparse") |
14 | 24 | ||
15 | local unpack = table.unpack or unpack | 25 | |
16 | local pack = table.pack or function(...) return { n = select("#", ...), ... } end | 26 | |
27 | |||
28 | |||
29 | |||
30 | |||
31 | |||
32 | |||
33 | |||
34 | |||
35 | |||
36 | |||
37 | |||
38 | |||
39 | |||
40 | |||
17 | 41 | ||
18 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") | 42 | local hc_ok, hardcoded = pcall(require, "luarocks.core.hardcoded") |
19 | if not hc_ok then | 43 | if not hc_ok then |
@@ -28,7 +52,7 @@ cmd.errorcodes = { | |||
28 | PERMISSIONDENIED = 2, | 52 | PERMISSIONDENIED = 2, |
29 | CONFIGFILE = 3, | 53 | CONFIGFILE = 3, |
30 | LOCK = 4, | 54 | LOCK = 4, |
31 | CRASH = 99 | 55 | CRASH = 99, |
32 | } | 56 | } |
33 | 57 | ||
34 | local function check_popen() | 58 | local function check_popen() |
@@ -53,10 +77,11 @@ do | |||
53 | end | 77 | end |
54 | 78 | ||
55 | local function strip_trailing_slashes() | 79 | local function strip_trailing_slashes() |
56 | if type(cfg.root_dir) == "string" then | 80 | local cfg_root_dir = cfg.root_dir |
57 | cfg.root_dir = cfg.root_dir:gsub("/+$", "") | 81 | if type(cfg_root_dir) == "string" then |
82 | cfg.root_dir = (cfg.root_dir):gsub("/+$", "") | ||
58 | else | 83 | else |
59 | cfg.root_dir.root = cfg.root_dir.root:gsub("/+$", "") | 84 | (cfg.root_dir).root = (cfg.root_dir).root:gsub("/+$", "") |
60 | end | 85 | end |
61 | cfg.rocks_dir = cfg.rocks_dir:gsub("/+$", "") | 86 | cfg.rocks_dir = cfg.rocks_dir:gsub("/+$", "") |
62 | cfg.deploy_bin_dir = cfg.deploy_bin_dir:gsub("/+$", "") | 87 | cfg.deploy_bin_dir = cfg.deploy_bin_dir:gsub("/+$", "") |
@@ -68,7 +93,7 @@ do | |||
68 | for _, tree in ipairs(cfg.rocks_trees) do | 93 | for _, tree in ipairs(cfg.rocks_trees) do |
69 | if type(tree) == "table" and name == tree.name then | 94 | if type(tree) == "table" and name == tree.name then |
70 | if not tree.root then | 95 | if not tree.root then |
71 | return nil, "Configuration error: tree '"..tree.name.."' has no 'root' field." | 96 | return nil, "Configuration error: tree '" .. tree.name .. "' has no 'root' field." |
72 | end | 97 | end |
73 | replace_tree(args, tree.root, tree) | 98 | replace_tree(args, tree.root, tree) |
74 | return true | 99 | return true |
@@ -90,14 +115,14 @@ do | |||
90 | local root_dir = fs.absolute_name(args.tree) | 115 | local root_dir = fs.absolute_name(args.tree) |
91 | replace_tree(args, root_dir) | 116 | replace_tree(args, root_dir) |
92 | if (args.deps_mode or cfg.deps_mode) ~= "order" then | 117 | if (args.deps_mode or cfg.deps_mode) ~= "order" then |
93 | table.insert(cfg.rocks_trees, 1, { name = "arg", root = root_dir } ) | 118 | table.insert(cfg.rocks_trees, 1, { name = "arg", root = root_dir }) |
94 | end | 119 | end |
95 | end | 120 | end |
96 | elseif args["local"] then | 121 | elseif args["local"] then |
97 | if fs.is_superuser() then | 122 | if fs.is_superuser() then |
98 | return nil, "The --local flag is meant for operating in a user's home directory.\n".. | 123 | return nil, "The --local flag is meant for operating in a user's home directory.\n" .. |
99 | "You are running as a superuser, which is intended for system-wide operation.\n".. | 124 | "You are running as a superuser, which is intended for system-wide operation.\n" .. |
100 | "To force using the superuser's home, use --tree explicitly." | 125 | "To force using the superuser's home, use --tree explicitly." |
101 | else | 126 | else |
102 | local ok, err = set_named_tree(args, "user") | 127 | local ok, err = set_named_tree(args, "user") |
103 | if not ok then | 128 | if not ok then |
@@ -106,12 +131,12 @@ do | |||
106 | end | 131 | end |
107 | elseif args.project_tree then | 132 | elseif args.project_tree then |
108 | local tree = args.project_tree | 133 | local tree = args.project_tree |
109 | table.insert(cfg.rocks_trees, 1, { name = "project", root = tree } ) | 134 | table.insert(cfg.rocks_trees, 1, { name = "project", root = tree }) |
110 | manif.load_rocks_tree_manifests() | 135 | manif.load_rocks_tree_manifests() |
111 | path.use_tree(tree) | 136 | path.use_tree(tree) |
112 | elseif project_dir then | 137 | elseif project_dir then |
113 | local project_tree = project_dir .. "/lua_modules" | 138 | local project_tree = project_dir .. "/lua_modules" |
114 | table.insert(cfg.rocks_trees, 1, { name = "project", root = project_tree } ) | 139 | table.insert(cfg.rocks_trees, 1, { name = "project", root = project_tree }) |
115 | manif.load_rocks_tree_manifests() | 140 | manif.load_rocks_tree_manifests() |
116 | path.use_tree(project_tree) | 141 | path.use_tree(project_tree) |
117 | elseif cfg.local_by_default then | 142 | elseif cfg.local_by_default then |
@@ -136,13 +161,19 @@ end | |||
136 | local function process_server_args(args) | 161 | local function process_server_args(args) |
137 | if args.server then | 162 | if args.server then |
138 | local protocol, pathname = dir.split_url(args.server) | 163 | local protocol, pathname = dir.split_url(args.server) |
139 | table.insert(cfg.rocks_servers, 1, protocol.."://"..pathname) | 164 | table.insert(cfg.rocks_servers, 1, protocol .. "://" .. pathname) |
140 | end | 165 | end |
141 | 166 | ||
142 | if args.dev then | 167 | if args.dev then |
143 | local append_dev = function(s) return dir.path(s, "dev") end | 168 | for i, server in ipairs(cfg.rocks_servers) do |
144 | local dev_servers = fun.traverse(cfg.rocks_servers, append_dev) | 169 | if type(server) == "string" then |
145 | cfg.rocks_servers = fun.concat(dev_servers, cfg.rocks_servers) | 170 | cfg.rocks_servers[i] = dir.path(server, "dev") |
171 | else | ||
172 | for j, mirror in ipairs(server) do | ||
173 | server[j] = dir.path(mirror, "dev") | ||
174 | end | ||
175 | end | ||
176 | end | ||
146 | end | 177 | end |
147 | 178 | ||
148 | if args.only_server then | 179 | if args.only_server then |
@@ -171,22 +202,22 @@ local function error_handler(err) | |||
171 | if cfg and cfg.is_binary then | 202 | if cfg and cfg.is_binary then |
172 | mode = mode .. " (binary)" | 203 | mode = mode .. " (binary)" |
173 | end | 204 | end |
174 | return debug.traceback("LuaRocks "..cfg.program_version.. | 205 | return debug.traceback("LuaRocks " .. cfg.program_version .. |
175 | " bug (please report at https://github.com/luarocks/luarocks/issues).\n".. | 206 | " bug (please report at https://github.com/luarocks/luarocks/issues).\n" .. |
176 | mode.."\n"..err, 2) | 207 | mode .. "\n" .. err, 2) |
177 | end | 208 | end |
178 | 209 | ||
179 | --- Display an error message and exit. | 210 | |
180 | -- @param message string: The error message. | 211 | |
181 | -- @param exitcode number: the exitcode to use | 212 | |
182 | local function die(message, exitcode) | 213 | local function die(message, exitcode) |
183 | assert(type(message) == "string", "bad error, expected string, got: " .. type(message)) | 214 | assert(type(message) == "string", "bad error, expected string, got: " .. type(message)) |
184 | assert(exitcode == nil or type(exitcode) == "number", "bad error, expected number, got: " .. type(exitcode) .. " - " .. tostring(exitcode)) | 215 | assert(exitcode == nil or type(exitcode) == "number", "bad error, expected number, got: " .. type(exitcode) .. " - " .. tostring(exitcode)) |
185 | util.printerr("\nError: "..message) | 216 | util.printerr("\nError: " .. message) |
186 | 217 | ||
187 | local ok, err = xpcall(util.run_scheduled_functions, error_handler) | 218 | local ok, err = xpcall(util.run_scheduled_functions, error_handler) |
188 | if not ok then | 219 | if not ok then |
189 | util.printerr("\nError: "..err) | 220 | util.printerr("\nError: " .. err) |
190 | exitcode = cmd.errorcodes.CRASH | 221 | exitcode = cmd.errorcodes.CRASH |
191 | end | 222 | end |
192 | 223 | ||
@@ -200,7 +231,7 @@ local function search_lua(lua_version, verbose, search_at) | |||
200 | 231 | ||
201 | local path_sep = (package.config:sub(1, 1) == "\\" and ";" or ":") | 232 | local path_sep = (package.config:sub(1, 1) == "\\" and ";" or ":") |
202 | local all_tried = {} | 233 | local all_tried = {} |
203 | for bindir in (os.getenv("PATH") or ""):gmatch("[^"..path_sep.."]+") do | 234 | for bindir in (os.getenv("PATH") or ""):gmatch("[^" .. path_sep .. "]+") do |
204 | local searchdir = (bindir:gsub("[\\/]+bin[\\/]?$", "")) | 235 | local searchdir = (bindir:gsub("[\\/]+bin[\\/]?$", "")) |
205 | local detected, tried = util.find_lua(searchdir, lua_version) | 236 | local detected, tried = util.find_lua(searchdir, lua_version) |
206 | if detected then | 237 | if detected then |
@@ -210,9 +241,9 @@ local function search_lua(lua_version, verbose, search_at) | |||
210 | end | 241 | end |
211 | end | 242 | end |
212 | return nil, "Could not find " .. | 243 | return nil, "Could not find " .. |
213 | (lua_version and "Lua " .. lua_version or "Lua") .. | 244 | (lua_version and "Lua " .. lua_version or "Lua") .. |
214 | " in PATH." .. | 245 | " in PATH." .. |
215 | (verbose and " Tried:\n" .. table.concat(all_tried, "\n") or "") | 246 | (verbose and " Tried:\n" .. table.concat(all_tried, "\n") or "") |
216 | end | 247 | end |
217 | 248 | ||
218 | local init_config | 249 | local init_config |
@@ -224,7 +255,7 @@ do | |||
224 | return project_tree:gsub("[/\\][^/\\]+$", ""), true | 255 | return project_tree:gsub("[/\\][^/\\]+$", ""), true |
225 | else | 256 | else |
226 | local try = "." | 257 | local try = "." |
227 | for _ = 1, 10 do -- FIXME detect when root dir was hit instead | 258 | for _ = 1, 10 do |
228 | if util.exists(try .. "/.luarocks") and util.exists(try .. "/lua_modules") then | 259 | if util.exists(try .. "/.luarocks") and util.exists(try .. "/lua_modules") then |
229 | return dir.normalize(try), false | 260 | return dir.normalize(try), false |
230 | elseif util.exists(try .. "/.luarocks-no-project") then | 261 | elseif util.exists(try .. "/.luarocks-no-project") then |
@@ -251,7 +282,7 @@ do | |||
251 | table.insert(dirs, cfg.sysconfdir) | 282 | table.insert(dirs, cfg.sysconfdir) |
252 | for _, d in ipairs(dirs) do | 283 | for _, d in ipairs(dirs) do |
253 | local f = dir.path(d, "default-lua-version.lua") | 284 | local f = dir.path(d, "default-lua-version.lua") |
254 | local mod, err = loadfile(f, "t") | 285 | local mod, _ = loadfile(f, "t") |
255 | if mod then | 286 | if mod then |
256 | local pok, ver = pcall(mod) | 287 | local pok, ver = pcall(mod) |
257 | if pok and type(ver) == "string" and ver:match("%d+.%d+") then | 288 | if pok and type(ver) == "string" and ver:match("%d+.%d+") then |
@@ -267,23 +298,23 @@ do | |||
267 | 298 | ||
268 | local function find_version_from_config(dirname) | 299 | local function find_version_from_config(dirname) |
269 | return fun.find(util.lua_versions("descending"), function(v) | 300 | return fun.find(util.lua_versions("descending"), function(v) |
270 | if util.exists(dir.path(dirname, ".luarocks", "config-"..v..".lua")) then | 301 | if util.exists(dir.path(dirname, ".luarocks", "config-" .. v .. ".lua")) then |
271 | return v | 302 | return v |
272 | end | 303 | end |
273 | end) | 304 | end) |
274 | end | 305 | end |
275 | 306 | ||
276 | local function detect_lua_via_args(args, project_dir) | 307 | local function detect_lua_via_args(args, project_dir) |
277 | local lua_version = args.lua_version | 308 | local lua_version = args.lua_version or |
278 | or find_default_lua_version(args, project_dir) | 309 | find_default_lua_version(args, project_dir) or |
279 | or (project_dir and find_version_from_config(project_dir)) | 310 | (project_dir and find_version_from_config(project_dir)) |
280 | 311 | ||
281 | if args.lua_dir then | 312 | if args.lua_dir then |
282 | local detected, err = util.find_lua(args.lua_dir, lua_version) | 313 | local detected, err = util.find_lua(args.lua_dir, lua_version) |
283 | if not detected then | 314 | if not detected then |
284 | local suggestion = (not args.lua_version) | 315 | local suggestion = (not args.lua_version) and |
285 | and "\nYou may want to specify a different Lua version with --lua-version\n" | 316 | "\nYou may want to specify a different Lua version with --lua-version\n" or |
286 | or "" | 317 | "" |
287 | die(err .. suggestion) | 318 | die(err .. suggestion) |
288 | end | 319 | end |
289 | return detected | 320 | return detected |
@@ -342,16 +373,16 @@ Variables: | |||
342 | 373 | ||
343 | ]] | 374 | ]] |
344 | 375 | ||
345 | local lua_example = package.config:sub(1, 1) == "\\" | 376 | local lua_example = package.config:sub(1, 1) == "\\" and |
346 | and "<d:\\path\\lua.exe>" | 377 | "<d:\\path\\lua.exe>" or |
347 | or "</path/lua>" | 378 | "</path/lua>" |
348 | 379 | ||
349 | local function show_status(file, status, err) | 380 | local function show_status(file, status, err) |
350 | return (file and file .. " " or "") .. (status and "(ok)" or ("(" .. (err or "not found") ..")")) | 381 | return (file and file .. " " or "") .. (status and "(ok)" or ("(" .. (err or "not found") .. ")")) |
351 | end | 382 | end |
352 | 383 | ||
353 | local function use_to_fix_location(key, what) | 384 | local function use_to_fix_location(key, what) |
354 | local buf = " ****************************************\n" | 385 | local buf = " ****************************************\n" |
355 | buf = buf .. " Use the command\n\n" | 386 | buf = buf .. " Use the command\n\n" |
356 | buf = buf .. " luarocks config " .. key .. " " .. (what or "<dir>") .. "\n\n" | 387 | buf = buf .. " luarocks config " .. key .. " " .. (what or "<dir>") .. "\n\n" |
357 | buf = buf .. " to fix the location\n" | 388 | buf = buf .. " to fix the location\n" |
@@ -359,7 +390,7 @@ local function use_to_fix_location(key, what) | |||
359 | return buf | 390 | return buf |
360 | end | 391 | end |
361 | 392 | ||
362 | local function get_config_text(cfg) -- luacheck: ignore 431 | 393 | local function get_config_text(cfg) |
363 | local deps = require("luarocks.deps") | 394 | local deps = require("luarocks.deps") |
364 | 395 | ||
365 | local libdir_ok = deps.check_lua_libdir(cfg.variables) | 396 | local libdir_ok = deps.check_lua_libdir(cfg.variables) |
@@ -367,42 +398,42 @@ local function get_config_text(cfg) -- luacheck: ignore 431 | |||
367 | local lua_ok = cfg.variables.LUA and fs.exists(cfg.variables.LUA) | 398 | local lua_ok = cfg.variables.LUA and fs.exists(cfg.variables.LUA) |
368 | 399 | ||
369 | local buf = "Configuration:\n" | 400 | local buf = "Configuration:\n" |
370 | buf = buf.." Lua:\n" | 401 | buf = buf .. " Lua:\n" |
371 | buf = buf.." Version : "..cfg.lua_version.."\n" | 402 | buf = buf .. " Version : " .. cfg.lua_version .. "\n" |
372 | if cfg.luajit_version then | 403 | if cfg.luajit_version then |
373 | buf = buf.." LuaJIT : "..cfg.luajit_version.."\n" | 404 | buf = buf .. " LuaJIT : " .. cfg.luajit_version .. "\n" |
374 | end | 405 | end |
375 | buf = buf.." LUA : "..show_status(cfg.variables.LUA, lua_ok, "interpreter not found").."\n" | 406 | buf = buf .. " LUA : " .. show_status(cfg.variables.LUA, lua_ok, "interpreter not found") .. "\n" |
376 | if not lua_ok then | 407 | if not lua_ok then |
377 | buf = buf .. use_to_fix_location("variables.LUA", lua_example) | 408 | buf = buf .. use_to_fix_location("variables.LUA", lua_example) |
378 | end | 409 | end |
379 | buf = buf.." LUA_INCDIR : "..show_status(cfg.variables.LUA_INCDIR, incdir_ok, "lua.h not found").."\n" | 410 | buf = buf .. " LUA_INCDIR : " .. show_status(cfg.variables.LUA_INCDIR, incdir_ok, "lua.h not found") .. "\n" |
380 | if lua_ok and not incdir_ok then | 411 | if lua_ok and not incdir_ok then |
381 | buf = buf .. use_to_fix_location("variables.LUA_INCDIR") | 412 | buf = buf .. use_to_fix_location("variables.LUA_INCDIR") |
382 | end | 413 | end |
383 | buf = buf.." LUA_LIBDIR : "..show_status(cfg.variables.LUA_LIBDIR, libdir_ok, "Lua library itself not found").."\n" | 414 | buf = buf .. " LUA_LIBDIR : " .. show_status(cfg.variables.LUA_LIBDIR, libdir_ok, "Lua library itself not found") .. "\n" |
384 | if lua_ok and not libdir_ok then | 415 | if lua_ok and not libdir_ok then |
385 | buf = buf .. use_to_fix_location("variables.LUA_LIBDIR") | 416 | buf = buf .. use_to_fix_location("variables.LUA_LIBDIR") |
386 | end | 417 | end |
387 | 418 | ||
388 | buf = buf.."\n Configuration files:\n" | 419 | buf = buf .. "\n Configuration files:\n" |
389 | local conf = cfg.config_files | 420 | local conf = cfg.config_files |
390 | buf = buf.." System : "..show_status(fs.absolute_name(conf.system.file), conf.system.found).."\n" | 421 | buf = buf .. " System : " .. show_status(fs.absolute_name(conf.system.file), conf.system.found) .. "\n" |
391 | if conf.user.file then | 422 | if conf.user.file then |
392 | buf = buf.." User : "..show_status(fs.absolute_name(conf.user.file), conf.user.found).."\n" | 423 | buf = buf .. " User : " .. show_status(fs.absolute_name(conf.user.file), conf.user.found) .. "\n" |
393 | else | 424 | else |
394 | buf = buf.." User : disabled in this LuaRocks installation.\n" | 425 | buf = buf .. " User : disabled in this LuaRocks installation.\n" |
395 | end | 426 | end |
396 | if conf.project then | 427 | if conf.project then |
397 | buf = buf.." Project : "..show_status(fs.absolute_name(conf.project.file), conf.project.found).."\n" | 428 | buf = buf .. " Project : " .. show_status(fs.absolute_name(conf.project.file), conf.project.found) .. "\n" |
398 | end | 429 | end |
399 | buf = buf.."\n Rocks trees in use: \n" | 430 | buf = buf .. "\n Rocks trees in use: \n" |
400 | for _, tree in ipairs(cfg.rocks_trees) do | 431 | for _, tree in ipairs(cfg.rocks_trees) do |
401 | if type(tree) == "string" then | 432 | if type(tree) == "string" then |
402 | buf = buf.." "..fs.absolute_name(tree) | 433 | buf = buf .. " " .. fs.absolute_name(tree) |
403 | else | 434 | else |
404 | local name = tree.name and " (\""..tree.name.."\")" or "" | 435 | local name = tree.name and " (\"" .. tree.name .. "\")" or "" |
405 | buf = buf.." "..fs.absolute_name(tree.root)..name | 436 | buf = buf .. " " .. fs.absolute_name(tree.root) .. name |
406 | end | 437 | end |
407 | buf = buf .. "\n" | 438 | buf = buf .. "\n" |
408 | end | 439 | end |
@@ -413,23 +444,23 @@ end | |||
413 | local function get_parser(description, cmd_modules) | 444 | local function get_parser(description, cmd_modules) |
414 | local basename = dir.base_name(program) | 445 | local basename = dir.base_name(program) |
415 | local parser = argparse( | 446 | local parser = argparse( |
416 | basename, "LuaRocks "..cfg.program_version..", the Lua package manager\n\n".. | 447 | basename, "LuaRocks " .. cfg.program_version .. ", the Lua package manager\n\n" .. |
417 | program.." - "..description, variables_help.."Run '"..basename.. | 448 | program .. " - " .. description, variables_help .. "Run '" .. basename .. |
418 | "' without any arguments to see the configuration.") | 449 | "' without any arguments to see the configuration."): |
419 | :help_max_width(80) | 450 | help_max_width(80): |
420 | :add_help_command() | 451 | add_help_command(): |
421 | :add_complete_command({ | 452 | add_complete_command({ |
422 | help_max_width = 100, | 453 | help_max_width = 100, |
423 | summary = "Output a shell completion script.", | 454 | summary = "Output a shell completion script.", |
424 | description = [[ | 455 | description = [[ |
425 | Output a shell completion script. | 456 | Output a shell completion script. |
426 | 457 | ||
427 | Enabling completions for Bash: | 458 | Enabling completions for Bash: |
428 | 459 | ||
429 | Add the following line to your ~/.bashrc: | 460 | Add the following line to your ~/.bashrc: |
430 | source <(]]..basename..[[ completion bash) | 461 | source <(]] .. basename .. [[ completion bash) |
431 | or save the completion script to the local completion directory: | 462 | or save the completion script to the local completion directory: |
432 | ]]..basename..[[ completion bash > ~/.local/share/bash-completion/completions/]]..basename..[[ | 463 | ]] .. basename .. [[ completion bash > ~/.local/share/bash-completion/completions/]] .. basename .. [[ |
433 | 464 | ||
434 | 465 | ||
435 | Enabling completions for Zsh: | 466 | Enabling completions for Zsh: |
@@ -439,61 +470,61 @@ Enabling completions for Zsh: | |||
439 | fpath=(~/.zfunc $fpath) | 470 | fpath=(~/.zfunc $fpath) |
440 | to your ~/.zshrc. | 471 | to your ~/.zshrc. |
441 | Then run: | 472 | Then run: |
442 | ]]..basename..[[ completion zsh > ~/.zfunc/_]]..basename..[[ | 473 | ]] .. basename .. [[ completion zsh > ~/.zfunc/_]] .. basename .. [[ |
443 | 474 | ||
444 | 475 | ||
445 | Enabling completion for Fish: | 476 | Enabling completion for Fish: |
446 | 477 | ||
447 | Add the following line to your ~/.config/fish/config.fish: | 478 | Add the following line to your ~/.config/fish/config.fish: |
448 | ]]..basename..[[ completion fish | source | 479 | ]] .. basename .. [[ completion fish | source |
449 | or save the completion script to the local completion directory: | 480 | or save the completion script to the local completion directory: |
450 | ]]..basename..[[ completion fish > ~/.config/fish/completions/]]..basename..[[.fish | 481 | ]] .. basename .. [[ completion fish > ~/.config/fish/completions/]] .. basename .. [[.fish |
451 | ]]}) | 482 | ]], }): |
452 | :command_target("command") | 483 | command_target("command"): |
453 | :require_command(false) | 484 | require_command(false) |
454 | 485 | ||
455 | parser:flag("--version", "Show version info and exit.") | 486 | parser:flag("--version", "Show version info and exit."): |
456 | :action(function() | 487 | action(function() |
457 | util.printout(program.." "..cfg.program_version) | 488 | util.printout(program .. " " .. cfg.program_version) |
458 | util.printout(description) | 489 | util.printout(description) |
459 | util.printout() | 490 | util.printout() |
460 | os.exit(cmd.errorcodes.OK) | 491 | os.exit(cmd.errorcodes.OK) |
461 | end) | 492 | end) |
462 | parser:flag("--dev", "Enable the sub-repositories in rocks servers for ".. | 493 | parser:flag("--dev", "Enable the sub-repositories in rocks servers for " .. |
463 | "rockspecs of in-development versions.") | 494 | "rockspecs of in-development versions.") |
464 | parser:option("--server", "Fetch rocks/rockspecs from this server ".. | 495 | parser:option("--server", "Fetch rocks/rockspecs from this server " .. |
465 | "(takes priority over config file).") | 496 | "(takes priority over config file)."): |
466 | :hidden_name("--from") | 497 | hidden_name("--from") |
467 | parser:option("--only-server", "Fetch rocks/rockspecs from this server only ".. | 498 | parser:option("--only-server", "Fetch rocks/rockspecs from this server only " .. |
468 | "(overrides any entries in the config file).") | 499 | "(overrides any entries in the config file)."): |
469 | :argname("<server>") | 500 | argname("<server>"): |
470 | :hidden_name("--only-from") | 501 | hidden_name("--only-from") |
471 | parser:option("--only-sources", "Restrict downloads to paths matching the given URL.") | 502 | parser:option("--only-sources", "Restrict downloads to paths matching the given URL."): |
472 | :argname("<url>") | 503 | argname("<url>"): |
473 | :hidden_name("--only-sources-from") | 504 | hidden_name("--only-sources-from") |
474 | parser:option("--namespace", "Specify the rocks server namespace to use.") | 505 | parser:option("--namespace", "Specify the rocks server namespace to use."): |
475 | :convert(string.lower) | 506 | convert(string.lower) |
476 | parser:option("--lua-dir", "Which Lua installation to use.") | 507 | parser:option("--lua-dir", "Which Lua installation to use."): |
477 | :argname("<prefix>") | 508 | argname("<prefix>") |
478 | parser:option("--lua-version", "Which Lua version to use.") | 509 | parser:option("--lua-version", "Which Lua version to use."): |
479 | :argname("<ver>") | 510 | argname("<ver>"): |
480 | :convert(function(s) return (s:match("^%d+%.%d+$")) end) | 511 | convert(function(s) return (s:match("^%d+%.%d+$")) end) |
481 | parser:option("--tree", "Which tree to operate on.") | 512 | parser:option("--tree", "Which tree to operate on."): |
482 | :hidden_name("--to") | 513 | hidden_name("--to") |
483 | parser:flag("--local", "Use the tree in the user's home directory.\n".. | 514 | parser:flag("--local", "Use the tree in the user's home directory.\n" .. |
484 | "To enable it, see '"..program.." help path'.") | 515 | "To enable it, see '" .. program .. " help path'.") |
485 | parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") | 516 | parser:flag("--global", "Use the system tree when `local_by_default` is `true`.") |
486 | parser:flag("--no-project", "Do not use project tree even if running from a project folder.") | 517 | parser:flag("--no-project", "Do not use project tree even if running from a project folder.") |
487 | parser:flag("--force-lock", "Attempt to overwrite the lock for commands " .. | 518 | parser:flag("--force-lock", "Attempt to overwrite the lock for commands " .. |
488 | "that require exclusive access, such as 'install'") | 519 | "that require exclusive access, such as 'install'") |
489 | parser:flag("--verbose", "Display verbose output of commands executed.") | 520 | parser:flag("--verbose", "Display verbose output of commands executed.") |
490 | parser:option("--timeout", "Timeout on network operations, in seconds.\n".. | 521 | parser:option("--timeout", "Timeout on network operations, in seconds.\n" .. |
491 | "0 means no timeout (wait forever). Default is ".. | 522 | "0 means no timeout (wait forever). Default is " .. |
492 | tostring(cfg.connection_timeout)..".") | 523 | tostring(cfg.connection_timeout) .. "."): |
493 | :argname("<seconds>") | 524 | argname("<seconds>"): |
494 | :convert(tonumber) | 525 | convert(tonumber) |
526 | |||
495 | 527 | ||
496 | -- Used internally to force the use of a particular project tree | ||
497 | parser:option("--project-tree"):hidden(true) | 528 | parser:option("--project-tree"):hidden(true) |
498 | 529 | ||
499 | for _, module in util.sortedpairs(cmd_modules) do | 530 | for _, module in util.sortedpairs(cmd_modules) do |
@@ -511,31 +542,31 @@ local function get_first_arg() | |||
511 | local i = -1 | 542 | local i = -1 |
512 | while arg[i] do | 543 | while arg[i] do |
513 | first_arg = arg[i] | 544 | first_arg = arg[i] |
514 | i = i -1 | 545 | i = i - 1 |
515 | end | 546 | end |
516 | return first_arg | 547 | return first_arg |
517 | end | 548 | end |
518 | 549 | ||
519 | --- Main command-line processor. | 550 | |
520 | -- Parses input arguments and calls the appropriate driver function | 551 | |
521 | -- to execute the action requested on the command-line, forwarding | 552 | |
522 | -- to it any additional arguments passed by the user. | 553 | |
523 | -- @param description string: Short summary description of the program. | 554 | |
524 | -- @param commands table: contains the loaded modules representing commands. | 555 | |
525 | -- @param external_namespace string: where to look for external commands. | 556 | |
526 | -- @param ... string: Arguments given on the command-line. | 557 | |
527 | function cmd.run_command(description, commands, external_namespace, ...) | 558 | function cmd.run_command(description, commands, external_namespace, ...) |
528 | 559 | ||
529 | check_popen() | 560 | check_popen() |
530 | 561 | ||
531 | -- Preliminary initialization | 562 | |
532 | cfg.init() | 563 | cfg.init() |
533 | 564 | ||
534 | fs.init() | 565 | fs.init() |
535 | 566 | ||
536 | for _, module_name in ipairs(fs.modules(external_namespace)) do | 567 | for _, module_name in ipairs(fs.modules(external_namespace)) do |
537 | if not commands[module_name] then | 568 | if not commands[module_name] then |
538 | commands[module_name] = external_namespace.."."..module_name | 569 | commands[module_name] = external_namespace .. "." .. module_name |
539 | end | 570 | end |
540 | end | 571 | end |
541 | 572 | ||
@@ -547,15 +578,15 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
547 | if original_command then | 578 | if original_command then |
548 | if not mod.add_to_parser then | 579 | if not mod.add_to_parser then |
549 | mod.add_to_parser = function(parser) | 580 | mod.add_to_parser = function(parser) |
550 | parser:command(name, mod.help, util.see_also()) | 581 | parser:command(name, mod.help, util.see_also()): |
551 | :summary(mod.help_summary) | 582 | summary(mod.help_summary): |
552 | :handle_options(false) | 583 | handle_options(false): |
553 | :argument("input") | 584 | argument("input"): |
554 | :args("*") | 585 | args("*") |
555 | end | 586 | end |
556 | 587 | ||
557 | mod.command = function(args) | 588 | mod.command = function(args) |
558 | return original_command(args, unpack(args.input)) | 589 | return original_command(args, _tl_table_unpack(args.input)) |
559 | end | 590 | end |
560 | end | 591 | end |
561 | cmd_modules[name] = mod | 592 | cmd_modules[name] = mod |
@@ -563,12 +594,12 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
563 | util.warning("command module " .. module .. " does not implement command(), skipping") | 594 | util.warning("command module " .. module .. " does not implement command(), skipping") |
564 | end | 595 | end |
565 | else | 596 | else |
566 | util.warning("failed to load command module " .. module .. ": " .. mod) | 597 | util.warning("failed to load command module " .. module .. ": " .. tostring(mod)) |
567 | end | 598 | end |
568 | end | 599 | end |
569 | 600 | ||
570 | local function process_cmdline_vars(...) | 601 | local function process_cmdline_vars(...) |
571 | local args = pack(...) | 602 | local args = table.pack(...) |
572 | local cmdline_vars = {} | 603 | local cmdline_vars = {} |
573 | local last = args.n | 604 | local last = args.n |
574 | for i = 1, args.n do | 605 | for i = 1, args.n do |
@@ -585,7 +616,7 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
585 | cmdline_vars[var] = val | 616 | cmdline_vars[var] = val |
586 | table.remove(args, i) | 617 | table.remove(args, i) |
587 | else | 618 | else |
588 | die("Invalid assignment: "..arg) | 619 | die("Invalid assignment: " .. arg) |
589 | end | 620 | end |
590 | end | 621 | end |
591 | end | 622 | end |
@@ -595,48 +626,48 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
595 | 626 | ||
596 | local args, cmdline_vars = process_cmdline_vars(...) | 627 | local args, cmdline_vars = process_cmdline_vars(...) |
597 | local parser = get_parser(description, cmd_modules) | 628 | local parser = get_parser(description, cmd_modules) |
598 | args = parser:parse(args) | 629 | local argsp = parser:parse(args) |
630 | |||
599 | 631 | ||
600 | -- Compatibility for old flag | 632 | if argsp.nodeps then |
601 | if args.nodeps then | 633 | argsp.deps_mode = "none" |
602 | args.deps_mode = "none" | ||
603 | end | 634 | end |
604 | 635 | ||
605 | if args.timeout then -- setting it in the config file will kick-in earlier in the process | 636 | if argsp.timeout then |
606 | cfg.connection_timeout = args.timeout | 637 | cfg.connection_timeout = argsp.timeout |
607 | end | 638 | end |
608 | 639 | ||
609 | if args.command == "config" then | 640 | if argsp.command == "config" then |
610 | if args.key == "lua_version" and args.value then | 641 | if argsp.key == "lua_version" and argsp.value then |
611 | args.lua_version = args.value | 642 | argsp.lua_version = argsp.value |
612 | elseif args.key == "lua_dir" and args.value then | 643 | elseif argsp.key == "lua_dir" and argsp.value then |
613 | args.lua_dir = args.value | 644 | argsp.lua_dir = argsp.value |
614 | end | 645 | end |
615 | end | 646 | end |
616 | 647 | ||
617 | ----------------------------------------------------------------------------- | 648 | |
618 | local lua_found, err = init_config(args) | 649 | local lua_found, err = init_config(argsp) |
619 | if err then | 650 | if err then |
620 | die(err) | 651 | die(err) |
621 | end | 652 | end |
622 | ----------------------------------------------------------------------------- | ||
623 | 653 | ||
624 | -- Now that the config is fully loaded, reinitialize fs using the full | 654 | |
625 | -- feature set. | 655 | |
656 | |||
626 | fs.init() | 657 | fs.init() |
627 | 658 | ||
628 | -- if the Lua interpreter wasn't explicitly found before cfg.init, | 659 | |
629 | -- try again now. | 660 | |
630 | local tried | 661 | local tried |
631 | if not lua_found then | 662 | if not lua_found then |
632 | local detected | 663 | local detected |
633 | detected, tried = search_lua(cfg.lua_version, args.verbose, cfg.variables.LUA_DIR) | 664 | detected, tried = search_lua(cfg.lua_version, argsp.verbose, cfg.variables.LUA_DIR) |
634 | if detected then | 665 | if detected then |
635 | lua_found = true | 666 | lua_found = true |
636 | cfg.variables.LUA = detected.lua | 667 | cfg.variables.LUA = detected.lua |
637 | cfg.variables.LUA_DIR = detected.lua_dir | 668 | cfg.variables.LUA_DIR = detected.lua_dir |
638 | cfg.variables.LUA_BINDIR = detected.lua_bindir | 669 | cfg.variables.LUA_BINDIR = detected.lua_bindir |
639 | if args.lua_dir then | 670 | if argsp.lua_dir then |
640 | cfg.variables.LUA_INCDIR = nil | 671 | cfg.variables.LUA_INCDIR = nil |
641 | cfg.variables.LUA_LIBDIR = nil | 672 | cfg.variables.LUA_LIBDIR = nil |
642 | end | 673 | end |
@@ -652,10 +683,10 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
652 | if lua_found then | 683 | if lua_found then |
653 | assert(cfg.variables.LUA) | 684 | assert(cfg.variables.LUA) |
654 | else | 685 | else |
655 | -- Fallback producing _some_ Lua configuration based on the running interpreter. | 686 | |
656 | -- Most likely won't produce correct results when running from the standalone binary, | 687 | |
657 | -- so eventually we need to drop this and outright fail if Lua is not found | 688 | |
658 | -- or explictly configured | 689 | |
659 | if not cfg.variables.LUA then | 690 | if not cfg.variables.LUA then |
660 | local first_arg = get_first_arg() | 691 | local first_arg = get_first_arg() |
661 | local bin_dir = dir.dir_name(fs.absolute_name(first_arg)) | 692 | local bin_dir = dir.dir_name(fs.absolute_name(first_arg)) |
@@ -678,7 +709,7 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
678 | cfg.project_dir = fs.absolute_name(cfg.project_dir) | 709 | cfg.project_dir = fs.absolute_name(cfg.project_dir) |
679 | end | 710 | end |
680 | 711 | ||
681 | if args.verbose then | 712 | if argsp.verbose then |
682 | cfg.verbose = true | 713 | cfg.verbose = true |
683 | print(("-"):rep(79)) | 714 | print(("-"):rep(79)) |
684 | print("Current configuration:") | 715 | print("Current configuration:") |
@@ -692,78 +723,78 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
692 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") | 723 | die("Current directory does not exist. Please run LuaRocks from an existing directory.") |
693 | end | 724 | end |
694 | 725 | ||
695 | local ok, err = process_tree_args(args, cfg.project_dir) | 726 | local ok, err = process_tree_args(argsp, cfg.project_dir) |
696 | if not ok then | 727 | if not ok then |
697 | die(err) | 728 | die(err) |
698 | end | 729 | end |
699 | 730 | ||
700 | ok, err = process_server_args(args) | 731 | ok, err = process_server_args(argsp) |
701 | if not ok then | 732 | if not ok then |
702 | die(err) | 733 | die(err) |
703 | end | 734 | end |
704 | 735 | ||
705 | if args.only_sources then | 736 | if argsp.only_sources then |
706 | cfg.only_sources_from = args.only_sources | 737 | cfg.only_sources_from = argsp.only_sources |
707 | end | 738 | end |
708 | 739 | ||
709 | for k, v in pairs(cmdline_vars) do | 740 | for k, v in pairs(cmdline_vars) do |
710 | cfg.variables[k] = v | 741 | cfg.variables[k] = v |
711 | end | 742 | end |
712 | 743 | ||
713 | -- if running as superuser, use system cache dir | 744 | |
714 | if fs.is_superuser() then | 745 | if fs.is_superuser() then |
715 | cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") | 746 | cfg.local_cache = dir.path(fs.system_cache_dir(), "luarocks") |
716 | end | 747 | end |
717 | 748 | ||
718 | if args.no_manifest then | 749 | if argsp.no_manifest then |
719 | cfg.no_manifest = true | 750 | cfg.no_manifest = true |
720 | end | 751 | end |
721 | 752 | ||
722 | if not args.command then | 753 | if not argsp.command then |
723 | parser:epilog(variables_help..get_config_text(cfg)) | 754 | parser:epilog(variables_help .. get_config_text(cfg)) |
724 | util.printout() | 755 | util.printout() |
725 | util.printout(parser:get_help()) | 756 | util.printout(parser:get_help()) |
726 | util.printout() | 757 | util.printout() |
727 | os.exit(cmd.errorcodes.OK) | 758 | os.exit(cmd.errorcodes.OK) |
728 | end | 759 | end |
729 | 760 | ||
730 | if not cfg.variables["LUA"] and args.command ~= "config" and args.command ~= "help" then | 761 | if not cfg.variables["LUA"] and argsp.command ~= "config" and argsp.command ~= "help" then |
731 | local flag = (not cfg.project_tree) | 762 | local flag = (not cfg.project_tree) and |
732 | and "--local " | 763 | "--local " or |
733 | or "" | 764 | "" |
734 | if args.lua_version then | 765 | if argsp.lua_version then |
735 | flag = "--lua-version=" .. args.lua_version .. " " .. flag | 766 | flag = "--lua-version=" .. argsp.lua_version .. " " .. flag |
736 | end | 767 | end |
737 | die((tried or "Lua interpreter not found.") .. | 768 | die((tried or "Lua interpreter not found.") .. |
738 | "\nPlease set your Lua interpreter with:\n\n" .. | 769 | "\nPlease set your Lua interpreter with:\n\n" .. |
739 | " luarocks " .. flag.. "config variables.LUA " .. lua_example .. "\n") | 770 | " luarocks " .. flag .. "config variables.LUA " .. lua_example .. "\n") |
740 | end | 771 | end |
741 | 772 | ||
742 | local cmd_mod = cmd_modules[args.command] | 773 | local cmd_mod = cmd_modules[argsp.command] |
743 | 774 | ||
744 | local lock | 775 | local lock |
745 | if cmd_mod.needs_lock and cmd_mod.needs_lock(args) then | 776 | if cmd_mod.needs_lock and cmd_mod.needs_lock(argsp) then |
746 | local ok, err = fs.check_command_permissions(args) | 777 | local ok, err = fs.check_command_permissions(argsp) |
747 | if not ok then | 778 | if not ok then |
748 | die(err, cmd.errorcodes.PERMISSIONDENIED) | 779 | die(err, cmd.errorcodes.PERMISSIONDENIED) |
749 | end | 780 | end |
750 | 781 | ||
751 | lock, err = fs.lock_access(path.root_dir(cfg.root_dir), args.force_lock) | 782 | lock, err = fs.lock_access(path.root_dir(cfg.root_dir), argsp.force_lock) |
752 | if not lock then | 783 | if not lock then |
753 | err = args.force_lock | 784 | err = argsp.force_lock and |
754 | and ("failed to force the lock" .. (err and ": " .. err or "")) | 785 | ("failed to force the lock" .. (err and ": " .. err or "")) or |
755 | or (err and err ~= "File exists") | 786 | (err and err ~= "File exists") and |
756 | and err | 787 | err or |
757 | or "try --force-lock to overwrite the lock" | 788 | "try --force-lock to overwrite the lock" |
758 | 789 | ||
759 | die("command '" .. args.command .. "' " .. | 790 | die("command '" .. argsp.command .. "' " .. |
760 | "requires exclusive write access to " .. path.root_dir(cfg.root_dir) .. " - " .. | 791 | "requires exclusive write access to " .. path.root_dir(cfg.root_dir) .. " - " .. |
761 | err, cmd.errorcodes.LOCK) | 792 | err, cmd.errorcodes.LOCK) |
762 | end | 793 | end |
763 | end | 794 | end |
764 | 795 | ||
765 | local call_ok, ok, err, exitcode = xpcall(function() | 796 | local call_ok, ok, err, exitcode = xpcall(function() |
766 | return cmd_mod.command(args) | 797 | return cmd_mod.command(argsp) |
767 | end, error_handler) | 798 | end, error_handler) |
768 | 799 | ||
769 | if lock then | 800 | if lock then |
@@ -771,7 +802,7 @@ function cmd.run_command(description, commands, external_namespace, ...) | |||
771 | end | 802 | end |
772 | 803 | ||
773 | if not call_ok then | 804 | if not call_ok then |
774 | die(ok, cmd.errorcodes.CRASH) | 805 | die(tostring(ok), cmd.errorcodes.CRASH) |
775 | elseif not ok then | 806 | elseif not ok then |
776 | die(err, exitcode) | 807 | die(err, exitcode) |
777 | end | 808 | end |
diff --git a/src/luarocks/cmd.tl b/src/luarocks/cmd.tl index b9490e66..64abf6ce 100644 --- a/src/luarocks/cmd.tl +++ b/src/luarocks/cmd.tl | |||
@@ -5,7 +5,7 @@ local record cmd | |||
5 | 5 | ||
6 | record Module | 6 | record Module |
7 | add_to_parser: function(Parser) | 7 | add_to_parser: function(Parser) |
8 | command: function(Args): boolean, string | 8 | command: function(Args, ...: string): boolean, string, integer |
9 | needs_lock: function(Args): boolean | 9 | needs_lock: function(Args): boolean |
10 | help: string | 10 | help: string |
11 | help_summary: string | 11 | help_summary: string |
@@ -585,7 +585,7 @@ function cmd.run_command(description: string, commands: {string: string}, extern | |||
585 | :args("*") | 585 | :args("*") |
586 | end | 586 | end |
587 | 587 | ||
588 | mod.command = function(args: Args): boolean, string | 588 | mod.command = function(args: Args): boolean, string, integer |
589 | return original_command(args, table.unpack(args.input)) | 589 | return original_command(args, table.unpack(args.input)) |
590 | end | 590 | end |
591 | end | 591 | end |
@@ -594,7 +594,7 @@ function cmd.run_command(description: string, commands: {string: string}, extern | |||
594 | util.warning("command module " .. module .. " does not implement command(), skipping") | 594 | util.warning("command module " .. module .. " does not implement command(), skipping") |
595 | end | 595 | end |
596 | else | 596 | else |
597 | util.warning("failed to load command module " .. module .. ": " .. mod) | 597 | util.warning("failed to load command module " .. module .. ": " .. tostring(mod)) |
598 | end | 598 | end |
599 | end | 599 | end |
600 | 600 | ||
@@ -793,7 +793,7 @@ function cmd.run_command(description: string, commands: {string: string}, extern | |||
793 | end | 793 | end |
794 | end | 794 | end |
795 | 795 | ||
796 | local call_ok, ok, err, exitcode = xpcall(function(): boolean, string | 796 | local call_ok, ok, err, exitcode = xpcall(function(): boolean, string, integer |
797 | return cmd_mod.command(argsp) | 797 | return cmd_mod.command(argsp) |
798 | end, error_handler) | 798 | end, error_handler) |
799 | 799 | ||
@@ -802,7 +802,7 @@ function cmd.run_command(description: string, commands: {string: string}, extern | |||
802 | end | 802 | end |
803 | 803 | ||
804 | if not call_ok then | 804 | if not call_ok then |
805 | die(ok, cmd.errorcodes.CRASH) | 805 | die(tostring(ok), cmd.errorcodes.CRASH) |
806 | elseif not ok then | 806 | elseif not ok then |
807 | die(err, exitcode) | 807 | die(err, exitcode) |
808 | end | 808 | end |
diff --git a/src/luarocks/cmd/build-original.lua b/src/luarocks/cmd/build-original.lua new file mode 100644 index 00000000..6d719d5a --- /dev/null +++ b/src/luarocks/cmd/build-original.lua | |||
@@ -0,0 +1,199 @@ | |||
1 | |||
2 | --- Module implementing the LuaRocks "build" command. | ||
3 | -- Builds a rock, compiling its C parts if any. | ||
4 | local cmd_build = {} | ||
5 | |||
6 | local pack = require("luarocks.pack") | ||
7 | local path = require("luarocks.path") | ||
8 | local dir = require("luarocks.dir") | ||
9 | local util = require("luarocks.util") | ||
10 | local fetch = require("luarocks.fetch") | ||
11 | local fs = require("luarocks.fs") | ||
12 | local deps = require("luarocks.deps") | ||
13 | local remove = require("luarocks.remove") | ||
14 | local cfg = require("luarocks.core.cfg") | ||
15 | local build = require("luarocks.build") | ||
16 | local search = require("luarocks.search") | ||
17 | local make = require("luarocks.cmd.make") | ||
18 | local repos = require("luarocks.repos") | ||
19 | |||
20 | function cmd_build.add_to_parser(parser) | ||
21 | local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.\n".. -- luacheck: ignore 431 | ||
22 | "If the sources contain a luarocks.lock file, uses it as an authoritative source for ".. | ||
23 | "exact version of dependencies.\n".. | ||
24 | "If no arguments are given, behaves as luarocks make.", util.see_also()) | ||
25 | :summary("Build/compile a rock.") | ||
26 | |||
27 | cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. | ||
28 | "a rock to be fetched from a repository.") | ||
29 | :args("?") | ||
30 | :action(util.namespaced_name_action) | ||
31 | cmd:argument("version", "Rock version.") | ||
32 | :args("?") | ||
33 | |||
34 | cmd:flag("--only-deps --deps-only", "Install only the dependencies of the rock.") | ||
35 | cmd:option("--branch", "Override the `source.branch` field in the loaded ".. | ||
36 | "rockspec. Allows to specify a different branch to fetch. Particularly ".. | ||
37 | 'for "dev" rocks.') | ||
38 | :argname("<name>") | ||
39 | cmd:flag("--pin", "Create a luarocks.lock file listing the exact ".. | ||
40 | "versions of each dependency found for this rock (recursively), ".. | ||
41 | "and store it in the rock's directory. ".. | ||
42 | "Ignores any existing luarocks.lock file in the rock's sources.") | ||
43 | make.cmd_options(cmd) | ||
44 | end | ||
45 | |||
46 | --- Build and install a rock. | ||
47 | -- @param rock_filename string: local or remote filename of a rock. | ||
48 | -- @param opts table: build options | ||
49 | -- @return boolean or (nil, string, [string]): True if build was successful, | ||
50 | -- or false and an error message and an optional error code. | ||
51 | local function build_rock(rock_filename, opts) | ||
52 | assert(type(rock_filename) == "string") | ||
53 | |||
54 | local cwd = fs.absolute_name(dir.path(".")) | ||
55 | |||
56 | local ok, err, errcode | ||
57 | |||
58 | local unpack_dir | ||
59 | unpack_dir, err, errcode = fetch.fetch_and_unpack_rock(rock_filename, nil, opts.verify) | ||
60 | if not unpack_dir then | ||
61 | return nil, err, errcode | ||
62 | end | ||
63 | |||
64 | local rockspec_filename = path.rockspec_name_from_rock(rock_filename) | ||
65 | |||
66 | ok, err = fs.change_dir(unpack_dir) | ||
67 | if not ok then return nil, err end | ||
68 | |||
69 | local rockspec | ||
70 | rockspec, err, errcode = fetch.load_rockspec(rockspec_filename) | ||
71 | if not rockspec then | ||
72 | return nil, err, errcode | ||
73 | end | ||
74 | |||
75 | ok, err, errcode = build.build_rockspec(rockspec, opts, cwd) | ||
76 | |||
77 | fs.pop_dir() | ||
78 | return ok, err, errcode | ||
79 | end | ||
80 | |||
81 | local function do_build(name, namespace, version, opts) | ||
82 | assert(type(name) == "string") | ||
83 | assert(type(namespace) == "string" or not namespace) | ||
84 | assert(version == nil or type(version) == "string") | ||
85 | |||
86 | local url, err | ||
87 | if name:match("%.rockspec$") or name:match("%.rock$") then | ||
88 | url = name | ||
89 | else | ||
90 | url, err = search.find_src_or_rockspec(name, namespace, version, opts.check_lua_versions) | ||
91 | if not url then | ||
92 | return nil, err | ||
93 | end | ||
94 | end | ||
95 | |||
96 | name, version = path.parse_name(url) | ||
97 | if name and repos.is_installed(name, version) then | ||
98 | if not opts.rebuild then | ||
99 | util.printout(name .. " " .. version .. " is already installed in " .. path.root_dir(cfg.root_dir)) | ||
100 | util.printout("Use --force to reinstall.") | ||
101 | return name, version, "skip" | ||
102 | end | ||
103 | end | ||
104 | |||
105 | if url:match("%.rockspec$") then | ||
106 | local cwd = fs.absolute_name(dir.path(".")) | ||
107 | local rockspec, err = fetch.load_rockspec(url, nil, opts.verify) | ||
108 | if not rockspec then | ||
109 | return nil, err | ||
110 | end | ||
111 | return build.build_rockspec(rockspec, opts, cwd) | ||
112 | end | ||
113 | |||
114 | if url:match("%.src%.rock$") then | ||
115 | opts.need_to_fetch = false | ||
116 | end | ||
117 | |||
118 | return build_rock(url, opts) | ||
119 | end | ||
120 | |||
121 | --- Driver function for "build" command. | ||
122 | -- If a package name is given, forwards the request to "search" and, | ||
123 | -- if returned a result, installs the matching rock. | ||
124 | -- When passing a package name, a version number may also be given. | ||
125 | -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an | ||
126 | -- error message otherwise. exitcode is optionally returned. | ||
127 | function cmd_build.command(args) | ||
128 | if not args.rock then | ||
129 | return make.command(args) | ||
130 | end | ||
131 | |||
132 | local opts = { | ||
133 | need_to_fetch = true, | ||
134 | minimal_mode = false, | ||
135 | deps_mode = deps.get_deps_mode(args), | ||
136 | build_only_deps = not not (args.only_deps and not args.pack_binary_rock), | ||
137 | namespace = args.namespace, | ||
138 | branch = args.branch, | ||
139 | verify = not not args.verify, | ||
140 | check_lua_versions = not not args.check_lua_versions, | ||
141 | pin = not not args.pin, | ||
142 | rebuild = not not (args.force or args.force_fast), | ||
143 | no_install = false | ||
144 | } | ||
145 | |||
146 | if args.sign and not args.pack_binary_rock then | ||
147 | return nil, "In the build command, --sign is meant to be used only with --pack-binary-rock" | ||
148 | end | ||
149 | |||
150 | if args.pack_binary_rock then | ||
151 | return pack.pack_binary_rock(args.rock, args.namespace, args.version, args.sign, function() | ||
152 | local name, version = do_build(args.rock, args.namespace, args.version, opts) | ||
153 | if name and args.no_doc then | ||
154 | util.remove_doc_dir(name, version) | ||
155 | end | ||
156 | return name, version | ||
157 | end) | ||
158 | end | ||
159 | |||
160 | local name, version, skip = do_build(args.rock, args.namespace, args.version, opts) | ||
161 | if not name then | ||
162 | return nil, version | ||
163 | end | ||
164 | if skip == "skip" then | ||
165 | return name, version | ||
166 | end | ||
167 | |||
168 | if args.no_doc then | ||
169 | util.remove_doc_dir(name, version) | ||
170 | end | ||
171 | |||
172 | if opts.build_only_deps then | ||
173 | util.printout("Stopping after installing dependencies for " ..name.." "..version) | ||
174 | util.printout() | ||
175 | else | ||
176 | if (not args.keep) and not cfg.keep_other_versions then | ||
177 | local ok, err, warn = remove.remove_other_versions(name, version, args.force, args.force_fast) | ||
178 | if not ok then | ||
179 | return nil, err | ||
180 | elseif warn then | ||
181 | util.printerr(err) | ||
182 | end | ||
183 | end | ||
184 | end | ||
185 | |||
186 | if opts.deps_mode ~= "none" then | ||
187 | deps.check_dependencies(nil, deps.get_deps_mode(args)) | ||
188 | end | ||
189 | return name, version | ||
190 | end | ||
191 | |||
192 | cmd_build.needs_lock = function(args) | ||
193 | if args.pack_binary_rock then | ||
194 | return false | ||
195 | end | ||
196 | return true | ||
197 | end | ||
198 | |||
199 | return cmd_build | ||
diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 6d719d5a..6aa3afe0 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua | |||
@@ -1,8 +1,10 @@ | |||
1 | local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local string = _tl_compat and _tl_compat.string or string | ||
2 | |||
1 | 3 | ||
2 | --- Module implementing the LuaRocks "build" command. | ||
3 | -- Builds a rock, compiling its C parts if any. | ||
4 | local cmd_build = {} | 4 | local cmd_build = {} |
5 | 5 | ||
6 | |||
7 | |||
6 | local pack = require("luarocks.pack") | 8 | local pack = require("luarocks.pack") |
7 | local path = require("luarocks.path") | 9 | local path = require("luarocks.path") |
8 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
@@ -17,39 +19,49 @@ local search = require("luarocks.search") | |||
17 | local make = require("luarocks.cmd.make") | 19 | local make = require("luarocks.cmd.make") |
18 | local repos = require("luarocks.repos") | 20 | local repos = require("luarocks.repos") |
19 | 21 | ||
22 | local argparse = require("luarocks.vendor.argparse") | ||
23 | |||
24 | |||
25 | |||
26 | |||
27 | |||
28 | |||
29 | |||
30 | |||
31 | |||
32 | |||
20 | function cmd_build.add_to_parser(parser) | 33 | function cmd_build.add_to_parser(parser) |
21 | local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.\n".. -- luacheck: ignore 431 | 34 | local cmd = parser:command("build", "Build and install a rock, compiling its C parts if any.\n" .. |
22 | "If the sources contain a luarocks.lock file, uses it as an authoritative source for ".. | 35 | "If the sources contain a luarocks.lock file, uses it as an authoritative source for " .. |
23 | "exact version of dependencies.\n".. | 36 | "exact version of dependencies.\n" .. |
24 | "If no arguments are given, behaves as luarocks make.", util.see_also()) | 37 | "If no arguments are given, behaves as luarocks make.", util.see_also()): |
25 | :summary("Build/compile a rock.") | 38 | summary("Build/compile a rock.") |
26 | 39 | ||
27 | cmd:argument("rock", "A rockspec file, a source rock file, or the name of ".. | 40 | cmd:argument("rock", "A rockspec file, a source rock file, or the name of " .. |
28 | "a rock to be fetched from a repository.") | 41 | "a rock to be fetched from a repository."): |
29 | :args("?") | 42 | args("?"): |
30 | :action(util.namespaced_name_action) | 43 | action(util.namespaced_name_action) |
31 | cmd:argument("version", "Rock version.") | 44 | cmd:argument("version", "Rock version."): |
32 | :args("?") | 45 | args("?") |
33 | 46 | ||
34 | cmd:flag("--only-deps --deps-only", "Install only the dependencies of the rock.") | 47 | cmd:flag("--only-deps --deps-only", "Install only the dependencies of the rock.") |
35 | cmd:option("--branch", "Override the `source.branch` field in the loaded ".. | 48 | cmd:option("--branch", "Override the `source.branch` field in the loaded " .. |
36 | "rockspec. Allows to specify a different branch to fetch. Particularly ".. | 49 | "rockspec. Allows to specify a different branch to fetch. Particularly " .. |
37 | 'for "dev" rocks.') | 50 | 'for "dev" rocks.'): |
38 | :argname("<name>") | 51 | argname("<name>") |
39 | cmd:flag("--pin", "Create a luarocks.lock file listing the exact ".. | 52 | cmd:flag("--pin", "Create a luarocks.lock file listing the exact " .. |
40 | "versions of each dependency found for this rock (recursively), ".. | 53 | "versions of each dependency found for this rock (recursively), " .. |
41 | "and store it in the rock's directory. ".. | 54 | "and store it in the rock's directory. " .. |
42 | "Ignores any existing luarocks.lock file in the rock's sources.") | 55 | "Ignores any existing luarocks.lock file in the rock's sources.") |
43 | make.cmd_options(cmd) | 56 | make.cmd_options(cmd) |
44 | end | 57 | end |
45 | 58 | ||
46 | --- Build and install a rock. | 59 | |
47 | -- @param rock_filename string: local or remote filename of a rock. | 60 | |
48 | -- @param opts table: build options | 61 | |
49 | -- @return boolean or (nil, string, [string]): True if build was successful, | 62 | |
50 | -- or false and an error message and an optional error code. | 63 | |
51 | local function build_rock(rock_filename, opts) | 64 | local function build_rock(rock_filename, opts) |
52 | assert(type(rock_filename) == "string") | ||
53 | 65 | ||
54 | local cwd = fs.absolute_name(dir.path(".")) | 66 | local cwd = fs.absolute_name(dir.path(".")) |
55 | 67 | ||
@@ -72,16 +84,15 @@ local function build_rock(rock_filename, opts) | |||
72 | return nil, err, errcode | 84 | return nil, err, errcode |
73 | end | 85 | end |
74 | 86 | ||
75 | ok, err, errcode = build.build_rockspec(rockspec, opts, cwd) | 87 | local n, v = build.build_rockspec(rockspec, opts, cwd) |
88 | |||
89 | ok, err, errcode = n ~= nil, v, nil | ||
76 | 90 | ||
77 | fs.pop_dir() | 91 | fs.pop_dir() |
78 | return ok, err, errcode | 92 | return ok, err, errcode |
79 | end | 93 | end |
80 | 94 | ||
81 | local function do_build(name, namespace, version, opts) | 95 | local function do_build(name, namespace, version, opts) |
82 | assert(type(name) == "string") | ||
83 | assert(type(namespace) == "string" or not namespace) | ||
84 | assert(version == nil or type(version) == "string") | ||
85 | 96 | ||
86 | local url, err | 97 | local url, err |
87 | if name:match("%.rockspec$") or name:match("%.rock$") then | 98 | if name:match("%.rockspec$") or name:match("%.rock$") then |
@@ -115,15 +126,19 @@ local function do_build(name, namespace, version, opts) | |||
115 | opts.need_to_fetch = false | 126 | opts.need_to_fetch = false |
116 | end | 127 | end |
117 | 128 | ||
118 | return build_rock(url, opts) | 129 | local ok, err, errcode = build_rock(url, opts) |
130 | if not ok then | ||
131 | return nil, err, errcode | ||
132 | end | ||
133 | return name, version | ||
119 | end | 134 | end |
120 | 135 | ||
121 | --- Driver function for "build" command. | 136 | |
122 | -- If a package name is given, forwards the request to "search" and, | 137 | |
123 | -- if returned a result, installs the matching rock. | 138 | |
124 | -- When passing a package name, a version number may also be given. | 139 | |
125 | -- @return boolean or (nil, string, exitcode): True if build was successful; nil and an | 140 | |
126 | -- error message otherwise. exitcode is optionally returned. | 141 | |
127 | function cmd_build.command(args) | 142 | function cmd_build.command(args) |
128 | if not args.rock then | 143 | if not args.rock then |
129 | return make.command(args) | 144 | return make.command(args) |
@@ -140,7 +155,7 @@ function cmd_build.command(args) | |||
140 | check_lua_versions = not not args.check_lua_versions, | 155 | check_lua_versions = not not args.check_lua_versions, |
141 | pin = not not args.pin, | 156 | pin = not not args.pin, |
142 | rebuild = not not (args.force or args.force_fast), | 157 | rebuild = not not (args.force or args.force_fast), |
143 | no_install = false | 158 | no_install = false, |
144 | } | 159 | } |
145 | 160 | ||
146 | if args.sign and not args.pack_binary_rock then | 161 | if args.sign and not args.pack_binary_rock then |
@@ -162,7 +177,7 @@ function cmd_build.command(args) | |||
162 | return nil, version | 177 | return nil, version |
163 | end | 178 | end |
164 | if skip == "skip" then | 179 | if skip == "skip" then |
165 | return name, version | 180 | return name ~= nil, version |
166 | end | 181 | end |
167 | 182 | ||
168 | if args.no_doc then | 183 | if args.no_doc then |
@@ -170,7 +185,7 @@ function cmd_build.command(args) | |||
170 | end | 185 | end |
171 | 186 | ||
172 | if opts.build_only_deps then | 187 | if opts.build_only_deps then |
173 | util.printout("Stopping after installing dependencies for " ..name.." "..version) | 188 | util.printout("Stopping after installing dependencies for " .. name .. " " .. version) |
174 | util.printout() | 189 | util.printout() |
175 | else | 190 | else |
176 | if (not args.keep) and not cfg.keep_other_versions then | 191 | if (not args.keep) and not cfg.keep_other_versions then |
@@ -186,7 +201,7 @@ function cmd_build.command(args) | |||
186 | if opts.deps_mode ~= "none" then | 201 | if opts.deps_mode ~= "none" then |
187 | deps.check_dependencies(nil, deps.get_deps_mode(args)) | 202 | deps.check_dependencies(nil, deps.get_deps_mode(args)) |
188 | end | 203 | end |
189 | return name, version | 204 | return name ~= nil, version |
190 | end | 205 | end |
191 | 206 | ||
192 | cmd_build.needs_lock = function(args) | 207 | cmd_build.needs_lock = function(args) |
diff --git a/src/luarocks/cmd/build.tl b/src/luarocks/cmd/build.tl index 9ec58c3e..96e2ec42 100644 --- a/src/luarocks/cmd/build.tl +++ b/src/luarocks/cmd/build.tl | |||
@@ -22,8 +22,7 @@ local repos = require("luarocks.repos") | |||
22 | local argparse = require("luarocks.vendor.argparse") | 22 | local argparse = require("luarocks.vendor.argparse") |
23 | local type Parser = argparse.Parser | 23 | local type Parser = argparse.Parser |
24 | 24 | ||
25 | local type a = require("luarocks.core.types.args") | 25 | local type Args = require("luarocks.core.types.args").Args |
26 | local type Args = a.Args | ||
27 | 26 | ||
28 | local type bo = require("luarocks.core.types.bopts") | 27 | local type bo = require("luarocks.core.types.bopts") |
29 | local type BOpts = bo.BOpts | 28 | local type BOpts = bo.BOpts |
@@ -85,7 +84,9 @@ local function build_rock(rock_filename: string, opts: BOpts): boolean, string, | |||
85 | return nil, err, errcode | 84 | return nil, err, errcode |
86 | end | 85 | end |
87 | 86 | ||
88 | ok, err, errcode = build.build_rockspec(rockspec, opts, cwd) | 87 | local n, v = build.build_rockspec(rockspec, opts, cwd) |
88 | |||
89 | ok, err, errcode = n ~= nil, v, nil | ||
89 | 90 | ||
90 | fs.pop_dir() | 91 | fs.pop_dir() |
91 | return ok, err, errcode | 92 | return ok, err, errcode |
@@ -125,7 +126,11 @@ local function do_build(name: string, namespace: string, version: string, opts: | |||
125 | opts.need_to_fetch = false | 126 | opts.need_to_fetch = false |
126 | end | 127 | end |
127 | 128 | ||
128 | return build_rock(url, opts) | 129 | local ok, err, errcode = build_rock(url, opts) |
130 | if not ok then | ||
131 | return nil, err, errcode | ||
132 | end | ||
133 | return name, version | ||
129 | end | 134 | end |
130 | 135 | ||
131 | --- Driver function for "build" command. | 136 | --- Driver function for "build" command. |
@@ -172,7 +177,7 @@ function cmd_build.command(args: Args): boolean, string, string | |||
172 | return nil, version | 177 | return nil, version |
173 | end | 178 | end |
174 | if skip == "skip" then | 179 | if skip == "skip" then |
175 | return name, version | 180 | return name ~= nil, version |
176 | end | 181 | end |
177 | 182 | ||
178 | if args.no_doc then | 183 | if args.no_doc then |
@@ -196,7 +201,7 @@ function cmd_build.command(args: Args): boolean, string, string | |||
196 | if opts.deps_mode ~= "none" then | 201 | if opts.deps_mode ~= "none" then |
197 | deps.check_dependencies(nil, deps.get_deps_mode(args)) | 202 | deps.check_dependencies(nil, deps.get_deps_mode(args)) |
198 | end | 203 | end |
199 | return name, version | 204 | return name ~= nil, version |
200 | end | 205 | end |
201 | 206 | ||
202 | cmd_build.needs_lock = function(args: Args): boolean | 207 | cmd_build.needs_lock = function(args: Args): boolean |
diff --git a/src/luarocks/cmd/install.tl b/src/luarocks/cmd/install.tl index 40f6c782..157ef772 100644 --- a/src/luarocks/cmd/install.tl +++ b/src/luarocks/cmd/install.tl | |||
@@ -259,4 +259,6 @@ install.needs_lock = function(args: Args): boolean | |||
259 | return true | 259 | return true |
260 | end | 260 | end |
261 | 261 | ||
262 | deps.installer = install.command | ||
263 | |||
262 | return install | 264 | return install |
diff --git a/src/luarocks/cmd/make.tl b/src/luarocks/cmd/make.tl index f151c950..4d29c6d6 100644 --- a/src/luarocks/cmd/make.tl +++ b/src/luarocks/cmd/make.tl | |||
@@ -43,7 +43,7 @@ function make.cmd_options(parser: Parser) | |||
43 | "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. | 43 | "built. If the rockspec or src.rock is being downloaded, LuaRocks will ".. |
44 | "attempt to download the signature as well. Otherwise, the signature ".. | 44 | "attempt to download the signature as well. Otherwise, the signature ".. |
45 | "file should be already available locally in the same directory.\n".. | 45 | "file should be already available locally in the same directory.\n".. |
46 | "You need the signer’s public key in your local keyring for this ".. | 46 | "You need the signer's public key in your local keyring for this ".. |
47 | "option to work properly.") | 47 | "option to work properly.") |
48 | parser:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. | 48 | parser:flag("--sign", "To be used with --pack-binary-rock. Also produce a ".. |
49 | "signature file for the generated .rock file.") | 49 | "signature file for the generated .rock file.") |
diff --git a/src/luarocks/cmd/show.tl b/src/luarocks/cmd/show.tl index 4850b3af..1d6eddda 100644 --- a/src/luarocks/cmd/show.tl +++ b/src/luarocks/cmd/show.tl | |||
@@ -23,23 +23,10 @@ local type Return = show.Return | |||
23 | 23 | ||
24 | local argparse = require("luarocks.vendor.argparse") | 24 | local argparse = require("luarocks.vendor.argparse") |
25 | local type Parser = argparse.Parser | 25 | local type Parser = argparse.Parser |
26 | local type Option = argparse.Option | ||
27 | 26 | ||
28 | local type a = require("luarocks.core.types.args") | 27 | local type a = require("luarocks.core.types.args") |
29 | local type Args = a.Args | 28 | local type Args = a.Args |
30 | 29 | ||
31 | local type bo = require("luarocks.core.types.bopts") | ||
32 | local type BOpts = bo.BOpts | ||
33 | |||
34 | local type i = require("luarocks.core.types.installs") | ||
35 | local type IOpts = i.IOpts | ||
36 | |||
37 | local type p = require("luarocks.core.types.persist") | ||
38 | local type PersistableTable = p.PersistableTable | ||
39 | |||
40 | local type res = require("luarocks.core.types.result") | ||
41 | local type Result = res.Result | ||
42 | |||
43 | local type t = require("luarocks.core.types.tree") | 30 | local type t = require("luarocks.core.types.tree") |
44 | local type Tree = t.Tree | 31 | local type Tree = t.Tree |
45 | 32 | ||
diff --git a/src/luarocks/cmd/upload.tl b/src/luarocks/cmd/upload.tl index 018d9f6e..ae02fc64 100644 --- a/src/luarocks/cmd/upload.tl +++ b/src/luarocks/cmd/upload.tl | |||
@@ -11,36 +11,10 @@ local Api = require("luarocks.upload.api") | |||
11 | 11 | ||
12 | local argparse = require("luarocks.vendor.argparse") | 12 | local argparse = require("luarocks.vendor.argparse") |
13 | local type Parser = argparse.Parser | 13 | local type Parser = argparse.Parser |
14 | local type Option = argparse.Option | ||
15 | 14 | ||
16 | local type a = require("luarocks.core.types.args") | 15 | local type a = require("luarocks.core.types.args") |
17 | local type Args = a.Args | 16 | local type Args = a.Args |
18 | 17 | ||
19 | local type bo = require("luarocks.core.types.bopts") | ||
20 | local type BOpts = bo.BOpts | ||
21 | |||
22 | local type i = require("luarocks.core.types.installs") | ||
23 | local type IOpts = i.IOpts | ||
24 | |||
25 | local type p = require("luarocks.core.types.persist") | ||
26 | local type PersistableTable = p.PersistableTable | ||
27 | |||
28 | local type res = require("luarocks.core.types.result") | ||
29 | local type Result = res.Result | ||
30 | |||
31 | local type t = require("luarocks.core.types.tree") | ||
32 | local type Tree = t.Tree | ||
33 | |||
34 | local type q = require("luarocks.core.types.query") | ||
35 | local type Query = q.Query | ||
36 | |||
37 | local type r = require("luarocks.core.types.rockspec") | ||
38 | local type Rockspec = r.Rockspec | ||
39 | local type Dependencies = r.Dependencies | ||
40 | |||
41 | local type m = require("luarocks.core.types.manifest") | ||
42 | local type Entry = m.Manifest.Entry | ||
43 | |||
44 | function upload.add_to_parser(parser: Parser) | 18 | function upload.add_to_parser(parser: Parser) |
45 | local cmd = parser:command("upload", "Pack a source rock file (.src.rock extension) ".. | 19 | local cmd = parser:command("upload", "Pack a source rock file (.src.rock extension) ".. |
46 | "and upload it and the rockspec to the public rocks repository.", util.see_also()) | 20 | "and upload it and the rockspec to the public rocks repository.", util.see_also()) |
diff --git a/src/luarocks/deps.tl b/src/luarocks/deps.tl index 1f5f24aa..58c0bd1c 100644 --- a/src/luarocks/deps.tl +++ b/src/luarocks/deps.tl | |||
@@ -1,6 +1,7 @@ | |||
1 | 1 | ||
2 | --- High-level dependency related functions. | 2 | --- High-level dependency related functions. |
3 | local record deps | 3 | local record deps |
4 | installer: function(Args): boolean, string, string | ||
4 | end | 5 | end |
5 | 6 | ||
6 | local cfg = require("luarocks.core.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
@@ -41,8 +42,7 @@ local type dr = require("luarocks.core.types.dir") | |||
41 | local type Dir = dr.Dir | 42 | local type Dir = dr.Dir |
42 | local type Dirs = dr.Dirs | 43 | local type Dirs = dr.Dirs |
43 | 44 | ||
44 | local type arg = require("luarocks.core.types.args") | 45 | local type Args = require("luarocks.core.types.args").Args |
45 | local type Args = arg.Args | ||
46 | 46 | ||
47 | --- Generate a function that matches dep queries against the manifest, | 47 | --- Generate a function that matches dep queries against the manifest, |
48 | -- taking into account rocks_provided, the list of versions to skip, | 48 | -- taking into account rocks_provided, the list of versions to skip, |
@@ -229,7 +229,6 @@ function deps.fulfill_dependency(dep: Query, deps_mode: string, rocks_provided: | |||
229 | end | 229 | end |
230 | 230 | ||
231 | local search = require("luarocks.search") | 231 | local search = require("luarocks.search") |
232 | local install = require("luarocks.cmd.install") | ||
233 | 232 | ||
234 | local url, search_err = search.find_suitable_rock(dep) | 233 | local url, search_err = search.find_suitable_rock(dep) |
235 | if not url then | 234 | if not url then |
@@ -242,7 +241,7 @@ function deps.fulfill_dependency(dep: Query, deps_mode: string, rocks_provided: | |||
242 | namespace = dep.namespace, | 241 | namespace = dep.namespace, |
243 | verify = verify, | 242 | verify = verify, |
244 | } | 243 | } |
245 | local ok, install_err, errcode = install.command(install_args) | 244 | local ok, install_err, errcode = deps.installer(install_args) |
246 | if not ok then | 245 | if not ok then |
247 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode | 246 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode |
248 | end | 247 | end |
diff --git a/src/luarocks/test/busted.tl b/src/luarocks/test/busted.tl index c0ac5503..01473f1f 100644 --- a/src/luarocks/test/busted.tl +++ b/src/luarocks/test/busted.tl | |||
@@ -7,6 +7,7 @@ local deps = require("luarocks.deps") | |||
7 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
8 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
9 | local queries = require("luarocks.queries") | 9 | local queries = require("luarocks.queries") |
10 | local install = require("luarocks.cmd.install") | ||
10 | 11 | ||
11 | local type r = require("luarocks.core.types.rockspec") | 12 | local type r = require("luarocks.core.types.rockspec") |
12 | local type Test = r.Test | 13 | local type Test = r.Test |