From bcdb901611b05870692de69bd2a7cd1eec88a114 Mon Sep 17 00:00:00 2001 From: Hisham Date: Sat, 29 Oct 2016 17:47:27 -0200 Subject: Adjust changes by @mpeterv in #638 to new locations. --- src/luarocks/manif/writer.lua | 189 +++++++++++++++++++++++++++--------------- src/luarocks/repos.lua | 4 +- 2 files changed, 126 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/luarocks/manif/writer.lua b/src/luarocks/manif/writer.lua index 1eb5ee7c..df971fca 100644 --- a/src/luarocks/manif/writer.lua +++ b/src/luarocks/manif/writer.lua @@ -13,33 +13,60 @@ local path = require("luarocks.path") local persist = require("luarocks.persist") local manif = require("luarocks.manif") ---- Output a table listing items of a package. --- @param itemsfn function: a function for obtaining items of a package. --- pkg and version will be passed to it; it should return a table with --- items as keys. --- @param pkg string: package name --- @param version string: package version --- @param tbl table: the package matching table: keys should be item names --- and values arrays of strings with packages names in "name/version" format. -local function store_package_items(itemsfn, pkg, version, tbl) - assert(type(itemsfn) == "function") - assert(type(pkg) == "string") +--- Update storage table to account for items provided by a package. +-- @param storage table: a table storing items in the following format: +-- keys are item names and values are arrays of packages providing each item, +-- where a package is specified as string `name/version`. +-- @param items table: a table mapping item names to paths. +-- @param name string: package name. +-- @param version string: package version. +local function store_package_items(storage, name, version, items) + assert(type(storage) == "table") + assert(type(items) == "table") + assert(type(name) == "string") assert(type(version) == "string") - assert(type(tbl) == "table") - local pkg_version = pkg.."/"..version - local result = {} + local package_identifier = name.."/"..version - for item, path in pairs(itemsfn(pkg, version)) do - result[item] = path - if not tbl[item] then - tbl[item] = {} + for item_name, path in pairs(items) do + if not storage[item_name] then + storage[item_name] = {} end - table.insert(tbl[item], pkg_version) + + table.insert(storage[item_name], package_identifier) end - return result end +--- Update storage table removing items provided by a package. +-- @param storage table: a table storing items in the following format: +-- keys are item names and values are arrays of packages providing each item, +-- where a package is specified as string `name/version`. +-- @param items table: a table mapping item names to paths. +-- @param name string: package name. +-- @param version string: package version. +local function remove_package_items(storage, name, version, items) + assert(type(storage) == "table") + assert(type(items) == "table") + assert(type(name) == "string") + assert(type(version) == "string") + + local package_identifier = name.."/"..version + + for item_name, path in pairs(items) do + local all_identifiers = storage[item_name] + + for i, identifier in ipairs(all_identifiers) do + if identifier == package_identifier then + table.remove(all_identifiers, i) + break + end + end + + if #all_identifiers == 0 then + storage[item_name] = nil + end + end +end --- Process the dependencies of a manifest table to determine its dependency -- chains for loading modules. The manifest dependencies information is filled @@ -174,12 +201,10 @@ end -- @param results table: The search results as returned by search.disk_search. -- @param manifest table: A manifest table (must contain repository, modules, commands tables). -- It will be altered to include the search results. --- @param dep_handler: dependency handler function -- @return boolean or (nil, string): true in case of success, or nil followed by an error message. -local function store_results(results, manifest, dep_handler) +local function store_results(results, manifest) assert(type(results) == "table") assert(type(manifest) == "table") - assert((not dep_handler) or type(dep_handler) == "function") for name, versions in pairs(results) do local pkgtable = manifest.repository[name] or {} @@ -189,10 +214,15 @@ local function store_results(results, manifest, dep_handler) local entrytable = {} entrytable.arch = entry.arch if entry.arch == "installed" then - local rock_manifest, err = manif.load_rock_manifest(name, version) - if not rock_manifest then return nil, err end - entrytable.modules = store_package_items(repos.package_modules, name, version, manifest.modules) - entrytable.commands = store_package_items(repos.package_commands, name, version, manifest.commands) + local rock_manifest = manif.load_rock_manifest(name, version) + if not rock_manifest then + return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks 2 tree?" + end + + entrytable.modules = repos.package_modules(name, version) + store_package_items(manifest.modules, name, version, entrytable.modules) + entrytable.commands = repos.package_commands(name, version) + store_package_items(manifest.commands, name, version, entrytable.commands) end table.insert(versiontable, entrytable) end @@ -200,9 +230,6 @@ local function store_results(results, manifest, dep_handler) end manifest.repository[name] = pkgtable end - if dep_handler then - dep_handler(manifest) - end sort_package_matching_table(manifest.modules) sort_package_matching_table(manifest.commands) return true @@ -265,7 +292,7 @@ end -- @param deps_mode string: Dependency mode: "one" for the current default tree, -- "all" for all trees, "order" for all trees with priority >= the current default, -- "none" for the default dependency mode from the configuration. --- @param versioned boolean: if versioned versions of the manifest should be created. +-- @param remote boolean: 'true' if making a manifest for a rocks server. -- @return boolean or (nil, string): True if manifest was generated, -- or nil and an error message. function writer.make_manifest(repo, deps_mode, remote) @@ -286,34 +313,26 @@ function writer.make_manifest(repo, deps_mode, remote) manif.cache_manifest(repo, nil, manifest) - local dep_handler = nil - if not remote then - dep_handler = function(manifest) - update_dependencies(manifest, deps_mode) - end - end - local ok, err = store_results(results, manifest, dep_handler) + local ok, err = store_results(results, manifest) if not ok then return nil, err end if remote then local cache = {} for luaver in util.lua_versions() do local vmanifest = { repository = {}, modules = {}, commands = {} } - local dep_handler = function(manifest) - filter_by_lua_version(manifest, luaver, repo, cache) - end - store_results(results, vmanifest, dep_handler) + local ok, err = store_results(results, vmanifest) + filter_by_lua_version(vmanifest, luaver, repo, cache) save_table(repo, "manifest-"..luaver, vmanifest) end + else + update_dependencies(manifest, deps_mode) end return save_table(repo, "manifest", manifest) end ---- Load a manifest file from a local repository and add to the repository --- information with regard to the given name and version. --- A file called 'manifest' will be written in the root of the given --- repository directory. +--- Update manifest file for a local repository +-- adding information about a version of a package installed in that repository. -- @param name string: Name of a package from the repository. -- @param version string: Version of a package from the repository. -- @param repo string or nil: Pathname of a local repository. If not given, @@ -321,38 +340,78 @@ end -- @param deps_mode string: Dependency mode: "one" for the current default tree, -- "all" for all trees, "order" for all trees with priority >= the current default, -- "none" for using the default dependency mode from the configuration. --- @return boolean or (nil, string): True if manifest was generated, +-- @return boolean or (nil, string): True if manifest was updated successfully, -- or nil and an error message. -function writer.update_manifest(name, version, repo, deps_mode) +function writer.add_to_manifest(name, version, repo, deps_mode) assert(type(name) == "string") assert(type(version) == "string") - repo = path.rocks_dir(repo or cfg.root_dir) + local rocks_dir = path.rocks_dir(repo or cfg.root_dir) assert(type(deps_mode) == "string") - + if deps_mode == "none" then deps_mode = cfg.deps_mode end - local manifest, err = manif.load_manifest(repo) + local manifest, err = manif.load_local_manifest(rocks_dir) if not manifest then util.printerr("No existing manifest. Attempting to rebuild...") - local ok, err = writer.make_manifest(repo, deps_mode) - if not ok then - return nil, err - end - manifest, err = manif.load_manifest(repo) - if not manifest then - return nil, err - end + -- Manifest built by `manif.make_manifest` should already + -- include information about given name and version, + -- no need to update it. + return manif.make_manifest(rocks_dir, deps_mode) end - local results = {[name] = {[version] = {{arch = "installed", repo = repo}}}} + local results = {[name] = {[version] = {{arch = "installed", repo = rocks_dir}}}} - local dep_handler = function(manifest) - update_dependencies(manifest, deps_mode) - end - local ok, err = store_results(results, manifest, dep_handler) + local ok, err = store_results(results, manifest) if not ok then return nil, err end - return save_table(repo, "manifest", manifest) + update_dependencies(manifest, deps_mode) + return save_table(rocks_dir, "manifest", manifest) +end + +--- Update manifest file for a local repository +-- removing information about a version of a package. +-- @param name string: Name of a package removed from the repository. +-- @param version string: Version of a package removed from the repository. +-- @param repo string or nil: Pathname of a local repository. If not given, +-- the default local repository is used. +-- @param deps_mode string: Dependency mode: "one" for the current default tree, +-- "all" for all trees, "order" for all trees with priority >= the current default, +-- "none" for using the default dependency mode from the configuration. +-- @return boolean or (nil, string): True if manifest was updated successfully, +-- or nil and an error message. +function writer.remove_from_manifest(name, version, repo, deps_mode) + assert(type(name) == "string") + assert(type(version) == "string") + local rocks_dir = path.rocks_dir(repo or cfg.root_dir) + assert(type(deps_mode) == "string") + + if deps_mode == "none" then deps_mode = cfg.deps_mode end + + local manifest, err = manif.load_local_manifest(rocks_dir) + if not manifest then + util.printerr("No existing manifest. Attempting to rebuild...") + -- Manifest built by `manif.make_manifest` should already + -- include up-to-date information, no need to update it. + return manif.make_manifest(rocks_dir, deps_mode) + end + + local package_entry = manifest.repository[name] + + local version_entry = package_entry[version][1] + remove_package_items(manifest.modules, name, version, version_entry.modules) + remove_package_items(manifest.commands, name, version, version_entry.commands) + + package_entry[version] = nil + manifest.dependencies[name][version] = nil + + if not next(package_entry) then + -- No more versions of this package. + manifest.repository[name] = nil + manifest.dependencies[name] = nil + end + + update_dependencies(manifest, deps_mode) + return save_table(rocks_dir, "manifest", manifest) end return writer diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua index 9616fe03..bbc9da79 100644 --- a/src/luarocks/repos.lua +++ b/src/luarocks/repos.lua @@ -315,7 +315,7 @@ function repos.deploy_files(name, version, wrap_bin_scripts, deps_mode) end local writer = require("luarocks.manif.writer") - return writer.update_manifest(name, version, nil, deps_mode) + return writer.add_to_manifest(name, version, nil, deps_mode) end --- Delete a package from the local repository. @@ -400,7 +400,7 @@ function repos.delete_version(name, version, deps_mode, quick) end local writer = require("luarocks.manif.writer") - return writer.make_manifest(cfg.rocks_dir, deps_mode) + return writer.remove_from_manifest(name, version, nil, deps_mode) end return repos -- cgit v1.2.3-55-g6feb