From aff559479ce9af00327295927e2ed85d72fe6cd0 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Thu, 4 Jul 2013 15:16:25 -0300 Subject: Remove other previously installed versions when running 'build' or 'install'. --- src/luarocks/build.lua | 28 ++++++++---- src/luarocks/deps.lua | 21 +++++---- src/luarocks/install.lua | 16 +++++-- src/luarocks/make_manifest.lua | 7 ++- src/luarocks/pack.lua | 2 +- src/luarocks/purge.lua | 2 +- src/luarocks/remove.lua | 97 ++++++++++++++++++++++++------------------ 7 files changed, 106 insertions(+), 67 deletions(-) diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 71b3cb89..71dcda94 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua @@ -12,18 +12,23 @@ local fs = require("luarocks.fs") local dir = require("luarocks.dir") local deps = require("luarocks.deps") local manif = require("luarocks.manif") +local search = require("luarocks.search") +local remove = require("luarocks.remove") local cfg = require("luarocks.cfg") help_summary = "Build/compile a rock." -help_arguments = "[--pack-binary-rock] {|| []}" +help_arguments = "[--pack-binary-rock] [--keep] {|| []}" help = [[ Build and install a rock, compiling its C parts if any. Argument may be a rockspec file, a source rock file or the name of a rock to be fetched from a repository. -If --pack-binary-rock is passed, the rock is not installed; -instead, a .rock file with the contents of compilation is produced -in the current directory. +--pack-binary-rock Do not install rock. Instead, produce a .rock file + with the contents of compilation in the current + directory. + +--keep Do not remove previously installed versions of the + rock after building a new one. ]] --- Install files to a given location. @@ -114,8 +119,8 @@ 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 no trees. --- @return boolean or (nil, string, [string]): True if succeeded or --- nil and an error message followed by an error code. +-- @return (string, string) or (nil, string, [string]): Name and version of +-- installed rock if succeeded or nil and an error message followed by an error code. function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode) assert(type(rockspec_file) == "string") assert(type(need_to_fetch) == "boolean") @@ -272,7 +277,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_mode) util.printout(name.." "..version.." is now built and installed in "..root_dir.." "..license) util.remove_scheduled_function(rollback) - return true + return name, version end --- Build and install a rock. @@ -336,6 +341,13 @@ function run(...) else local ok, err = fs.check_command_permissions(flags) if not ok then return nil, err end - return do_build(name, version, deps.get_deps_mode(flags)) + ok, err = do_build(name, version, deps.get_deps_mode(flags)) + if not ok then return nil, err end + local name, version = ok, err + if (not flags["keep"]) and not cfg.keep_other_versions then + local ok, err = remove.remove_other_versions(name, version, flags["force"]) + if not ok then util.printerr(err) end + end + return name, version end end diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 6d5f3fef..7aefd40e 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -290,15 +290,18 @@ function match_constraints(version, constraints) local ok = true setmetatable(version, version_mt) for _, constr in pairs(constraints) do - local constr_version = constr.version - setmetatable(constr.version, version_mt) - if constr.op == "==" then ok = version == constr_version - elseif constr.op == "~=" then ok = version ~= constr_version - elseif constr.op == ">" then ok = version > constr_version - elseif constr.op == "<" then ok = version < constr_version - elseif constr.op == ">=" then ok = version >= constr_version - elseif constr.op == "<=" then ok = version <= constr_version - elseif constr.op == "~>" then ok = partial_match(version, constr_version) + if type(constr.version) == "string" then + constr.version = parse_version(constr.version) + end + local constr_version, constr_op = constr.version, constr.op + setmetatable(constr_version, version_mt) + if constr_op == "==" then ok = version == constr_version + elseif constr_op == "~=" then ok = version ~= constr_version + elseif constr_op == ">" then ok = version > constr_version + elseif constr_op == "<" then ok = version < constr_version + elseif constr_op == ">=" then ok = version >= constr_version + elseif constr_op == "<=" then ok = version <= constr_version + elseif constr_op == "~>" then ok = partial_match(version, constr_version) end if not ok then break end end diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index 3960dcb8..8ada2d50 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua @@ -10,6 +10,7 @@ local util = require("luarocks.util") local fs = require("luarocks.fs") local deps = require("luarocks.deps") local manif = require("luarocks.manif") +local remove = require("luarocks.remove") local cfg = require("luarocks.cfg") help_summary = "Install a rock." @@ -26,8 +27,8 @@ or a filename of a locally available rock. -- @param deps_mode: string: Which trees to check dependencies for: -- "one" for the current default tree, "all" for all trees, -- "order" for all trees with priority >= the current default, "none" for no trees. --- @return boolean or (nil, string, [string]): True if succeeded or --- nil and an error message and an optional error code. +-- @return (string, string) or (nil, string, [string]): Name and version of +-- installed rock if succeeded or nil and an error message followed by an error code. function install_binary_rock(rock_file, deps_mode) assert(type(rock_file) == "string") @@ -103,7 +104,7 @@ function install_binary_rock(rock_file, deps_mode) util.printout(name.." "..version.." is now installed in "..root_dir.." "..license) util.remove_scheduled_function(rollback) - return true + return name, version end --- Driver function for the "install" command. @@ -130,7 +131,14 @@ function run(...) local build = require("luarocks.build") return build.run(name, deps.get_deps_mode(flags), flags["local"] and "--local") elseif name:match("%.rock$") then - return install_binary_rock(name, deps.get_deps_mode(flags)) + ok, err = install_binary_rock(name, deps.get_deps_mode(flags)) + if not ok then return nil, err end + local name, version = ok, err + if (not flags["keep"]) and not cfg.keep_other_versions then + local ok, err = remove.remove_other_versions(name, version, flags["force"]) + if not ok then util.printerr(err) end + end + return name, version else local search = require("luarocks.search") local results, err = search.find_suitable_rock(search.make_query(name:lower(), version)) diff --git a/src/luarocks/make_manifest.lua b/src/luarocks/make_manifest.lua index f793dcf2..a698f830 100644 --- a/src/luarocks/make_manifest.lua +++ b/src/luarocks/make_manifest.lua @@ -13,6 +13,9 @@ help_summary = "Compile a manifest file for a repository." help = [[ , if given, is a local repository pathname. + +--local-tree If given, do not write versioned versions of the manifest file. + Use this when rebuilding the manifest of a local rocks tree. ]] --- Driver function for "make_manifest" command. @@ -28,8 +31,8 @@ function run(...) util.printout("Making manifest for "..repo) - local ok, err = manif.make_manifest(repo, deps.get_deps_mode(flags), true) - if ok then + local ok, err = manif.make_manifest(repo, deps.get_deps_mode(flags), not flags["local-tree"]) + if ok and not flags["local-tree"] then util.printout("Generating index.html for "..repo) index.make_index(repo) end diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua index eaa0e165..ed340a35 100644 --- a/src/luarocks/pack.lua +++ b/src/luarocks/pack.lua @@ -111,7 +111,7 @@ local function do_pack_binary_rock(name, version) local root = path.root_dir(info.repo) local prefix = path.install_dir(name, version, root) - +print(prefix) if not fs.exists(prefix) then return nil, "'"..name.." "..version.."' does not seem to be an installed rock." end diff --git a/src/luarocks/purge.lua b/src/luarocks/purge.lua index 46a023e9..6b094061 100644 --- a/src/luarocks/purge.lua +++ b/src/luarocks/purge.lua @@ -44,5 +44,5 @@ function run(...) end end end - return manif.make_manifest(cfg.rocks_dir, "one", true) + return manif.make_manifest(cfg.rocks_dir, "one") end diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index 8c899a0a..96816419 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua @@ -69,6 +69,58 @@ local function delete_versions(name, versions) return true end +function remove_search_results(results, name, deps_mode, force) + local versions = results[name] + + local version = next(versions) + local second = next(versions, version) + + util.printout("Checking stability of dependencies on the absence of") + util.printout(name.." "..table.concat(util.keys(versions), ", ").."...") + util.printout() + + local dependents = check_dependents(name, versions, deps_mode) + + if #dependents == 0 or force then + if #dependents > 0 then + util.printerr("The following packages may be broken by this forced removal:") + for _, dependent in ipairs(dependents) do + util.printerr(dependent.name.." "..dependent.version) + end + util.printerr() + end + local ok, err = delete_versions(name, versions) + if not ok then return nil, err end + ok, err = manif.make_manifest(cfg.rocks_dir, deps_mode) + if not ok then return nil, err end + else + if not second then + util.printerr("Will not remove "..name.." "..version..".") + util.printerr("Removing it would break dependencies for: ") + else + util.printerr("Will not remove installed versions of "..name..".") + util.printerr("Removing them would break dependencies for: ") + end + for _, dependent in ipairs(dependents) do + util.printerr(dependent.name.." "..dependent.version) + end + util.printerr() + util.printerr("Use --force to force removal (warning: this may break modules).") + return nil, "Failed removing." + end + util.printout("Removal successful.") + return true +end + +function remove_other_versions(name, version, force) + local results = {} + search.manifest_search(results, cfg.rocks_dir, { name = name, exact_name = true, constraints = {{ op = "~=", version = version}} }) + if results[name] then + return remove_search_results(results, name, cfg.deps_mode, force) + end + return true +end + --- Driver function for the "remove" command. -- @param name string: name of a rock. If a version is given, refer to -- a specific version; otherwise, try to remove all versions. @@ -97,48 +149,9 @@ function run(...) local results = {} search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version)) - - local versions = results[name] - if not versions then + if not results[name] then return nil, "Could not find rock '"..name..(version and " "..version or "").."' in local tree." - else - local version = next(versions) - local second = next(versions, version) - - util.printout("Checking stability of dependencies on the absence of") - util.printout(name.." "..table.concat(util.keys(versions), ", ").."...") - util.printout() - - local dependents = check_dependents(name, versions, deps_mode) - - if #dependents == 0 or flags["force"] then - if #dependents > 0 then - util.printerr("The following packages may be broken by this forced removal:") - for _, dependent in ipairs(dependents) do - util.printerr(dependent.name.." "..dependent.version) - end - util.printerr() - end - local ok, err = delete_versions(name, versions) - if not ok then return nil, err end - ok, err = manif.make_manifest(cfg.rocks_dir, deps_mode) - if not ok then return nil, err end - else - if not second then - util.printerr("Will not remove "..name.." "..version..".") - util.printerr("Removing it would break dependencies for: ") - else - util.printerr("Will not remove all versions of "..name..".") - util.printerr("Removing them would break dependencies for: ") - end - for _, dependent in ipairs(dependents) do - util.printerr(dependent.name.." "..dependent.version) - end - util.printerr() - util.printerr("Use --force to force removal (warning: this may break modules).") - return nil, "Failed removing." - end end - util.printout("Removal successful.") - return true + + return remove_search_results(results, name, deps_mode, flags["force"]) end -- cgit v1.2.3-55-g6feb