From e5b7df87128e34b7f99baeb8c17290786e5b5ec9 Mon Sep 17 00:00:00 2001 From: Peter Melnichenko Date: Sat, 29 Oct 2016 23:19:53 +0300 Subject: Get rid of repeated missing deps checks Do not report missing dependencies on manifest update, which is now done more often. Instead do it at the end of commands that may alter manifest (install, build, make, remove - excluding purge). For reporting reuse format used when showing missing deps to be installed. Do not report missing indirect dependencies, only direct ones. --- src/luarocks/build.lua | 10 +++---- src/luarocks/deps.lua | 70 +++++++++++++++++++++++++----------------------- src/luarocks/install.lua | 3 +++ src/luarocks/make.lua | 4 +++ src/luarocks/manif.lua | 43 ++++++++++++++++++++--------- src/luarocks/remove.lua | 9 ++++++- 6 files changed, 87 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 20d094b1..96b232ff 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua @@ -400,14 +400,14 @@ function build.command(flags, name, version) if not ok then return nil, err, cfg.errorcodes.PERMISSIONDENIED end ok, err = do_build(name, version, deps.get_deps_mode(flags), flags["only-deps"]) if not ok then return nil, err end - local name, version = ok, err - if flags["only-deps"] then - return name, version - end - if (not flags["keep"]) and not cfg.keep_other_versions then + name, version = ok, err + + if (not flags["only-deps"]) and (not flags["keep"]) and not cfg.keep_other_versions then local ok, err = remove.remove_other_versions(name, version, flags["force"], flags["force-fast"]) if not ok then util.printerr(err) end end + + manif.check_dependencies(nil, deps.get_deps_mode(flags)) return name, version end end diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 756ba6bd..dcebec9b 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -400,6 +400,28 @@ local function rock_status(name, deps_mode) return installed and installed.." "..installation_type or "not installed" end +--- Check depenendencies of a package and report any missing ones. +-- @param name string: package name. +-- @param version string: package version. +-- @param dependencies table: array of dependencies. +-- @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. +function deps.report_missing_dependencies(name, version, dependencies, deps_mode) + local first_missing_dep = true + + for _, dep in ipairs(dependencies) do + if not match_dep(dep, nil, deps_mode) then + if first_missing_dep then + util.printout(("Missing dependencies for %s %s:"):format(name, version)) + first_missing_dep = false + end + + util.printout((" %s (%s)"):format(deps.show_dep(dep), rock_status(dep.name, deps_mode))) + end + end +end + --- Check dependencies of a rock and attempt to install any missing ones. -- Packages are installed using the LuaRocks "install" command. -- Aborts the program if a dependency could not be fulfilled. @@ -439,20 +461,9 @@ function deps.fulfill_dependencies(rockspec, deps_mode) end end - local first_missing_dep = true - - for _, dep in ipairs(rockspec.dependencies) do - if not match_dep(dep, nil, deps_mode) then - if first_missing_dep then - util.printout(("Missing dependencies for %s %s:"):format(rockspec.name, rockspec.version)) - first_missing_dep = false - end - - util.printout((" %s (%s)"):format(deps.show_dep(dep), rock_status(dep.name, deps_mode))) - end - end + deps.report_missing_dependencies(rockspec.name, rockspec.version, rockspec.dependencies, deps_mode) - first_missing_dep = true + local first_missing_dep = true for _, dep in ipairs(rockspec.dependencies) do if not match_dep(dep, nil, deps_mode) then @@ -674,17 +685,15 @@ function deps.check_external_deps(rockspec, mode) return true end ---- Recursively scan dependencies, to build a transitive closure of all --- dependent packages. --- @param results table: The results table being built. --- @param missing table: The table of missing dependencies being recursively built. +--- Recursively add satisfied dependencies of a package to a table, +-- to build a transitive closure of all dependent packages. +-- Additionally ensures that `dependencies` table of the manifest is up-to-date. +-- @param results table: The results table being built, maps package names to versions. -- @param manifest table: The manifest table containing dependencies. -- @param name string: Package name. -- @param version string: Package version. --- @return (table, table): The results and a table of missing dependencies. -function deps.scan_deps(results, missing, manifest, name, version, deps_mode) +function deps.scan_deps(results, manifest, name, version, deps_mode) assert(type(results) == "table") - assert(type(missing) == "table") assert(type(manifest) == "table") assert(type(name) == "string") assert(type(version) == "string") @@ -692,7 +701,7 @@ function deps.scan_deps(results, missing, manifest, name, version, deps_mode) local fetch = require("luarocks.fetch") if results[name] then - return results, missing + return end if not manifest.dependencies then manifest.dependencies = {} end local dependencies = manifest.dependencies @@ -702,26 +711,19 @@ function deps.scan_deps(results, missing, manifest, name, version, deps_mode) local rockspec, err if not deplist then rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version), false) - if err then - missing[name.." "..version] = err - return results, missing + if not rockspec then + util.printerr("Couldn't load rockspec for "..name.." "..version..": "..err) + return end dependencies_name[version] = rockspec.dependencies else rockspec = { dependencies = deplist } end - local matched, failures = deps.match_deps(rockspec, nil, deps_mode) - results[name] = results + local matched = deps.match_deps(rockspec, nil, deps_mode) + results[name] = version for _, match in pairs(matched) do - results, missing = deps.scan_deps(results, missing, manifest, match.name, match.version, deps_mode) + deps.scan_deps(results, manifest, match.name, match.version, deps_mode) end - if next(failures) then - for _, failure in pairs(failures) do - missing[deps.show_dep(failure)] = "failed" - end - end - results[name] = version - return results, missing end local valid_deps_modes = { diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index b5128430..e28c24f0 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua @@ -166,10 +166,13 @@ function install.command(flags, name, version) end if not ok then return nil, err end name, version = ok, err + if (not flags["only-deps"]) and (not flags["keep"]) and not cfg.keep_other_versions then local ok, err = remove.remove_other_versions(name, version, flags["force"], flags["force-fast"]) if not ok then util.printerr(err) end end + + manif.check_dependencies(nil, deps.get_deps_mode(flags)) return name, version else local search = require("luarocks.search") diff --git a/src/luarocks/make.lua b/src/luarocks/make.lua index 1464def7..15167c1e 100644 --- a/src/luarocks/make.lua +++ b/src/luarocks/make.lua @@ -14,6 +14,7 @@ local fetch = require("luarocks.fetch") local pack = require("luarocks.pack") local remove = require("luarocks.remove") local deps = require("luarocks.deps") +local manif = require("luarocks.manif") util.add_run_function(make) make.help_summary = "Compile package in current directory using a rockspec." @@ -77,10 +78,13 @@ function make.command(flags, rockspec) ok, err = build.build_rockspec(rockspec, false, true, 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"], flags["force-fast"]) if not ok then util.printerr(err) end end + + manif.check_dependencies(nil, deps.get_deps_mode(flags)) return name, version end end diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index c4c52bd2..86209d06 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua @@ -274,21 +274,11 @@ local function update_dependencies(manifest, deps_mode) for pkg, versions in pairs(manifest.repository) do for version, repositories in pairs(versions) do - local current = pkg.." "..version for _, repo in ipairs(repositories) do if repo.arch == "installed" then - local missing - repo.dependencies, missing = deps.scan_deps({}, {}, manifest, pkg, version, deps_mode) + repo.dependencies = {} + deps.scan_deps(repo.dependencies, manifest, pkg, version, deps_mode) repo.dependencies[pkg] = nil - if missing then - for miss, err in pairs(missing) do - if miss == current then - util.printerr("Tree inconsistency detected: "..current.." has no rockspec. "..err) - elseif deps_mode ~= "none" then - util.printerr("Missing dependency for "..pkg.." "..version..": "..miss) - end - end - end end end end @@ -512,6 +502,35 @@ function manif.remove_from_manifest(name, version, repo, deps_mode) return save_table(rocks_dir, "manifest", manifest) end +--- Report missing dependencies for all rocks installed in a 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. +function manif.check_dependencies(repo, deps_mode) + 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 = manif_core.load_local_manifest(rocks_dir) + if not manifest then + return + end + + for name, versions in util.sortedpairs(manifest.repository) do + for version, version_entries in util.sortedpairs(versions, deps.compare_versions) do + for _, entry in ipairs(version_entries) do + if entry.arch == "installed" then + if manifest.dependencies[name] and manifest.dependencies[name][version] then + deps.report_missing_dependencies(name, version, manifest.dependencies[name][version], deps_mode) + end + end + end + end + end +end + function manif.zip_manifests() for ver in util.lua_versions() do local file = "manifest-"..ver diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index 601eedcf..514c6dfa 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua @@ -12,6 +12,7 @@ local path = require("luarocks.path") local util = require("luarocks.util") local cfg = require("luarocks.cfg") local fs = require("luarocks.fs") +local manif = require("luarocks.manif") util.add_run_function(remove) remove.help_summary = "Uninstall a rock." @@ -161,7 +162,13 @@ function remove.command(flags, name, version) return nil, "Could not find rock '"..name..(version and " "..version or "").."' in "..path.rocks_tree_to_string(cfg.root_dir) end - return remove.remove_search_results(results, name, deps_mode, flags["force"], flags["force-fast"]) + local ok, err = remove.remove_search_results(results, name, deps_mode, flags["force"], flags["force-fast"]) + if not ok then + return nil, err + end + + manif.check_dependencies(nil, deps.get_deps_mode(flags)) + return true end return remove -- cgit v1.2.3-55-g6feb