From b9a6f9e6cb2b0f32e8a42db59025cbfba3e4c94d Mon Sep 17 00:00:00 2001 From: V1K1NGbg Date: Tue, 6 Aug 2024 12:21:52 +0300 Subject: manif --- src/luarocks/fetch.tl | 4 +- src/luarocks/manif-original.lua | 225 ++++++++++++++++++++++++++++++++++++++++ src/luarocks/manif.lua | 114 ++++++++++---------- src/luarocks/manif.tl | 8 +- 4 files changed, 292 insertions(+), 59 deletions(-) create mode 100644 src/luarocks/manif-original.lua (limited to 'src') diff --git a/src/luarocks/fetch.tl b/src/luarocks/fetch.tl index fa084507..321d4f4e 100644 --- a/src/luarocks/fetch.tl +++ b/src/luarocks/fetch.tl @@ -54,7 +54,7 @@ local function download_with_mirrors(url: string, filename: string, cache: boole end local name, _, _, from_cache = fs.download(try_url, filename, cache) if name then - return ok, name, from_cache + return name, nil, nil, from_cache else err = err .. name .. "\n" end @@ -581,7 +581,7 @@ function fetch.fetch_sources(rockspec: Rockspec, extract: boolean, dest_dir?: st if dir.is_basic_protocol(protocol) then proto = fetch as Fetch else - ok, proto = pcall(require, "luarocks.fetch."..protocol:gsub("[+-]", "_")) as (boolean, Fetch) + ok, proto = pcall(require, ("luarocks.fetch."..protocol:gsub("[+-]", "_")) as string) as (boolean, Fetch) if not ok then return nil, "Unknown protocol "..protocol end diff --git a/src/luarocks/manif-original.lua b/src/luarocks/manif-original.lua new file mode 100644 index 00000000..a4ddda11 --- /dev/null +++ b/src/luarocks/manif-original.lua @@ -0,0 +1,225 @@ +--- Module for handling manifest files and tables. +-- Manifest files describe the contents of a LuaRocks tree or server. +-- They are loaded into manifest tables, which are then used for +-- performing searches, matching dependencies, etc. +local manif = {} + +local core = require("luarocks.core.manif") +local persist = require("luarocks.persist") +local fetch = require("luarocks.fetch") +local dir = require("luarocks.dir") +local fs = require("luarocks.fs") +local cfg = require("luarocks.core.cfg") +local path = require("luarocks.path") +local util = require("luarocks.util") +local queries = require("luarocks.queries") +local type_manifest = require("luarocks.type.manifest") + +manif.cache_manifest = core.cache_manifest +manif.load_rocks_tree_manifests = core.load_rocks_tree_manifests +manif.scan_dependencies = core.scan_dependencies + +manif.rock_manifest_cache = {} + +local function check_manifest(repo_url, manifest, globals) + local ok, err = type_manifest.check(manifest, globals) + if not ok then + core.cache_manifest(repo_url, cfg.lua_version, nil) + return nil, "Error checking manifest: "..err, "type" + end + return manifest +end + +local postprocess_dependencies +do + local postprocess_check = setmetatable({}, { __mode = "k" }) + postprocess_dependencies = function(manifest) + if postprocess_check[manifest] then + return + end + if manifest.dependencies then + for name, versions in pairs(manifest.dependencies) do + for version, entries in pairs(versions) do + for k, v in pairs(entries) do + entries[k] = queries.from_persisted_table(v) + end + end + end + end + postprocess_check[manifest] = true + end +end + +function manif.load_rock_manifest(name, version, root) + assert(type(name) == "string" and not name:match("/")) + assert(type(version) == "string") + + local name_version = name.."/"..version + if manif.rock_manifest_cache[name_version] then + return manif.rock_manifest_cache[name_version].rock_manifest + end + local pathname = path.rock_manifest_file(name, version, root) + local rock_manifest = persist.load_into_table(pathname) + if not rock_manifest then + return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks tree?" + end + manif.rock_manifest_cache[name_version] = rock_manifest + return rock_manifest.rock_manifest +end + +--- Load a local or remote manifest describing a repository. +-- All functions that use manifest tables assume they were obtained +-- through this function. +-- @param repo_url string: URL or pathname for the repository. +-- @param lua_version string: Lua version in "5.x" format, defaults to installed version. +-- @param versioned_only boolean: If true, do not fall back to the main manifest +-- if a versioned manifest was not found. +-- @return table or (nil, string, [string]): A table representing the manifest, +-- or nil followed by an error message and an optional error code. +function manif.load_manifest(repo_url, lua_version, versioned_only) + assert(type(repo_url) == "string") + assert(type(lua_version) == "string" or not lua_version) + lua_version = lua_version or cfg.lua_version + + local cached_manifest = core.get_cached_manifest(repo_url, lua_version) + if cached_manifest then + postprocess_dependencies(cached_manifest) + return cached_manifest + end + + local filenames = { + "manifest-"..lua_version..".zip", + "manifest-"..lua_version, + not versioned_only and "manifest" or nil, + } + + local protocol, repodir = dir.split_url(repo_url) + local pathname, from_cache + if protocol == "file" then + for _, filename in ipairs(filenames) do + pathname = dir.path(repodir, filename) + if fs.exists(pathname) then + break + end + end + else + local err, errcode + for _, filename in ipairs(filenames) do + pathname, err, errcode, from_cache = fetch.fetch_caching(dir.path(repo_url, filename), "no_mirror") + if pathname then + break + end + end + if not pathname then + return nil, err, errcode + end + end + if pathname:match(".*%.zip$") then + pathname = fs.absolute_name(pathname) + local nozip = pathname:match("(.*)%.zip$") + if not from_cache then + local dirname = dir.dir_name(pathname) + fs.change_dir(dirname) + fs.delete(nozip) + local ok, err = fs.unzip(pathname) + fs.pop_dir() + if not ok then + fs.delete(pathname) + fs.delete(pathname..".timestamp") + return nil, "Failed extracting manifest file: " .. err + end + end + pathname = nozip + end + local manifest, err, errcode = core.manifest_loader(pathname, repo_url, lua_version) + if not manifest then + return nil, err, errcode + end + + postprocess_dependencies(manifest) + return check_manifest(repo_url, manifest, err) +end + +--- Get type and name of an item (a module or a command) provided by a file. +-- @param deploy_type string: rock manifest subtree the file comes from ("bin", "lua", or "lib"). +-- @param file_path string: path to the file relatively to deploy_type subdirectory. +-- @return (string, string): item type ("module" or "command") and name. +function manif.get_provided_item(deploy_type, file_path) + assert(type(deploy_type) == "string") + assert(type(file_path) == "string") + local item_type = deploy_type == "bin" and "command" or "module" + local item_name = item_type == "command" and file_path or path.path_to_module(file_path) + return item_type, item_name +end + +local function get_providers(item_type, item_name, repo) + assert(type(item_type) == "string") + assert(type(item_name) == "string") + local rocks_dir = path.rocks_dir(repo or cfg.root_dir) + local manifest = manif.load_manifest(rocks_dir) + return manifest and manifest[item_type .. "s"][item_name] +end + +--- Given a name of a module or a command, figure out which rock name and version +-- correspond to it in the rock tree manifest. +-- @param item_type string: "module" or "command". +-- @param item_name string: module or command name. +-- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used. +-- @return (string, string) or nil: name and version of the provider rock or nil if there +-- is no provider. +function manif.get_current_provider(item_type, item_name, repo) + local providers = get_providers(item_type, item_name, repo) + if providers then + return providers[1]:match("([^/]*)/([^/]*)") + end +end + +function manif.get_next_provider(item_type, item_name, repo) + local providers = get_providers(item_type, item_name, repo) + if providers and providers[2] then + return providers[2]:match("([^/]*)/([^/]*)") + end +end + +--- Get all versions of a package listed in a manifest file. +-- @param name string: a package name. +-- @param deps_mode string: "one", to use only the currently +-- configured tree; "order" to select trees based on order +-- (use the current tree and all trees below it on the list) +-- or "all", to use all trees. +-- @return table: An array of strings listing installed +-- versions of a package, and a table indicating where they are found. +function manif.get_versions(dep, deps_mode) + assert(type(dep) == "table") + assert(type(deps_mode) == "string") + + local name = dep.name + local namespace = dep.namespace + + local version_set = {} + path.map_trees(deps_mode, function(tree) + local manifest = manif.load_manifest(path.rocks_dir(tree)) + + if manifest and manifest.repository[name] then + for version in pairs(manifest.repository[name]) do + if dep.namespace then + local ns_file = path.rock_namespace_file(name, version, tree) + local fd = io.open(ns_file, "r") + if fd then + local ns = fd:read("*a") + fd:close() + if ns == namespace then + version_set[version] = tree + end + end + else + version_set[version] = tree + end + end + end + end) + + return util.keys(version_set), version_set +end + +return manif diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index a4ddda11..437ebe3b 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua @@ -1,9 +1,18 @@ ---- Module for handling manifest files and tables. --- Manifest files describe the contents of a LuaRocks tree or server. --- They are loaded into manifest tables, which are then used for --- performing searches, matching dependencies, etc. +local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local assert = _tl_compat and _tl_compat.assert or assert; local io = _tl_compat and _tl_compat.io or io; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local pairs = _tl_compat and _tl_compat.pairs or pairs; local string = _tl_compat and _tl_compat.string or string + + + local manif = {} + + + + + + + + + local core = require("luarocks.core.manif") local persist = require("luarocks.persist") local fetch = require("luarocks.fetch") @@ -15,6 +24,14 @@ local util = require("luarocks.util") local queries = require("luarocks.queries") local type_manifest = require("luarocks.type.manifest") + + + + + + + + manif.cache_manifest = core.cache_manifest manif.load_rocks_tree_manifests = core.load_rocks_tree_manifests manif.scan_dependencies = core.scan_dependencies @@ -25,7 +42,7 @@ local function check_manifest(repo_url, manifest, globals) local ok, err = type_manifest.check(manifest, globals) if not ok then core.cache_manifest(repo_url, cfg.lua_version, nil) - return nil, "Error checking manifest: "..err, "type" + return nil, "Error checking manifest: " .. err, "type" end return manifest end @@ -38,9 +55,9 @@ do return end if manifest.dependencies then - for name, versions in pairs(manifest.dependencies) do - for version, entries in pairs(versions) do - for k, v in pairs(entries) do + for _, versions in pairs(manifest.dependencies) do + for _, entries in pairs(versions) do + for k, v in ipairs(entries) do entries[k] = queries.from_persisted_table(v) end end @@ -51,34 +68,31 @@ do end function manif.load_rock_manifest(name, version, root) - assert(type(name) == "string" and not name:match("/")) - assert(type(version) == "string") + assert(not name:match("/")) - local name_version = name.."/"..version + local name_version = name .. "/" .. version if manif.rock_manifest_cache[name_version] then return manif.rock_manifest_cache[name_version].rock_manifest end local pathname = path.rock_manifest_file(name, version, root) local rock_manifest = persist.load_into_table(pathname) if not rock_manifest then - return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks tree?" + return nil, "rock_manifest file not found for " .. name .. " " .. version .. " - not a LuaRocks tree?" end manif.rock_manifest_cache[name_version] = rock_manifest return rock_manifest.rock_manifest end ---- Load a local or remote manifest describing a repository. --- All functions that use manifest tables assume they were obtained --- through this function. --- @param repo_url string: URL or pathname for the repository. --- @param lua_version string: Lua version in "5.x" format, defaults to installed version. --- @param versioned_only boolean: If true, do not fall back to the main manifest --- if a versioned manifest was not found. --- @return table or (nil, string, [string]): A table representing the manifest, --- or nil followed by an error message and an optional error code. + + + + + + + + + function manif.load_manifest(repo_url, lua_version, versioned_only) - assert(type(repo_url) == "string") - assert(type(lua_version) == "string" or not lua_version) lua_version = lua_version or cfg.lua_version local cached_manifest = core.get_cached_manifest(repo_url, lua_version) @@ -88,8 +102,8 @@ function manif.load_manifest(repo_url, lua_version, versioned_only) end local filenames = { - "manifest-"..lua_version..".zip", - "manifest-"..lua_version, + "manifest-" .. lua_version .. ".zip", + "manifest-" .. lua_version, not versioned_only and "manifest" or nil, } @@ -125,14 +139,14 @@ function manif.load_manifest(repo_url, lua_version, versioned_only) fs.pop_dir() if not ok then fs.delete(pathname) - fs.delete(pathname..".timestamp") + fs.delete(pathname .. ".timestamp") return nil, "Failed extracting manifest file: " .. err end end pathname = nozip end local manifest, err, errcode = core.manifest_loader(pathname, repo_url, lua_version) - if not manifest then + if not manifest and type(err) == "string" then return nil, err, errcode end @@ -140,33 +154,29 @@ function manif.load_manifest(repo_url, lua_version, versioned_only) return check_manifest(repo_url, manifest, err) end ---- Get type and name of an item (a module or a command) provided by a file. --- @param deploy_type string: rock manifest subtree the file comes from ("bin", "lua", or "lib"). --- @param file_path string: path to the file relatively to deploy_type subdirectory. --- @return (string, string): item type ("module" or "command") and name. + + + + function manif.get_provided_item(deploy_type, file_path) - assert(type(deploy_type) == "string") - assert(type(file_path) == "string") local item_type = deploy_type == "bin" and "command" or "module" local item_name = item_type == "command" and file_path or path.path_to_module(file_path) return item_type, item_name end local function get_providers(item_type, item_name, repo) - assert(type(item_type) == "string") - assert(type(item_name) == "string") local rocks_dir = path.rocks_dir(repo or cfg.root_dir) local manifest = manif.load_manifest(rocks_dir) - return manifest and manifest[item_type .. "s"][item_name] + return manifest and (manifest)[item_type .. "s"][item_name] end ---- Given a name of a module or a command, figure out which rock name and version --- correspond to it in the rock tree manifest. --- @param item_type string: "module" or "command". --- @param item_name string: module or command name. --- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used. --- @return (string, string) or nil: name and version of the provider rock or nil if there --- is no provider. + + + + + + + function manif.get_current_provider(item_type, item_name, repo) local providers = get_providers(item_type, item_name, repo) if providers then @@ -181,17 +191,15 @@ function manif.get_next_provider(item_type, item_name, repo) end end ---- Get all versions of a package listed in a manifest file. --- @param name string: a package name. --- @param deps_mode string: "one", to use only the currently --- configured tree; "order" to select trees based on order --- (use the current tree and all trees below it on the list) --- or "all", to use all trees. --- @return table: An array of strings listing installed --- versions of a package, and a table indicating where they are found. + + + + + + + + function manif.get_versions(dep, deps_mode) - assert(type(dep) == "table") - assert(type(deps_mode) == "string") local name = dep.name local namespace = dep.namespace diff --git a/src/luarocks/manif.tl b/src/luarocks/manif.tl index ff725e5f..f1963150 100644 --- a/src/luarocks/manif.tl +++ b/src/luarocks/manif.tl @@ -26,9 +26,9 @@ local type_manifest = require("luarocks.type.manifest") local type tree = require("luarocks.core.types.tree") local type Tree = tree.Tree -local type manifest = require("luarocks.core.types.manifest") -local type Manifest = manifest.Manifest -local type Tree_manifest = manifest.Tree_manifest +local type m = require("luarocks.core.types.manifest") +local type Manifest = m.Manifest +local type Tree_manifest = m .Tree_manifest local type query = require("luarocks.core.types.query") local type Query = query.Query @@ -167,7 +167,7 @@ end local function get_providers(item_type: string, item_name: string, repo: string | Tree): {string} local rocks_dir = path.rocks_dir(repo or cfg.root_dir) local manifest = manif.load_manifest(rocks_dir) - return manifest and manifest[item_type .. "s"][item_name] + return manifest and (manifest as {string: {string: {string}}})[item_type .. "s"][item_name] end --- Given a name of a module or a command, figure out which rock name and version -- cgit v1.2.3-55-g6feb