From 7ce4a5c9accb22eb1fc422036c72f809e8c026b9 Mon Sep 17 00:00:00 2001 From: Peter Melnichenko Date: Fri, 28 Oct 2016 18:36:21 +0300 Subject: Update manifest after removal without rebuilding Rename `manif.update_manifest` to `manif.add_to_manifest`. Add `manif.remove_from_manifest` that performs reverse action. Use it in `repos.delete_version` to avoid rebuilding manifest everytime a package is removed. --- src/luarocks/manif.lua | 89 ++++++++++++++++++++++++++++++++++++++++++++++---- src/luarocks/repos.lua | 4 +-- 2 files changed, 84 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index 9213f362..c4c52bd2 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua @@ -185,6 +185,37 @@ local function store_package_items(storage, name, version, items) end 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 + --- Sort function for ordering rock identifiers in a manifest's -- modules table. Rocks are ordered alphabetically by name, and then -- by version which greater first. @@ -398,10 +429,8 @@ function manif.make_manifest(repo, deps_mode, remote) 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, @@ -409,14 +438,14 @@ 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 manif.update_manifest(name, version, repo, deps_mode) +function manif.add_to_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_core.load_local_manifest(rocks_dir) @@ -437,6 +466,52 @@ function manif.update_manifest(name, version, repo, 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 manif.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_core.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 + function manif.zip_manifests() for ver in util.lua_versions() do local file = "manifest-"..ver diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua index c5f157c4..d4d9694e 100644 --- a/src/luarocks/repos.lua +++ b/src/luarocks/repos.lua @@ -312,7 +312,7 @@ function repos.deploy_files(name, version, wrap_bin_scripts, deps_mode) return nil, err end - return manif.update_manifest(name, version, nil, deps_mode) + return manif.add_to_manifest(name, version, nil, deps_mode) end --- Delete a package from the local repository. @@ -398,7 +398,7 @@ function repos.delete_version(name, version, deps_mode, quick) return true end - return manif.make_manifest(cfg.rocks_dir, deps_mode) + return manif.remove_from_manifest(name, version, nil, deps_mode) end return repos -- cgit v1.2.3-55-g6feb