diff options
-rw-r--r-- | src/luarocks/deps.tl (renamed from src/luarocks/deps.lua) | 346 |
1 files changed, 195 insertions, 151 deletions
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.tl index 344991f6..e26ba60f 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.tl | |||
@@ -1,6 +1,8 @@ | |||
1 | 1 | ||
2 | --- High-level dependency related functions. | 2 | --- High-level dependency related functions. |
3 | local deps = {} | 3 | local record deps |
4 | installer: function(Args): boolean, string, string | ||
5 | end | ||
4 | 6 | ||
5 | local cfg = require("luarocks.core.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
6 | local manif = require("luarocks.manif") | 8 | local manif = require("luarocks.manif") |
@@ -12,6 +14,29 @@ local vers = require("luarocks.core.vers") | |||
12 | local queries = require("luarocks.queries") | 14 | local queries = require("luarocks.queries") |
13 | local deplocks = require("luarocks.deplocks") | 15 | local deplocks = require("luarocks.deplocks") |
14 | 16 | ||
17 | local type Rockspec = require("luarocks.core.types.rockspec").Rockspec | ||
18 | local type Dependencies = require("luarocks.core.types.rockspec").Dependencies | ||
19 | |||
20 | local type BuiltinBuild = require("luarocks.core.types.build").BuiltinBuild | ||
21 | local type Module = BuiltinBuild.Module | ||
22 | |||
23 | local type Build = require("luarocks.core.types.build").Build | ||
24 | |||
25 | local type Tree = require("luarocks.core.types.tree").Tree | ||
26 | |||
27 | local type Query = require("luarocks.core.types.query").Query | ||
28 | |||
29 | local type Version = require("luarocks.core.types.version").Version | ||
30 | |||
31 | local type PersistableTable = require("luarocks.core.types.persist").PersistableTable | ||
32 | |||
33 | local type Result = require("luarocks.core.types.result").Result | ||
34 | |||
35 | local type Dir = require("luarocks.core.types.dir").Dir | ||
36 | local type Dirs = require("luarocks.core.types.dir").Dirs | ||
37 | |||
38 | local type Args = require("luarocks.core.types.args").Args | ||
39 | |||
15 | --- Generate a function that matches dep queries against the manifest, | 40 | --- Generate a function that matches dep queries against the manifest, |
16 | -- taking into account rocks_provided, the list of versions to skip, | 41 | -- taking into account rocks_provided, the list of versions to skip, |
17 | -- and the lockfile. | 42 | -- and the lockfile. |
@@ -29,14 +54,10 @@ local deplocks = require("luarocks.deplocks") | |||
29 | -- * map of versions to locations | 54 | -- * map of versions to locations |
30 | -- * version matched via lockfile if any | 55 | -- * version matched via lockfile if any |
31 | -- * true if rock matched via rocks_provided | 56 | -- * true if rock matched via rocks_provided |
32 | local function prepare_get_versions(deps_mode, rocks_provided, depskey, skip_set) | 57 | local function prepare_get_versions(deps_mode: string, rocks_provided: {string : string}, depskey: string, skip_set?: {string: {string: boolean}}): function(Query): {string}, {string: string | Tree}, string | number | boolean | PersistableTable, boolean |
33 | assert(type(deps_mode) == "string") | 58 | |
34 | assert(type(rocks_provided) == "table") | 59 | return function(dep: Query): {string}, {string: string | Tree}, string | number | boolean | PersistableTable, boolean |
35 | assert(type(depskey) == "string") | 60 | local versions, locations: {string}, {string: string | Tree} |
36 | assert(type(skip_set) == "table" or skip_set == nil) | ||
37 | |||
38 | return function(dep) | ||
39 | local versions, locations | ||
40 | local provided = rocks_provided[dep.name] | 61 | local provided = rocks_provided[dep.name] |
41 | if provided then | 62 | if provided then |
42 | -- Provided rocks have higher priority than manifest's rocks. | 63 | -- Provided rocks have higher priority than manifest's rocks. |
@@ -57,7 +78,7 @@ local function prepare_get_versions(deps_mode, rocks_provided, depskey, skip_set | |||
57 | end | 78 | end |
58 | end | 79 | end |
59 | 80 | ||
60 | local lockversion = deplocks.get(depskey, dep.name) | 81 | local lockversion = deplocks.get(depskey, dep.name) --! cast? |
61 | 82 | ||
62 | return versions, locations, lockversion, provided ~= nil | 83 | return versions, locations, lockversion, provided ~= nil |
63 | end | 84 | end |
@@ -75,17 +96,16 @@ end | |||
75 | -- 2. nil | 96 | -- 2. nil |
76 | -- 3. either 'dep' or an alternative query to be used | 97 | -- 3. either 'dep' or an alternative query to be used |
77 | -- 4. false | 98 | -- 4. false |
78 | local function match_dep(dep, get_versions) | 99 | local function match_dep(depq: Query, |
79 | assert(type(dep) == "table") | 100 | get_versions: function(Query): {string}, {string: string | Tree}, string, boolean): string, string | Tree, Query, boolean |
80 | assert(type(get_versions) == "function") | ||
81 | 101 | ||
82 | local versions, locations, lockversion, provided = get_versions(dep) | 102 | local versions, locations, lockversion, provided = get_versions(depq) |
83 | 103 | ||
84 | local latest_version | 104 | local latest_version: Version |
85 | local latest_vstring | 105 | local latest_vstring: string |
86 | for _, vstring in ipairs(versions) do | 106 | for _, vstring in ipairs(versions) do |
87 | local version = vers.parse_version(vstring) | 107 | local version = vers.parse_version(vstring) |
88 | if vers.match_constraints(version, dep.constraints) then | 108 | if vers.match_constraints(version, depq.constraints) then |
89 | if not latest_version or version > latest_version then | 109 | if not latest_version or version > latest_version then |
90 | latest_version = version | 110 | latest_version = version |
91 | latest_vstring = vstring | 111 | latest_vstring = vstring |
@@ -98,31 +118,30 @@ local function match_dep(dep, get_versions) | |||
98 | if latest_vstring and latest_vstring ~= lockversion then | 118 | if latest_vstring and latest_vstring ~= lockversion then |
99 | latest_matching_msg = " (latest matching is " .. latest_vstring .. ")" | 119 | latest_matching_msg = " (latest matching is " .. latest_vstring .. ")" |
100 | end | 120 | end |
101 | util.printout("Forcing " .. dep.name .. " to pinned version " .. lockversion .. latest_matching_msg) | 121 | util.printout("Forcing " .. depq.name .. " to pinned version " .. lockversion .. latest_matching_msg) |
102 | return nil, nil, queries.new(dep.name, dep.namespace, lockversion) | 122 | return nil, nil, queries.new(depq.name, depq.namespace, lockversion) |
103 | end | 123 | end |
104 | 124 | ||
105 | return latest_vstring, locations[latest_vstring], dep, provided | 125 | return latest_vstring, locations[latest_vstring], depq, provided |
106 | end | 126 | end |
107 | 127 | ||
108 | local function match_all_deps(dependencies, get_versions) | 128 | local function match_all_deps(dependencies: {Query}, |
109 | assert(type(dependencies) == "table") | 129 | get_versions: function(Query): {string}, {string: string | Tree}, string, boolean): {Query: Result}, {string: Query}, {string: Query} |
110 | assert(type(get_versions) == "function") | ||
111 | 130 | ||
112 | local matched, missing, no_upgrade = {}, {}, {} | 131 | local matched, missing, no_upgrade = {}, {}, {} |
113 | 132 | ||
114 | for _, dep in ipairs(dependencies) do | 133 | for _, depq in ipairs(dependencies) do |
115 | local found, _, provided | 134 | local found, _, provided: string, string | Tree, boolean |
116 | found, _, dep, provided = match_dep(dep, get_versions) | 135 | found, _, depq, provided = match_dep(depq, get_versions) |
117 | if found then | 136 | if found then |
118 | if not provided then | 137 | if not provided then |
119 | matched[dep] = {name = dep.name, version = found} | 138 | matched[depq] = {name = depq.name, version = found} as Result |
120 | end | 139 | end |
121 | else | 140 | else |
122 | if dep.constraints[1] and dep.constraints[1].no_upgrade then | 141 | if depq.constraints and depq.constraints[1] and depq.constraints[1].no_upgrade then |
123 | no_upgrade[dep.name] = dep | 142 | no_upgrade[depq.name] = depq |
124 | else | 143 | else |
125 | missing[dep.name] = dep | 144 | missing[depq.name] = depq |
126 | end | 145 | end |
127 | end | 146 | end |
128 | end | 147 | end |
@@ -142,20 +161,13 @@ end | |||
142 | -- parsed as tables; and a table of "no-upgrade" missing dependencies | 161 | -- parsed as tables; and a table of "no-upgrade" missing dependencies |
143 | -- (to be used in plugin modules so that a plugin does not force upgrade of | 162 | -- (to be used in plugin modules so that a plugin does not force upgrade of |
144 | -- its parent application). | 163 | -- its parent application). |
145 | function deps.match_deps(dependencies, rocks_provided, skip_set, deps_mode) | 164 | function deps.match_deps(dependencies: {Query}, rocks_provided: {string: string}, deps_mode: string, skip_set?: {string: {string: boolean}}): {Query : Result}, {string : Query}, {string : Query} |
146 | assert(type(dependencies) == "table") | ||
147 | assert(type(rocks_provided) == "table") | ||
148 | assert(type(skip_set) == "table" or skip_set == nil) | ||
149 | assert(type(deps_mode) == "string") | ||
150 | 165 | ||
151 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, "dependencies", skip_set) | 166 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, "dependencies", skip_set) |
152 | return match_all_deps(dependencies, get_versions) | 167 | return match_all_deps(dependencies, get_versions) |
153 | end | 168 | end |
154 | 169 | ||
155 | local function rock_status(dep, get_versions) | 170 | local function rock_status(dep: Query, get_versions: function(Query): {string}, {string : string | Tree}, string, boolean): string, string |
156 | assert(dep:type() == "query") | ||
157 | assert(type(get_versions) == "function") | ||
158 | |||
159 | local installed, _, _, provided = match_dep(dep, get_versions) | 171 | local installed, _, _, provided = match_dep(dep, get_versions) |
160 | local installation_type = provided and "provided by VM" or "installed" | 172 | local installation_type = provided and "provided by VM" or "installed" |
161 | return installed and installed.." "..installation_type..": success" or "not installed" | 173 | return installed and installed.." "..installation_type..": success" or "not installed" |
@@ -170,12 +182,7 @@ end | |||
170 | -- by this Lua implementation for the given dependency. | 182 | -- by this Lua implementation for the given dependency. |
171 | -- "one" for the current default tree, "all" for all trees, | 183 | -- "one" for the current default tree, "all" for all trees, |
172 | -- "order" for all trees with priority >= the current default, "none" for no trees. | 184 | -- "order" for all trees with priority >= the current default, "none" for no trees. |
173 | function deps.report_missing_dependencies(name, version, dependencies, deps_mode, rocks_provided) | 185 | function deps.report_missing_dependencies(name: string, version: string, dependencies: {Query}, deps_mode: string, rocks_provided: {string: string}) |
174 | assert(type(name) == "string") | ||
175 | assert(type(version) == "string") | ||
176 | assert(type(dependencies) == "table") | ||
177 | assert(type(deps_mode) == "string") | ||
178 | assert(type(rocks_provided) == "table") | ||
179 | 186 | ||
180 | if deps_mode == "none" then | 187 | if deps_mode == "none" then |
181 | return | 188 | return |
@@ -185,33 +192,28 @@ function deps.report_missing_dependencies(name, version, dependencies, deps_mode | |||
185 | 192 | ||
186 | local first_missing_dep = true | 193 | local first_missing_dep = true |
187 | 194 | ||
188 | for _, dep in ipairs(dependencies) do | 195 | for _, depq in ipairs(dependencies) do |
189 | local found, _ | 196 | local found, _: string, string | Tree |
190 | found, _, dep = match_dep(dep, get_versions) | 197 | found, _, depq = match_dep(depq, get_versions) |
191 | if not found then | 198 | if not found then |
192 | if first_missing_dep then | 199 | if first_missing_dep then |
193 | util.printout(("Missing dependencies for %s %s:"):format(name, version)) | 200 | util.printout(("Missing dependencies for %s %s:"):format(name, version)) |
194 | first_missing_dep = false | 201 | first_missing_dep = false |
195 | end | 202 | end |
196 | 203 | ||
197 | util.printout((" %s (%s)"):format(tostring(dep), rock_status(dep, get_versions))) | 204 | util.printout((" %s (%s)"):format(tostring(depq), rock_status(depq, get_versions))) |
198 | end | 205 | end |
199 | end | 206 | end |
200 | end | 207 | end |
201 | 208 | ||
202 | function deps.fulfill_dependency(dep, deps_mode, rocks_provided, verify, depskey) | 209 | function deps.fulfill_dependency(dep: Query, deps_mode: string, rocks_provided: {string: string}, verify: boolean, depskey?: string): boolean, string, string | Tree |
203 | assert(dep:type() == "query") | ||
204 | assert(type(deps_mode) == "string" or deps_mode == nil) | ||
205 | assert(type(rocks_provided) == "table" or rocks_provided == nil) | ||
206 | assert(type(verify) == "boolean" or verify == nil) | ||
207 | assert(type(depskey) == "string") | ||
208 | 210 | ||
209 | deps_mode = deps_mode or "all" | 211 | deps_mode = deps_mode or "all" |
210 | rocks_provided = rocks_provided or {} | 212 | rocks_provided = rocks_provided or {} |
211 | 213 | ||
212 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, depskey) | 214 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, depskey) |
213 | 215 | ||
214 | local found, where | 216 | local found, where: string, string | Tree |
215 | found, where, dep = match_dep(dep, get_versions) | 217 | found, where, dep = match_dep(dep, get_versions) |
216 | if found then | 218 | if found then |
217 | local tree_manifests = manif.load_rocks_tree_manifests(deps_mode) | 219 | local tree_manifests = manif.load_rocks_tree_manifests(deps_mode) |
@@ -220,7 +222,6 @@ function deps.fulfill_dependency(dep, deps_mode, rocks_provided, verify, depskey | |||
220 | end | 222 | end |
221 | 223 | ||
222 | local search = require("luarocks.search") | 224 | local search = require("luarocks.search") |
223 | local install = require("luarocks.cmd.install") | ||
224 | 225 | ||
225 | local url, search_err = search.find_suitable_rock(dep) | 226 | local url, search_err = search.find_suitable_rock(dep) |
226 | if not url then | 227 | if not url then |
@@ -233,24 +234,24 @@ function deps.fulfill_dependency(dep, deps_mode, rocks_provided, verify, depskey | |||
233 | namespace = dep.namespace, | 234 | namespace = dep.namespace, |
234 | verify = verify, | 235 | verify = verify, |
235 | } | 236 | } |
236 | local ok, install_err, errcode = install.command(install_args) | 237 | local ok, install_err, errcode = deps.installer(install_args) |
237 | if not ok then | 238 | if not ok then |
238 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode | 239 | return nil, "Failed installing dependency: "..url.." - "..install_err, errcode |
239 | end | 240 | end |
240 | 241 | ||
241 | found, where = match_dep(dep, get_versions) | 242 | found, where = match_dep(dep, get_versions) |
242 | if not found then | 243 | if not found then |
243 | return nil, "Repository inconsistency detected (previously unfinished/corrupted installation?)" | 244 | return nil, "Repository inconsistency detected (previously unfinished/corrupted installation?)" |
244 | end | 245 | end |
245 | return true, found, where | 246 | return true, found, where |
246 | end | 247 | end |
247 | 248 | ||
248 | local function check_supported_platforms(rockspec) | 249 | local function check_supported_platforms(rockspec: Rockspec): boolean, string |
249 | if rockspec.supported_platforms and next(rockspec.supported_platforms) then | 250 | if rockspec.supported_platforms and next(rockspec.supported_platforms) then |
250 | local all_negative = true | 251 | local all_negative = true |
251 | local supported = false | 252 | local supported = false |
252 | for _, plat in pairs(rockspec.supported_platforms) do | 253 | for _, plat in ipairs(rockspec.supported_platforms) do |
253 | local neg | 254 | local neg: string |
254 | neg, plat = plat:match("^(!?)(.*)") | 255 | neg, plat = plat:match("^(!?)(.*)") |
255 | if neg == "!" then | 256 | if neg == "!" then |
256 | if cfg.is_platform(plat) then | 257 | if cfg.is_platform(plat) then |
@@ -285,13 +286,7 @@ end | |||
285 | -- @return boolean or (nil, string, [string]): True if no errors occurred, or | 286 | -- @return boolean or (nil, string, [string]): True if no errors occurred, or |
286 | -- nil and an error message if any test failed, followed by an optional | 287 | -- nil and an error message if any test failed, followed by an optional |
287 | -- error code. | 288 | -- error code. |
288 | function deps.fulfill_dependencies(rockspec, depskey, deps_mode, verify, deplock_dir) | 289 | function deps.fulfill_dependencies(rockspec: Rockspec, depskey: string, deps_mode: string, verify?: boolean, deplock_dir?: string): boolean, string, string |
289 | assert(type(rockspec) == "table") | ||
290 | assert(type(depskey) == "string") | ||
291 | assert(type(deps_mode) == "string") | ||
292 | assert(type(verify) == "boolean" or verify == nil) | ||
293 | assert(type(deplock_dir) == "string" or deplock_dir == nil) | ||
294 | |||
295 | local name = rockspec.name | 290 | local name = rockspec.name |
296 | local version = rockspec.version | 291 | local version = rockspec.version |
297 | local rocks_provided = rockspec.rocks_provided | 292 | local rocks_provided = rockspec.rocks_provided |
@@ -301,16 +296,23 @@ function deps.fulfill_dependencies(rockspec, depskey, deps_mode, verify, deplock | |||
301 | util.printout("Using dependencies pinned in lockfile: " .. filename) | 296 | util.printout("Using dependencies pinned in lockfile: " .. filename) |
302 | 297 | ||
303 | local get_versions = prepare_get_versions("none", rocks_provided, depskey) | 298 | local get_versions = prepare_get_versions("none", rocks_provided, depskey) |
299 | local dnsnamestr, dversionstr: string, string | ||
304 | for dnsname, dversion in deplocks.each(depskey) do | 300 | for dnsname, dversion in deplocks.each(depskey) do |
305 | local dname, dnamespace = util.split_namespace(dnsname) | 301 | if dnsname is string then |
306 | local dep = queries.new(dname, dnamespace, dversion) | 302 | dnsnamestr = dnsname |
303 | end | ||
304 | if dversion is string then | ||
305 | dversionstr = dversion | ||
306 | end | ||
307 | local dname, dnamespace = util.split_namespace(dnsnamestr) | ||
308 | local depq = queries.new(dname, dnamespace, dversionstr) | ||
307 | 309 | ||
308 | util.printout(("%s %s is pinned to %s (%s)"):format( | 310 | util.printout(("%s %s is pinned to %s (%s)"):format( |
309 | name, version, tostring(dep), rock_status(dep, get_versions))) | 311 | name, version, tostring(depq), rock_status(depq, get_versions))) |
310 | 312 | ||
311 | local ok, err = deps.fulfill_dependency(dep, "none", rocks_provided, verify, depskey) | 313 | local okfullfill, errfullfill = deps.fulfill_dependency(depq, "none", rocks_provided, verify, depskey) |
312 | if not ok then | 314 | if not okfullfill then |
313 | return nil, err | 315 | return nil, errfullfill |
314 | end | 316 | end |
315 | end | 317 | end |
316 | util.printout() | 318 | util.printout() |
@@ -324,28 +326,28 @@ function deps.fulfill_dependencies(rockspec, depskey, deps_mode, verify, deplock | |||
324 | return nil, err | 326 | return nil, err |
325 | end | 327 | end |
326 | 328 | ||
327 | deps.report_missing_dependencies(name, version, rockspec[depskey], deps_mode, rocks_provided) | 329 | deps.report_missing_dependencies(name, version, (rockspec as {string: Dependencies})[depskey].queries, deps_mode, rocks_provided) |
328 | 330 | ||
329 | util.printout() | 331 | util.printout() |
330 | 332 | ||
331 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, depskey) | 333 | local get_versions = prepare_get_versions(deps_mode, rocks_provided, depskey) |
332 | for _, dep in ipairs(rockspec[depskey]) do | 334 | for _, depq in ipairs((rockspec as {string: Dependencies})[depskey].queries) do |
333 | 335 | ||
334 | util.printout(("%s %s depends on %s (%s)"):format( | 336 | util.printout(("%s %s depends on %s (%s)"):format( |
335 | name, version, tostring(dep), rock_status(dep, get_versions))) | 337 | name, version, tostring(depq), rock_status(depq, get_versions))) |
336 | 338 | ||
337 | local ok, found_or_err, _, no_upgrade = deps.fulfill_dependency(dep, deps_mode, rocks_provided, verify, depskey) | 339 | local okfulfill, found_or_err, _ = deps.fulfill_dependency(depq, deps_mode, rocks_provided, verify, depskey) |
338 | if ok then | 340 | if okfulfill then |
339 | deplocks.add(depskey, dep.name, found_or_err) | 341 | deplocks.add(depskey, depq.name, found_or_err) |
340 | else | 342 | else |
341 | if no_upgrade then | 343 | -- if no_upgrade then |
342 | util.printerr("This version of "..name.." is designed for use with") | 344 | -- util.printerr("This version of "..name.." is designed for use with") |
343 | util.printerr(tostring(dep)..", but is configured to avoid upgrading it") | 345 | -- util.printerr(tostring(dep)..", but is configured to avoid upgrading it") |
344 | util.printerr("automatically. Please upgrade "..dep.name.." with") | 346 | -- util.printerr("automatically. Please upgrade "..dep.name.." with") |
345 | util.printerr(" luarocks install "..dep.name) | 347 | -- util.printerr(" luarocks install "..dep.name) |
346 | util.printerr("or look for a suitable version of "..name.." with") | 348 | -- util.printerr("or look for a suitable version of "..name.." with") |
347 | util.printerr(" luarocks search "..name) | 349 | -- util.printerr(" luarocks search "..name) |
348 | end | 350 | -- end |
349 | return nil, found_or_err | 351 | return nil, found_or_err |
350 | end | 352 | end |
351 | end | 353 | end |
@@ -360,7 +362,7 @@ end | |||
360 | -- @param file string: a filename | 362 | -- @param file string: a filename |
361 | -- @param pattern string: a pattern, where ? is to be matched by the filename. | 363 | -- @param pattern string: a pattern, where ? is to be matched by the filename. |
362 | -- @return string The pattern, if found, or nil. | 364 | -- @return string The pattern, if found, or nil. |
363 | local function deconstruct_pattern(file, pattern) | 365 | local function deconstruct_pattern(file: string, pattern: string): string |
364 | local depattern = "^"..(pattern:gsub("%.", "%%."):gsub("%*", ".*"):gsub("?", "(.*)")).."$" | 366 | local depattern = "^"..(pattern:gsub("%.", "%%."):gsub("%*", ".*"):gsub("?", "(.*)")).."$" |
365 | return (file:match(depattern)) | 367 | return (file:match(depattern)) |
366 | end | 368 | end |
@@ -372,13 +374,13 @@ end | |||
372 | -- @param array of string An array of patterns with "?" as the wildcard | 374 | -- @param array of string An array of patterns with "?" as the wildcard |
373 | -- (e.g. {"?.so", "lib?.so"}) | 375 | -- (e.g. {"?.so", "lib?.so"}) |
374 | -- @param files The array of constructed names | 376 | -- @param files The array of constructed names |
375 | local function add_all_patterns(file, patterns, files) | 377 | local function add_all_patterns(file: string, patterns: {string}, files: {{integer, string}}): Dirs |
376 | for _, pattern in ipairs(patterns) do | 378 | for _, pattern in ipairs(patterns) do |
377 | table.insert(files, {#files + 1, (pattern:gsub("?", file))}) | 379 | table.insert(files, {#files + 1, (pattern:gsub("?", file))}) |
378 | end | 380 | end |
379 | end | 381 | end |
380 | 382 | ||
381 | local function get_external_deps_dirs(mode) | 383 | local function get_external_deps_dirs(mode: string): Dirs |
382 | local patterns = cfg.external_deps_patterns | 384 | local patterns = cfg.external_deps_patterns |
383 | local subdirs = cfg.external_deps_subdirs | 385 | local subdirs = cfg.external_deps_subdirs |
384 | if mode == "install" then | 386 | if mode == "install" then |
@@ -393,13 +395,13 @@ local function get_external_deps_dirs(mode) | |||
393 | if mode == "install" then | 395 | if mode == "install" then |
394 | dirs.INCDIR = nil | 396 | dirs.INCDIR = nil |
395 | end | 397 | end |
396 | return dirs | 398 | return dirs as Dirs |
397 | end | 399 | end |
398 | 400 | ||
399 | local function resolve_prefix(prefix, dirs) | 401 | local function resolve_prefix(prefix: string | {string: string}, dirs: Dirs): string |
400 | if type(prefix) == "string" then | 402 | if prefix is string then |
401 | return prefix | 403 | return prefix |
402 | elseif type(prefix) == "table" then | 404 | elseif prefix is {string: string} then |
403 | if prefix.bin then | 405 | if prefix.bin then |
404 | dirs.BINDIR.subdir = prefix.bin | 406 | dirs.BINDIR.subdir = prefix.bin |
405 | end | 407 | end |
@@ -415,7 +417,7 @@ local function resolve_prefix(prefix, dirs) | |||
415 | end | 417 | end |
416 | end | 418 | end |
417 | 419 | ||
418 | local function add_patterns_for_file(files, file, patterns) | 420 | local function add_patterns_for_file(files: {{integer, string}}, file: string, patterns: {string}) |
419 | -- If it doesn't look like it contains a filename extension | 421 | -- If it doesn't look like it contains a filename extension |
420 | if not (file:match("%.[a-z]+$") or file:match("%.[a-z]+%.")) then | 422 | if not (file:match("%.[a-z]+$") or file:match("%.[a-z]+%.")) then |
421 | add_all_patterns(file, patterns, files) | 423 | add_all_patterns(file, patterns, files) |
@@ -430,36 +432,45 @@ local function add_patterns_for_file(files, file, patterns) | |||
430 | end | 432 | end |
431 | end | 433 | end |
432 | 434 | ||
433 | local function check_external_dependency_at(prefix, name, ext_files, vars, dirs, err_files, cache) | 435 | local function check_external_dependency_at( |
436 | prefix: string, | ||
437 | name: string, | ||
438 | ext_files: {string: string | {string}}, | ||
439 | vars: {string: string}, | ||
440 | dirs: Dirs, | ||
441 | err_files: {string: {string}}, | ||
442 | cache: {string: {string}}): boolean, string, string | ||
443 | |||
434 | local fs = require("luarocks.fs") | 444 | local fs = require("luarocks.fs") |
435 | cache = cache or {} | 445 | cache = cache or {} |
436 | 446 | ||
437 | for dirname, dirdata in util.sortedpairs(dirs) do | 447 | for dirname, dirdata in util.sortedpairs(dirs) do |
438 | local paths | 448 | local paths: {string} |
439 | local path_var_value = vars[name.."_"..dirname] | 449 | local path_var_value = vars[name.."_"..dirname] |
450 | local dirdatastr = dirdata.subdir | ||
440 | if path_var_value then | 451 | if path_var_value then |
441 | paths = { path_var_value } | 452 | paths = { path_var_value } |
442 | elseif type(dirdata.subdir) == "table" then | 453 | elseif dirdatastr is {string} then |
443 | paths = {} | 454 | paths = {} |
444 | for i,v in ipairs(dirdata.subdir) do | 455 | for i,v in ipairs(dirdatastr) do |
445 | paths[i] = dir.path(prefix, v) | 456 | paths[i] = dir.path(prefix, v) |
446 | end | 457 | end |
447 | else | 458 | else |
448 | paths = { dir.path(prefix, dirdata.subdir) } | 459 | paths = { dir.path(prefix, dirdatastr) } |
449 | end | 460 | end |
450 | local file_or_files = ext_files[dirdata.testfile] | 461 | local file_or_files = ext_files[dirdata.testfile] |
451 | if file_or_files then | 462 | if file_or_files then |
452 | local files = {} | 463 | local files = {} |
453 | if type(file_or_files) == "string" then | 464 | if file_or_files is string then |
454 | add_patterns_for_file(files, file_or_files, dirdata.pattern) | 465 | add_patterns_for_file(files, file_or_files, dirdata.pattern) |
455 | elseif type(file_or_files) == "table" then | 466 | elseif file_or_files is {string} then |
456 | for _, f in ipairs(file_or_files) do | 467 | for _, f in ipairs(file_or_files) do |
457 | add_patterns_for_file(files, f, dirdata.pattern) | 468 | add_patterns_for_file(files, f, dirdata.pattern) |
458 | end | 469 | end |
459 | end | 470 | end |
460 | 471 | ||
461 | local found = false | 472 | local found = false |
462 | table.sort(files, function(a, b) | 473 | table.sort(files, function(a: {integer, string}, b: {integer, string}): boolean |
463 | if (not a[2]:match("%*")) and b[2]:match("%*") then | 474 | if (not a[2]:match("%*")) and b[2]:match("%*") then |
464 | return true | 475 | return true |
465 | elseif a[2]:match("%*") and (not b[2]:match("%*")) then | 476 | elseif a[2]:match("%*") and (not b[2]:match("%*")) then |
@@ -476,7 +487,7 @@ local function check_external_dependency_at(prefix, name, ext_files, vars, dirs, | |||
476 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) | 487 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) |
477 | end | 488 | end |
478 | 489 | ||
479 | local pattern | 490 | local pattern: string |
480 | if f:match("%*") then | 491 | if f:match("%*") then |
481 | pattern = "^" .. f:gsub("([-.+])", "%%%1"):gsub("%*", ".*") .. "$" | 492 | pattern = "^" .. f:gsub("([-.+])", "%%%1"):gsub("%*", ".*") .. "$" |
482 | f = "matching "..f | 493 | f = "matching "..f |
@@ -526,7 +537,7 @@ local function check_external_dependency_at(prefix, name, ext_files, vars, dirs, | |||
526 | end | 537 | end |
527 | end | 538 | end |
528 | 539 | ||
529 | for dirname, dirdata in pairs(dirs) do | 540 | for dirname, dirdata in pairs(dirs as {string: Dir}) do |
530 | vars[name.."_"..dirname] = dirdata.dir | 541 | vars[name.."_"..dirname] = dirdata.dir |
531 | vars[name.."_"..dirname.."_FILE"] = dirdata.file | 542 | vars[name.."_"..dirname.."_FILE"] = dirdata.file |
532 | end | 543 | end |
@@ -534,15 +545,20 @@ local function check_external_dependency_at(prefix, name, ext_files, vars, dirs, | |||
534 | return true | 545 | return true |
535 | end | 546 | end |
536 | 547 | ||
537 | local function check_external_dependency(name, ext_files, vars, mode, cache) | 548 | local function check_external_dependency( |
538 | local ok | 549 | name: string, |
539 | local err_dirname | 550 | ext_files: {string: string | {string}}, |
540 | local err_testfile | 551 | vars: {string: string}, |
541 | local err_files = {program = {}, header = {}, library = {}} | 552 | mode: string, |
553 | cache?: {string : {string}}): boolean, string, string, {string : {string}} | ||
554 | local ok: boolean | ||
555 | local err_dirname: string | ||
556 | local err_testfile: string | ||
557 | local err_files: {string: {string}} = {program = {}, header = {}, library = {}} | ||
542 | 558 | ||
543 | local dirs = get_external_deps_dirs(mode) | 559 | local dirs = get_external_deps_dirs(mode) |
544 | 560 | ||
545 | local prefixes | 561 | local prefixes: {string} |
546 | if vars[name .. "_DIR"] then | 562 | if vars[name .. "_DIR"] then |
547 | prefixes = { vars[name .. "_DIR"] } | 563 | prefixes = { vars[name .. "_DIR"] } |
548 | elseif vars.DEPS_DIR then | 564 | elseif vars.DEPS_DIR then |
@@ -554,11 +570,11 @@ local function check_external_dependency(name, ext_files, vars, mode, cache) | |||
554 | for _, prefix in ipairs(prefixes) do | 570 | for _, prefix in ipairs(prefixes) do |
555 | prefix = resolve_prefix(prefix, dirs) | 571 | prefix = resolve_prefix(prefix, dirs) |
556 | if cfg.is_platform("mingw32") and name == "LUA" then | 572 | if cfg.is_platform("mingw32") and name == "LUA" then |
557 | dirs.LIBDIR.pattern = fun.filter(util.deep_copy(dirs.LIBDIR.pattern), function(s) | 573 | dirs.LIBDIR.pattern = fun.filter(util.deep_copy(dirs.LIBDIR.pattern) as {string}, function(s: string): boolean |
558 | return not s:match("%.a$") | 574 | return not s:match("%.a$") |
559 | end) | 575 | end) |
560 | elseif cfg.is_platform("windows") and name == "LUA" then | 576 | elseif cfg.is_platform("windows") and name == "LUA" then |
561 | dirs.LIBDIR.pattern = fun.filter(util.deep_copy(dirs.LIBDIR.pattern), function(s) | 577 | dirs.LIBDIR.pattern = fun.filter(util.deep_copy(dirs.LIBDIR.pattern) as {string}, function(s: string): boolean |
562 | return not s:match("%.dll$") | 578 | return not s:match("%.dll$") |
563 | end) | 579 | end) |
564 | end | 580 | end |
@@ -571,19 +587,22 @@ local function check_external_dependency(name, ext_files, vars, mode, cache) | |||
571 | return nil, err_dirname, err_testfile, err_files | 587 | return nil, err_dirname, err_testfile, err_files |
572 | end | 588 | end |
573 | 589 | ||
574 | function deps.autodetect_external_dependencies(build) | 590 | function deps.autodetect_external_dependencies(build: Build): {string : {string : string}} |
575 | -- only applies to the 'builtin' build type | 591 | -- only applies to the 'builtin' build type |
576 | if not build or not build.modules then | 592 | if not build or not (build as BuiltinBuild).modules then |
577 | return nil | 593 | return nil |
578 | end | 594 | end |
579 | 595 | ||
580 | local extdeps = {} | 596 | local extdeps: {string: {string: string}} = {} |
581 | local any = false | 597 | local any = false |
582 | for _, data in pairs(build.modules) do | 598 | for _, data in pairs((build as BuiltinBuild).modules) do |
583 | if type(data) == "table" and data.libraries then | 599 | if data is Module and data.libraries then |
584 | local libraries = data.libraries | 600 | local libraries: {string} |
585 | if type(libraries) == "string" then | 601 | local librariesstr: string | {string} = data.libraries |
586 | libraries = { libraries } | 602 | if librariesstr is string then |
603 | libraries = { librariesstr } | ||
604 | else | ||
605 | libraries = librariesstr | ||
587 | end | 606 | end |
588 | local incdirs = {} | 607 | local incdirs = {} |
589 | local libdirs = {} | 608 | local libdirs = {} |
@@ -618,18 +637,17 @@ end | |||
618 | -- if "install" is given, do not scan for headers. | 637 | -- if "install" is given, do not scan for headers. |
619 | -- @return boolean or (nil, string): True if no errors occurred, or | 638 | -- @return boolean or (nil, string): True if no errors occurred, or |
620 | -- nil and an error message if any test failed. | 639 | -- nil and an error message if any test failed. |
621 | function deps.check_external_deps(rockspec, mode) | 640 | function deps.check_external_deps(rockspec: Rockspec, mode: string): boolean, string, string |
622 | assert(rockspec:type() == "rockspec") | ||
623 | 641 | ||
624 | if not rockspec.external_dependencies then | 642 | if not rockspec.external_dependencies then |
625 | rockspec.external_dependencies = deps.autodetect_external_dependencies(rockspec.build) | 643 | rockspec.external_dependencies = deps.autodetect_external_dependencies(rockspec.build) as {string: {string: string}} |
626 | end | 644 | end |
627 | if not rockspec.external_dependencies then | 645 | if not rockspec.external_dependencies then |
628 | return true | 646 | return true |
629 | end | 647 | end |
630 | 648 | ||
631 | for name, ext_files in util.sortedpairs(rockspec.external_dependencies) do | 649 | for name, ext_files in util.sortedpairs(rockspec.external_dependencies) do |
632 | local ok, err_dirname, err_testfile, err_files = check_external_dependency(name, ext_files, rockspec.variables, mode) | 650 | local ok, err_dirname, err_testfile, err_files = check_external_dependency(name, ext_files as {string : string | {string}}, rockspec.variables, mode) |
633 | if not ok then | 651 | if not ok then |
634 | local lines = {"Could not find "..err_testfile.." file for "..name} | 652 | local lines = {"Could not find "..err_testfile.." file for "..name} |
635 | 653 | ||
@@ -657,11 +675,8 @@ end | |||
657 | -- @param mdeps table: The manifest dependencies table. | 675 | -- @param mdeps table: The manifest dependencies table. |
658 | -- @param name string: Package name. | 676 | -- @param name string: Package name. |
659 | -- @param version string: Package version. | 677 | -- @param version string: Package version. |
660 | function deps.scan_deps(results, mdeps, name, version, deps_mode) | 678 | function deps.scan_deps(results: {string: string}, mdeps: {string: {string: {Query}}}, name: string, version: string, deps_mode: string) |
661 | assert(type(results) == "table") | 679 | assert(not name:match("/")) |
662 | assert(type(mdeps) == "table") | ||
663 | assert(type(name) == "string" and not name:match("/")) | ||
664 | assert(type(version) == "string") | ||
665 | 680 | ||
666 | local fetch = require("luarocks.fetch") | 681 | local fetch = require("luarocks.fetch") |
667 | 682 | ||
@@ -671,13 +686,13 @@ function deps.scan_deps(results, mdeps, name, version, deps_mode) | |||
671 | if not mdeps[name] then mdeps[name] = {} end | 686 | if not mdeps[name] then mdeps[name] = {} end |
672 | local mdn = mdeps[name] | 687 | local mdn = mdeps[name] |
673 | local dependencies = mdn[version] | 688 | local dependencies = mdn[version] |
674 | local rocks_provided | 689 | local rocks_provided: {string : string} |
675 | if not dependencies then | 690 | if not dependencies then |
676 | local rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version), false) | 691 | local rockspec = fetch.load_local_rockspec(path.rockspec_file(name, version), false) |
677 | if not rockspec then | 692 | if not rockspec then |
678 | return | 693 | return |
679 | end | 694 | end |
680 | dependencies = rockspec.dependencies | 695 | dependencies = rockspec.dependencies.queries |
681 | rocks_provided = rockspec.rocks_provided | 696 | rocks_provided = rockspec.rocks_provided |
682 | mdn[version] = dependencies | 697 | mdn[version] = dependencies |
683 | else | 698 | else |
@@ -693,7 +708,7 @@ function deps.scan_deps(results, mdeps, name, version, deps_mode) | |||
693 | end | 708 | end |
694 | end | 709 | end |
695 | 710 | ||
696 | local function lua_h_exists(d, luaver) | 711 | local function lua_h_exists(d: string, luaver: string): boolean, string, string, integer |
697 | local major, minor = luaver:match("(%d+)%.(%d+)") | 712 | local major, minor = luaver:match("(%d+)%.(%d+)") |
698 | local luanum = ("%s%02d"):format(major, tonumber(minor)) | 713 | local luanum = ("%s%02d"):format(major, tonumber(minor)) |
699 | 714 | ||
@@ -703,7 +718,7 @@ local function lua_h_exists(d, luaver) | |||
703 | local data = fd:read("*a") | 718 | local data = fd:read("*a") |
704 | fd:close() | 719 | fd:close() |
705 | if data:match("LUA_VERSION_NUM%s*" .. tostring(luanum)) then | 720 | if data:match("LUA_VERSION_NUM%s*" .. tostring(luanum)) then |
706 | return d | 721 | return d ~= nil |
707 | end | 722 | end |
708 | return nil, "Lua header lua.h found at " .. d .. " does not match Lua version " .. luaver .. ". You can use `luarocks config variables.LUA_INCDIR <path>` to set the correct location.", "dependency", 2 | 723 | return nil, "Lua header lua.h found at " .. d .. " does not match Lua version " .. luaver .. ". You can use `luarocks config variables.LUA_INCDIR <path>` to set the correct location.", "dependency", 2 |
709 | end | 724 | end |
@@ -711,7 +726,7 @@ local function lua_h_exists(d, luaver) | |||
711 | return nil, "Failed finding Lua header lua.h (searched at " .. d .. "). You may need to install Lua development headers. You can use `luarocks config variables.LUA_INCDIR <path>` to set the correct location.", "dependency", 1 | 726 | return nil, "Failed finding Lua header lua.h (searched at " .. d .. "). You may need to install Lua development headers. You can use `luarocks config variables.LUA_INCDIR <path>` to set the correct location.", "dependency", 1 |
712 | end | 727 | end |
713 | 728 | ||
714 | local function find_lua_incdir(prefix, luaver, luajitver) | 729 | local function find_lua_incdir(prefix: string, luaver: string, luajitver: string): string, string |
715 | luajitver = luajitver and luajitver:gsub("%-.*", "") | 730 | luajitver = luajitver and luajitver:gsub("%-.*", "") |
716 | local shortv = luaver:gsub("%.", "") | 731 | local shortv = luaver:gsub("%.", "") |
717 | local incdirs = { | 732 | local incdirs = { |
@@ -724,7 +739,7 @@ local function find_lua_incdir(prefix, luaver, luajitver) | |||
724 | luajitver and (prefix .. "/include/luajit-" .. (luajitver:match("^(%d+%.%d+)") or "")), | 739 | luajitver and (prefix .. "/include/luajit-" .. (luajitver:match("^(%d+%.%d+)") or "")), |
725 | } | 740 | } |
726 | local errprio = 0 | 741 | local errprio = 0 |
727 | local mainerr | 742 | local mainerr: string |
728 | for _, d in ipairs(incdirs) do | 743 | for _, d in ipairs(incdirs) do |
729 | local ok, err, _, prio = lua_h_exists(d, luaver) | 744 | local ok, err, _, prio = lua_h_exists(d, luaver) |
730 | if ok then | 745 | if ok then |
@@ -740,8 +755,8 @@ local function find_lua_incdir(prefix, luaver, luajitver) | |||
740 | return nil, mainerr | 755 | return nil, mainerr |
741 | end | 756 | end |
742 | 757 | ||
743 | function deps.check_lua_incdir(vars) | 758 | function deps.check_lua_incdir(vars: {string: string}): boolean, string, string |
744 | if vars.LUA_INCDIR_OK == true | 759 | if vars.LUA_INCDIR_OK == "ok" |
745 | then return true | 760 | then return true |
746 | end | 761 | end |
747 | 762 | ||
@@ -750,7 +765,7 @@ function deps.check_lua_incdir(vars) | |||
750 | if vars.LUA_INCDIR then | 765 | if vars.LUA_INCDIR then |
751 | local ok, err = lua_h_exists(vars.LUA_INCDIR, cfg.lua_version) | 766 | local ok, err = lua_h_exists(vars.LUA_INCDIR, cfg.lua_version) |
752 | if ok then | 767 | if ok then |
753 | vars.LUA_INCDIR_OK = true | 768 | vars.LUA_INCDIR_OK = "ok" |
754 | end | 769 | end |
755 | return ok, err | 770 | return ok, err |
756 | end | 771 | end |
@@ -759,7 +774,7 @@ function deps.check_lua_incdir(vars) | |||
759 | local d, err = find_lua_incdir(vars.LUA_DIR, cfg.lua_version, ljv) | 774 | local d, err = find_lua_incdir(vars.LUA_DIR, cfg.lua_version, ljv) |
760 | if d then | 775 | if d then |
761 | vars.LUA_INCDIR = d | 776 | vars.LUA_INCDIR = d |
762 | vars.LUA_INCDIR_OK = true | 777 | vars.LUA_INCDIR_OK = "ok" |
763 | return true | 778 | return true |
764 | end | 779 | end |
765 | return nil, err | 780 | return nil, err |
@@ -768,8 +783,8 @@ function deps.check_lua_incdir(vars) | |||
768 | return nil, "Failed finding Lua headers; neither LUA_DIR or LUA_INCDIR are set. You may need to install them or configure LUA_INCDIR.", "dependency" | 783 | return nil, "Failed finding Lua headers; neither LUA_DIR or LUA_INCDIR are set. You may need to install them or configure LUA_INCDIR.", "dependency" |
769 | end | 784 | end |
770 | 785 | ||
771 | function deps.check_lua_libdir(vars) | 786 | function deps.check_lua_libdir(vars: {string: string}): boolean, string, string, {string : {string}} |
772 | if vars.LUA_LIBDIR_OK == true | 787 | if vars.LUA_LIBDIR_OK == "ok" |
773 | then return true | 788 | then return true |
774 | end | 789 | end |
775 | 790 | ||
@@ -777,7 +792,7 @@ function deps.check_lua_libdir(vars) | |||
777 | local ljv = util.get_luajit_version() | 792 | local ljv = util.get_luajit_version() |
778 | 793 | ||
779 | if vars.LUA_LIBDIR and vars.LUALIB and fs.exists(dir.path(vars.LUA_LIBDIR, vars.LUALIB)) then | 794 | if vars.LUA_LIBDIR and vars.LUALIB and fs.exists(dir.path(vars.LUA_LIBDIR, vars.LUALIB)) then |
780 | vars.LUA_LIBDIR_OK = true | 795 | vars.LUA_LIBDIR_OK = "ok" |
781 | return true | 796 | return true |
782 | end | 797 | end |
783 | 798 | ||
@@ -797,7 +812,7 @@ function deps.check_lua_libdir(vars) | |||
797 | local save_LUA_INCDIR = vars.LUA_INCDIR | 812 | local save_LUA_INCDIR = vars.LUA_INCDIR |
798 | local ok, _, _, errfiles = check_external_dependency("LUA", { library = libnames }, vars, "build", cache) | 813 | local ok, _, _, errfiles = check_external_dependency("LUA", { library = libnames }, vars, "build", cache) |
799 | vars.LUA_INCDIR = save_LUA_INCDIR | 814 | vars.LUA_INCDIR = save_LUA_INCDIR |
800 | local err | 815 | local err: string |
801 | if ok then | 816 | if ok then |
802 | local filename = dir.path(vars.LUA_LIBDIR, vars.LUA_LIBDIR_FILE) | 817 | local filename = dir.path(vars.LUA_LIBDIR, vars.LUA_LIBDIR_FILE) |
803 | local fd = io.open(filename, "r") | 818 | local fd = io.open(filename, "r") |
@@ -805,8 +820,9 @@ function deps.check_lua_libdir(vars) | |||
805 | if not vars.LUA_LIBDIR_FILE:match((cfg.lua_version:gsub("%.", "%%.?"))) then | 820 | if not vars.LUA_LIBDIR_FILE:match((cfg.lua_version:gsub("%.", "%%.?"))) then |
806 | -- if filename isn't versioned, check file contents | 821 | -- if filename isn't versioned, check file contents |
807 | local txt = fd:read("*a") | 822 | local txt = fd:read("*a") |
808 | ok = txt:match("Lua " .. cfg.lua_version, 1, true) | 823 | ok = txt:find("Lua " .. cfg.lua_version, 1, true) |
809 | or txt:match("lua" .. (cfg.lua_version:gsub("%.", "")), 1, true) | 824 | or txt:find("lua" .. (cfg.lua_version:gsub("%.", "")), 1, true) |
825 | and true | ||
810 | if not ok then | 826 | if not ok then |
811 | err = "Lua library at " .. filename .. " does not match Lua version " .. cfg.lua_version .. ". You can use `luarocks config variables.LUA_LIBDIR <path>` to set the correct location." | 827 | err = "Lua library at " .. filename .. " does not match Lua version " .. cfg.lua_version .. ". You can use `luarocks config variables.LUA_LIBDIR <path>` to set the correct location." |
812 | end | 828 | end |
@@ -818,7 +834,7 @@ function deps.check_lua_libdir(vars) | |||
818 | 834 | ||
819 | if ok then | 835 | if ok then |
820 | vars.LUALIB = vars.LUA_LIBDIR_FILE | 836 | vars.LUALIB = vars.LUA_LIBDIR_FILE |
821 | vars.LUA_LIBDIR_OK = true | 837 | vars.LUA_LIBDIR_OK = "ok" |
822 | return true | 838 | return true |
823 | else | 839 | else |
824 | err = err or "Failed finding the Lua library. You can use `luarocks config variables.LUA_LIBDIR <path>` to set the correct location." | 840 | err = err or "Failed finding the Lua library. You can use `luarocks config variables.LUA_LIBDIR <path>` to set the correct location." |
@@ -826,8 +842,36 @@ function deps.check_lua_libdir(vars) | |||
826 | end | 842 | end |
827 | end | 843 | end |
828 | 844 | ||
829 | function deps.get_deps_mode(args) | 845 | function deps.get_deps_mode(args: Args): string |
830 | return args.deps_mode or cfg.deps_mode | 846 | return args.deps_mode or cfg.deps_mode |
831 | end | 847 | end |
832 | 848 | ||
849 | --- Report missing dependencies for all rocks installed in a repository. | ||
850 | -- @param repo string or nil: Pathname of a local repository. If not given, | ||
851 | -- the default local repository is used. | ||
852 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
853 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
854 | -- "none" for using the default dependency mode from the configuration. | ||
855 | function deps.check_dependencies(repo: string, deps_mode: string) | ||
856 | local rocks_dir = path.rocks_dir(repo or cfg.root_dir) | ||
857 | if deps_mode == "none" then deps_mode = cfg.deps_mode end | ||
858 | |||
859 | local manifest = manif.load_manifest(rocks_dir) | ||
860 | if not manifest then | ||
861 | return | ||
862 | end | ||
863 | |||
864 | for name, versions in util.sortedpairs(manifest.repository) do | ||
865 | for version, version_entries in util.sortedpairs(versions, vers.compare_versions) do | ||
866 | for _, entry in ipairs(version_entries) do | ||
867 | if entry.arch == "installed" then | ||
868 | if manifest.dependencies[name] and manifest.dependencies[name][version] then | ||
869 | deps.report_missing_dependencies(name, version, manifest.dependencies[name][version], deps_mode, util.get_rocks_provided()) | ||
870 | end | ||
871 | end | ||
872 | end | ||
873 | end | ||
874 | end | ||
875 | end | ||
876 | |||
833 | return deps | 877 | return deps |