diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2021-03-16 14:55:11 -0300 |
|---|---|---|
| committer | Hisham Muhammad <hisham@gobolinux.org> | 2021-03-19 13:15:53 -0300 |
| commit | 2efec770b1b1b27a4b15c3b06a2f5fcadc0b546d (patch) | |
| tree | f7c2e34abe3314658df0970dde6e1bc346c1e627 /src | |
| parent | 08ae98e309c3f09be00b547bab74a5fd875bfa36 (diff) | |
| download | luarocks-2efec770b1b1b27a4b15c3b06a2f5fcadc0b546d.tar.gz luarocks-2efec770b1b1b27a4b15c3b06a2f5fcadc0b546d.tar.bz2 luarocks-2efec770b1b1b27a4b15c3b06a2f5fcadc0b546d.zip | |
repos: double-check that all files from a rock are installed
Ensure that `luarocks` fails if an installation does not successfully
deploy all files registered in the `rock_manifest`.
See #1276.
Diffstat (limited to 'src')
| -rw-r--r-- | src/luarocks/cmd/build.lua | 4 | ||||
| -rw-r--r-- | src/luarocks/cmd/install.lua | 8 | ||||
| -rw-r--r-- | src/luarocks/cmd/make.lua | 8 | ||||
| -rw-r--r-- | src/luarocks/cmd/purge.lua | 4 | ||||
| -rw-r--r-- | src/luarocks/remove.lua | 20 | ||||
| -rw-r--r-- | src/luarocks/repos.lua | 59 |
6 files changed, 95 insertions, 8 deletions
diff --git a/src/luarocks/cmd/build.lua b/src/luarocks/cmd/build.lua index 4500bcc9..6ad76b6e 100644 --- a/src/luarocks/cmd/build.lua +++ b/src/luarocks/cmd/build.lua | |||
| @@ -165,8 +165,10 @@ function cmd_build.command(args) | |||
| 165 | util.printout() | 165 | util.printout() |
| 166 | else | 166 | else |
| 167 | if (not args.keep) and not cfg.keep_other_versions then | 167 | if (not args.keep) and not cfg.keep_other_versions then |
| 168 | local ok, err = remove.remove_other_versions(name, version, args.force, args.force_fast) | 168 | local ok, err, warn = remove.remove_other_versions(name, version, args.force, args.force_fast) |
| 169 | if not ok then | 169 | if not ok then |
| 170 | return nil, err | ||
| 171 | elseif warn then | ||
| 170 | util.printerr(err) | 172 | util.printerr(err) |
| 171 | end | 173 | end |
| 172 | end | 174 | end |
diff --git a/src/luarocks/cmd/install.lua b/src/luarocks/cmd/install.lua index da9e1ce3..0d6ad63f 100644 --- a/src/luarocks/cmd/install.lua +++ b/src/luarocks/cmd/install.lua | |||
| @@ -195,8 +195,12 @@ local function install_rock_file(filename, opts) | |||
| 195 | end | 195 | end |
| 196 | 196 | ||
| 197 | if (not opts.keep) and not cfg.keep_other_versions then | 197 | if (not opts.keep) and not cfg.keep_other_versions then |
| 198 | local ok, err = remove.remove_other_versions(name, version, opts.force, opts.force_fast) | 198 | local ok, err, warn = remove.remove_other_versions(name, version, opts.force, opts.force_fast) |
| 199 | if not ok then util.printerr(err) end | 199 | if not ok then |
| 200 | return nil, err | ||
| 201 | elseif warn then | ||
| 202 | util.printerr(err) | ||
| 203 | end | ||
| 200 | end | 204 | end |
| 201 | 205 | ||
| 202 | writer.check_dependencies(nil, opts.deps_mode) | 206 | writer.check_dependencies(nil, opts.deps_mode) |
diff --git a/src/luarocks/cmd/make.lua b/src/luarocks/cmd/make.lua index a72e6817..8b313bb9 100644 --- a/src/luarocks/cmd/make.lua +++ b/src/luarocks/cmd/make.lua | |||
| @@ -142,8 +142,12 @@ function make.command(args) | |||
| 142 | end | 142 | end |
| 143 | 143 | ||
| 144 | if (not args.keep) and not cfg.keep_other_versions then | 144 | if (not args.keep) and not cfg.keep_other_versions then |
| 145 | local ok, err = remove.remove_other_versions(name, version, args.force, args.force_fast) | 145 | local ok, err, warn = remove.remove_other_versions(name, version, args.force, args.force_fast) |
| 146 | if not ok then util.printerr(err) end | 146 | if not ok then |
| 147 | return nil, err | ||
| 148 | elseif warn then | ||
| 149 | util.printerr(warn) | ||
| 150 | end | ||
| 147 | end | 151 | end |
| 148 | 152 | ||
| 149 | writer.check_dependencies(nil, deps.get_deps_mode(args)) | 153 | writer.check_dependencies(nil, deps.get_deps_mode(args)) |
diff --git a/src/luarocks/cmd/purge.lua b/src/luarocks/cmd/purge.lua index 2b5873d7..c300e286 100644 --- a/src/luarocks/cmd/purge.lua +++ b/src/luarocks/cmd/purge.lua | |||
| @@ -62,9 +62,11 @@ function purge.command(args) | |||
| 62 | for version, _ in util.sortedpairs(versions, sort) do | 62 | for version, _ in util.sortedpairs(versions, sort) do |
| 63 | if args.old_versions then | 63 | if args.old_versions then |
| 64 | util.printout("Keeping "..package.." "..version.."...") | 64 | util.printout("Keeping "..package.." "..version.."...") |
| 65 | local ok, err = remove.remove_other_versions(package, version, args.force, args.force_fast) | 65 | local ok, err, warn = remove.remove_other_versions(package, version, args.force, args.force_fast) |
| 66 | if not ok then | 66 | if not ok then |
| 67 | util.printerr(err) | 67 | util.printerr(err) |
| 68 | elseif warn then | ||
| 69 | util.printerr(err) | ||
| 68 | end | 70 | end |
| 69 | break | 71 | break |
| 70 | else | 72 | else |
diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index 9f816c7e..385930eb 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua | |||
| @@ -7,6 +7,7 @@ local repos = require("luarocks.repos") | |||
| 7 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
| 8 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
| 9 | local cfg = require("luarocks.core.cfg") | 9 | local cfg = require("luarocks.core.cfg") |
| 10 | local manif = require("luarocks.manif") | ||
| 10 | local queries = require("luarocks.queries") | 11 | local queries = require("luarocks.queries") |
| 11 | 12 | ||
| 12 | --- Obtain a list of packages that depend on the given set of packages | 13 | --- Obtain a list of packages that depend on the given set of packages |
| @@ -107,10 +108,25 @@ function remove.remove_other_versions(name, version, force, fast) | |||
| 107 | local results = {} | 108 | local results = {} |
| 108 | local query = queries.new(name, nil, version, false, nil, "~=") | 109 | local query = queries.new(name, nil, version, false, nil, "~=") |
| 109 | search.local_manifest_search(results, cfg.rocks_dir, query) | 110 | search.local_manifest_search(results, cfg.rocks_dir, query) |
| 111 | local warn | ||
| 110 | if results[name] then | 112 | if results[name] then |
| 111 | return remove.remove_search_results(results, name, cfg.deps_mode, force, fast) | 113 | local ok, err = remove.remove_search_results(results, name, cfg.deps_mode, force, fast) |
| 114 | if not ok then -- downgrade failure to a warning | ||
| 115 | warn = err | ||
| 116 | end | ||
| 112 | end | 117 | end |
| 113 | return true | 118 | |
| 119 | if not fast then | ||
| 120 | -- since we're not using --keep, this means that all files of the rock being installed | ||
| 121 | -- should be available as non-versioned variants. Double-check that: | ||
| 122 | local rock_manifest, load_err = manif.load_rock_manifest(name, version) | ||
| 123 | local ok, err = repos.check_everything_is_installed(name, version, rock_manifest, cfg.root_dir, false) | ||
| 124 | if not ok then | ||
| 125 | return nil, err | ||
| 126 | end | ||
| 127 | end | ||
| 128 | |||
| 129 | return true, nil, warn | ||
| 114 | end | 130 | end |
| 115 | 131 | ||
| 116 | return remove | 132 | return remove |
diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua index 8eecf8fd..6827cd0f 100644 --- a/src/luarocks/repos.lua +++ b/src/luarocks/repos.lua | |||
| @@ -392,6 +392,28 @@ local function rollback_ops(ops, op_fn, n) | |||
| 392 | end | 392 | end |
| 393 | end | 393 | end |
| 394 | 394 | ||
| 395 | --- Double check that all files referenced in `rock_manifest` are installed in `repo`. | ||
| 396 | function repos.check_everything_is_installed(name, version, rock_manifest, repo, accept_versioned) | ||
| 397 | local missing = {} | ||
| 398 | for _, category in ipairs({"bin", "lua", "lib"}) do | ||
| 399 | local suffix = (category == "bin") and cfg.wrapper_suffix or "" | ||
| 400 | if rock_manifest[category] then | ||
| 401 | repos.recurse_rock_manifest_entry(rock_manifest[category], function(file_path) | ||
| 402 | local paths = get_deploy_paths(name, version, category, file_path, repo) | ||
| 403 | if not (fs.exists(paths.nv .. suffix) or (accept_versioned and fs.exists(paths.v .. suffix))) then | ||
| 404 | table.insert(missing, paths.nv .. suffix) | ||
| 405 | end | ||
| 406 | end) | ||
| 407 | end | ||
| 408 | end | ||
| 409 | if #missing > 0 then | ||
| 410 | return nil, "failed deploying files. " .. | ||
| 411 | "The following files were not installed:\n" .. | ||
| 412 | table.concat(missing, "\n") | ||
| 413 | end | ||
| 414 | return true | ||
| 415 | end | ||
| 416 | |||
| 395 | --- Deploy a package from the rocks subdirectory. | 417 | --- Deploy a package from the rocks subdirectory. |
| 396 | -- @param name string: name of package | 418 | -- @param name string: name of package |
| 397 | -- @param version string: exact package version in string format | 419 | -- @param version string: exact package version in string format |
| @@ -503,10 +525,37 @@ function repos.deploy_files(name, version, wrap_bin_scripts, deps_mode) | |||
| 503 | end | 525 | end |
| 504 | done_op_install() | 526 | done_op_install() |
| 505 | 527 | ||
| 528 | local ok, err = repos.check_everything_is_installed(name, version, rock_manifest, repo, true) | ||
| 529 | if not ok then | ||
| 530 | return nil, err | ||
| 531 | end | ||
| 532 | |||
| 506 | local writer = require("luarocks.manif.writer") | 533 | local writer = require("luarocks.manif.writer") |
| 507 | return writer.add_to_manifest(name, version, nil, deps_mode) | 534 | return writer.add_to_manifest(name, version, nil, deps_mode) |
| 508 | end | 535 | end |
| 509 | 536 | ||
| 537 | local function add_to_double_checks(double_checks, name, version) | ||
| 538 | double_checks[name] = double_checks[name] or {} | ||
| 539 | double_checks[name][version] = true | ||
| 540 | end | ||
| 541 | |||
| 542 | local function double_check_all(double_checks, repo) | ||
| 543 | local errs = {} | ||
| 544 | for next_name, versions in pairs(double_checks) do | ||
| 545 | for next_version in pairs(versions) do | ||
| 546 | local rock_manifest, load_err = manif.load_rock_manifest(next_name, next_version) | ||
| 547 | local ok, err = repos.check_everything_is_installed(next_name, next_version, rock_manifest, repo, true) | ||
| 548 | if not ok then | ||
| 549 | table.insert(errs, err) | ||
| 550 | end | ||
| 551 | end | ||
| 552 | end | ||
| 553 | if next(errs) then | ||
| 554 | return nil, table.concat(errs, "\n") | ||
| 555 | end | ||
| 556 | return true | ||
| 557 | end | ||
| 558 | |||
| 510 | --- Delete a package from the local repository. | 559 | --- Delete a package from the local repository. |
| 511 | -- @param name string: name of package | 560 | -- @param name string: name of package |
| 512 | -- @param version string: exact package version in string format | 561 | -- @param version string: exact package version in string format |
| @@ -536,6 +585,8 @@ function repos.delete_version(name, version, deps_mode, quick) | |||
| 536 | local renames = {} | 585 | local renames = {} |
| 537 | local deletes = {} | 586 | local deletes = {} |
| 538 | 587 | ||
| 588 | local double_checks = {} | ||
| 589 | |||
| 539 | if rock_manifest.bin then | 590 | if rock_manifest.bin then |
| 540 | repos.recurse_rock_manifest_entry(rock_manifest.bin, function(file_path) | 591 | repos.recurse_rock_manifest_entry(rock_manifest.bin, function(file_path) |
| 541 | local paths = get_deploy_paths(name, version, "bin", file_path, repo) | 592 | local paths = get_deploy_paths(name, version, "bin", file_path, repo) |
| @@ -547,6 +598,7 @@ function repos.delete_version(name, version, deps_mode, quick) | |||
| 547 | 598 | ||
| 548 | local next_name, next_version = manif.get_next_provider("command", item_name) | 599 | local next_name, next_version = manif.get_next_provider("command", item_name) |
| 549 | if next_name then | 600 | if next_name then |
| 601 | add_to_double_checks(double_checks, next_name, next_version) | ||
| 550 | local next_paths = get_deploy_paths(next_name, next_version, "lua", file_path, repo) | 602 | local next_paths = get_deploy_paths(next_name, next_version, "lua", file_path, repo) |
| 551 | table.insert(renames, { src = next_paths.v, dst = next_paths.nv, suffix = cfg.wrapper_suffix }) | 603 | table.insert(renames, { src = next_paths.v, dst = next_paths.nv, suffix = cfg.wrapper_suffix }) |
| 552 | end | 604 | end |
| @@ -565,6 +617,7 @@ function repos.delete_version(name, version, deps_mode, quick) | |||
| 565 | 617 | ||
| 566 | local next_name, next_version = manif.get_next_provider("module", item_name) | 618 | local next_name, next_version = manif.get_next_provider("module", item_name) |
| 567 | if next_name then | 619 | if next_name then |
| 620 | add_to_double_checks(double_checks, next_name, next_version) | ||
| 568 | local next_lua_paths = get_deploy_paths(next_name, next_version, "lua", file_path, repo) | 621 | local next_lua_paths = get_deploy_paths(next_name, next_version, "lua", file_path, repo) |
| 569 | table.insert(renames, { src = next_lua_paths.v, dst = next_lua_paths.nv }) | 622 | table.insert(renames, { src = next_lua_paths.v, dst = next_lua_paths.nv }) |
| 570 | local next_lib_paths = get_deploy_paths(next_name, next_version, "lib", file_path:gsub("%.[^.]+$", ".lua"), repo) | 623 | local next_lib_paths = get_deploy_paths(next_name, next_version, "lib", file_path:gsub("%.[^.]+$", ".lua"), repo) |
| @@ -585,6 +638,7 @@ function repos.delete_version(name, version, deps_mode, quick) | |||
| 585 | 638 | ||
| 586 | local next_name, next_version = manif.get_next_provider("module", item_name) | 639 | local next_name, next_version = manif.get_next_provider("module", item_name) |
| 587 | if next_name then | 640 | if next_name then |
| 641 | add_to_double_checks(double_checks, next_name, next_version) | ||
| 588 | local next_lua_paths = get_deploy_paths(next_name, next_version, "lua", file_path:gsub("%.[^.]+$", ".lua"), repo) | 642 | local next_lua_paths = get_deploy_paths(next_name, next_version, "lua", file_path:gsub("%.[^.]+$", ".lua"), repo) |
| 589 | table.insert(renames, { src = next_lua_paths.v, dst = next_lua_paths.nv }) | 643 | table.insert(renames, { src = next_lua_paths.v, dst = next_lua_paths.nv }) |
| 590 | local next_lib_paths = get_deploy_paths(next_name, next_version, "lib", file_path, repo) | 644 | local next_lib_paths = get_deploy_paths(next_name, next_version, "lib", file_path, repo) |
| @@ -604,6 +658,11 @@ function repos.delete_version(name, version, deps_mode, quick) | |||
| 604 | for _, op in ipairs(renames) do | 658 | for _, op in ipairs(renames) do |
| 605 | op_rename(op) | 659 | op_rename(op) |
| 606 | end | 660 | end |
| 661 | |||
| 662 | local ok, err = double_check_all(double_checks, repo) | ||
| 663 | if not ok then | ||
| 664 | return nil, err | ||
| 665 | end | ||
| 607 | end | 666 | end |
| 608 | 667 | ||
| 609 | fs.delete(path.install_dir(name, version)) | 668 | fs.delete(path.install_dir(name, version)) |
