aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-08-22 17:48:59 -0300
committerHisham Muhammad <hisham@gobolinux.org>2024-10-21 13:30:51 -0300
commit05f6ead6055e59b80900d34448ed13a4654bc14f (patch)
tree43321e2e599a5e8808e923d51d3eecd93f6ef7d8
parent76b20ac03c47ebe4df599f5667f6ff1b5b7c82a5 (diff)
downloadluarocks-05f6ead6055e59b80900d34448ed13a4654bc14f.tar.gz
luarocks-05f6ead6055e59b80900d34448ed13a4654bc14f.tar.bz2
luarocks-05f6ead6055e59b80900d34448ed13a4654bc14f.zip
Teal: convert luarocks.util
-rw-r--r--src/luarocks/util.tl (renamed from src/luarocks/util.lua)217
1 files changed, 97 insertions, 120 deletions
diff --git a/src/luarocks/util.lua b/src/luarocks/util.tl
index de9157fc..823ee1db 100644
--- a/src/luarocks/util.lua
+++ b/src/luarocks/util.tl
@@ -4,9 +4,30 @@
4-- inside specific functions) to avoid interdependencies, 4-- inside specific functions) to avoid interdependencies,
5-- as this is used in the bootstrapping stage of luarocks.core.cfg. 5-- as this is used in the bootstrapping stage of luarocks.core.cfg.
6 6
7local util = {}
8
9local core = require("luarocks.core.util") 7local core = require("luarocks.core.util")
8local cfg = require("luarocks.core.cfg")
9
10local type Ordering= require("luarocks.core.types.ordering").Ordering
11local type SortBy = require("luarocks.core.types.ordering").SortBy
12
13local record util
14 cleanup_path: function(string, string, string, boolean): string
15 split_string: function(string, string, ?number): {string}
16 sortedpairs: function<K, V>(tbl: {K: V}, sort_by?: SortBy): function(): K, V, Ordering<K>
17 deep_merge: function({any : any}, {any : any})
18 deep_merge_under: function({any : any}, {any : any})
19 popen_read: function(string, ?string): string
20 show_table: function({any : any}, string, string): string
21 printerr: function(...: string | number)
22 warning: function(string)
23 keys: function<K, V>({K : V}): {K}
24 matchquote: function(string): string
25
26 record Fn
27 fn: function(...: any)
28 args: table.PackTable<any>
29 end
30end
10 31
11util.cleanup_path = core.cleanup_path 32util.cleanup_path = core.cleanup_path
12util.split_string = core.split_string 33util.split_string = core.split_string
@@ -18,11 +39,15 @@ util.show_table = core.show_table
18util.printerr = core.printerr 39util.printerr = core.printerr
19util.warning = core.warning 40util.warning = core.warning
20util.keys = core.keys 41util.keys = core.keys
42util.matchquote = core.matchquote
21 43
22local unpack = unpack or table.unpack 44local type Fn = util.Fn
23local pack = table.pack or function(...) return { n = select("#", ...), ... } end 45local type Rockspec = require("luarocks.core.types.rockspec").Rockspec
24 46
25local scheduled_functions = {} 47local type Parser = require("luarocks.vendor.argparse").Parser
48
49
50local scheduled_functions: {Fn} = {}
26 51
27--- Schedule a function to be executed upon program termination. 52--- Schedule a function to be executed upon program termination.
28-- This is useful for actions such as deleting temporary directories 53-- This is useful for actions such as deleting temporary directories
@@ -31,10 +56,8 @@ local scheduled_functions = {}
31-- @param ... arguments to be passed to function. 56-- @param ... arguments to be passed to function.
32-- @return table: A token representing the scheduled execution, 57-- @return table: A token representing the scheduled execution,
33-- which can be used to remove the item later from the list. 58-- which can be used to remove the item later from the list.
34function util.schedule_function(f, ...) 59function util.schedule_function(f: function(...: any), ...:any): Fn
35 assert(type(f) == "function") 60 local item: Fn = { fn = f, args = table.pack(...) }
36
37 local item = { fn = f, args = pack(...) }
38 table.insert(scheduled_functions, item) 61 table.insert(scheduled_functions, item)
39 return item 62 return item
40end 63end
@@ -43,8 +66,8 @@ end
43-- This is useful for cancelling a rollback of a completed operation. 66-- This is useful for cancelling a rollback of a completed operation.
44-- @param item table: The token representing the scheduled function that was 67-- @param item table: The token representing the scheduled function that was
45-- returned from the schedule_function call. 68-- returned from the schedule_function call.
46function util.remove_scheduled_function(item) 69function util.remove_scheduled_function(item: Fn)
47 for k, v in pairs(scheduled_functions) do 70 for k, v in ipairs(scheduled_functions) do
48 if v == item then 71 if v == item then
49 table.remove(scheduled_functions, k) 72 table.remove(scheduled_functions, k)
50 return 73 return
@@ -57,26 +80,17 @@ end
57-- corresponding cleanup functions. Calling this function will run 80-- corresponding cleanup functions. Calling this function will run
58-- these function, erasing temporaries. 81-- these function, erasing temporaries.
59-- Functions are executed in the inverse order they were scheduled. 82-- Functions are executed in the inverse order they were scheduled.
60function util.run_scheduled_functions() 83function util.run_scheduled_functions(): string --! a hack for xpcall
61 local fs = require("luarocks.fs") 84 local fs = require("luarocks.fs")
62 if fs.change_dir_to_root then 85 if fs.change_dir_to_root then
63 fs.change_dir_to_root() 86 fs.change_dir_to_root()
64 end 87 end
65 for i = #scheduled_functions, 1, -1 do 88 for i = #scheduled_functions, 1, -1 do
66 local item = scheduled_functions[i] 89 local item = scheduled_functions[i]
67 item.fn(unpack(item.args, 1, item.args.n)) 90 item.fn(table.unpack(item.args, 1, item.args.n))
68 end 91 end
69end 92end
70 93
71--- Produce a Lua pattern that matches precisely the given string
72-- (this is suitable to be concatenating to other patterns,
73-- so it does not include beginning- and end-of-string markers (^$)
74-- @param s string: The input string
75-- @return string: The equivalent pattern
76function util.matchquote(s)
77 return (s:gsub("[?%-+*%[%].%%()$^]","%%%1"))
78end
79
80local var_format_pattern = "%$%((%a[%a%d_]+)%)" 94local var_format_pattern = "%$%((%a[%a%d_]+)%)"
81 95
82-- Check if a set of needed variables are referenced 96-- Check if a set of needed variables are referenced
@@ -89,7 +103,7 @@ local var_format_pattern = "%$%((%a[%a%d_]+)%)"
89-- @param needed_set: a set where keys are the names of 103-- @param needed_set: a set where keys are the names of
90-- needed variables. 104-- needed variables.
91-- @param msg string: the warning message to display. 105-- @param msg string: the warning message to display.
92function util.warn_if_not_used(var_defs, needed_set, msg) 106function util.warn_if_not_used(var_defs: {string: string}, needed_set: {string: boolean}, msg: string)
93 local seen = {} 107 local seen = {}
94 for _, val in pairs(var_defs) do 108 for _, val in pairs(var_defs) do
95 for used in val:gmatch(var_format_pattern) do 109 for used in val:gmatch(var_format_pattern) do
@@ -106,7 +120,7 @@ end
106-- Output any entries that might remain in $(XYZ) format, 120-- Output any entries that might remain in $(XYZ) format,
107-- warning the user that substitutions have failed. 121-- warning the user that substitutions have failed.
108-- @param line string: the input string 122-- @param line string: the input string
109local function warn_failed_matches(line) 123local function warn_failed_matches(line: string): boolean
110 local any_failed = false 124 local any_failed = false
111 if line:match(var_format_pattern) then 125 if line:match(var_format_pattern) then
112 for unmatched in line:gmatch(var_format_pattern) do 126 for unmatched in line:gmatch(var_format_pattern) do
@@ -125,14 +139,12 @@ end
125-- @param tbl table: Table to have its string values modified. 139-- @param tbl table: Table to have its string values modified.
126-- @param vars table: Table containing string-string key-value pairs 140-- @param vars table: Table containing string-string key-value pairs
127-- representing variables to replace in the strings values of tbl. 141-- representing variables to replace in the strings values of tbl.
128function util.variable_substitutions(tbl, vars) 142function util.variable_substitutions<K>(tbl: {K: string}, vars: {string: string})
129 assert(type(tbl) == "table")
130 assert(type(vars) == "table")
131 143
132 local updated = {} 144 local updated: {K: string} = {}
133 for k, v in pairs(tbl) do 145 for k, v in pairs(tbl) do
134 if type(v) == "string" then 146 if v is string then
135 updated[k] = v:gsub(var_format_pattern, vars) 147 updated[k] = string.gsub(v, var_format_pattern, vars)
136 if warn_failed_matches(updated[k]) then 148 if warn_failed_matches(updated[k]) then
137 updated[k] = updated[k]:gsub(var_format_pattern, "") 149 updated[k] = updated[k]:gsub(var_format_pattern, "")
138 end 150 end
@@ -143,25 +155,24 @@ function util.variable_substitutions(tbl, vars)
143 end 155 end
144end 156end
145 157
146function util.lua_versions(sort) 158function util.lua_versions(sort?: string): function(): string
147 local versions = { "5.1", "5.2", "5.3", "5.4" } 159 local versions = { "5.1", "5.2", "5.3", "5.4" }
148 local i = 0 160 local i = 0
149 if sort == "descending" then 161 if sort == "descending" then
150 i = #versions + 1 162 i = #versions + 1
151 return function() 163 return function(): string
152 i = i - 1 164 i = i - 1
153 return versions[i] 165 return versions[i]
154 end 166 end
155 else 167 else
156 return function() 168 return function(): string
157 i = i + 1 169 i = i + 1
158 return versions[i] 170 return versions[i]
159 end 171 end
160 end 172 end
161end 173end
162 174
163function util.lua_path_variables() 175function util.lua_path_variables(): string, string
164 local cfg = require("luarocks.core.cfg")
165 local lpath_var = "LUA_PATH" 176 local lpath_var = "LUA_PATH"
166 local lcpath_var = "LUA_CPATH" 177 local lcpath_var = "LUA_CPATH"
167 178
@@ -177,17 +188,17 @@ function util.lua_path_variables()
177 return lpath_var, lcpath_var 188 return lpath_var, lcpath_var
178end 189end
179 190
180function util.starts_with(s, prefix) 191function util.starts_with(s: string, prefix: string): boolean
181 return s:sub(1,#prefix) == prefix 192 return s:sub(1,#prefix) == prefix
182end 193end
183 194
184--- Print a line to standard output 195--- Print a line to standard output
185function util.printout(...) 196function util.printout(...: string)
186 io.stdout:write(table.concat({...},"\t")) 197 io.stdout:write(table.concat({...},"\t"))
187 io.stdout:write("\n") 198 io.stdout:write("\n")
188end 199end
189 200
190function util.title(msg, porcelain, underline) 201function util.title(msg: string, porcelain?: boolean, underline?: string)
191 if porcelain then return end 202 if porcelain then return end
192 util.printout() 203 util.printout()
193 util.printout(msg) 204 util.printout(msg)
@@ -195,7 +206,7 @@ function util.title(msg, porcelain, underline)
195 util.printout() 206 util.printout()
196end 207end
197 208
198function util.this_program(default) 209function util.this_program(default: string): string
199 local i = 1 210 local i = 1
200 local last, cur = default, default 211 local last, cur = default, default
201 while i do 212 while i do
@@ -217,12 +228,11 @@ function util.this_program(default)
217 return prog 228 return prog
218end 229end
219 230
220function util.format_rock_name(name, namespace, version) 231function util.format_rock_name(name: string, namespace: string, version: string): string
221 return (namespace and namespace.."/" or "")..name..(version and " "..version or "") 232 return (namespace and namespace.."/" or "")..name..(version and " "..version or "")
222end 233end
223 234
224function util.deps_mode_option(parser, program) 235function util.deps_mode_option(parser: Parser, program?: string)
225 local cfg = require("luarocks.core.cfg")
226 236
227 parser:option("--deps-mode", "How to handle dependencies. Four modes are supported:\n".. 237 parser:option("--deps-mode", "How to handle dependencies. Four modes are supported:\n"..
228 "* all - use all trees from the rocks_trees list for finding dependencies\n".. 238 "* all - use all trees from the rocks_trees list for finding dependencies\n"..
@@ -239,11 +249,11 @@ function util.deps_mode_option(parser, program)
239 parser:flag("--nodeps"):hidden(true) 249 parser:flag("--nodeps"):hidden(true)
240end 250end
241 251
242function util.see_help(command, program) 252function util.see_help(command: string, program?: string): string
243 return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'." 253 return "See '"..util.this_program(program or "luarocks")..' help'..(command and " "..command or "").."'."
244end 254end
245 255
246function util.see_also(text) 256function util.see_also(text?: string): string
247 local see_also = "See also:\n" 257 local see_also = "See also:\n"
248 if text then 258 if text then
249 see_also = see_also..text.."\n" 259 see_also = see_also..text.."\n"
@@ -251,9 +261,8 @@ function util.see_also(text)
251 return see_also.." '"..util.this_program("luarocks").." help' for general options and configuration." 261 return see_also.." '"..util.this_program("luarocks").." help' for general options and configuration."
252end 262end
253 263
254function util.announce_install(rockspec) 264function util.announce_install(rockspec: Rockspec)
255 local cfg = require("luarocks.core.cfg") 265 local path = require("luarocks.path") --TEAL BUG?
256 local path = require("luarocks.path")
257 266
258 local suffix = "" 267 local suffix = ""
259 if rockspec.description and rockspec.description.license then 268 if rockspec.description and rockspec.description.license then
@@ -270,12 +279,11 @@ end
270-- @param unnamed_paths table: An array of rockspec paths that don't contain rock 279-- @param unnamed_paths table: An array of rockspec paths that don't contain rock
271-- name and version in regular format. 280-- name and version in regular format.
272-- @param subdir string: path to subdirectory. 281-- @param subdir string: path to subdirectory.
273local function collect_rockspecs(versions, paths, unnamed_paths, subdir) 282local function collect_rockspecs(versions: {string: string}, paths: {string: string}, unnamed_paths: {string}, subdir: string)
274 local fs = require("luarocks.fs") 283 local fs = require("luarocks.fs")
275 local dir = require("luarocks.dir") 284 local dir = require("luarocks.dir")
276 local path = require("luarocks.path") 285 local path = require("luarocks.path")
277 local vers = require("luarocks.core.vers") 286 local vers = require("luarocks.core.vers")
278
279 if fs.is_dir(subdir) then 287 if fs.is_dir(subdir) then
280 for file in fs.dir(subdir) do 288 for file in fs.dir(subdir) do
281 file = dir.path(subdir, file) 289 file = dir.path(subdir, file)
@@ -298,8 +306,11 @@ end
298 306
299--- Get default rockspec name for commands that take optional rockspec name. 307--- Get default rockspec name for commands that take optional rockspec name.
300-- @return string or (nil, string): path to the rockspec or nil and error message. 308-- @return string or (nil, string): path to the rockspec or nil and error message.
301function util.get_default_rockspec() 309function util.get_default_rockspec(): string, string
302 local versions, paths, unnamed_paths = {}, {}, {} 310
311 local versions: {string: string} = {}
312 local paths: {string: string} = {}
313 local unnamed_paths: {string} = {}
303 -- Look for rockspecs in some common locations. 314 -- Look for rockspecs in some common locations.
304 collect_rockspecs(versions, paths, unnamed_paths, ".") 315 collect_rockspecs(versions, paths, unnamed_paths, ".")
305 collect_rockspecs(versions, paths, unnamed_paths, "rockspec") 316 collect_rockspecs(versions, paths, unnamed_paths, "rockspec")
@@ -340,14 +351,14 @@ end
340-- Quote Lua string, analogous to fs.Q. 351-- Quote Lua string, analogous to fs.Q.
341-- @param s A string, such as "hello" 352-- @param s A string, such as "hello"
342-- @return string: A quoted string, such as '"hello"' 353-- @return string: A quoted string, such as '"hello"'
343function util.LQ(s) 354function util.LQ(s: string): string
344 return ("%q"):format(s) 355 return ("%q"):format(s)
345end 356end
346 357
347-- Split name and namespace of a package name. 358-- Split name and namespace of a package name.
348-- @param ns_name a name that may be in "namespace/name" format 359-- @param ns_name a name that may be in "namespace/name" format
349-- @return string, string? - name and optionally a namespace 360-- @return string, string? - name and optionally a namespace
350function util.split_namespace(ns_name) 361function util.split_namespace(ns_name: string): string, string
351 local p1, p2 = ns_name:match("^([^/]+)/([^/]+)$") 362 local p1, p2 = ns_name:match("^([^/]+)/([^/]+)$")
352 if p1 then 363 if p1 then
353 return p2, p1 364 return p2, p1
@@ -356,10 +367,7 @@ function util.split_namespace(ns_name)
356end 367end
357 368
358--- Argparse action callback for namespaced rock arguments. 369--- Argparse action callback for namespaced rock arguments.
359function util.namespaced_name_action(args, target, ns_name) 370function util.namespaced_name_action(args: {any: any}, target: string, ns_name: string)
360 assert(type(args) == "table")
361 assert(type(target) == "string")
362 assert(type(ns_name) == "string" or not ns_name)
363 371
364 if not ns_name then 372 if not ns_name then
365 return 373 return
@@ -376,10 +384,10 @@ function util.namespaced_name_action(args, target, ns_name)
376 end 384 end
377end 385end
378 386
379function util.deep_copy(tbl) 387function util.deep_copy(tbl: {any: any}): {any: any}
380 local copy = {} 388 local copy: {any: any} = {}
381 for k, v in pairs(tbl) do 389 for k, v in pairs(tbl) do
382 if type(v) == "table" then 390 if v is {any: any} then
383 copy[k] = util.deep_copy(v) 391 copy[k] = util.deep_copy(v)
384 else 392 else
385 copy[k] = v 393 copy[k] = v
@@ -391,7 +399,7 @@ end
391-- A portable version of fs.exists that can be used at early startup, 399-- A portable version of fs.exists that can be used at early startup,
392-- before the platform has been determined and luarocks.fs has been 400-- before the platform has been determined and luarocks.fs has been
393-- initialized. 401-- initialized.
394function util.exists(file) 402function util.exists(file: string): boolean
395 local fd, _, code = io.open(file, "r") 403 local fd, _, code = io.open(file, "r")
396 if code == 13 then 404 if code == 13 then
397 -- code 13 means "Permission denied" on both Unix and Windows 405 -- code 13 means "Permission denied" on both Unix and Windows
@@ -405,19 +413,33 @@ function util.exists(file)
405 return false 413 return false
406end 414end
407 415
416function util.lua_is_wrapper(interp: string): boolean, string
417 local fd, err = io.open(interp, "r")
418 if not fd then
419 return nil, err
420 end
421 local data: string
422 data, err = fd:read(1000)
423 fd:close()
424 if not data then
425 return nil, err
426 end
427 return not not data:match("LUAROCKS_SYSCONFDIR")
428end
429
408do 430do
409 local function Q(pathname) 431 local function Q(pathname: string): string
410 if pathname:match("^.:") then 432 if pathname:match("^.:") then
411 return pathname:sub(1, 2) .. '"' .. pathname:sub(3) .. '"' 433 return pathname:sub(1, 2) .. '"' .. pathname:sub(3) .. '"'
412 end 434 end
413 return '"' .. pathname .. '"' 435 return '"' .. pathname .. '"'
414 end 436 end
415 437
416 function util.check_lua_version(lua, luaver) 438 function util.check_lua_version(lua:string, luaver: string): string
417 if not util.exists(lua) then 439 if not util.exists(lua) then
418 return nil 440 return nil
419 end 441 end
420 local lv, err = util.popen_read(Q(lua) .. ' -e "io.write(_VERSION:sub(5))"') 442 local lv = util.popen_read(Q(lua) .. ' -e "io.write(_VERSION:sub(5))"')
421 if lv == "" then 443 if lv == "" then
422 return nil 444 return nil
423 end 445 end
@@ -427,9 +449,8 @@ do
427 return lv 449 return lv
428 end 450 end
429 451
430 function util.get_luajit_version() 452 function util.get_luajit_version(): string
431 local cfg = require("luarocks.core.cfg") 453 if cfg.cache.luajit_version_checked then
432 if cfg.cache.luajit_version_checked then
433 return cfg.cache.luajit_version 454 return cfg.cache.luajit_version
434 end 455 end
435 cfg.cache.luajit_version_checked = true 456 cfg.cache.luajit_version_checked = true
@@ -438,7 +459,7 @@ do
438 return nil 459 return nil
439 end 460 end
440 461
441 local ljv 462 local ljv: string
442 if cfg.lua_version == "5.1" then 463 if cfg.lua_version == "5.1" then
443 -- Ignores extra version info for custom builds, e.g. "LuaJIT 2.1.0-beta3 some-other-version-info" 464 -- Ignores extra version info for custom builds, e.g. "LuaJIT 2.1.0-beta3 some-other-version-info"
444 ljv = util.popen_read(Q(cfg.variables.LUA) .. ' -e "io.write(tostring(jit and jit.version:gsub([[^%S+ (%S+).*]], [[%1]])))"') 465 ljv = util.popen_read(Q(cfg.variables.LUA) .. ' -e "io.write(tostring(jit and jit.version:gsub([[^%S+ (%S+).*]], [[%1]])))"')
@@ -450,11 +471,11 @@ do
450 return ljv 471 return ljv
451 end 472 end
452 473
453 local find_lua_bindir 474 local find_lua_bindir: function(prefix: string, luaver: string, verbose: string): string, string, string
454 do 475 do
455 local exe_suffix = (package.config:sub(1, 1) == "\\" and ".exe" or "") 476 local exe_suffix = (package.config:sub(1, 1) == "\\" and ".exe" or "")
456 477
457 local function insert_lua_variants(names, luaver) 478 local function insert_lua_variants(names: {string}, luaver: string)
458 local variants = { 479 local variants = {
459 "lua" .. luaver .. exe_suffix, 480 "lua" .. luaver .. exe_suffix,
460 "lua" .. luaver:gsub("%.", "") .. exe_suffix, 481 "lua" .. luaver:gsub("%.", "") .. exe_suffix,
@@ -462,13 +483,12 @@ do
462 "lua-" .. luaver:gsub("%.", "") .. exe_suffix, 483 "lua-" .. luaver:gsub("%.", "") .. exe_suffix,
463 } 484 }
464 for _, name in ipairs(variants) do 485 for _, name in ipairs(variants) do
465 names[name] = luaver
466 table.insert(names, name) 486 table.insert(names, name)
467 end 487 end
468 end 488 end
469 489
470 find_lua_bindir = function(prefix, luaver, verbose) 490 find_lua_bindir = function(prefix: string, luaver: string, verbose: string): string, string, string
471 local names = {} 491 local names: {string} = {}
472 if luaver then 492 if luaver then
473 insert_lua_variants(names, luaver) 493 insert_lua_variants(names, luaver)
474 else 494 else
@@ -507,8 +527,8 @@ do
507 end 527 end
508 end 528 end
509 529
510 function util.find_lua(prefix, luaver, verbose) 530 function util.find_lua(prefix: string, luaver: string, verbose?: string): {string: string}, string
511 local lua, bindir 531 local lua, bindir: string, string
512 lua, bindir, luaver = find_lua_bindir(prefix, luaver, verbose) 532 lua, bindir, luaver = find_lua_bindir(prefix, luaver, verbose)
513 if not lua then 533 if not lua then
514 return nil, bindir 534 return nil, bindir
@@ -523,48 +543,6 @@ do
523 end 543 end
524end 544end
525 545
526function util.lua_is_wrapper(interp)
527 local fd, err = io.open(interp, "r")
528 if not fd then
529 return nil, err
530 end
531 local data, err = fd:read(1000)
532 fd:close()
533 if not data then
534 return nil, err
535 end
536 return not not data:match("LUAROCKS_SYSCONFDIR")
537end
538
539function util.opts_table(type_name, valid_opts)
540 local opts_mt = {}
541
542 opts_mt.__index = opts_mt
543
544 function opts_mt.type()
545 return type_name
546 end
547
548 return function(opts)
549 for k, v in pairs(opts) do
550 local tv = type(v)
551 if not valid_opts[k] then
552 error("invalid option: "..k)
553 end
554 local vo, optional = valid_opts[k]:match("^(.-)(%??)$")
555 if not (tv == vo or (optional == "?" and tv == nil)) then
556 error("invalid type option: "..k.." - got "..tv..", expected "..vo)
557 end
558 end
559 for k, v in pairs(valid_opts) do
560 if (not v:find("?", 1, true)) and opts[k] == nil then
561 error("missing option: "..k)
562 end
563 end
564 return setmetatable(opts, opts_mt)
565 end
566end
567
568--- Return a table of modules that are already provided by the VM, which 546--- Return a table of modules that are already provided by the VM, which
569-- can be specified as dependencies without having to install an actual rock. 547-- can be specified as dependencies without having to install an actual rock.
570-- @param rockspec (optional) a rockspec table, so that rockspec format 548-- @param rockspec (optional) a rockspec table, so that rockspec format
@@ -573,8 +551,7 @@ end
573-- @return a table with rock names as keys and versions and values, 551-- @return a table with rock names as keys and versions and values,
574-- specifying modules that are already provided by the VM (including 552-- specifying modules that are already provided by the VM (including
575-- "lua" for the Lua version and, for format 3.0+, "luajit" if detected). 553-- "lua" for the Lua version and, for format 3.0+, "luajit" if detected).
576function util.get_rocks_provided(rockspec) 554function util.get_rocks_provided(rockspec?: Rockspec): {string: string}
577 local cfg = require("luarocks.core.cfg")
578 555
579 if not rockspec and cfg.cache.rocks_provided then 556 if not rockspec and cfg.cache.rocks_provided then
580 return cfg.cache.rocks_provided 557 return cfg.cache.rocks_provided
@@ -615,7 +592,7 @@ function util.get_rocks_provided(rockspec)
615 return rocks_provided 592 return rocks_provided
616end 593end
617 594
618function util.remove_doc_dir(name, version) 595function util.remove_doc_dir(name: string, version: string)
619 local path = require("luarocks.path") 596 local path = require("luarocks.path")
620 local fs = require("luarocks.fs") 597 local fs = require("luarocks.fs")
621 local dir = require("luarocks.dir") 598 local dir = require("luarocks.dir")