diff options
Diffstat (limited to 'src/luarocks.lua')
| -rw-r--r-- | src/luarocks.lua | 241 |
1 files changed, 0 insertions, 241 deletions
diff --git a/src/luarocks.lua b/src/luarocks.lua deleted file mode 100644 index 4059755b..00000000 --- a/src/luarocks.lua +++ /dev/null | |||
| @@ -1,241 +0,0 @@ | |||
| 1 | --- Install a custom LuaRocks loader. | ||
| 2 | -- TODO use new tree format. | ||
| 3 | |||
| 4 | local global_env = _G | ||
| 5 | local plain_package_path = package.path | ||
| 6 | local plain_package_cpath = package.cpath | ||
| 7 | local package, require, assert, ipairs, pairs, os, print, table, type, next, unpack = | ||
| 8 | package, require, assert, ipairs, pairs, os, print, table, type, next, unpack | ||
| 9 | |||
| 10 | module("luarocks") | ||
| 11 | |||
| 12 | local path = require("luarocks.path") | ||
| 13 | local manif_core = require("luarocks.manif_core") | ||
| 14 | local deps = require("luarocks.deps") | ||
| 15 | local cfg = require("luarocks.cfg") | ||
| 16 | |||
| 17 | context = {} | ||
| 18 | |||
| 19 | -- Contains a table when rocks trees are loaded, | ||
| 20 | -- or 'false' to indicate rocks trees failed to load. | ||
| 21 | -- 'nil' indicates rocks trees were not attempted to be loaded yet. | ||
| 22 | rocks_trees = nil | ||
| 23 | |||
| 24 | local function load_rocks_trees() | ||
| 25 | local any_ok = false | ||
| 26 | local trees = {} | ||
| 27 | for _, tree in pairs(cfg.rocks_trees) do | ||
| 28 | local rocks_dir = path.rocks_dir(tree) | ||
| 29 | local manifest, err = manif_core.load_local_manifest(rocks_dir) | ||
| 30 | if manifest then | ||
| 31 | any_ok = true | ||
| 32 | table.insert(trees, {rocks_dir=rocks_dir, manifest=manifest}) | ||
| 33 | end | ||
| 34 | end | ||
| 35 | if not any_ok then | ||
| 36 | rocks_trees = false | ||
| 37 | return false | ||
| 38 | end | ||
| 39 | rocks_trees = trees | ||
| 40 | return true | ||
| 41 | end | ||
| 42 | |||
| 43 | --- Process the dependencies of a package to determine its dependency | ||
| 44 | -- chain for loading modules. | ||
| 45 | -- @parse name string: The name of an installed rock. | ||
| 46 | -- @parse version string: The version of the rock, in string format | ||
| 47 | -- @parse manifest table: The local manifest table where this rock | ||
| 48 | -- is installed. | ||
| 49 | local function add_context(name, version, manifest) | ||
| 50 | -- assert(type(name) == "string") | ||
| 51 | -- assert(type(version) == "string") | ||
| 52 | -- assert(type(manifest) == "table") | ||
| 53 | |||
| 54 | if context[name] then | ||
| 55 | return | ||
| 56 | end | ||
| 57 | context[name] = version | ||
| 58 | |||
| 59 | local pkgdeps = manifest.dependencies and manifest.dependencies[name][version] | ||
| 60 | if not pkgdeps then | ||
| 61 | return | ||
| 62 | end | ||
| 63 | for _, dep in ipairs(pkgdeps) do | ||
| 64 | local package, constraints = dep.name, dep.constraints | ||
| 65 | |||
| 66 | for _, tree in pairs(rocks_trees) do | ||
| 67 | local entries = tree.manifest.repository[package] | ||
| 68 | if entries then | ||
| 69 | for version, packages in pairs(entries) do | ||
| 70 | if (not constraints) or deps.match_constraints(deps.parse_version(version), constraints) then | ||
| 71 | add_context(package, version, tree.manifest) | ||
| 72 | end | ||
| 73 | end | ||
| 74 | end | ||
| 75 | end | ||
| 76 | end | ||
| 77 | end | ||
| 78 | |||
| 79 | --- Internal sorting function. | ||
| 80 | -- @param a table: A provider table. | ||
| 81 | -- @param b table: Another provider table. | ||
| 82 | -- @return boolean: True if the version of a is greater than that of b. | ||
| 83 | local function sort_versions(a,b) | ||
| 84 | return a.version > b.version | ||
| 85 | end | ||
| 86 | |||
| 87 | --- Specify a dependency chain for LuaRocks. | ||
| 88 | -- In the presence of multiple versions of packages, it is necessary to, | ||
| 89 | -- at some point, indicate which dependency chain we're following. | ||
| 90 | -- set_context does this by allowing one to pick a package to be the | ||
| 91 | -- root of this dependency chain. Once a dependency chain is picked it's | ||
| 92 | -- easy to know which modules to load ("I want to use *this* version of | ||
| 93 | -- A, which requires *that* version of B, which requires etc etc etc"). | ||
| 94 | -- @param name string: The package name of an installed rock. | ||
| 95 | -- @param version string or nil: Optionally, a version number | ||
| 96 | -- When a version is not given, it picks the highest version installed. | ||
| 97 | -- @return boolean: true if succeeded, false otherwise. | ||
| 98 | function set_context(name, version) | ||
| 99 | --assert(type(name) == "string") | ||
| 100 | --assert(type(version) == "string" or not version) | ||
| 101 | |||
| 102 | if rocks_trees == false or (not rocks_trees and not load_rocks_trees()) then | ||
| 103 | return false | ||
| 104 | end | ||
| 105 | |||
| 106 | local manifest | ||
| 107 | local vtables = {} | ||
| 108 | for _, tree in ipairs(rocks_trees) do | ||
| 109 | if version then | ||
| 110 | local manif_repo = tree.manifest.repository | ||
| 111 | if manif_repo[name] and manif_repo[name][version] then | ||
| 112 | manifest = tree.manifest | ||
| 113 | break | ||
| 114 | end | ||
| 115 | else | ||
| 116 | local versions = manif_core.get_versions(name, tree.manifest) | ||
| 117 | for _, version in ipairs(versions) do | ||
| 118 | table.insert(vtables, {version = deps.parse_version(version), manifest = tree.manifest}) | ||
| 119 | end | ||
| 120 | end | ||
| 121 | end | ||
| 122 | if not version then | ||
| 123 | if not next(vtables) then | ||
| 124 | table.sort(vtables, sort_versions) | ||
| 125 | local highest = vtables[#vtables] | ||
| 126 | version = highest.version.string | ||
| 127 | manifest = highest.manifest | ||
| 128 | end | ||
| 129 | end | ||
| 130 | if not manifest then | ||
| 131 | return false | ||
| 132 | end | ||
| 133 | |||
| 134 | add_context(name, version, manifest) | ||
| 135 | -- TODO: platform independence | ||
| 136 | local lpath, cpath = "", "" | ||
| 137 | for name, version in pairs(context) do | ||
| 138 | lpath = lpath .. path.lua_dir(name, version) .. "/?.lua;" | ||
| 139 | lpath = lpath .. path.lua_dir(name, version) .. "/?/init.lua;" | ||
| 140 | cpath = cpath .. path.lib_dir(name, version) .."/?."..cfg.lib_extension..";" | ||
| 141 | end | ||
| 142 | global_env.package.path = lpath .. plain_package_path | ||
| 143 | global_env.package.cpath = cpath .. plain_package_cpath | ||
| 144 | end | ||
| 145 | |||
| 146 | local function call_other_loaders(module, name, version, rocks_dir) | ||
| 147 | local save_path = package.path | ||
| 148 | local save_cpath = package.cpath | ||
| 149 | package.path = path.lua_dir(name, version, rocks_dir) .. "/?.lua;" | ||
| 150 | .. path.lua_dir(name, version, rocks_dir) .. "/?/init.lua;" .. save_path | ||
| 151 | package.cpath = path.lib_dir(name, version, rocks_dir) .. "/?."..cfg.lib_extension..";" .. save_cpath | ||
| 152 | for i, loader in pairs(package.loaders) do | ||
| 153 | if loader ~= luarocks_loader then | ||
| 154 | local results = { loader(module) } | ||
| 155 | if type(results[1]) == "function" then | ||
| 156 | package.path = save_path | ||
| 157 | package.cpath = save_cpath | ||
| 158 | return unpack(results) | ||
| 159 | end | ||
| 160 | end | ||
| 161 | end | ||
| 162 | package.path = save_path | ||
| 163 | package.cpath = save_cpath | ||
| 164 | return nil, "Failed loading module "..module.." in LuaRocks rock "..name.." "..version | ||
| 165 | end | ||
| 166 | |||
| 167 | local function pick_module(module, constraints) | ||
| 168 | --assert(type(module) == "string") | ||
| 169 | --assert(not constraints or type(constraints) == "string") | ||
| 170 | |||
| 171 | if not rocks_trees and not load_rocks_trees() then | ||
| 172 | return nil | ||
| 173 | end | ||
| 174 | |||
| 175 | if constraints then | ||
| 176 | if type(constraints) == "string" then | ||
| 177 | constraints = deps.parse_constraints(constraints) | ||
| 178 | else | ||
| 179 | constraints = nil | ||
| 180 | end | ||
| 181 | end | ||
| 182 | |||
| 183 | local providers = {} | ||
| 184 | for _, tree in pairs(rocks_trees) do | ||
| 185 | local entries = tree.manifest.modules[module] | ||
| 186 | if entries then | ||
| 187 | for entry, _ in pairs(entries) do | ||
| 188 | local name, version = entry:match("^([^/]*)/(.*)$") | ||
| 189 | if context[name] == version then | ||
| 190 | return name, version, tree | ||
| 191 | end | ||
| 192 | version = deps.parse_version(version) | ||
| 193 | if (not constraints) or deps.match_constraints(version, constraints) then | ||
| 194 | table.insert(providers, {name = name, version = version, repo = tree}) | ||
| 195 | end | ||
| 196 | end | ||
| 197 | end | ||
| 198 | end | ||
| 199 | |||
| 200 | if next(providers) then | ||
| 201 | table.sort(providers, sort_versions) | ||
| 202 | local first = providers[1] | ||
| 203 | return first.name, first.version.string, first.repo | ||
| 204 | end | ||
| 205 | end | ||
| 206 | |||
| 207 | --- Inform which rock LuaRocks would use if require() is called | ||
| 208 | -- with the given arguments. | ||
| 209 | -- @param module string: The module name, like in plain require(). | ||
| 210 | -- @param constraints string or nil: An optional comma-separated | ||
| 211 | -- list of version constraints. | ||
| 212 | -- @return (string, string) or nil: Rock name and version if the | ||
| 213 | -- requested module can be supplied by LuaRocks, or nil if it can't. | ||
| 214 | function get_rock_from_module(module, constraints) | ||
| 215 | --assert(type(module) == "string") | ||
| 216 | --assert(not constraints or type(constraints) == "string") | ||
| 217 | local name, version = pick_module(module, constraints) | ||
| 218 | return name, version | ||
| 219 | end | ||
| 220 | |||
| 221 | --- Package loader for LuaRocks support. | ||
| 222 | -- A module is searched in installed rocks that match the | ||
| 223 | -- current LuaRocks context. If module is not part of the | ||
| 224 | -- context, or if a context has not yet been set, the module | ||
| 225 | -- in the package with the highest version is used. | ||
| 226 | -- @param module string: The module name, like in plain require(). | ||
| 227 | -- @return table: The module table (typically), like in plain | ||
| 228 | -- require(). See <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require">require()</a> | ||
| 229 | -- in the Lua reference manual for details. | ||
| 230 | |||
| 231 | function luarocks_loader(module) | ||
| 232 | local name, version, repo = pick_module(module) | ||
| 233 | if not name then | ||
| 234 | return nil, "No LuaRocks module found for "..module | ||
| 235 | else | ||
| 236 | add_context(name, version, repo.manifest) | ||
| 237 | return call_other_loaders(module, name, version, repo.rocks_dir) | ||
| 238 | end | ||
| 239 | end | ||
| 240 | |||
| 241 | table.insert(global_env.package.loaders, luarocks_loader) | ||
