1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
local global_env = _G
local package, require, assert, ipairs, pairs, os, print, table, type, next, unpack =
package, require, assert, ipairs, pairs, os, print, table, type, next, unpack
module("luarocks")
local path = require("luarocks.path")
local manif_core = require("luarocks.manif_core")
local deps = require("luarocks.deps")
local cfg = require("luarocks.cfg")
context = {}
-- Contains a table when rocks trees are loaded,
-- or 'false' to indicate rocks trees failed to load.
-- 'nil' indicates rocks trees were not attempted to be loaded yet.
rocks_trees = nil
local function load_rocks_trees()
local any_ok = false
local trees = {}
-- FIXME select correctly file to be fetched
local persist = require("luarocks.persist")
table.insert(trees, { manifest = persist.load_into_table("manifest2") } )
any_ok = true
if not any_ok then
rocks_trees = false
return false
end
rocks_trees = trees
return true
end
--- Process the dependencies of a package to determine its dependency
-- chain for loading modules.
-- @parse name string: The name of an installed rock.
-- @parse version string: The version of the rock, in string format
-- @parse manifest table: The local manifest table where this rock
-- is installed.
local function add_context(name, version)
-- assert(type(name) == "string")
-- assert(type(version) == "string")
-- assert(type(manifest) == "table")
if context[name] then
return
end
context[name] = version
--[[
local pkgdeps = manifest.dependencies and manifest.dependencies[name][version]
if not pkgdeps then
return
end
for _, dep in ipairs(pkgdeps) do
local package, constraints = dep.name, dep.constraints
for _, tree in pairs(rocks_trees) do
local entries = tree.manifest.repository[package]
if entries then
for version, packages in pairs(entries) do
if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then
add_context(package, version, tree.manifest)
end
end
end
end
end
]]
end
--- Internal sorting function.
-- @param a table: A provider table.
-- @param b table: Another provider table.
-- @return boolean: True if the version of a is greater than that of b.
local function sort_versions(a,b)
return a.version > b.version
end
local function call_other_loaders(module, name, version, file)
local actual_module = file:match("(.*)%.[^.]+$")
for i, loader in pairs(package.loaders) do
if loader ~= luarocks_loader then
local results = { loader(actual_module) }
if type(results[1]) == "function" then
return unpack(results)
end
end
end
return nil, "Failed loading module "..module.." in LuaRocks rock "..name.." "..version
end
local function pick_module(module)
--assert(type(module) == "string")
if not rocks_trees and not load_rocks_trees() then
return nil
end
local providers = {}
for _, tree in pairs(rocks_trees) do
local entries = tree.manifest.modules[module]
if entries then
for entry, file in pairs(entries) do
local name, version = entry:match("^([^/]*)/(.*)$")
if context[name] == version then
return name, version, file
end
version = deps.parse_version(version)
table.insert(providers, {name = name, version = version, file = file})
end
end
end
if next(providers) then
table.sort(providers, sort_versions)
local first = providers[1]
return first.name, first.version.string, first.file
end
end
--- Package loader for LuaRocks support.
-- A module is searched in installed rocks that match the
-- current LuaRocks context. If module is not part of the
-- context, or if a context has not yet been set, the module
-- in the package with the highest version is used.
-- @param module string: The module name, like in plain require().
-- @return table: The module table (typically), like in plain
-- require(). See <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require">require()</a>
-- in the Lua reference manual for details.
function luarocks_loader(module)
local name, version, file = pick_module(module)
if not name then
return nil, "No LuaRocks module found for "..module
else
add_context(name, version)
return call_other_loaders(module, name, version, file)
end
end
table.insert(global_env.package.loaders, 1, luarocks_loader)
|