From ba906abeafae6ebc199bb3ed447bc2a31bb9b770 Mon Sep 17 00:00:00 2001 From: hisham Date: Thu, 16 Jul 2009 21:04:24 +0000 Subject: add wip version of new package loader git-svn-id: http://luarocks.org/svn/luarocks/trunk@40 9ca3f7c1-7366-0410-b1a3-b5c78f85698c --- src/luarocks2.lua | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 src/luarocks2.lua (limited to 'src') diff --git a/src/luarocks2.lua b/src/luarocks2.lua new file mode 100644 index 00000000..0ca2f505 --- /dev/null +++ b/src/luarocks2.lua @@ -0,0 +1,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 require() +-- 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) -- cgit v1.2.3-55-g6feb