diff options
| author | Hisham Muhammad <hisham@gobolinux.org> | 2016-07-15 10:44:46 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-07-15 10:44:46 -0300 |
| commit | 5f5b26206068ba597091bb6fc22d8d63c0fef408 (patch) | |
| tree | 46f958aa7efb4d6b31612178026228ba49e612f5 /src | |
| parent | 6b38323d10743c83e377d9be2fa734a3a3d5a300 (diff) | |
| parent | f2beb5ee1fd2c54d59a43f4f2a8fe0f7a1701daa (diff) | |
| download | luarocks-5f5b26206068ba597091bb6fc22d8d63c0fef408.tar.gz luarocks-5f5b26206068ba597091bb6fc22d8d63c0fef408.tar.bz2 luarocks-5f5b26206068ba597091bb6fc22d8d63c0fef408.zip | |
Merge pull request #577 from keplerproject/core-modules
Core modules reorganization.
Diffstat (limited to 'src')
58 files changed, 1420 insertions, 1518 deletions
diff --git a/src/bin/luarocks b/src/bin/luarocks index be6c2b81..21f17da9 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
| 2 | 2 | ||
| 3 | -- this should be loaded first. | 3 | -- this should be loaded first. |
| 4 | local cfg = require("luarocks.cfg") | 4 | local cfg = require("luarocks.core.cfg") |
| 5 | 5 | ||
| 6 | local loader = require("luarocks.loader") | 6 | local loader = require("luarocks.loader") |
| 7 | local command_line = require("luarocks.command_line") | 7 | local command_line = require("luarocks.command_line") |
diff --git a/src/bin/luarocks-admin b/src/bin/luarocks-admin index 2890d1f1..660c0a70 100755 --- a/src/bin/luarocks-admin +++ b/src/bin/luarocks-admin | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #!/usr/bin/env lua | 1 | #!/usr/bin/env lua |
| 2 | 2 | ||
| 3 | -- this should be loaded first. | 3 | -- this should be loaded first. |
| 4 | local cfg = require("luarocks.cfg") | 4 | local cfg = require("luarocks.core.cfg") |
| 5 | 5 | ||
| 6 | local loader = require("luarocks.loader") | 6 | local loader = require("luarocks.loader") |
| 7 | local command_line = require("luarocks.command_line") | 7 | local command_line = require("luarocks.command_line") |
| @@ -10,10 +10,10 @@ program_description = "LuaRocks repository administration interface" | |||
| 10 | 10 | ||
| 11 | commands = { | 11 | commands = { |
| 12 | help = "luarocks.help", | 12 | help = "luarocks.help", |
| 13 | make_manifest = "luarocks.make_manifest", | 13 | make_manifest = "luarocks.admin.make_manifest", |
| 14 | add = "luarocks.add", | 14 | add = "luarocks.admin.add", |
| 15 | remove = "luarocks.admin_remove", | 15 | remove = "luarocks.admin.remove", |
| 16 | refresh_cache = "luarocks.refresh_cache", | 16 | refresh_cache = "luarocks.admin.refresh_cache", |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | command_line.run_command(...) | 19 | command_line.run_command(...) |
diff --git a/src/luarocks/add.lua b/src/luarocks/admin/add.lua index 66f7504f..daf46c1d 100644 --- a/src/luarocks/add.lua +++ b/src/luarocks/admin/add.lua | |||
| @@ -2,15 +2,14 @@ | |||
| 2 | --- Module implementing the luarocks-admin "add" command. | 2 | --- Module implementing the luarocks-admin "add" command. |
| 3 | -- Adds a rock or rockspec to a rocks server. | 3 | -- Adds a rock or rockspec to a rocks server. |
| 4 | local add = {} | 4 | local add = {} |
| 5 | package.loaded["luarocks.add"] = add | ||
| 6 | 5 | ||
| 7 | local cfg = require("luarocks.cfg") | 6 | local cfg = require("luarocks.core.cfg") |
| 8 | local util = require("luarocks.util") | 7 | local util = require("luarocks.util") |
| 9 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 10 | local manif = require("luarocks.manif") | 9 | local writer = require("luarocks.manif.writer") |
| 11 | local index = require("luarocks.index") | 10 | local index = require("luarocks.index") |
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| 13 | local cache = require("luarocks.cache") | 12 | local cache = require("luarocks.admin.cache") |
| 14 | 13 | ||
| 15 | add.help_summary = "Add a rock or rockspec to a rocks server." | 14 | add.help_summary = "Add a rock or rockspec to a rocks server." |
| 16 | add.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}" | 15 | add.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}" |
| @@ -23,6 +22,15 @@ The flag --no-refresh indicates the local cache should not be refreshed | |||
| 23 | prior to generation of the updated manifest. | 22 | prior to generation of the updated manifest. |
| 24 | ]] | 23 | ]] |
| 25 | 24 | ||
| 25 | local function zip_manifests() | ||
| 26 | for ver in util.lua_versions() do | ||
| 27 | local file = "manifest-"..ver | ||
| 28 | local zip = file..".zip" | ||
| 29 | fs.delete(dir.path(fs.current_dir(), zip)) | ||
| 30 | fs.zip(zip, file) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 26 | local function add_files_to_server(refresh, rockfiles, server, upload_server) | 34 | local function add_files_to_server(refresh, rockfiles, server, upload_server) |
| 27 | assert(type(refresh) == "boolean" or not refresh) | 35 | assert(type(refresh) == "boolean" or not refresh) |
| 28 | assert(type(rockfiles) == "table") | 36 | assert(type(rockfiles) == "table") |
| @@ -67,9 +75,9 @@ local function add_files_to_server(refresh, rockfiles, server, upload_server) | |||
| 67 | if not ok then return nil, err end | 75 | if not ok then return nil, err end |
| 68 | 76 | ||
| 69 | util.printout("Updating manifest...") | 77 | util.printout("Updating manifest...") |
| 70 | manif.make_manifest(local_cache, "one", true) | 78 | writer.make_manifest(local_cache, "one", true) |
| 71 | 79 | ||
| 72 | manif.zip_manifests() | 80 | zip_manifests() |
| 73 | 81 | ||
| 74 | util.printout("Updating index.html...") | 82 | util.printout("Updating index.html...") |
| 75 | index.make_index(local_cache) | 83 | index.make_index(local_cache) |
diff --git a/src/luarocks/cache.lua b/src/luarocks/admin/cache.lua index 4a95f70e..0daa0fc0 100644 --- a/src/luarocks/cache.lua +++ b/src/luarocks/admin/cache.lua | |||
| @@ -2,10 +2,9 @@ | |||
| 2 | --- Module handling the LuaRocks local cache. | 2 | --- Module handling the LuaRocks local cache. |
| 3 | -- Adds a rock or rockspec to a rocks server. | 3 | -- Adds a rock or rockspec to a rocks server. |
| 4 | local cache = {} | 4 | local cache = {} |
| 5 | package.loaded["luarocks.cache"] = cache | ||
| 6 | 5 | ||
| 7 | local fs = require("luarocks.fs") | 6 | local fs = require("luarocks.fs") |
| 8 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 9 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 10 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 11 | 10 | ||
diff --git a/src/luarocks/make_manifest.lua b/src/luarocks/admin/make_manifest.lua index b89ba47f..57851942 100644 --- a/src/luarocks/make_manifest.lua +++ b/src/luarocks/admin/make_manifest.lua | |||
| @@ -2,11 +2,10 @@ | |||
| 2 | --- Module implementing the luarocks-admin "make_manifest" command. | 2 | --- Module implementing the luarocks-admin "make_manifest" command. |
| 3 | -- Compile a manifest file for a repository. | 3 | -- Compile a manifest file for a repository. |
| 4 | local make_manifest = {} | 4 | local make_manifest = {} |
| 5 | package.loaded["luarocks.make_manifest"] = make_manifest | ||
| 6 | 5 | ||
| 7 | local manif = require("luarocks.manif") | 6 | local writer = require("luarocks.manif.writer") |
| 8 | local index = require("luarocks.index") | 7 | local index = require("luarocks.index") |
| 9 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
| 10 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 11 | local deps = require("luarocks.deps") | 10 | local deps = require("luarocks.deps") |
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| @@ -36,7 +35,7 @@ function make_manifest.command(flags, repo) | |||
| 36 | util.warning("This looks like a local rocks tree, but you did not pass --local-tree.") | 35 | util.warning("This looks like a local rocks tree, but you did not pass --local-tree.") |
| 37 | end | 36 | end |
| 38 | 37 | ||
| 39 | local ok, err = manif.make_manifest(repo, deps.get_deps_mode(flags), not flags["local-tree"]) | 38 | local ok, err = writer.make_manifest(repo, deps.get_deps_mode(flags), not flags["local-tree"]) |
| 40 | if ok and not flags["local-tree"] then | 39 | if ok and not flags["local-tree"] then |
| 41 | util.printout("Generating index.html for "..repo) | 40 | util.printout("Generating index.html for "..repo) |
| 42 | index.make_index(repo) | 41 | index.make_index(repo) |
diff --git a/src/luarocks/refresh_cache.lua b/src/luarocks/admin/refresh_cache.lua index 1261044f..947dbfb0 100644 --- a/src/luarocks/refresh_cache.lua +++ b/src/luarocks/admin/refresh_cache.lua | |||
| @@ -1,10 +1,9 @@ | |||
| 1 | 1 | ||
| 2 | --- Module implementing the luarocks-admin "refresh_cache" command. | 2 | --- Module implementing the luarocks-admin "refresh_cache" command. |
| 3 | local refresh_cache = {} | 3 | local refresh_cache = {} |
| 4 | package.loaded["luarocks.refresh_cache"] = refresh_cache | ||
| 5 | 4 | ||
| 6 | local cfg = require("luarocks.cfg") | 5 | local cfg = require("luarocks.core.cfg") |
| 7 | local cache = require("luarocks.cache") | 6 | local cache = require("luarocks.admin.cache") |
| 8 | 7 | ||
| 9 | refresh_cache.help_summary = "Refresh local cache of a remote rocks server." | 8 | refresh_cache.help_summary = "Refresh local cache of a remote rocks server." |
| 10 | refresh_cache.help_arguments = "[--from=<server>]" | 9 | refresh_cache.help_arguments = "[--from=<server>]" |
diff --git a/src/luarocks/admin_remove.lua b/src/luarocks/admin/remove.lua index be1e7cbc..763a166f 100644 --- a/src/luarocks/admin_remove.lua +++ b/src/luarocks/admin/remove.lua | |||
| @@ -2,15 +2,14 @@ | |||
| 2 | --- Module implementing the luarocks-admin "remove" command. | 2 | --- Module implementing the luarocks-admin "remove" command. |
| 3 | -- Removes a rock or rockspec from a rocks server. | 3 | -- Removes a rock or rockspec from a rocks server. |
| 4 | local admin_remove = {} | 4 | local admin_remove = {} |
| 5 | package.loaded["luarocks.admin_remove"] = admin_remove | ||
| 6 | 5 | ||
| 7 | local cfg = require("luarocks.cfg") | 6 | local cfg = require("luarocks.core.cfg") |
| 8 | local util = require("luarocks.util") | 7 | local util = require("luarocks.util") |
| 9 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 10 | local manif = require("luarocks.manif") | 9 | local writer = require("luarocks.manif.writer") |
| 11 | local index = require("luarocks.index") | 10 | local index = require("luarocks.index") |
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| 13 | local cache = require("luarocks.cache") | 12 | local cache = require("luarocks.admin.cache") |
| 14 | 13 | ||
| 15 | admin_remove.help_summary = "Remove a rock or rockspec from a rocks server." | 14 | admin_remove.help_summary = "Remove a rock or rockspec from a rocks server." |
| 16 | admin_remove.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}" | 15 | admin_remove.help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}" |
| @@ -64,7 +63,7 @@ local function remove_files_from_server(refresh, rockfiles, server, upload_serve | |||
| 64 | if not ok then return nil, err end | 63 | if not ok then return nil, err end |
| 65 | 64 | ||
| 66 | util.printout("Updating manifest...") | 65 | util.printout("Updating manifest...") |
| 67 | manif.make_manifest(local_cache, "one", true) | 66 | writer.make_manifest(local_cache, "one", true) |
| 68 | util.printout("Updating index.html...") | 67 | util.printout("Updating index.html...") |
| 69 | index.make_index(local_cache) | 68 | index.make_index(local_cache) |
| 70 | 69 | ||
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 2d29e23f..d7d8ed07 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "build" command. | 2 | --- Module implementing the LuaRocks "build" command. |
| 3 | -- Builds a rock, compiling its C parts if any. | 3 | -- Builds a rock, compiling its C parts if any. |
| 4 | local build = {} | 4 | local build = {} |
| 5 | package.loaded["luarocks.build"] = build | ||
| 6 | 5 | ||
| 7 | local pack = require("luarocks.pack") | 6 | local pack = require("luarocks.pack") |
| 8 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
| @@ -12,9 +11,9 @@ local fetch = require("luarocks.fetch") | |||
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| 13 | local dir = require("luarocks.dir") | 12 | local dir = require("luarocks.dir") |
| 14 | local deps = require("luarocks.deps") | 13 | local deps = require("luarocks.deps") |
| 15 | local manif = require("luarocks.manif") | 14 | local writer = require("luarocks.manif.writer") |
| 16 | local remove = require("luarocks.remove") | 15 | local remove = require("luarocks.remove") |
| 17 | local cfg = require("luarocks.cfg") | 16 | local cfg = require("luarocks.core.cfg") |
| 18 | 17 | ||
| 19 | build.help_summary = "Build/compile a rock." | 18 | build.help_summary = "Build/compile a rock." |
| 20 | build.help_arguments = "[--pack-binary-rock] [--keep] {<rockspec>|<rock>|<name> [<version>]}" | 19 | build.help_arguments = "[--pack-binary-rock] [--keep] {<rockspec>|<rock>|<name> [<version>]}" |
| @@ -346,7 +345,7 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m | |||
| 346 | fs.pop_dir() | 345 | fs.pop_dir() |
| 347 | end | 346 | end |
| 348 | 347 | ||
| 349 | ok, err = manif.make_rock_manifest(name, version) | 348 | ok, err = writer.make_rock_manifest(name, version) |
| 350 | if err then return nil, err end | 349 | if err then return nil, err end |
| 351 | 350 | ||
| 352 | ok, err = repos.deploy_files(name, version, repos.should_wrap_bin_scripts(rockspec)) | 351 | ok, err = repos.deploy_files(name, version, repos.should_wrap_bin_scripts(rockspec)) |
| @@ -360,7 +359,7 @@ function build.build_rockspec(rockspec_file, need_to_fetch, minimal_mode, deps_m | |||
| 360 | ok, err = repos.run_hook(rockspec, "post_install") | 359 | ok, err = repos.run_hook(rockspec, "post_install") |
| 361 | if err then return nil, err end | 360 | if err then return nil, err end |
| 362 | 361 | ||
| 363 | ok, err = manif.update_manifest(name, version, nil, deps_mode) | 362 | ok, err = writer.update_manifest(name, version, nil, deps_mode) |
| 364 | if err then return nil, err end | 363 | if err then return nil, err end |
| 365 | 364 | ||
| 366 | util.announce_install(rockspec) | 365 | util.announce_install(rockspec) |
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index 81fa8b13..d9785b0c 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua | |||
| @@ -7,7 +7,7 @@ local unpack = unpack or table.unpack | |||
| 7 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| 8 | local path = require("luarocks.path") | 8 | local path = require("luarocks.path") |
| 9 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 10 | local cfg = require("luarocks.cfg") | 10 | local cfg = require("luarocks.core.cfg") |
| 11 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
| 12 | 12 | ||
| 13 | --- Run a command displaying its execution on standard output. | 13 | --- Run a command displaying its execution on standard output. |
diff --git a/src/luarocks/build/cmake.lua b/src/luarocks/build/cmake.lua index c2712bb2..43702979 100644 --- a/src/luarocks/build/cmake.lua +++ b/src/luarocks/build/cmake.lua | |||
| @@ -4,7 +4,7 @@ local cmake = {} | |||
| 4 | 4 | ||
| 5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 7 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 8 | local deps = require("luarocks.deps") | 8 | local deps = require("luarocks.deps") |
| 9 | 9 | ||
| 10 | --- Driver function for the "cmake" build back-end. | 10 | --- Driver function for the "cmake" build back-end. |
diff --git a/src/luarocks/build/make.lua b/src/luarocks/build/make.lua index 69e73c2e..ded015b7 100644 --- a/src/luarocks/build/make.lua +++ b/src/luarocks/build/make.lua | |||
| @@ -6,7 +6,7 @@ local unpack = unpack or table.unpack | |||
| 6 | 6 | ||
| 7 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| 8 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
| 9 | local cfg = require("luarocks.cfg") | 9 | local cfg = require("luarocks.core.cfg") |
| 10 | 10 | ||
| 11 | --- Call "make" with given target and variables | 11 | --- Call "make" with given target and variables |
| 12 | -- @param make_cmd string: the make command to be used (typically | 12 | -- @param make_cmd string: the make command to be used (typically |
diff --git a/src/luarocks/command_line.lua b/src/luarocks/command_line.lua index 1a8c0fe7..936e9950 100644 --- a/src/luarocks/command_line.lua +++ b/src/luarocks/command_line.lua | |||
| @@ -5,7 +5,7 @@ local command_line = {} | |||
| 5 | local unpack = unpack or table.unpack | 5 | local unpack = unpack or table.unpack |
| 6 | 6 | ||
| 7 | local util = require("luarocks.util") | 7 | local util = require("luarocks.util") |
| 8 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
| 9 | local path = require("luarocks.path") | 9 | local path = require("luarocks.path") |
| 10 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
| 11 | local deps = require("luarocks.deps") | 11 | local deps = require("luarocks.deps") |
diff --git a/src/luarocks/config_cmd.lua b/src/luarocks/config_cmd.lua index 9e73d228..b68f7898 100644 --- a/src/luarocks/config_cmd.lua +++ b/src/luarocks/config_cmd.lua | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | -- Queries information about the LuaRocks configuration. | 2 | -- Queries information about the LuaRocks configuration. |
| 3 | local config_cmd = {} | 3 | local config_cmd = {} |
| 4 | 4 | ||
| 5 | local cfg = require("luarocks.cfg") | 5 | local cfg = require("luarocks.core.cfg") |
| 6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 7 | local dir = require("luarocks.dir") | 7 | local dir = require("luarocks.dir") |
| 8 | 8 | ||
diff --git a/src/luarocks/cfg.lua b/src/luarocks/core/cfg.lua index 53387276..42508b9e 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/core/cfg.lua | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | |||
| 1 | --- Configuration for LuaRocks. | 2 | --- Configuration for LuaRocks. |
| 2 | -- Tries to load the user's configuration file and | 3 | -- Tries to load the user's configuration file and |
| 3 | -- defines defaults for unset values. See the | 4 | -- defines defaults for unset values. See the |
| @@ -13,11 +14,7 @@ | |||
| 13 | local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION = | 14 | local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION = |
| 14 | rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION | 15 | rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION |
| 15 | 16 | ||
| 16 | --module("luarocks.cfg") | ||
| 17 | local cfg = {} | 17 | local cfg = {} |
| 18 | package.loaded["luarocks.cfg"] = cfg | ||
| 19 | |||
| 20 | local util = require("luarocks.util") | ||
| 21 | 18 | ||
| 22 | cfg.lua_version = _VERSION:sub(5) | 19 | cfg.lua_version = _VERSION:sub(5) |
| 23 | local version_suffix = cfg.lua_version:gsub("%.", "_") | 20 | local version_suffix = cfg.lua_version:gsub("%.", "_") |
| @@ -32,15 +29,18 @@ if not ok then | |||
| 32 | site_config = {} | 29 | site_config = {} |
| 33 | end | 30 | end |
| 34 | 31 | ||
| 32 | local util = require("luarocks.core.util") | ||
| 33 | local persist = require("luarocks.core.persist") | ||
| 34 | local require = nil | ||
| 35 | -------------------------------------------------------------------------------- | ||
| 36 | |||
| 35 | cfg.program_version = "scm" | 37 | cfg.program_version = "scm" |
| 36 | cfg.program_series = "2.2" | 38 | cfg.program_series = "3.0" |
| 37 | cfg.major_version = (cfg.program_version:match("([^.]%.[^.])")) or cfg.program_series | 39 | cfg.major_version = (cfg.program_version:match("([^.]%.[^.])")) or cfg.program_series |
| 38 | cfg.variables = {} | 40 | cfg.variables = {} |
| 39 | cfg.rocks_trees = {} | 41 | cfg.rocks_trees = {} |
| 40 | cfg.platforms = {} | 42 | cfg.platforms = {} |
| 41 | 43 | ||
| 42 | local persist = require("luarocks.persist") | ||
| 43 | |||
| 44 | cfg.errorcodes = setmetatable({ | 44 | cfg.errorcodes = setmetatable({ |
| 45 | OK = 0, | 45 | OK = 0, |
| 46 | UNSPECIFIED = 1, | 46 | UNSPECIFIED = 1, |
diff --git a/src/luarocks/core/deps.lua b/src/luarocks/core/deps.lua new file mode 100644 index 00000000..6d539eb8 --- /dev/null +++ b/src/luarocks/core/deps.lua | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | |||
| 2 | local deps = {} | ||
| 3 | |||
| 4 | local util = require("luarocks.core.util") | ||
| 5 | local require = nil | ||
| 6 | -------------------------------------------------------------------------------- | ||
| 7 | |||
| 8 | local deltas = { | ||
| 9 | scm = 1100, | ||
| 10 | cvs = 1000, | ||
| 11 | rc = -1000, | ||
| 12 | pre = -10000, | ||
| 13 | beta = -100000, | ||
| 14 | alpha = -1000000 | ||
| 15 | } | ||
| 16 | |||
| 17 | local version_mt = { | ||
| 18 | --- Equality comparison for versions. | ||
| 19 | -- All version numbers must be equal. | ||
| 20 | -- If both versions have revision numbers, they must be equal; | ||
| 21 | -- otherwise the revision number is ignored. | ||
| 22 | -- @param v1 table: version table to compare. | ||
| 23 | -- @param v2 table: version table to compare. | ||
| 24 | -- @return boolean: true if they are considered equivalent. | ||
| 25 | __eq = function(v1, v2) | ||
| 26 | if #v1 ~= #v2 then | ||
| 27 | return false | ||
| 28 | end | ||
| 29 | for i = 1, #v1 do | ||
| 30 | if v1[i] ~= v2[i] then | ||
| 31 | return false | ||
| 32 | end | ||
| 33 | end | ||
| 34 | if v1.revision and v2.revision then | ||
| 35 | return (v1.revision == v2.revision) | ||
| 36 | end | ||
| 37 | return true | ||
| 38 | end, | ||
| 39 | --- Size comparison for versions. | ||
| 40 | -- All version numbers are compared. | ||
| 41 | -- If both versions have revision numbers, they are compared; | ||
| 42 | -- otherwise the revision number is ignored. | ||
| 43 | -- @param v1 table: version table to compare. | ||
| 44 | -- @param v2 table: version table to compare. | ||
| 45 | -- @return boolean: true if v1 is considered lower than v2. | ||
| 46 | __lt = function(v1, v2) | ||
| 47 | for i = 1, math.max(#v1, #v2) do | ||
| 48 | local v1i, v2i = v1[i] or 0, v2[i] or 0 | ||
| 49 | if v1i ~= v2i then | ||
| 50 | return (v1i < v2i) | ||
| 51 | end | ||
| 52 | end | ||
| 53 | if v1.revision and v2.revision then | ||
| 54 | return (v1.revision < v2.revision) | ||
| 55 | end | ||
| 56 | return false | ||
| 57 | end | ||
| 58 | } | ||
| 59 | |||
| 60 | local version_cache = {} | ||
| 61 | setmetatable(version_cache, { | ||
| 62 | __mode = "kv" | ||
| 63 | }) | ||
| 64 | |||
| 65 | --- Parse a version string, converting to table format. | ||
| 66 | -- A version table contains all components of the version string | ||
| 67 | -- converted to numeric format, stored in the array part of the table. | ||
| 68 | -- If the version contains a revision, it is stored numerically | ||
| 69 | -- in the 'revision' field. The original string representation of | ||
| 70 | -- the string is preserved in the 'string' field. | ||
| 71 | -- Returned version tables use a metatable | ||
| 72 | -- allowing later comparison through relational operators. | ||
| 73 | -- @param vstring string: A version number in string format. | ||
| 74 | -- @return table or nil: A version table or nil | ||
| 75 | -- if the input string contains invalid characters. | ||
| 76 | function deps.parse_version(vstring) | ||
| 77 | if not vstring then return nil end | ||
| 78 | assert(type(vstring) == "string") | ||
| 79 | |||
| 80 | local cached = version_cache[vstring] | ||
| 81 | if cached then | ||
| 82 | return cached | ||
| 83 | end | ||
| 84 | |||
| 85 | local version = {} | ||
| 86 | local i = 1 | ||
| 87 | |||
| 88 | local function add_token(number) | ||
| 89 | version[i] = version[i] and version[i] + number/100000 or number | ||
| 90 | i = i + 1 | ||
| 91 | end | ||
| 92 | |||
| 93 | -- trim leading and trailing spaces | ||
| 94 | vstring = vstring:match("^%s*(.*)%s*$") | ||
| 95 | version.string = vstring | ||
| 96 | -- store revision separately if any | ||
| 97 | local main, revision = vstring:match("(.*)%-(%d+)$") | ||
| 98 | if revision then | ||
| 99 | vstring = main | ||
| 100 | version.revision = tonumber(revision) | ||
| 101 | end | ||
| 102 | while #vstring > 0 do | ||
| 103 | -- extract a number | ||
| 104 | local token, rest = vstring:match("^(%d+)[%.%-%_]*(.*)") | ||
| 105 | if token then | ||
| 106 | add_token(tonumber(token)) | ||
| 107 | else | ||
| 108 | -- extract a word | ||
| 109 | token, rest = vstring:match("^(%a+)[%.%-%_]*(.*)") | ||
| 110 | if not token then | ||
| 111 | util.printerr("Warning: version number '"..vstring.."' could not be parsed.") | ||
| 112 | version[i] = 0 | ||
| 113 | break | ||
| 114 | end | ||
| 115 | version[i] = deltas[token] or (token:byte() / 1000) | ||
| 116 | end | ||
| 117 | vstring = rest | ||
| 118 | end | ||
| 119 | setmetatable(version, version_mt) | ||
| 120 | version_cache[vstring] = version | ||
| 121 | return version | ||
| 122 | end | ||
| 123 | |||
| 124 | --- Utility function to compare version numbers given as strings. | ||
| 125 | -- @param a string: one version. | ||
| 126 | -- @param b string: another version. | ||
| 127 | -- @return boolean: True if a > b. | ||
| 128 | function deps.compare_versions(a, b) | ||
| 129 | return deps.parse_version(a) > deps.parse_version(b) | ||
| 130 | end | ||
| 131 | |||
| 132 | --- A more lenient check for equivalence between versions. | ||
| 133 | -- This returns true if the requested components of a version | ||
| 134 | -- match and ignore the ones that were not given. For example, | ||
| 135 | -- when requesting "2", then "2", "2.1", "2.3.5-9"... all match. | ||
| 136 | -- When requesting "2.1", then "2.1", "2.1.3" match, but "2.2" | ||
| 137 | -- doesn't. | ||
| 138 | -- @param version string or table: Version to be tested; may be | ||
| 139 | -- in string format or already parsed into a table. | ||
| 140 | -- @param requested string or table: Version requested; may be | ||
| 141 | -- in string format or already parsed into a table. | ||
| 142 | -- @return boolean: True if the tested version matches the requested | ||
| 143 | -- version, false otherwise. | ||
| 144 | local function partial_match(version, requested) | ||
| 145 | assert(type(version) == "string" or type(version) == "table") | ||
| 146 | assert(type(requested) == "string" or type(version) == "table") | ||
| 147 | |||
| 148 | if type(version) ~= "table" then version = deps.parse_version(version) end | ||
| 149 | if type(requested) ~= "table" then requested = deps.parse_version(requested) end | ||
| 150 | if not version or not requested then return false end | ||
| 151 | |||
| 152 | for i, ri in ipairs(requested) do | ||
| 153 | local vi = version[i] or 0 | ||
| 154 | if ri ~= vi then return false end | ||
| 155 | end | ||
| 156 | if requested.revision then | ||
| 157 | return requested.revision == version.revision | ||
| 158 | end | ||
| 159 | return true | ||
| 160 | end | ||
| 161 | |||
| 162 | --- Check if a version satisfies a set of constraints. | ||
| 163 | -- @param version table: A version in table format | ||
| 164 | -- @param constraints table: An array of constraints in table format. | ||
| 165 | -- @return boolean: True if version satisfies all constraints, | ||
| 166 | -- false otherwise. | ||
| 167 | function deps.match_constraints(version, constraints) | ||
| 168 | assert(type(version) == "table") | ||
| 169 | assert(type(constraints) == "table") | ||
| 170 | local ok = true | ||
| 171 | setmetatable(version, version_mt) | ||
| 172 | for _, constr in pairs(constraints) do | ||
| 173 | if type(constr.version) == "string" then | ||
| 174 | constr.version = deps.parse_version(constr.version) | ||
| 175 | end | ||
| 176 | local constr_version, constr_op = constr.version, constr.op | ||
| 177 | setmetatable(constr_version, version_mt) | ||
| 178 | if constr_op == "==" then ok = version == constr_version | ||
| 179 | elseif constr_op == "~=" then ok = version ~= constr_version | ||
| 180 | elseif constr_op == ">" then ok = version > constr_version | ||
| 181 | elseif constr_op == "<" then ok = version < constr_version | ||
| 182 | elseif constr_op == ">=" then ok = version >= constr_version | ||
| 183 | elseif constr_op == "<=" then ok = version <= constr_version | ||
| 184 | elseif constr_op == "~>" then ok = partial_match(version, constr_version) | ||
| 185 | end | ||
| 186 | if not ok then break end | ||
| 187 | end | ||
| 188 | return ok | ||
| 189 | end | ||
| 190 | |||
| 191 | return deps | ||
| 192 | |||
diff --git a/src/luarocks/core/dir.lua b/src/luarocks/core/dir.lua new file mode 100644 index 00000000..240bb38a --- /dev/null +++ b/src/luarocks/core/dir.lua | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | |||
| 2 | local dir = {} | ||
| 3 | |||
| 4 | local require = nil | ||
| 5 | -------------------------------------------------------------------------------- | ||
| 6 | |||
| 7 | dir.separator = "/" | ||
| 8 | |||
| 9 | --- Describe a path in a cross-platform way. | ||
| 10 | -- Use this function to avoid platform-specific directory | ||
| 11 | -- separators in other modules. Removes trailing slashes from | ||
| 12 | -- each component given, to avoid repeated separators. | ||
| 13 | -- Separators inside strings are kept, to handle URLs containing | ||
| 14 | -- protocols. | ||
| 15 | -- @param ... strings representing directories | ||
| 16 | -- @return string: a string with a platform-specific representation | ||
| 17 | -- of the path. | ||
| 18 | function dir.path(...) | ||
| 19 | local t = {...} | ||
| 20 | while t[1] == "" do | ||
| 21 | table.remove(t, 1) | ||
| 22 | end | ||
| 23 | return (table.concat(t, "/"):gsub("([^:])/+", "%1/"):gsub("^/+", "/"):gsub("/*$", "")) | ||
| 24 | end | ||
| 25 | |||
| 26 | --- Split protocol and path from an URL or local pathname. | ||
| 27 | -- URLs should be in the "protocol://path" format. | ||
| 28 | -- For local pathnames, "file" is returned as the protocol. | ||
| 29 | -- @param url string: an URL or a local pathname. | ||
| 30 | -- @return string, string: the protocol, and the pathname without the protocol. | ||
| 31 | function dir.split_url(url) | ||
| 32 | assert(type(url) == "string") | ||
| 33 | |||
| 34 | local protocol, pathname = url:match("^([^:]*)://(.*)") | ||
| 35 | if not protocol then | ||
| 36 | protocol = "file" | ||
| 37 | pathname = url | ||
| 38 | end | ||
| 39 | return protocol, pathname | ||
| 40 | end | ||
| 41 | |||
| 42 | --- Normalize a url or local path. | ||
| 43 | -- URLs should be in the "protocol://path" format. System independent | ||
| 44 | -- forward slashes are used, removing trailing and double slashes | ||
| 45 | -- @param url string: an URL or a local pathname. | ||
| 46 | -- @return string: Normalized result. | ||
| 47 | function dir.normalize(name) | ||
| 48 | local protocol, pathname = dir.split_url(name) | ||
| 49 | pathname = pathname:gsub("\\", "/"):gsub("(.)/*$", "%1"):gsub("//", "/") | ||
| 50 | if protocol ~= "file" then pathname = protocol .."://"..pathname end | ||
| 51 | return pathname | ||
| 52 | end | ||
| 53 | |||
| 54 | return dir | ||
| 55 | |||
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/core/manif.lua index 5c8928d4..f0912bfd 100644 --- a/src/luarocks/manif_core.lua +++ b/src/luarocks/core/manif.lua | |||
| @@ -1,15 +1,15 @@ | |||
| 1 | 1 | ||
| 2 | --- Core functions for querying manifest files. | 2 | --- Core functions for querying manifest files. |
| 3 | -- This module requires no specific 'fs' functionality. | 3 | local manif = {} |
| 4 | local manif_core = {} | ||
| 5 | package.loaded["luarocks.manif_core"] = manif_core | ||
| 6 | 4 | ||
| 7 | local persist = require("luarocks.persist") | 5 | local persist = require("luarocks.core.persist") |
| 8 | local type_check = require("luarocks.type_check") | 6 | local type_check = require("luarocks.core.type_check") |
| 9 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 10 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.core.dir") |
| 11 | local util = require("luarocks.util") | 9 | local util = require("luarocks.core.util") |
| 12 | local path = require("luarocks.path") | 10 | local path = require("luarocks.core.path") |
| 11 | local require = nil | ||
| 12 | -------------------------------------------------------------------------------- | ||
| 13 | 13 | ||
| 14 | -- Table with repository identifiers as keys and tables mapping | 14 | -- Table with repository identifiers as keys and tables mapping |
| 15 | -- Lua versions to cached loaded manifests as values. | 15 | -- Lua versions to cached loaded manifests as values. |
| @@ -19,7 +19,7 @@ local manifest_cache = {} | |||
| 19 | -- @param repo_url string: The repository identifier. | 19 | -- @param repo_url string: The repository identifier. |
| 20 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | 20 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. |
| 21 | -- @param manifest table: the manifest to be cached. | 21 | -- @param manifest table: the manifest to be cached. |
| 22 | function manif_core.cache_manifest(repo_url, lua_version, manifest) | 22 | function manif.cache_manifest(repo_url, lua_version, manifest) |
| 23 | lua_version = lua_version or cfg.lua_version | 23 | lua_version = lua_version or cfg.lua_version |
| 24 | manifest_cache[repo_url] = manifest_cache[repo_url] or {} | 24 | manifest_cache[repo_url] = manifest_cache[repo_url] or {} |
| 25 | manifest_cache[repo_url][lua_version] = manifest | 25 | manifest_cache[repo_url][lua_version] = manifest |
| @@ -29,7 +29,7 @@ end | |||
| 29 | -- @param repo_url string: The repository identifier. | 29 | -- @param repo_url string: The repository identifier. |
| 30 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. | 30 | -- @param lua_version string: Lua version in "5.x" format, defaults to installed version. |
| 31 | -- @return table or nil: loaded manifest or nil if cache is empty. | 31 | -- @return table or nil: loaded manifest or nil if cache is empty. |
| 32 | function manif_core.get_cached_manifest(repo_url, lua_version) | 32 | function manif.get_cached_manifest(repo_url, lua_version) |
| 33 | lua_version = lua_version or cfg.lua_version | 33 | lua_version = lua_version or cfg.lua_version |
| 34 | return manifest_cache[repo_url] and manifest_cache[repo_url][lua_version] | 34 | return manifest_cache[repo_url] and manifest_cache[repo_url][lua_version] |
| 35 | end | 35 | end |
| @@ -42,7 +42,7 @@ end | |||
| 42 | -- @param quick boolean: If given, skips type checking. | 42 | -- @param quick boolean: If given, skips type checking. |
| 43 | -- @return table or (nil, string, string): the manifest or nil, | 43 | -- @return table or (nil, string, string): the manifest or nil, |
| 44 | -- error message and error code ("open", "load", "run" or "type"). | 44 | -- error message and error code ("open", "load", "run" or "type"). |
| 45 | function manif_core.manifest_loader(file, repo_url, lua_version, quick) | 45 | function manif.manifest_loader(file, repo_url, lua_version, quick) |
| 46 | local manifest, err, errcode = persist.load_into_table(file) | 46 | local manifest, err, errcode = persist.load_into_table(file) |
| 47 | if not manifest then | 47 | if not manifest then |
| 48 | return nil, "Failed loading manifest for "..repo_url..": "..err, errcode | 48 | return nil, "Failed loading manifest for "..repo_url..": "..err, errcode |
| @@ -55,7 +55,7 @@ function manif_core.manifest_loader(file, repo_url, lua_version, quick) | |||
| 55 | end | 55 | end |
| 56 | end | 56 | end |
| 57 | 57 | ||
| 58 | manif_core.cache_manifest(repo_url, lua_version, manifest) | 58 | manif.cache_manifest(repo_url, lua_version, manifest) |
| 59 | return manifest | 59 | return manifest |
| 60 | end | 60 | end |
| 61 | 61 | ||
| @@ -65,16 +65,16 @@ end | |||
| 65 | -- @param repo_url string: URL or pathname for the repository. | 65 | -- @param repo_url string: URL or pathname for the repository. |
| 66 | -- @return table or (nil, string, string): A table representing the manifest, | 66 | -- @return table or (nil, string, string): A table representing the manifest, |
| 67 | -- or nil followed by an error message and an error code, see manifest_loader. | 67 | -- or nil followed by an error message and an error code, see manifest_loader. |
| 68 | function manif_core.load_local_manifest(repo_url) | 68 | function manif.load_local_manifest(repo_url) |
| 69 | assert(type(repo_url) == "string") | 69 | assert(type(repo_url) == "string") |
| 70 | 70 | ||
| 71 | local cached_manifest = manif_core.get_cached_manifest(repo_url) | 71 | local cached_manifest = manif.get_cached_manifest(repo_url) |
| 72 | if cached_manifest then | 72 | if cached_manifest then |
| 73 | return cached_manifest | 73 | return cached_manifest |
| 74 | end | 74 | end |
| 75 | 75 | ||
| 76 | local pathname = dir.path(repo_url, "manifest") | 76 | local pathname = dir.path(repo_url, "manifest") |
| 77 | return manif_core.manifest_loader(pathname, repo_url, nil, true) | 77 | return manif.manifest_loader(pathname, repo_url, nil, true) |
| 78 | end | 78 | end |
| 79 | 79 | ||
| 80 | --- Get all versions of a package listed in a manifest file. | 80 | --- Get all versions of a package listed in a manifest file. |
| @@ -85,13 +85,13 @@ end | |||
| 85 | -- or "all", to use all trees. | 85 | -- or "all", to use all trees. |
| 86 | -- @return table: An array of strings listing installed | 86 | -- @return table: An array of strings listing installed |
| 87 | -- versions of a package. | 87 | -- versions of a package. |
| 88 | function manif_core.get_versions(name, deps_mode) | 88 | function manif.get_versions(name, deps_mode) |
| 89 | assert(type(name) == "string") | 89 | assert(type(name) == "string") |
| 90 | assert(type(deps_mode) == "string") | 90 | assert(type(deps_mode) == "string") |
| 91 | 91 | ||
| 92 | local manifest = {} | 92 | local manifest = {} |
| 93 | path.map_trees(deps_mode, function(tree) | 93 | path.map_trees(deps_mode, function(tree) |
| 94 | local loaded = manif_core.load_local_manifest(path.rocks_dir(tree)) | 94 | local loaded = manif.load_local_manifest(path.rocks_dir(tree)) |
| 95 | if loaded then | 95 | if loaded then |
| 96 | util.deep_merge(manifest, loaded) | 96 | util.deep_merge(manifest, loaded) |
| 97 | end | 97 | end |
| @@ -104,4 +104,4 @@ function manif_core.get_versions(name, deps_mode) | |||
| 104 | return {} | 104 | return {} |
| 105 | end | 105 | end |
| 106 | 106 | ||
| 107 | return manif_core | 107 | return manif |
diff --git a/src/luarocks/core/path.lua b/src/luarocks/core/path.lua new file mode 100644 index 00000000..ffde2c68 --- /dev/null +++ b/src/luarocks/core/path.lua | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | |||
| 2 | --- Core LuaRocks-specific path handling functions. | ||
| 3 | local path = {} | ||
| 4 | |||
| 5 | local cfg = require("luarocks.core.cfg") | ||
| 6 | local dir = require("luarocks.core.dir") | ||
| 7 | local require = nil | ||
| 8 | -------------------------------------------------------------------------------- | ||
| 9 | |||
| 10 | function path.rocks_dir(tree) | ||
| 11 | if type(tree) == "string" then | ||
| 12 | return dir.path(tree, cfg.rocks_subdir) | ||
| 13 | else | ||
| 14 | assert(type(tree) == "table") | ||
| 15 | return tree.rocks_dir or dir.path(tree.root, cfg.rocks_subdir) | ||
| 16 | end | ||
| 17 | end | ||
| 18 | |||
| 19 | --- Produce a versioned version of a filename. | ||
| 20 | -- @param file string: filename (must start with prefix) | ||
| 21 | -- @param prefix string: Path prefix for file | ||
| 22 | -- @param name string: Rock name | ||
| 23 | -- @param version string: Rock version | ||
| 24 | -- @return string: a pathname with the same directory parts and a versioned basename. | ||
| 25 | function path.versioned_name(file, prefix, name, version) | ||
| 26 | assert(type(file) == "string") | ||
| 27 | assert(type(name) == "string") | ||
| 28 | assert(type(version) == "string") | ||
| 29 | |||
| 30 | local rest = file:sub(#prefix+1):gsub("^/*", "") | ||
| 31 | local name_version = (name.."_"..version):gsub("%-", "_"):gsub("%.", "_") | ||
| 32 | return dir.path(prefix, name_version.."-"..rest) | ||
| 33 | end | ||
| 34 | |||
| 35 | --- Convert a pathname to a module identifier. | ||
| 36 | -- In Unix, for example, a path "foo/bar/baz.lua" is converted to | ||
| 37 | -- "foo.bar.baz"; "bla/init.lua" returns "bla"; "foo.so" returns "foo". | ||
| 38 | -- @param file string: Pathname of module | ||
| 39 | -- @return string: The module identifier, or nil if given path is | ||
| 40 | -- not a conformant module path (the function does not check if the | ||
| 41 | -- path actually exists). | ||
| 42 | function path.path_to_module(file) | ||
| 43 | assert(type(file) == "string") | ||
| 44 | |||
| 45 | local name = file:match("(.*)%."..cfg.lua_extension.."$") | ||
| 46 | if name then | ||
| 47 | name = name:gsub(dir.separator, ".") | ||
| 48 | local init = name:match("(.*)%.init$") | ||
| 49 | if init then | ||
| 50 | name = init | ||
| 51 | end | ||
| 52 | else | ||
| 53 | name = file:match("(.*)%."..cfg.lib_extension.."$") | ||
| 54 | if name then | ||
| 55 | name = name:gsub(dir.separator, ".") | ||
| 56 | else | ||
| 57 | name = file:match("(.*)%."..cfg.static_lib_extension.."$") | ||
| 58 | if name then | ||
| 59 | name = name:gsub(dir.separator, ".") | ||
| 60 | end | ||
| 61 | end | ||
| 62 | end | ||
| 63 | if not name then name = file end | ||
| 64 | name = name:gsub("^%.+", ""):gsub("%.+$", "") | ||
| 65 | return name | ||
| 66 | end | ||
| 67 | |||
| 68 | function path.deploy_lua_dir(tree) | ||
| 69 | if type(tree) == "string" then | ||
| 70 | return dir.path(tree, cfg.lua_modules_path) | ||
| 71 | else | ||
| 72 | assert(type(tree) == "table") | ||
| 73 | return tree.lua_dir or dir.path(tree.root, cfg.lua_modules_path) | ||
| 74 | end | ||
| 75 | end | ||
| 76 | |||
| 77 | function path.deploy_lib_dir(tree) | ||
| 78 | if type(tree) == "string" then | ||
| 79 | return dir.path(tree, cfg.lib_modules_path) | ||
| 80 | else | ||
| 81 | assert(type(tree) == "table") | ||
| 82 | return tree.lib_dir or dir.path(tree.root, cfg.lib_modules_path) | ||
| 83 | end | ||
| 84 | end | ||
| 85 | |||
| 86 | local is_src_extension = { [".lua"] = true, [".tl"] = true, [".tld"] = true, [".moon"] = true } | ||
| 87 | |||
| 88 | --- Return the pathname of the file that would be loaded for a module, indexed. | ||
| 89 | -- @param file_name string: module file name as in manifest (eg. "socket/core.so") | ||
| 90 | -- @param name string: name of the package (eg. "luasocket") | ||
| 91 | -- @param version string: version number (eg. "2.0.2-1") | ||
| 92 | -- @param tree string: repository path (eg. "/usr/local") | ||
| 93 | -- @param i number: the index, 1 if version is the current default, > 1 otherwise. | ||
| 94 | -- This is done this way for use by select_module in luarocks.loader. | ||
| 95 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") | ||
| 96 | function path.which_i(file_name, name, version, tree, i) | ||
| 97 | local deploy_dir | ||
| 98 | local extension = file_name:match("%.[a-z]+$") | ||
| 99 | if is_src_extension[extension] then | ||
| 100 | deploy_dir = path.deploy_lua_dir(tree) | ||
| 101 | file_name = dir.path(deploy_dir, file_name) | ||
| 102 | else | ||
| 103 | deploy_dir = path.deploy_lib_dir(tree) | ||
| 104 | file_name = dir.path(deploy_dir, file_name) | ||
| 105 | end | ||
| 106 | if i > 1 then | ||
| 107 | file_name = path.versioned_name(file_name, deploy_dir, name, version) | ||
| 108 | end | ||
| 109 | return file_name | ||
| 110 | end | ||
| 111 | |||
| 112 | function path.rocks_tree_to_string(tree) | ||
| 113 | if type(tree) == "string" then | ||
| 114 | return tree | ||
| 115 | else | ||
| 116 | assert(type(tree) == "table") | ||
| 117 | return tree.root | ||
| 118 | end | ||
| 119 | end | ||
| 120 | |||
| 121 | --- Apply a given function to the active rocks trees based on chosen dependency mode. | ||
| 122 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 123 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 124 | -- "none" for no trees (this function becomes a nop). | ||
| 125 | -- @param fn function: function to be applied, with the tree dir (string) as the first | ||
| 126 | -- argument and the remaining varargs of map_trees as the following arguments. | ||
| 127 | -- @return a table with all results of invocations of fn collected. | ||
| 128 | function path.map_trees(deps_mode, fn, ...) | ||
| 129 | local result = {} | ||
| 130 | if deps_mode == "one" then | ||
| 131 | table.insert(result, (fn(cfg.root_dir, ...)) or 0) | ||
| 132 | elseif deps_mode == "all" or deps_mode == "order" then | ||
| 133 | local use = false | ||
| 134 | if deps_mode == "all" then | ||
| 135 | use = true | ||
| 136 | end | ||
| 137 | for _, tree in ipairs(cfg.rocks_trees) do | ||
| 138 | if dir.normalize(path.rocks_tree_to_string(tree)) == dir.normalize(path.rocks_tree_to_string(cfg.root_dir)) then | ||
| 139 | use = true | ||
| 140 | end | ||
| 141 | if use then | ||
| 142 | table.insert(result, (fn(tree, ...)) or 0) | ||
| 143 | end | ||
| 144 | end | ||
| 145 | end | ||
| 146 | return result | ||
| 147 | end | ||
| 148 | |||
| 149 | return path | ||
diff --git a/src/luarocks/core/persist.lua b/src/luarocks/core/persist.lua new file mode 100644 index 00000000..48979184 --- /dev/null +++ b/src/luarocks/core/persist.lua | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | |||
| 2 | local persist = {} | ||
| 3 | |||
| 4 | local require = nil | ||
| 5 | -------------------------------------------------------------------------------- | ||
| 6 | |||
| 7 | --- Load and run a Lua file in an environment. | ||
| 8 | -- @param filename string: the name of the file. | ||
| 9 | -- @param env table: the environment table. | ||
| 10 | -- @return (true, any) or (nil, string, string): true and the return value | ||
| 11 | -- of the file, or nil, an error message and an error code ("open", "load" | ||
| 12 | -- or "run") in case of errors. | ||
| 13 | local function run_file(filename, env) | ||
| 14 | local fd, err = io.open(filename) | ||
| 15 | if not fd then | ||
| 16 | return nil, err, "open" | ||
| 17 | end | ||
| 18 | local str, err = fd:read("*a") | ||
| 19 | fd:close() | ||
| 20 | if not str then | ||
| 21 | return nil, err, "open" | ||
| 22 | end | ||
| 23 | str = str:gsub("^#![^\n]*\n", "") | ||
| 24 | local chunk, ran | ||
| 25 | if _VERSION == "Lua 5.1" then -- Lua 5.1 | ||
| 26 | chunk, err = loadstring(str, filename) | ||
| 27 | if chunk then | ||
| 28 | setfenv(chunk, env) | ||
| 29 | ran, err = pcall(chunk) | ||
| 30 | end | ||
| 31 | else -- Lua 5.2 | ||
| 32 | chunk, err = load(str, filename, "t", env) | ||
| 33 | if chunk then | ||
| 34 | ran, err = pcall(chunk) | ||
| 35 | end | ||
| 36 | end | ||
| 37 | if not chunk then | ||
| 38 | return nil, "Error loading file: "..err, "load" | ||
| 39 | end | ||
| 40 | if not ran then | ||
| 41 | return nil, "Error running file: "..err, "run" | ||
| 42 | end | ||
| 43 | return true, err | ||
| 44 | end | ||
| 45 | |||
| 46 | --- Load a Lua file containing assignments, storing them in a table. | ||
| 47 | -- The global environment is not propagated to the loaded file. | ||
| 48 | -- @param filename string: the name of the file. | ||
| 49 | -- @param tbl table or nil: if given, this table is used to store | ||
| 50 | -- loaded values. | ||
| 51 | -- @return (table, table) or (nil, string, string): a table with the file's assignments | ||
| 52 | -- as fields and set of undefined globals accessed in file, | ||
| 53 | -- or nil, an error message and an error code ("open"; couldn't open the file, | ||
| 54 | -- "load"; compile-time error, or "run"; run-time error) | ||
| 55 | -- in case of errors. | ||
| 56 | function persist.load_into_table(filename, tbl) | ||
| 57 | assert(type(filename) == "string") | ||
| 58 | assert(type(tbl) == "table" or not tbl) | ||
| 59 | |||
| 60 | local result = tbl or {} | ||
| 61 | local globals = {} | ||
| 62 | local globals_mt = { | ||
| 63 | __index = function(t, k) | ||
| 64 | globals[k] = true | ||
| 65 | end | ||
| 66 | } | ||
| 67 | local save_mt = getmetatable(result) | ||
| 68 | setmetatable(result, globals_mt) | ||
| 69 | |||
| 70 | local ok, err, errcode = run_file(filename, result) | ||
| 71 | |||
| 72 | setmetatable(result, save_mt) | ||
| 73 | |||
| 74 | if not ok then | ||
| 75 | return nil, err, errcode | ||
| 76 | end | ||
| 77 | return result, globals | ||
| 78 | end | ||
| 79 | |||
| 80 | return persist | ||
| 81 | |||
diff --git a/src/luarocks/core/type_check.lua b/src/luarocks/core/type_check.lua new file mode 100644 index 00000000..a2e14efd --- /dev/null +++ b/src/luarocks/core/type_check.lua | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | |||
| 2 | local type_check = {} | ||
| 3 | |||
| 4 | local cfg = require("luarocks.core.cfg") | ||
| 5 | local deps = require("luarocks.core.deps") | ||
| 6 | local require = nil | ||
| 7 | -------------------------------------------------------------------------------- | ||
| 8 | |||
| 9 | type_check.string_1 = { _type = "string" } | ||
| 10 | type_check.number_1 = { _type = "number" } | ||
| 11 | type_check.mandatory_string_1 = { _type = "string", _mandatory = true } | ||
| 12 | |||
| 13 | local number_1 = type_check.number_1 | ||
| 14 | local string_1 = type_check.string_1 | ||
| 15 | local mandatory_string_1 = type_check.mandatory_string_1 | ||
| 16 | |||
| 17 | local manifest_types = { | ||
| 18 | repository = { | ||
| 19 | _mandatory = true, | ||
| 20 | -- packages | ||
| 21 | _any = { | ||
| 22 | -- versions | ||
| 23 | _any = { | ||
| 24 | -- items | ||
| 25 | _any = { | ||
| 26 | arch = mandatory_string_1, | ||
| 27 | modules = { _any = string_1 }, | ||
| 28 | commands = { _any = string_1 }, | ||
| 29 | dependencies = { _any = string_1 }, | ||
| 30 | -- TODO: to be extended with more metadata. | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | }, | ||
| 35 | modules = { | ||
| 36 | _mandatory = true, | ||
| 37 | -- modules | ||
| 38 | _any = { | ||
| 39 | -- providers | ||
| 40 | _any = string_1 | ||
| 41 | } | ||
| 42 | }, | ||
| 43 | commands = { | ||
| 44 | _mandatory = true, | ||
| 45 | -- modules | ||
| 46 | _any = { | ||
| 47 | -- commands | ||
| 48 | _any = string_1 | ||
| 49 | } | ||
| 50 | }, | ||
| 51 | dependencies = { | ||
| 52 | -- each module | ||
| 53 | _any = { | ||
| 54 | -- each version | ||
| 55 | _any = { | ||
| 56 | -- each dependency | ||
| 57 | _any = { | ||
| 58 | name = string_1, | ||
| 59 | constraints = { | ||
| 60 | _any = { | ||
| 61 | no_upgrade = { _type = "boolean" }, | ||
| 62 | op = string_1, | ||
| 63 | version = { | ||
| 64 | string = string_1, | ||
| 65 | _any = number_1, | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | local function check_version(version, typetbl, context) | ||
| 76 | local typetbl_version = typetbl._version or "1.0" | ||
| 77 | if deps.compare_versions(typetbl_version, version) then | ||
| 78 | if context == "" then | ||
| 79 | return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly." | ||
| 80 | else | ||
| 81 | return nil, context.." is not supported in rockspec format "..version.." (requires version "..typetbl_version.."), please fix the rockspec_format field accordingly." | ||
| 82 | end | ||
| 83 | end | ||
| 84 | return true | ||
| 85 | end | ||
| 86 | |||
| 87 | --- Type check an object. | ||
| 88 | -- The object is compared against an archetypical value | ||
| 89 | -- matching the expected type -- the actual values don't matter, | ||
| 90 | -- only their types. Tables are type checked recursively. | ||
| 91 | -- @param version string: The version of the item. | ||
| 92 | -- @param item any: The object being checked. | ||
| 93 | -- @param typetbl any: The type-checking table for the object. | ||
| 94 | -- @param context string: A string indicating the "context" where the | ||
| 95 | -- error occurred (the full table path), for error messages. | ||
| 96 | -- @return boolean or (nil, string): true if type checking | ||
| 97 | -- succeeded, or nil and an error message if it failed. | ||
| 98 | -- @see type_check_table | ||
| 99 | local function type_check_item(version, item, typetbl, context) | ||
| 100 | assert(type(version) == "string") | ||
| 101 | |||
| 102 | local ok, err = check_version(version, typetbl, context) | ||
| 103 | if not ok then | ||
| 104 | return nil, err | ||
| 105 | end | ||
| 106 | |||
| 107 | local item_type = type(item) or "nil" | ||
| 108 | local expected_type = typetbl._type or "table" | ||
| 109 | |||
| 110 | if expected_type == "number" then | ||
| 111 | if not tonumber(item) then | ||
| 112 | return nil, "Type mismatch on field "..context..": expected a number" | ||
| 113 | end | ||
| 114 | elseif expected_type == "string" then | ||
| 115 | if item_type ~= "string" then | ||
| 116 | return nil, "Type mismatch on field "..context..": expected a string, got "..item_type | ||
| 117 | end | ||
| 118 | if typetbl._pattern then | ||
| 119 | if not item:match("^"..typetbl._pattern.."$") then | ||
| 120 | return nil, "Type mismatch on field "..context..": invalid value "..item.." does not match '"..typetbl._pattern.."'" | ||
| 121 | end | ||
| 122 | end | ||
| 123 | elseif expected_type == "table" then | ||
| 124 | if item_type ~= expected_type then | ||
| 125 | return nil, "Type mismatch on field "..context..": expected a table" | ||
| 126 | else | ||
| 127 | return type_check.type_check_table(version, item, typetbl, context) | ||
| 128 | end | ||
| 129 | elseif item_type ~= expected_type then | ||
| 130 | return nil, "Type mismatch on field "..context..": expected "..expected_type | ||
| 131 | end | ||
| 132 | return true | ||
| 133 | end | ||
| 134 | |||
| 135 | local function mkfield(context, field) | ||
| 136 | if context == "" then | ||
| 137 | return field | ||
| 138 | end | ||
| 139 | return context.."."..field | ||
| 140 | end | ||
| 141 | |||
| 142 | --- Type check the contents of a table. | ||
| 143 | -- The table's contents are compared against a reference table, | ||
| 144 | -- which contains the recognized fields, with archetypical values | ||
| 145 | -- matching the expected types -- the actual values of items in the | ||
| 146 | -- reference table don't matter, only their types (ie, for field x | ||
| 147 | -- in tbl that is correctly typed, type(tbl.x) == type(types.x)). | ||
| 148 | -- If the reference table contains a field called MORE, then | ||
| 149 | -- unknown fields in the checked table are accepted. | ||
| 150 | -- If it contains a field called ANY, then its type will be | ||
| 151 | -- used to check any unknown fields. If a field is prefixed | ||
| 152 | -- with MUST_, it is mandatory; its absence from the table is | ||
| 153 | -- a type error. | ||
| 154 | -- Tables are type checked recursively. | ||
| 155 | -- @param version string: The version of tbl. | ||
| 156 | -- @param tbl table: The table to be type checked. | ||
| 157 | -- @param typetbl table: The type-checking table, containing | ||
| 158 | -- values for recognized fields in the checked table. | ||
| 159 | -- @param context string: A string indicating the "context" where the | ||
| 160 | -- error occurred (such as the name of the table the item is a part of), | ||
| 161 | -- to be used by error messages. | ||
| 162 | -- @return boolean or (nil, string): true if type checking | ||
| 163 | -- succeeded, or nil and an error message if it failed. | ||
| 164 | function type_check.type_check_table(version, tbl, typetbl, context) | ||
| 165 | assert(type(version) == "string") | ||
| 166 | assert(type(tbl) == "table") | ||
| 167 | assert(type(typetbl) == "table") | ||
| 168 | |||
| 169 | local ok, err = check_version(version, typetbl, context) | ||
| 170 | if not ok then | ||
| 171 | return nil, err | ||
| 172 | end | ||
| 173 | |||
| 174 | for k, v in pairs(tbl) do | ||
| 175 | local t = typetbl[k] or typetbl._any | ||
| 176 | if t then | ||
| 177 | local ok, err = type_check_item(version, v, t, mkfield(context, k)) | ||
| 178 | if not ok then return nil, err end | ||
| 179 | elseif typetbl._more then | ||
| 180 | -- Accept unknown field | ||
| 181 | else | ||
| 182 | if not cfg.accept_unknown_fields then | ||
| 183 | return nil, "Unknown field "..k | ||
| 184 | end | ||
| 185 | end | ||
| 186 | end | ||
| 187 | for k, v in pairs(typetbl) do | ||
| 188 | if k:sub(1,1) ~= "_" and v._mandatory then | ||
| 189 | if not tbl[k] then | ||
| 190 | return nil, "Mandatory field "..mkfield(context, k).." is missing." | ||
| 191 | end | ||
| 192 | end | ||
| 193 | end | ||
| 194 | return true | ||
| 195 | end | ||
| 196 | |||
| 197 | function type_check.check_undeclared_globals(globals, typetbl) | ||
| 198 | local undeclared = {} | ||
| 199 | for glob, _ in pairs(globals) do | ||
| 200 | if not (typetbl[glob] or typetbl["MUST_"..glob]) then | ||
| 201 | table.insert(undeclared, glob) | ||
| 202 | end | ||
| 203 | end | ||
| 204 | if #undeclared == 1 then | ||
| 205 | return nil, "Unknown variable: "..undeclared[1] | ||
| 206 | elseif #undeclared > 1 then | ||
| 207 | return nil, "Unknown variables: "..table.concat(undeclared, ", ") | ||
| 208 | end | ||
| 209 | return true | ||
| 210 | end | ||
| 211 | |||
| 212 | --- Type check a manifest table. | ||
| 213 | -- Verify the correctness of elements from a | ||
| 214 | -- manifest table, reporting on unknown fields and type | ||
| 215 | -- mismatches. | ||
| 216 | -- @return boolean or (nil, string): true if type checking | ||
| 217 | -- succeeded, or nil and an error message if it failed. | ||
| 218 | function type_check.type_check_manifest(manifest, globals) | ||
| 219 | assert(type(manifest) == "table") | ||
| 220 | local ok, err = type_check.check_undeclared_globals(globals, manifest_types) | ||
| 221 | if not ok then return nil, err end | ||
| 222 | return type_check.type_check_table("1.0", manifest, manifest_types, "") | ||
| 223 | end | ||
| 224 | |||
| 225 | return type_check | ||
| 226 | |||
diff --git a/src/luarocks/core/util.lua b/src/luarocks/core/util.lua new file mode 100644 index 00000000..4f896b17 --- /dev/null +++ b/src/luarocks/core/util.lua | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | |||
| 2 | local util = {} | ||
| 3 | |||
| 4 | local require = nil | ||
| 5 | -------------------------------------------------------------------------------- | ||
| 6 | |||
| 7 | --- Run a process and read a its output. | ||
| 8 | -- Equivalent to io.popen(cmd):read("*l"), except that it | ||
| 9 | -- closes the fd right away. | ||
| 10 | -- @param cmd string: The command to execute | ||
| 11 | -- @param spec string: "*l" by default, to read a single line. | ||
| 12 | -- May be used to read more, passing, for instance, "*a". | ||
| 13 | -- @return string: the output of the program. | ||
| 14 | function util.popen_read(cmd, spec) | ||
| 15 | local fd = io.popen(cmd) | ||
| 16 | local out = fd:read(spec or "*l") | ||
| 17 | fd:close() | ||
| 18 | return out | ||
| 19 | end | ||
| 20 | |||
| 21 | --- Create a new shallow copy of a table: a new table with | ||
| 22 | -- the same keys and values. Keys point to the same objects as | ||
| 23 | -- the original table (ie, does not copy recursively). | ||
| 24 | -- @param tbl table: the input table | ||
| 25 | -- @return table: a new table with the same contents. | ||
| 26 | function util.make_shallow_copy(tbl) | ||
| 27 | local copy = {} | ||
| 28 | for k,v in pairs(tbl) do | ||
| 29 | copy[k] = v | ||
| 30 | end | ||
| 31 | return copy | ||
| 32 | end | ||
| 33 | |||
| 34 | --- | ||
| 35 | -- Formats tables with cycles recursively to any depth. | ||
| 36 | -- References to other tables are shown as values. | ||
| 37 | -- Self references are indicated. | ||
| 38 | -- The string returned is "Lua code", which can be procesed | ||
| 39 | -- (in the case in which indent is composed by spaces or "--"). | ||
| 40 | -- Userdata and function keys and values are shown as strings, | ||
| 41 | -- which logically are exactly not equivalent to the original code. | ||
| 42 | -- This routine can serve for pretty formating tables with | ||
| 43 | -- proper indentations, apart from printing them: | ||
| 44 | -- io.write(table.show(t, "t")) -- a typical use | ||
| 45 | -- Written by Julio Manuel Fernandez-Diaz, | ||
| 46 | -- Heavily based on "Saving tables with cycles", PIL2, p. 113. | ||
| 47 | -- @param t table: is the table. | ||
| 48 | -- @param name string: is the name of the table (optional) | ||
| 49 | -- @param indent string: is a first indentation (optional). | ||
| 50 | -- @return string: the pretty-printed table | ||
| 51 | function util.show_table(t, name, indent) | ||
| 52 | local cart -- a container | ||
| 53 | local autoref -- for self references | ||
| 54 | |||
| 55 | local function is_empty_table(t) return next(t) == nil end | ||
| 56 | |||
| 57 | local function basic_serialize (o) | ||
| 58 | local so = tostring(o) | ||
| 59 | if type(o) == "function" then | ||
| 60 | local info = debug.getinfo(o, "S") | ||
| 61 | -- info.name is nil because o is not a calling level | ||
| 62 | if info.what == "C" then | ||
| 63 | return ("%q"):format(so .. ", C function") | ||
| 64 | else | ||
| 65 | -- the information is defined through lines | ||
| 66 | return ("%q"):format(so .. ", defined in (" .. info.linedefined .. "-" .. info.lastlinedefined .. ")" .. info.source) | ||
| 67 | end | ||
| 68 | elseif type(o) == "number" then | ||
| 69 | return so | ||
| 70 | else | ||
| 71 | return ("%q"):format(so) | ||
| 72 | end | ||
| 73 | end | ||
| 74 | |||
| 75 | local function add_to_cart (value, name, indent, saved, field) | ||
| 76 | indent = indent or "" | ||
| 77 | saved = saved or {} | ||
| 78 | field = field or name | ||
| 79 | |||
| 80 | cart = cart .. indent .. field | ||
| 81 | |||
| 82 | if type(value) ~= "table" then | ||
| 83 | cart = cart .. " = " .. basic_serialize(value) .. ";\n" | ||
| 84 | else | ||
| 85 | if saved[value] then | ||
| 86 | cart = cart .. " = {}; -- " .. saved[value] .. " (self reference)\n" | ||
| 87 | autoref = autoref .. name .. " = " .. saved[value] .. ";\n" | ||
| 88 | else | ||
| 89 | saved[value] = name | ||
| 90 | --if tablecount(value) == 0 then | ||
| 91 | if is_empty_table(value) then | ||
| 92 | cart = cart .. " = {};\n" | ||
| 93 | else | ||
| 94 | cart = cart .. " = {\n" | ||
| 95 | for k, v in pairs(value) do | ||
| 96 | k = basic_serialize(k) | ||
| 97 | local fname = ("%s[%s]"):format(name, k) | ||
| 98 | field = ("[%s]"):format(k) | ||
| 99 | -- three spaces between levels | ||
| 100 | add_to_cart(v, fname, indent .. " ", saved, field) | ||
| 101 | end | ||
| 102 | cart = cart .. indent .. "};\n" | ||
| 103 | end | ||
| 104 | end | ||
| 105 | end | ||
| 106 | end | ||
| 107 | |||
| 108 | name = name or "__unnamed__" | ||
| 109 | if type(t) ~= "table" then | ||
| 110 | return name .. " = " .. basic_serialize(t) | ||
| 111 | end | ||
| 112 | cart, autoref = "", "" | ||
| 113 | add_to_cart(t, name, indent) | ||
| 114 | return cart .. autoref | ||
| 115 | end | ||
| 116 | |||
| 117 | --- Merges contents of src on top of dst's contents. | ||
| 118 | -- @param dst Destination table, which will receive src's contents. | ||
| 119 | -- @param src Table which provides new contents to dst. | ||
| 120 | -- @see platform_overrides | ||
| 121 | function util.deep_merge(dst, src) | ||
| 122 | for k, v in pairs(src) do | ||
| 123 | if type(v) == "table" then | ||
| 124 | if not dst[k] then | ||
| 125 | dst[k] = {} | ||
| 126 | end | ||
| 127 | if type(dst[k]) == "table" then | ||
| 128 | util.deep_merge(dst[k], v) | ||
| 129 | else | ||
| 130 | dst[k] = v | ||
| 131 | end | ||
| 132 | else | ||
| 133 | dst[k] = v | ||
| 134 | end | ||
| 135 | end | ||
| 136 | end | ||
| 137 | |||
| 138 | --- Remove repeated entries from a path-style string. | ||
| 139 | -- Example: given ("a;b;c;a;b;d", ";"), returns "a;b;c;d". | ||
| 140 | -- @param list string: A path string (from $PATH or package.path) | ||
| 141 | -- @param sep string: The separator | ||
| 142 | function util.remove_path_dupes(list, sep) | ||
| 143 | assert(type(list) == "string") | ||
| 144 | assert(type(sep) == "string") | ||
| 145 | local parts = util.split_string(list, sep) | ||
| 146 | local final, entries = {}, {} | ||
| 147 | for _, part in ipairs(parts) do | ||
| 148 | part = part:gsub("//", "/") | ||
| 149 | if not entries[part] then | ||
| 150 | table.insert(final, part) | ||
| 151 | entries[part] = true | ||
| 152 | end | ||
| 153 | end | ||
| 154 | return table.concat(final, sep) | ||
| 155 | end | ||
| 156 | |||
| 157 | -- from http://lua-users.org/wiki/SplitJoin | ||
| 158 | -- by Philippe Lhoste | ||
| 159 | function util.split_string(str, delim, maxNb) | ||
| 160 | -- Eliminate bad cases... | ||
| 161 | if string.find(str, delim) == nil then | ||
| 162 | return { str } | ||
| 163 | end | ||
| 164 | if maxNb == nil or maxNb < 1 then | ||
| 165 | maxNb = 0 -- No limit | ||
| 166 | end | ||
| 167 | local result = {} | ||
| 168 | local pat = "(.-)" .. delim .. "()" | ||
| 169 | local nb = 0 | ||
| 170 | local lastPos | ||
| 171 | for part, pos in string.gmatch(str, pat) do | ||
| 172 | nb = nb + 1 | ||
| 173 | result[nb] = part | ||
| 174 | lastPos = pos | ||
| 175 | if nb == maxNb then break end | ||
| 176 | end | ||
| 177 | -- Handle the last field | ||
| 178 | if nb ~= maxNb then | ||
| 179 | result[nb + 1] = string.sub(str, lastPos) | ||
| 180 | end | ||
| 181 | return result | ||
| 182 | end | ||
| 183 | |||
| 184 | --- Return an array of keys of a table. | ||
| 185 | -- @param tbl table: The input table. | ||
| 186 | -- @return table: The array of keys. | ||
| 187 | function util.keys(tbl) | ||
| 188 | local ks = {} | ||
| 189 | for k,_ in pairs(tbl) do | ||
| 190 | table.insert(ks, k) | ||
| 191 | end | ||
| 192 | return ks | ||
| 193 | end | ||
| 194 | |||
| 195 | --- Print a line to standard error | ||
| 196 | function util.printerr(...) | ||
| 197 | io.stderr:write(table.concat({...},"\t")) | ||
| 198 | io.stderr:write("\n") | ||
| 199 | end | ||
| 200 | |||
| 201 | return util | ||
| 202 | |||
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 0d85d33e..acbf1dd6 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua | |||
| @@ -12,14 +12,23 @@ | |||
| 12 | -- test/test_deps.lua file included with LuaRocks provides some | 12 | -- test/test_deps.lua file included with LuaRocks provides some |
| 13 | -- insights on what these criteria are. | 13 | -- insights on what these criteria are. |
| 14 | local deps = {} | 14 | local deps = {} |
| 15 | package.loaded["luarocks.deps"] = deps | 15 | setmetatable(deps, { __index = require("luarocks.core.deps") }) |
| 16 | 16 | ||
| 17 | local cfg = require("luarocks.cfg") | 17 | local cfg = require("luarocks.core.cfg") |
| 18 | local manif_core = require("luarocks.manif_core") | 18 | local manif = require("luarocks.core.manif") |
| 19 | local path = require("luarocks.path") | 19 | local path = require("luarocks.path") |
| 20 | local dir = require("luarocks.dir") | 20 | local dir = require("luarocks.dir") |
| 21 | local util = require("luarocks.util") | 21 | local util = require("luarocks.util") |
| 22 | 22 | ||
| 23 | --- Check if rockspec format version satisfies version requirement. | ||
| 24 | -- @param rockspec table: The rockspec table. | ||
| 25 | -- @param version string: required version. | ||
| 26 | -- @return boolean: true if rockspec format matches version or is newer, false otherwise. | ||
| 27 | function deps.format_is_at_least(rockspec, version) | ||
| 28 | local rockspec_format = rockspec.rockspec_format or "1.0" | ||
| 29 | return deps.parse_version(rockspec_format) >= deps.parse_version(version) | ||
| 30 | end | ||
| 31 | |||
| 23 | local operators = { | 32 | local operators = { |
| 24 | ["=="] = "==", | 33 | ["=="] = "==", |
| 25 | ["~="] = "~=", | 34 | ["~="] = "~=", |
| @@ -34,139 +43,6 @@ local operators = { | |||
| 34 | ["!="] = "~=" | 43 | ["!="] = "~=" |
| 35 | } | 44 | } |
| 36 | 45 | ||
| 37 | local deltas = { | ||
| 38 | scm = 1100, | ||
| 39 | cvs = 1000, | ||
| 40 | rc = -1000, | ||
| 41 | pre = -10000, | ||
| 42 | beta = -100000, | ||
| 43 | alpha = -1000000 | ||
| 44 | } | ||
| 45 | |||
| 46 | local version_mt = { | ||
| 47 | --- Equality comparison for versions. | ||
| 48 | -- All version numbers must be equal. | ||
| 49 | -- If both versions have revision numbers, they must be equal; | ||
| 50 | -- otherwise the revision number is ignored. | ||
| 51 | -- @param v1 table: version table to compare. | ||
| 52 | -- @param v2 table: version table to compare. | ||
| 53 | -- @return boolean: true if they are considered equivalent. | ||
| 54 | __eq = function(v1, v2) | ||
| 55 | if #v1 ~= #v2 then | ||
| 56 | return false | ||
| 57 | end | ||
| 58 | for i = 1, #v1 do | ||
| 59 | if v1[i] ~= v2[i] then | ||
| 60 | return false | ||
| 61 | end | ||
| 62 | end | ||
| 63 | if v1.revision and v2.revision then | ||
| 64 | return (v1.revision == v2.revision) | ||
| 65 | end | ||
| 66 | return true | ||
| 67 | end, | ||
| 68 | --- Size comparison for versions. | ||
| 69 | -- All version numbers are compared. | ||
| 70 | -- If both versions have revision numbers, they are compared; | ||
| 71 | -- otherwise the revision number is ignored. | ||
| 72 | -- @param v1 table: version table to compare. | ||
| 73 | -- @param v2 table: version table to compare. | ||
| 74 | -- @return boolean: true if v1 is considered lower than v2. | ||
| 75 | __lt = function(v1, v2) | ||
| 76 | for i = 1, math.max(#v1, #v2) do | ||
| 77 | local v1i, v2i = v1[i] or 0, v2[i] or 0 | ||
| 78 | if v1i ~= v2i then | ||
| 79 | return (v1i < v2i) | ||
| 80 | end | ||
| 81 | end | ||
| 82 | if v1.revision and v2.revision then | ||
| 83 | return (v1.revision < v2.revision) | ||
| 84 | end | ||
| 85 | return false | ||
| 86 | end | ||
| 87 | } | ||
| 88 | |||
| 89 | local version_cache = {} | ||
| 90 | setmetatable(version_cache, { | ||
| 91 | __mode = "kv" | ||
| 92 | }) | ||
| 93 | |||
| 94 | --- Parse a version string, converting to table format. | ||
| 95 | -- A version table contains all components of the version string | ||
| 96 | -- converted to numeric format, stored in the array part of the table. | ||
| 97 | -- If the version contains a revision, it is stored numerically | ||
| 98 | -- in the 'revision' field. The original string representation of | ||
| 99 | -- the string is preserved in the 'string' field. | ||
| 100 | -- Returned version tables use a metatable | ||
| 101 | -- allowing later comparison through relational operators. | ||
| 102 | -- @param vstring string: A version number in string format. | ||
| 103 | -- @return table or nil: A version table or nil | ||
| 104 | -- if the input string contains invalid characters. | ||
| 105 | function deps.parse_version(vstring) | ||
| 106 | if not vstring then return nil end | ||
| 107 | assert(type(vstring) == "string") | ||
| 108 | |||
| 109 | local cached = version_cache[vstring] | ||
| 110 | if cached then | ||
| 111 | return cached | ||
| 112 | end | ||
| 113 | |||
| 114 | local version = {} | ||
| 115 | local i = 1 | ||
| 116 | |||
| 117 | local function add_token(number) | ||
| 118 | version[i] = version[i] and version[i] + number/100000 or number | ||
| 119 | i = i + 1 | ||
| 120 | end | ||
| 121 | |||
| 122 | -- trim leading and trailing spaces | ||
| 123 | vstring = vstring:match("^%s*(.*)%s*$") | ||
| 124 | version.string = vstring | ||
| 125 | -- store revision separately if any | ||
| 126 | local main, revision = vstring:match("(.*)%-(%d+)$") | ||
| 127 | if revision then | ||
| 128 | vstring = main | ||
| 129 | version.revision = tonumber(revision) | ||
| 130 | end | ||
| 131 | while #vstring > 0 do | ||
| 132 | -- extract a number | ||
| 133 | local token, rest = vstring:match("^(%d+)[%.%-%_]*(.*)") | ||
| 134 | if token then | ||
| 135 | add_token(tonumber(token)) | ||
| 136 | else | ||
| 137 | -- extract a word | ||
| 138 | token, rest = vstring:match("^(%a+)[%.%-%_]*(.*)") | ||
| 139 | if not token then | ||
| 140 | util.printerr("Warning: version number '"..vstring.."' could not be parsed.") | ||
| 141 | version[i] = 0 | ||
| 142 | break | ||
| 143 | end | ||
| 144 | version[i] = deltas[token] or (token:byte() / 1000) | ||
| 145 | end | ||
| 146 | vstring = rest | ||
| 147 | end | ||
| 148 | setmetatable(version, version_mt) | ||
| 149 | version_cache[vstring] = version | ||
| 150 | return version | ||
| 151 | end | ||
| 152 | |||
| 153 | --- Utility function to compare version numbers given as strings. | ||
| 154 | -- @param a string: one version. | ||
| 155 | -- @param b string: another version. | ||
| 156 | -- @return boolean: True if a > b. | ||
| 157 | function deps.compare_versions(a, b) | ||
| 158 | return deps.parse_version(a) > deps.parse_version(b) | ||
| 159 | end | ||
| 160 | |||
| 161 | --- Check if rockspec format version satisfies version requirement. | ||
| 162 | -- @param rockspec table: The rockspec table. | ||
| 163 | -- @param version string: required version. | ||
| 164 | -- @return boolean: true if rockspec format matches version or is newer, false otherwise. | ||
| 165 | function deps.format_is_at_least(rockspec, version) | ||
| 166 | local rockspec_format = rockspec.rockspec_format or "1.0" | ||
| 167 | return deps.parse_version(rockspec_format) >= deps.parse_version(version) | ||
| 168 | end | ||
| 169 | |||
| 170 | --- Consumes a constraint from a string, converting it to table format. | 46 | --- Consumes a constraint from a string, converting it to table format. |
| 171 | -- For example, a string ">= 1.0, > 2.0" is converted to a table in the | 47 | -- For example, a string ">= 1.0, > 2.0" is converted to a table in the |
| 172 | -- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned | 48 | -- format {op = ">=", version={1,0}} and the rest, "> 2.0", is returned |
| @@ -201,7 +77,7 @@ end | |||
| 201 | function deps.parse_constraints(input) | 77 | function deps.parse_constraints(input) |
| 202 | assert(type(input) == "string") | 78 | assert(type(input) == "string") |
| 203 | 79 | ||
| 204 | local constraints, constraint, oinput = {}, nil, input | 80 | local constraints, oinput, constraint = {}, input |
| 205 | while #input > 0 do | 81 | while #input > 0 do |
| 206 | constraint, input = parse_constraint(input) | 82 | constraint, input = parse_constraint(input) |
| 207 | if constraint then | 83 | if constraint then |
| @@ -267,65 +143,6 @@ function deps.show_dep(dep, internal) | |||
| 267 | end | 143 | end |
| 268 | end | 144 | end |
| 269 | 145 | ||
| 270 | --- A more lenient check for equivalence between versions. | ||
| 271 | -- This returns true if the requested components of a version | ||
| 272 | -- match and ignore the ones that were not given. For example, | ||
| 273 | -- when requesting "2", then "2", "2.1", "2.3.5-9"... all match. | ||
| 274 | -- When requesting "2.1", then "2.1", "2.1.3" match, but "2.2" | ||
| 275 | -- doesn't. | ||
| 276 | -- @param version string or table: Version to be tested; may be | ||
| 277 | -- in string format or already parsed into a table. | ||
| 278 | -- @param requested string or table: Version requested; may be | ||
| 279 | -- in string format or already parsed into a table. | ||
| 280 | -- @return boolean: True if the tested version matches the requested | ||
| 281 | -- version, false otherwise. | ||
| 282 | local function partial_match(version, requested) | ||
| 283 | assert(type(version) == "string" or type(version) == "table") | ||
| 284 | assert(type(requested) == "string" or type(version) == "table") | ||
| 285 | |||
| 286 | if type(version) ~= "table" then version = deps.parse_version(version) end | ||
| 287 | if type(requested) ~= "table" then requested = deps.parse_version(requested) end | ||
| 288 | if not version or not requested then return false end | ||
| 289 | |||
| 290 | for i, ri in ipairs(requested) do | ||
| 291 | local vi = version[i] or 0 | ||
| 292 | if ri ~= vi then return false end | ||
| 293 | end | ||
| 294 | if requested.revision then | ||
| 295 | return requested.revision == version.revision | ||
| 296 | end | ||
| 297 | return true | ||
| 298 | end | ||
| 299 | |||
| 300 | --- Check if a version satisfies a set of constraints. | ||
| 301 | -- @param version table: A version in table format | ||
| 302 | -- @param constraints table: An array of constraints in table format. | ||
| 303 | -- @return boolean: True if version satisfies all constraints, | ||
| 304 | -- false otherwise. | ||
| 305 | function deps.match_constraints(version, constraints) | ||
| 306 | assert(type(version) == "table") | ||
| 307 | assert(type(constraints) == "table") | ||
| 308 | local ok = true | ||
| 309 | setmetatable(version, version_mt) | ||
| 310 | for _, constr in pairs(constraints) do | ||
| 311 | if type(constr.version) == "string" then | ||
| 312 | constr.version = deps.parse_version(constr.version) | ||
| 313 | end | ||
| 314 | local constr_version, constr_op = constr.version, constr.op | ||
| 315 | setmetatable(constr_version, version_mt) | ||
| 316 | if constr_op == "==" then ok = version == constr_version | ||
| 317 | elseif constr_op == "~=" then ok = version ~= constr_version | ||
| 318 | elseif constr_op == ">" then ok = version > constr_version | ||
| 319 | elseif constr_op == "<" then ok = version < constr_version | ||
| 320 | elseif constr_op == ">=" then ok = version >= constr_version | ||
| 321 | elseif constr_op == "<=" then ok = version <= constr_version | ||
| 322 | elseif constr_op == "~>" then ok = partial_match(version, constr_version) | ||
| 323 | end | ||
| 324 | if not ok then break end | ||
| 325 | end | ||
| 326 | return ok | ||
| 327 | end | ||
| 328 | |||
| 329 | --- Attempt to match a dependency to an installed rock. | 146 | --- Attempt to match a dependency to an installed rock. |
| 330 | -- @param dep table: A dependency parsed in table format. | 147 | -- @param dep table: A dependency parsed in table format. |
| 331 | -- @param blacklist table: Versions that can't be accepted. Table where keys | 148 | -- @param blacklist table: Versions that can't be accepted. Table where keys |
| @@ -344,7 +161,7 @@ local function match_dep(dep, blacklist, deps_mode, rocks_provided) | |||
| 344 | -- Provided rocks have higher priority than manifest's rocks. | 161 | -- Provided rocks have higher priority than manifest's rocks. |
| 345 | versions = { provided } | 162 | versions = { provided } |
| 346 | else | 163 | else |
| 347 | versions = manif_core.get_versions(dep.name, deps_mode) | 164 | versions = manif.get_versions(dep.name, deps_mode) |
| 348 | end | 165 | end |
| 349 | 166 | ||
| 350 | local latest_version | 167 | local latest_version |
| @@ -431,7 +248,8 @@ function deps.fulfill_dependencies(rockspec, deps_mode) | |||
| 431 | end | 248 | end |
| 432 | local supported = nil | 249 | local supported = nil |
| 433 | for _, plat in pairs(rockspec.supported_platforms) do | 250 | for _, plat in pairs(rockspec.supported_platforms) do |
| 434 | local neg, plat = plat:match("^(!?)(.*)") | 251 | local neg |
| 252 | neg, plat = plat:match("^(!?)(.*)") | ||
| 435 | if neg == "!" then | 253 | if neg == "!" then |
| 436 | if deps.platforms_set[plat] then | 254 | if deps.platforms_set[plat] then |
| 437 | return nil, "This rockspec for "..rockspec.package.." does not support "..plat.." platforms." | 255 | return nil, "This rockspec for "..rockspec.package.." does not support "..plat.." platforms." |
| @@ -704,7 +522,6 @@ function deps.scan_deps(results, missing, manifest, name, version, deps_mode) | |||
| 704 | 522 | ||
| 705 | local fetch = require("luarocks.fetch") | 523 | local fetch = require("luarocks.fetch") |
| 706 | 524 | ||
| 707 | local err | ||
| 708 | if results[name] then | 525 | if results[name] then |
| 709 | return results, missing | 526 | return results, missing |
| 710 | end | 527 | end |
diff --git a/src/luarocks/dir.lua b/src/luarocks/dir.lua index f72ebd6c..ad7fb870 100644 --- a/src/luarocks/dir.lua +++ b/src/luarocks/dir.lua | |||
| @@ -1,9 +1,7 @@ | |||
| 1 | 1 | ||
| 2 | --- Generic utilities for handling pathnames. | 2 | --- Generic utilities for handling pathnames. |
| 3 | local dir = {} | 3 | local dir = {} |
| 4 | package.loaded["luarocks.dir"] = dir | 4 | setmetatable(dir, { __index = require("luarocks.core.dir") }) |
| 5 | |||
| 6 | dir.separator = "/" | ||
| 7 | 5 | ||
| 8 | --- Strip the path off a path+filename. | 6 | --- Strip the path off a path+filename. |
| 9 | -- @param pathname string: A path+name, such as "/a/b/c" | 7 | -- @param pathname string: A path+name, such as "/a/b/c" |
| @@ -26,49 +24,4 @@ function dir.dir_name(pathname) | |||
| 26 | return (pathname:gsub("/*$", ""):match("(.*)[/]+[^/]*")) or "" | 24 | return (pathname:gsub("/*$", ""):match("(.*)[/]+[^/]*")) or "" |
| 27 | end | 25 | end |
| 28 | 26 | ||
| 29 | --- Describe a path in a cross-platform way. | ||
| 30 | -- Use this function to avoid platform-specific directory | ||
| 31 | -- separators in other modules. Removes trailing slashes from | ||
| 32 | -- each component given, to avoid repeated separators. | ||
| 33 | -- Separators inside strings are kept, to handle URLs containing | ||
| 34 | -- protocols. | ||
| 35 | -- @param ... strings representing directories | ||
| 36 | -- @return string: a string with a platform-specific representation | ||
| 37 | -- of the path. | ||
| 38 | function dir.path(...) | ||
| 39 | local t = {...} | ||
| 40 | while t[1] == "" do | ||
| 41 | table.remove(t, 1) | ||
| 42 | end | ||
| 43 | return (table.concat(t, "/"):gsub("([^:])/+", "%1/"):gsub("^/+", "/"):gsub("/*$", "")) | ||
| 44 | end | ||
| 45 | |||
| 46 | --- Split protocol and path from an URL or local pathname. | ||
| 47 | -- URLs should be in the "protocol://path" format. | ||
| 48 | -- For local pathnames, "file" is returned as the protocol. | ||
| 49 | -- @param url string: an URL or a local pathname. | ||
| 50 | -- @return string, string: the protocol, and the pathname without the protocol. | ||
| 51 | function dir.split_url(url) | ||
| 52 | assert(type(url) == "string") | ||
| 53 | |||
| 54 | local protocol, pathname = url:match("^([^:]*)://(.*)") | ||
| 55 | if not protocol then | ||
| 56 | protocol = "file" | ||
| 57 | pathname = url | ||
| 58 | end | ||
| 59 | return protocol, pathname | ||
| 60 | end | ||
| 61 | |||
| 62 | --- Normalize a url or local path. | ||
| 63 | -- URLs should be in the "protocol://path" format. System independent | ||
| 64 | -- forward slashes are used, removing trailing and double slashes | ||
| 65 | -- @param url string: an URL or a local pathname. | ||
| 66 | -- @return string: Normalized result. | ||
| 67 | function dir.normalize(name) | ||
| 68 | local protocol, pathname = dir.split_url(name) | ||
| 69 | pathname = pathname:gsub("\\", "/"):gsub("(.)/*$", "%1"):gsub("//", "/") | ||
| 70 | if protocol ~= "file" then pathname = protocol .."://"..pathname end | ||
| 71 | return pathname | ||
| 72 | end | ||
| 73 | |||
| 74 | return dir | 27 | return dir |
diff --git a/src/luarocks/doc.lua b/src/luarocks/doc.lua index 758fd9c5..8378bbc2 100644 --- a/src/luarocks/doc.lua +++ b/src/luarocks/doc.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "doc" command. | 2 | --- Module implementing the LuaRocks "doc" command. |
| 3 | -- Shows documentation for an installed rock. | 3 | -- Shows documentation for an installed rock. |
| 4 | local doc = {} | 4 | local doc = {} |
| 5 | package.loaded["luarocks.doc"] = doc | ||
| 6 | 5 | ||
| 7 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 8 | local show = require("luarocks.show") | 7 | local show = require("luarocks.show") |
diff --git a/src/luarocks/download.lua b/src/luarocks/download.lua index d793cab7..c81958de 100644 --- a/src/luarocks/download.lua +++ b/src/luarocks/download.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the luarocks "download" command. | 2 | --- Module implementing the luarocks "download" command. |
| 3 | -- Download a rock from the repository. | 3 | -- Download a rock from the repository. |
| 4 | local download = {} | 4 | local download = {} |
| 5 | package.loaded["luarocks.download"] = download | ||
| 6 | 5 | ||
| 7 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 8 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
| @@ -10,7 +9,7 @@ local fetch = require("luarocks.fetch") | |||
| 10 | local search = require("luarocks.search") | 9 | local search = require("luarocks.search") |
| 11 | local fs = require("luarocks.fs") | 10 | local fs = require("luarocks.fs") |
| 12 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
| 13 | local cfg = require("luarocks.cfg") | 12 | local cfg = require("luarocks.core.cfg") |
| 14 | 13 | ||
| 15 | download.help_summary = "Download a specific rock file from a rocks server." | 14 | download.help_summary = "Download a specific rock file from a rocks server." |
| 16 | download.help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]" | 15 | download.help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]" |
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua index 2590afd4..9bf1922a 100644 --- a/src/luarocks/fetch.lua +++ b/src/luarocks/fetch.lua | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | 1 | ||
| 2 | --- Functions related to fetching and loading local and remote files. | 2 | --- Functions related to fetching and loading local and remote files. |
| 3 | local fetch = {} | 3 | local fetch = {} |
| 4 | package.loaded["luarocks.fetch"] = fetch | ||
| 5 | 4 | ||
| 6 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 7 | local dir = require("luarocks.dir") | 6 | local dir = require("luarocks.dir") |
| @@ -10,7 +9,7 @@ local path = require("luarocks.path") | |||
| 10 | local deps = require("luarocks.deps") | 9 | local deps = require("luarocks.deps") |
| 11 | local persist = require("luarocks.persist") | 10 | local persist = require("luarocks.persist") |
| 12 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
| 13 | local cfg = require("luarocks.cfg") | 12 | local cfg = require("luarocks.core.cfg") |
| 14 | 13 | ||
| 15 | function fetch.is_basic_protocol(protocol, remote) | 14 | function fetch.is_basic_protocol(protocol, remote) |
| 16 | return protocol == "http" or protocol == "https" or protocol == "ftp" or (not remote and protocol == "file") | 15 | return protocol == "http" or protocol == "https" or protocol == "ftp" or (not remote and protocol == "file") |
diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua index 54cc7d73..7322e552 100644 --- a/src/luarocks/fs.lua +++ b/src/luarocks/fs.lua | |||
| @@ -8,9 +8,10 @@ | |||
| 8 | local pairs = pairs | 8 | local pairs = pairs |
| 9 | 9 | ||
| 10 | local fs = {} | 10 | local fs = {} |
| 11 | -- To avoid a loop when loading the other fs modules. | ||
| 11 | package.loaded["luarocks.fs"] = fs | 12 | package.loaded["luarocks.fs"] = fs |
| 12 | 13 | ||
| 13 | local cfg = require("luarocks.cfg") | 14 | local cfg = require("luarocks.core.cfg") |
| 14 | 15 | ||
| 15 | local pack = table.pack or function(...) return { n = select("#", ...), ... } end | 16 | local pack = table.pack or function(...) return { n = select("#", ...), ... } end |
| 16 | local unpack = table.unpack or unpack | 17 | local unpack = table.unpack or unpack |
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index a31cbb4e..770da2b7 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
| @@ -6,7 +6,7 @@ local fs_lua = {} | |||
| 6 | 6 | ||
| 7 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| 8 | 8 | ||
| 9 | local cfg = require("luarocks.cfg") | 9 | local cfg = require("luarocks.core.cfg") |
| 10 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
| 11 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
| 12 | local path = require("luarocks.path") | 12 | local path = require("luarocks.path") |
diff --git a/src/luarocks/fs/tools.lua b/src/luarocks/fs/tools.lua index ed51b545..d2062ed8 100644 --- a/src/luarocks/fs/tools.lua +++ b/src/luarocks/fs/tools.lua | |||
| @@ -4,7 +4,7 @@ local tools = {} | |||
| 4 | 4 | ||
| 5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 6 | local dir = require("luarocks.dir") | 6 | local dir = require("luarocks.dir") |
| 7 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 8 | 8 | ||
| 9 | local vars = cfg.variables | 9 | local vars = cfg.variables |
| 10 | 10 | ||
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua index 5c6b542c..df9d256d 100644 --- a/src/luarocks/fs/unix.lua +++ b/src/luarocks/fs/unix.lua | |||
| @@ -4,7 +4,7 @@ local unix = {} | |||
| 4 | 4 | ||
| 5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 6 | 6 | ||
| 7 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 8 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 9 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 10 | 10 | ||
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index d0802725..d9dc009f 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua | |||
| @@ -4,7 +4,7 @@ local tools = {} | |||
| 4 | 4 | ||
| 5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 6 | local dir = require("luarocks.dir") | 6 | local dir = require("luarocks.dir") |
| 7 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 8 | 8 | ||
| 9 | local vars = cfg.variables | 9 | local vars = cfg.variables |
| 10 | 10 | ||
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index 8debaeef..c03db6a0 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua | |||
| @@ -5,7 +5,7 @@ local win32 = {} | |||
| 5 | 5 | ||
| 6 | local fs = require("luarocks.fs") | 6 | local fs = require("luarocks.fs") |
| 7 | 7 | ||
| 8 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
| 9 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
| 10 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
| 11 | 11 | ||
diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua index 4adc78d1..7f6b853e 100644 --- a/src/luarocks/fs/win32/tools.lua +++ b/src/luarocks/fs/win32/tools.lua | |||
| @@ -6,7 +6,7 @@ local tools = {} | |||
| 6 | 6 | ||
| 7 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| 8 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 9 | local cfg = require("luarocks.cfg") | 9 | local cfg = require("luarocks.core.cfg") |
| 10 | 10 | ||
| 11 | local vars = cfg.variables | 11 | local vars = cfg.variables |
| 12 | 12 | ||
diff --git a/src/luarocks/help.lua b/src/luarocks/help.lua index 5bac77ce..51e2cf57 100644 --- a/src/luarocks/help.lua +++ b/src/luarocks/help.lua | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | local help = {} | 7 | local help = {} |
| 8 | 8 | ||
| 9 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 10 | local cfg = require("luarocks.cfg") | 10 | local cfg = require("luarocks.core.cfg") |
| 11 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
| 12 | 12 | ||
| 13 | local program = util.this_program("luarocks") | 13 | local program = util.this_program("luarocks") |
diff --git a/src/luarocks/index.lua b/src/luarocks/index.lua index e1f563ef..468f5cf8 100644 --- a/src/luarocks/index.lua +++ b/src/luarocks/index.lua | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | 1 | ||
| 2 | --- Module which builds the index.html page to be used in rocks servers. | 2 | --- Module which builds the index.html page to be used in rocks servers. |
| 3 | local index = {} | 3 | local index = {} |
| 4 | package.loaded["luarocks.index"] = index | ||
| 5 | 4 | ||
| 6 | local util = require("luarocks.util") | 5 | local util = require("luarocks.util") |
| 7 | local fs = require("luarocks.fs") | 6 | local fs = require("luarocks.fs") |
diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index 10d57f37..c4139fd0 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | --- Module implementing the LuaRocks "install" command. | 1 | --- Module implementing the LuaRocks "install" command. |
| 2 | -- Installs binary rocks. | 2 | -- Installs binary rocks. |
| 3 | local install = {} | 3 | local install = {} |
| 4 | package.loaded["luarocks.install"] = install | ||
| 5 | 4 | ||
| 6 | local path = require("luarocks.path") | 5 | local path = require("luarocks.path") |
| 7 | local repos = require("luarocks.repos") | 6 | local repos = require("luarocks.repos") |
| @@ -9,9 +8,9 @@ local fetch = require("luarocks.fetch") | |||
| 9 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
| 10 | local fs = require("luarocks.fs") | 9 | local fs = require("luarocks.fs") |
| 11 | local deps = require("luarocks.deps") | 10 | local deps = require("luarocks.deps") |
| 12 | local manif = require("luarocks.manif") | 11 | local writer = require("luarocks.manif.writer") |
| 13 | local remove = require("luarocks.remove") | 12 | local remove = require("luarocks.remove") |
| 14 | local cfg = require("luarocks.cfg") | 13 | local cfg = require("luarocks.core.cfg") |
| 15 | 14 | ||
| 16 | install.help_summary = "Install a rock." | 15 | install.help_summary = "Install a rock." |
| 17 | 16 | ||
| @@ -74,7 +73,7 @@ function install.install_binary_rock(rock_file, deps_mode) | |||
| 74 | 73 | ||
| 75 | -- For compatibility with .rock files built with LuaRocks 1 | 74 | -- For compatibility with .rock files built with LuaRocks 1 |
| 76 | if not fs.exists(path.rock_manifest_file(name, version)) then | 75 | if not fs.exists(path.rock_manifest_file(name, version)) then |
| 77 | ok, err = manif.make_rock_manifest(name, version) | 76 | ok, err = writer.make_rock_manifest(name, version) |
| 78 | if err then return nil, err end | 77 | if err then return nil, err end |
| 79 | end | 78 | end |
| 80 | 79 | ||
| @@ -94,7 +93,7 @@ function install.install_binary_rock(rock_file, deps_mode) | |||
| 94 | ok, err = repos.run_hook(rockspec, "post_install") | 93 | ok, err = repos.run_hook(rockspec, "post_install") |
| 95 | if err then return nil, err end | 94 | if err then return nil, err end |
| 96 | 95 | ||
| 97 | ok, err = manif.update_manifest(name, version, nil, deps_mode) | 96 | ok, err = writer.update_manifest(name, version, nil, deps_mode) |
| 98 | if err then return nil, err end | 97 | if err then return nil, err end |
| 99 | 98 | ||
| 100 | util.announce_install(rockspec) | 99 | util.announce_install(rockspec) |
diff --git a/src/luarocks/lint.lua b/src/luarocks/lint.lua index 4c30804b..742f1736 100644 --- a/src/luarocks/lint.lua +++ b/src/luarocks/lint.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "lint" command. | 2 | --- Module implementing the LuaRocks "lint" command. |
| 3 | -- Utility function that checks syntax of the rockspec. | 3 | -- Utility function that checks syntax of the rockspec. |
| 4 | local lint = {} | 4 | local lint = {} |
| 5 | package.loaded["luarocks.lint"] = lint | ||
| 6 | 5 | ||
| 7 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 8 | local download = require("luarocks.download") | 7 | local download = require("luarocks.download") |
diff --git a/src/luarocks/list.lua b/src/luarocks/list.lua index 8c9c5107..45f1a26f 100644 --- a/src/luarocks/list.lua +++ b/src/luarocks/list.lua | |||
| @@ -2,11 +2,10 @@ | |||
| 2 | --- Module implementing the LuaRocks "list" command. | 2 | --- Module implementing the LuaRocks "list" command. |
| 3 | -- Lists currently installed rocks. | 3 | -- Lists currently installed rocks. |
| 4 | local list = {} | 4 | local list = {} |
| 5 | package.loaded["luarocks.list"] = list | ||
| 6 | 5 | ||
| 7 | local search = require("luarocks.search") | 6 | local search = require("luarocks.search") |
| 8 | local deps = require("luarocks.deps") | 7 | local deps = require("luarocks.deps") |
| 9 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
| 10 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 11 | local path = require("luarocks.path") | 10 | local path = require("luarocks.path") |
| 12 | 11 | ||
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index 26280e94..0faaebda 100644 --- a/src/luarocks/loader.lua +++ b/src/luarocks/loader.lua | |||
| @@ -6,21 +6,24 @@ | |||
| 6 | -- used to load previous modules, so that the loader chooses versions | 6 | -- used to load previous modules, so that the loader chooses versions |
| 7 | -- that are declared to be compatible with the ones loaded earlier. | 7 | -- that are declared to be compatible with the ones loaded earlier. |
| 8 | local loaders = package.loaders or package.searchers | 8 | local loaders = package.loaders or package.searchers |
| 9 | local package, require, ipairs, table, type, next, tostring, error = | 9 | local require, ipairs, table, type, next, tostring, error = |
| 10 | package, require, ipairs, table, type, next, tostring, error | 10 | require, ipairs, table, type, next, tostring, error |
| 11 | local unpack = unpack or table.unpack | 11 | local unpack = unpack or table.unpack |
| 12 | 12 | ||
| 13 | --module("luarocks.loader") | ||
| 14 | local loader = {} | 13 | local loader = {} |
| 15 | package.loaded["luarocks.loader"] = loader | ||
| 16 | 14 | ||
| 17 | local cfg = require("luarocks.cfg") | 15 | local is_clean = not package.loaded["luarocks.core.cfg"] |
| 16 | |||
| 17 | -- This loader module depends only on core modules. | ||
| 18 | local cfg = require("luarocks.core.cfg") | ||
| 18 | cfg.init_package_paths() | 19 | cfg.init_package_paths() |
| 19 | 20 | ||
| 20 | local path = require("luarocks.path") | 21 | local path = require("luarocks.core.path") |
| 21 | local manif_core = require("luarocks.manif_core") | 22 | local manif = require("luarocks.core.manif") |
| 22 | local deps = require("luarocks.deps") | 23 | local deps = require("luarocks.core.deps") |
| 23 | local util = require("luarocks.util") | 24 | local util = require("luarocks.core.util") |
| 25 | local require = nil | ||
| 26 | -------------------------------------------------------------------------------- | ||
| 24 | 27 | ||
| 25 | loader.context = {} | 28 | loader.context = {} |
| 26 | 29 | ||
| @@ -33,7 +36,7 @@ local function load_rocks_trees() | |||
| 33 | local any_ok = false | 36 | local any_ok = false |
| 34 | local trees = {} | 37 | local trees = {} |
| 35 | for _, tree in ipairs(cfg.rocks_trees) do | 38 | for _, tree in ipairs(cfg.rocks_trees) do |
| 36 | local manifest, err = manif_core.load_local_manifest(path.rocks_dir(tree)) | 39 | local manifest, err = manif.load_local_manifest(path.rocks_dir(tree)) |
| 37 | if manifest then | 40 | if manifest then |
| 38 | any_ok = true | 41 | any_ok = true |
| 39 | table.insert(trees, {tree=tree, manifest=manifest}) | 42 | table.insert(trees, {tree=tree, manifest=manifest}) |
| @@ -217,4 +220,12 @@ end | |||
| 217 | 220 | ||
| 218 | table.insert(loaders, 1, loader.luarocks_loader) | 221 | table.insert(loaders, 1, loader.luarocks_loader) |
| 219 | 222 | ||
| 223 | if is_clean then | ||
| 224 | for modname, _ in pairs(package.loaded) do | ||
| 225 | if modname:match("^luarocks%.") then | ||
| 226 | package.loaded[modname] = nil | ||
| 227 | end | ||
| 228 | end | ||
| 229 | end | ||
| 230 | |||
| 220 | return loader | 231 | return loader |
diff --git a/src/luarocks/make.lua b/src/luarocks/make.lua index 476150eb..eb38bff0 100644 --- a/src/luarocks/make.lua +++ b/src/luarocks/make.lua | |||
| @@ -4,12 +4,11 @@ | |||
| 4 | -- it does not fetch sources, etc., assuming everything is | 4 | -- it does not fetch sources, etc., assuming everything is |
| 5 | -- available in the current directory. | 5 | -- available in the current directory. |
| 6 | local make = {} | 6 | local make = {} |
| 7 | package.loaded["luarocks.make"] = make | ||
| 8 | 7 | ||
| 9 | local build = require("luarocks.build") | 8 | local build = require("luarocks.build") |
| 10 | local fs = require("luarocks.fs") | 9 | local fs = require("luarocks.fs") |
| 11 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
| 12 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.core.cfg") |
| 13 | local fetch = require("luarocks.fetch") | 12 | local fetch = require("luarocks.fetch") |
| 14 | local pack = require("luarocks.pack") | 13 | local pack = require("luarocks.pack") |
| 15 | local remove = require("luarocks.remove") | 14 | local remove = require("luarocks.remove") |
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index e30c2a33..c4da9a8e 100644 --- a/src/luarocks/manif.lua +++ b/src/luarocks/manif.lua | |||
| @@ -3,41 +3,18 @@ | |||
| 3 | -- They are loaded into manifest tables, which are then used for | 3 | -- They are loaded into manifest tables, which are then used for |
| 4 | -- performing searches, matching dependencies, etc. | 4 | -- performing searches, matching dependencies, etc. |
| 5 | local manif = {} | 5 | local manif = {} |
| 6 | package.loaded["luarocks.manif"] = manif | 6 | setmetatable(manif, { __index = require("luarocks.core.manif") }) |
| 7 | 7 | ||
| 8 | local manif_core = require("luarocks.manif_core") | ||
| 9 | local persist = require("luarocks.persist") | 8 | local persist = require("luarocks.persist") |
| 10 | local fetch = require("luarocks.fetch") | 9 | local fetch = require("luarocks.fetch") |
| 11 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| 13 | local search = require("luarocks.search") | ||
| 14 | local util = require("luarocks.util") | 12 | local util = require("luarocks.util") |
| 15 | local cfg = require("luarocks.cfg") | 13 | local cfg = require("luarocks.core.cfg") |
| 16 | local path = require("luarocks.path") | 14 | local path = require("luarocks.path") |
| 17 | local repos = require("luarocks.repos") | ||
| 18 | local deps = require("luarocks.deps") | ||
| 19 | 15 | ||
| 20 | manif.rock_manifest_cache = {} | 16 | manif.rock_manifest_cache = {} |
| 21 | 17 | ||
| 22 | --- Commit a table to disk in given local path. | ||
| 23 | -- @param where string: The directory where the table should be saved. | ||
| 24 | -- @param name string: The filename. | ||
| 25 | -- @param tbl table: The table to be saved. | ||
| 26 | -- @return boolean or (nil, string): true if successful, or nil and a | ||
| 27 | -- message in case of errors. | ||
| 28 | local function save_table(where, name, tbl) | ||
| 29 | assert(type(where) == "string") | ||
| 30 | assert(type(name) == "string") | ||
| 31 | assert(type(tbl) == "table") | ||
| 32 | |||
| 33 | local filename = dir.path(where, name) | ||
| 34 | local ok, err = persist.save_from_table(filename..".tmp", tbl) | ||
| 35 | if ok then | ||
| 36 | ok, err = fs.replace_file(filename, filename..".tmp") | ||
| 37 | end | ||
| 38 | return ok, err | ||
| 39 | end | ||
| 40 | |||
| 41 | function manif.load_rock_manifest(name, version, root) | 18 | function manif.load_rock_manifest(name, version, root) |
| 42 | assert(type(name) == "string") | 19 | assert(type(name) == "string") |
| 43 | assert(type(version) == "string") | 20 | assert(type(version) == "string") |
| @@ -53,38 +30,6 @@ function manif.load_rock_manifest(name, version, root) | |||
| 53 | return rock_manifest.rock_manifest | 30 | return rock_manifest.rock_manifest |
| 54 | end | 31 | end |
| 55 | 32 | ||
| 56 | function manif.make_rock_manifest(name, version) | ||
| 57 | local install_dir = path.install_dir(name, version) | ||
| 58 | local rock_manifest = path.rock_manifest_file(name, version) | ||
| 59 | local tree = {} | ||
| 60 | for _, file in ipairs(fs.find(install_dir)) do | ||
| 61 | local full_path = dir.path(install_dir, file) | ||
| 62 | local walk = tree | ||
| 63 | local last | ||
| 64 | local last_name | ||
| 65 | for name in file:gmatch("[^/]+") do | ||
| 66 | local next = walk[name] | ||
| 67 | if not next then | ||
| 68 | next = {} | ||
| 69 | walk[name] = next | ||
| 70 | end | ||
| 71 | last = walk | ||
| 72 | last_name = name | ||
| 73 | walk = next | ||
| 74 | end | ||
| 75 | if fs.is_file(full_path) then | ||
| 76 | local sum, err = fs.get_md5(full_path) | ||
| 77 | if not sum then | ||
| 78 | return nil, "Failed producing checksum: "..tostring(err) | ||
| 79 | end | ||
| 80 | last[last_name] = sum | ||
| 81 | end | ||
| 82 | end | ||
| 83 | rock_manifest = { rock_manifest=tree } | ||
| 84 | manif.rock_manifest_cache[name.."/"..version] = rock_manifest | ||
| 85 | save_table(install_dir, "rock_manifest", rock_manifest ) | ||
| 86 | end | ||
| 87 | |||
| 88 | local function fetch_manifest_from(repo_url, filename) | 33 | local function fetch_manifest_from(repo_url, filename) |
| 89 | local url = dir.path(repo_url, filename) | 34 | local url = dir.path(repo_url, filename) |
| 90 | local name = repo_url:gsub("[/:]","_") | 35 | local name = repo_url:gsub("[/:]","_") |
| @@ -112,7 +57,7 @@ function manif.load_manifest(repo_url, lua_version) | |||
| 112 | assert(type(lua_version) == "string" or not lua_version) | 57 | assert(type(lua_version) == "string" or not lua_version) |
| 113 | lua_version = lua_version or cfg.lua_version | 58 | lua_version = lua_version or cfg.lua_version |
| 114 | 59 | ||
| 115 | local cached_manifest = manif_core.get_cached_manifest(repo_url, lua_version) | 60 | local cached_manifest = manif.get_cached_manifest(repo_url, lua_version) |
| 116 | if cached_manifest then | 61 | if cached_manifest then |
| 117 | return cached_manifest | 62 | return cached_manifest |
| 118 | end | 63 | end |
| @@ -159,316 +104,14 @@ function manif.load_manifest(repo_url, lua_version) | |||
| 159 | end | 104 | end |
| 160 | pathname = nozip | 105 | pathname = nozip |
| 161 | end | 106 | end |
| 162 | return manif_core.manifest_loader(pathname, repo_url, lua_version) | 107 | return manif.manifest_loader(pathname, repo_url, lua_version) |
| 163 | end | ||
| 164 | |||
| 165 | --- Output a table listing items of a package. | ||
| 166 | -- @param itemsfn function: a function for obtaining items of a package. | ||
| 167 | -- pkg and version will be passed to it; it should return a table with | ||
| 168 | -- items as keys. | ||
| 169 | -- @param pkg string: package name | ||
| 170 | -- @param version string: package version | ||
| 171 | -- @param tbl table: the package matching table: keys should be item names | ||
| 172 | -- and values arrays of strings with packages names in "name/version" format. | ||
| 173 | local function store_package_items(itemsfn, pkg, version, tbl) | ||
| 174 | assert(type(itemsfn) == "function") | ||
| 175 | assert(type(pkg) == "string") | ||
| 176 | assert(type(version) == "string") | ||
| 177 | assert(type(tbl) == "table") | ||
| 178 | |||
| 179 | local pkg_version = pkg.."/"..version | ||
| 180 | local result = {} | ||
| 181 | |||
| 182 | for item, path in pairs(itemsfn(pkg, version)) do | ||
| 183 | result[item] = path | ||
| 184 | if not tbl[item] then | ||
| 185 | tbl[item] = {} | ||
| 186 | end | ||
| 187 | table.insert(tbl[item], pkg_version) | ||
| 188 | end | ||
| 189 | return result | ||
| 190 | end | ||
| 191 | |||
| 192 | --- Sort function for ordering rock identifiers in a manifest's | ||
| 193 | -- modules table. Rocks are ordered alphabetically by name, and then | ||
| 194 | -- by version which greater first. | ||
| 195 | -- @param a string: Version to compare. | ||
| 196 | -- @param b string: Version to compare. | ||
| 197 | -- @return boolean: The comparison result, according to the | ||
| 198 | -- rule outlined above. | ||
| 199 | local function sort_pkgs(a, b) | ||
| 200 | assert(type(a) == "string") | ||
| 201 | assert(type(b) == "string") | ||
| 202 | |||
| 203 | local na, va = a:match("(.*)/(.*)$") | ||
| 204 | local nb, vb = b:match("(.*)/(.*)$") | ||
| 205 | |||
| 206 | return (na == nb) and deps.compare_versions(va, vb) or na < nb | ||
| 207 | end | ||
| 208 | |||
| 209 | --- Sort items of a package matching table by version number (higher versions first). | ||
| 210 | -- @param tbl table: the package matching table: keys should be strings | ||
| 211 | -- and values arrays of strings with packages names in "name/version" format. | ||
| 212 | local function sort_package_matching_table(tbl) | ||
| 213 | assert(type(tbl) == "table") | ||
| 214 | |||
| 215 | if next(tbl) then | ||
| 216 | for item, pkgs in pairs(tbl) do | ||
| 217 | if #pkgs > 1 then | ||
| 218 | table.sort(pkgs, sort_pkgs) | ||
| 219 | -- Remove duplicates from the sorted array. | ||
| 220 | local prev = nil | ||
| 221 | local i = 1 | ||
| 222 | while pkgs[i] do | ||
| 223 | local curr = pkgs[i] | ||
| 224 | if curr == prev then | ||
| 225 | table.remove(pkgs, i) | ||
| 226 | else | ||
| 227 | prev = curr | ||
| 228 | i = i + 1 | ||
| 229 | end | ||
| 230 | end | ||
| 231 | end | ||
| 232 | end | ||
| 233 | end | ||
| 234 | end | ||
| 235 | |||
| 236 | --- Process the dependencies of a manifest table to determine its dependency | ||
| 237 | -- chains for loading modules. The manifest dependencies information is filled | ||
| 238 | -- and any dependency inconsistencies or missing dependencies are reported to | ||
| 239 | -- standard error. | ||
| 240 | -- @param manifest table: a manifest table. | ||
| 241 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 242 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 243 | -- "none" for no trees. | ||
| 244 | local function update_dependencies(manifest, deps_mode) | ||
| 245 | assert(type(manifest) == "table") | ||
| 246 | assert(type(deps_mode) == "string") | ||
| 247 | |||
| 248 | for pkg, versions in pairs(manifest.repository) do | ||
| 249 | for version, repositories in pairs(versions) do | ||
| 250 | local current = pkg.." "..version | ||
| 251 | for _, repo in ipairs(repositories) do | ||
| 252 | if repo.arch == "installed" then | ||
| 253 | local missing | ||
| 254 | repo.dependencies, missing = deps.scan_deps({}, {}, manifest, pkg, version, deps_mode) | ||
| 255 | repo.dependencies[pkg] = nil | ||
| 256 | if missing then | ||
| 257 | for miss, err in pairs(missing) do | ||
| 258 | if miss == current then | ||
| 259 | util.printerr("Tree inconsistency detected: "..current.." has no rockspec. "..err) | ||
| 260 | elseif deps_mode ~= "none" then | ||
| 261 | util.printerr("Missing dependency for "..pkg.." "..version..": "..miss) | ||
| 262 | end | ||
| 263 | end | ||
| 264 | end | ||
| 265 | end | ||
| 266 | end | ||
| 267 | end | ||
| 268 | end | ||
| 269 | end | ||
| 270 | |||
| 271 | --- Filter manifest table by Lua version, removing rockspecs whose Lua version | ||
| 272 | -- does not match. | ||
| 273 | -- @param manifest table: a manifest table. | ||
| 274 | -- @param lua_version string or nil: filter by Lua version | ||
| 275 | -- @param repodir string: directory of repository being scanned | ||
| 276 | -- @param cache table: temporary rockspec cache table | ||
| 277 | local function filter_by_lua_version(manifest, lua_version, repodir, cache) | ||
| 278 | assert(type(manifest) == "table") | ||
| 279 | assert(type(repodir) == "string") | ||
| 280 | assert((not cache) or type(cache) == "table") | ||
| 281 | |||
| 282 | cache = cache or {} | ||
| 283 | lua_version = deps.parse_version(lua_version) | ||
| 284 | for pkg, versions in pairs(manifest.repository) do | ||
| 285 | local to_remove = {} | ||
| 286 | for version, repositories in pairs(versions) do | ||
| 287 | for _, repo in ipairs(repositories) do | ||
| 288 | if repo.arch == "rockspec" then | ||
| 289 | local pathname = dir.path(repodir, pkg.."-"..version..".rockspec") | ||
| 290 | local rockspec, err = cache[pathname] | ||
| 291 | if not rockspec then | ||
| 292 | rockspec, err = fetch.load_local_rockspec(pathname, true) | ||
| 293 | end | ||
| 294 | if rockspec then | ||
| 295 | cache[pathname] = rockspec | ||
| 296 | for _, dep in ipairs(rockspec.dependencies) do | ||
| 297 | if dep.name == "lua" then | ||
| 298 | if not deps.match_constraints(lua_version, dep.constraints) then | ||
| 299 | table.insert(to_remove, version) | ||
| 300 | end | ||
| 301 | break | ||
| 302 | end | ||
| 303 | end | ||
| 304 | else | ||
| 305 | util.printerr("Error loading rockspec for "..pkg.." "..version..": "..err) | ||
| 306 | end | ||
| 307 | end | ||
| 308 | end | ||
| 309 | end | ||
| 310 | if next(to_remove) then | ||
| 311 | for _, incompat in ipairs(to_remove) do | ||
| 312 | versions[incompat] = nil | ||
| 313 | end | ||
| 314 | if not next(versions) then | ||
| 315 | manifest.repository[pkg] = nil | ||
| 316 | end | ||
| 317 | end | ||
| 318 | end | ||
| 319 | end | ||
| 320 | |||
| 321 | --- Store search results in a manifest table. | ||
| 322 | -- @param results table: The search results as returned by search.disk_search. | ||
| 323 | -- @param manifest table: A manifest table (must contain repository, modules, commands tables). | ||
| 324 | -- It will be altered to include the search results. | ||
| 325 | -- @param dep_handler: dependency handler function | ||
| 326 | -- @return boolean or (nil, string): true in case of success, or nil followed by an error message. | ||
| 327 | local function store_results(results, manifest, dep_handler) | ||
| 328 | assert(type(results) == "table") | ||
| 329 | assert(type(manifest) == "table") | ||
| 330 | assert((not dep_handler) or type(dep_handler) == "function") | ||
| 331 | |||
| 332 | for name, versions in pairs(results) do | ||
| 333 | local pkgtable = manifest.repository[name] or {} | ||
| 334 | for version, entries in pairs(versions) do | ||
| 335 | local versiontable = {} | ||
| 336 | for _, entry in ipairs(entries) do | ||
| 337 | local entrytable = {} | ||
| 338 | entrytable.arch = entry.arch | ||
| 339 | if entry.arch == "installed" then | ||
| 340 | local rock_manifest = manif.load_rock_manifest(name, version) | ||
| 341 | if not rock_manifest then | ||
| 342 | return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks 2 tree?" | ||
| 343 | end | ||
| 344 | entrytable.modules = store_package_items(repos.package_modules, name, version, manifest.modules) | ||
| 345 | entrytable.commands = store_package_items(repos.package_commands, name, version, manifest.commands) | ||
| 346 | end | ||
| 347 | table.insert(versiontable, entrytable) | ||
| 348 | end | ||
| 349 | pkgtable[version] = versiontable | ||
| 350 | end | ||
| 351 | manifest.repository[name] = pkgtable | ||
| 352 | end | ||
| 353 | if dep_handler then | ||
| 354 | dep_handler(manifest) | ||
| 355 | end | ||
| 356 | sort_package_matching_table(manifest.modules) | ||
| 357 | sort_package_matching_table(manifest.commands) | ||
| 358 | return true | ||
| 359 | end | ||
| 360 | |||
| 361 | --- Scan a LuaRocks repository and output a manifest file. | ||
| 362 | -- A file called 'manifest' will be written in the root of the given | ||
| 363 | -- repository directory. | ||
| 364 | -- @param repo A local repository directory. | ||
| 365 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 366 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 367 | -- "none" for the default dependency mode from the configuration. | ||
| 368 | -- @param versioned boolean: if versioned versions of the manifest should be created. | ||
| 369 | -- @return boolean or (nil, string): True if manifest was generated, | ||
| 370 | -- or nil and an error message. | ||
| 371 | function manif.make_manifest(repo, deps_mode, remote) | ||
| 372 | assert(type(repo) == "string") | ||
| 373 | assert(type(deps_mode) == "string") | ||
| 374 | |||
| 375 | if deps_mode == "none" then deps_mode = cfg.deps_mode end | ||
| 376 | |||
| 377 | if not fs.is_dir(repo) then | ||
| 378 | return nil, "Cannot access repository at "..repo | ||
| 379 | end | ||
| 380 | |||
| 381 | local query = search.make_query("") | ||
| 382 | query.exact_name = false | ||
| 383 | query.arch = "any" | ||
| 384 | local results = search.disk_search(repo, query) | ||
| 385 | local manifest = { repository = {}, modules = {}, commands = {} } | ||
| 386 | |||
| 387 | manif_core.cache_manifest(repo, nil, manifest) | ||
| 388 | |||
| 389 | local dep_handler = nil | ||
| 390 | if not remote then | ||
| 391 | dep_handler = function(manifest) | ||
| 392 | update_dependencies(manifest, deps_mode) | ||
| 393 | end | ||
| 394 | end | ||
| 395 | local ok, err = store_results(results, manifest, dep_handler) | ||
| 396 | if not ok then return nil, err end | ||
| 397 | |||
| 398 | if remote then | ||
| 399 | local cache = {} | ||
| 400 | for luaver in util.lua_versions() do | ||
| 401 | local vmanifest = { repository = {}, modules = {}, commands = {} } | ||
| 402 | local dep_handler = function(manifest) | ||
| 403 | filter_by_lua_version(manifest, luaver, repo, cache) | ||
| 404 | end | ||
| 405 | local ok, err = store_results(results, vmanifest, dep_handler) | ||
| 406 | save_table(repo, "manifest-"..luaver, vmanifest) | ||
| 407 | end | ||
| 408 | end | ||
| 409 | |||
| 410 | return save_table(repo, "manifest", manifest) | ||
| 411 | end | ||
| 412 | |||
| 413 | --- Load a manifest file from a local repository and add to the repository | ||
| 414 | -- information with regard to the given name and version. | ||
| 415 | -- A file called 'manifest' will be written in the root of the given | ||
| 416 | -- repository directory. | ||
| 417 | -- @param name string: Name of a package from the repository. | ||
| 418 | -- @param version string: Version of a package from the repository. | ||
| 419 | -- @param repo string or nil: Pathname of a local repository. If not given, | ||
| 420 | -- the default local repository is used. | ||
| 421 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 422 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 423 | -- "none" for using the default dependency mode from the configuration. | ||
| 424 | -- @return boolean or (nil, string): True if manifest was generated, | ||
| 425 | -- or nil and an error message. | ||
| 426 | function manif.update_manifest(name, version, repo, deps_mode) | ||
| 427 | assert(type(name) == "string") | ||
| 428 | assert(type(version) == "string") | ||
| 429 | repo = path.rocks_dir(repo or cfg.root_dir) | ||
| 430 | assert(type(deps_mode) == "string") | ||
| 431 | |||
| 432 | if deps_mode == "none" then deps_mode = cfg.deps_mode end | ||
| 433 | |||
| 434 | local manifest, err = manif.load_manifest(repo) | ||
| 435 | if not manifest then | ||
| 436 | util.printerr("No existing manifest. Attempting to rebuild...") | ||
| 437 | local ok, err = manif.make_manifest(repo, deps_mode) | ||
| 438 | if not ok then | ||
| 439 | return nil, err | ||
| 440 | end | ||
| 441 | manifest, err = manif.load_manifest(repo) | ||
| 442 | if not manifest then | ||
| 443 | return nil, err | ||
| 444 | end | ||
| 445 | end | ||
| 446 | |||
| 447 | local results = {[name] = {[version] = {{arch = "installed", repo = repo}}}} | ||
| 448 | |||
| 449 | local dep_handler = function(manifest) | ||
| 450 | update_dependencies(manifest, deps_mode) | ||
| 451 | end | ||
| 452 | local ok, err = store_results(results, manifest, dep_handler) | ||
| 453 | if not ok then return nil, err end | ||
| 454 | |||
| 455 | return save_table(repo, "manifest", manifest) | ||
| 456 | end | ||
| 457 | |||
| 458 | function manif.zip_manifests() | ||
| 459 | for ver in util.lua_versions() do | ||
| 460 | local file = "manifest-"..ver | ||
| 461 | local zip = file..".zip" | ||
| 462 | fs.delete(dir.path(fs.current_dir(), zip)) | ||
| 463 | fs.zip(zip, file) | ||
| 464 | end | ||
| 465 | end | 108 | end |
| 466 | 109 | ||
| 467 | local function find_providers(file, root) | 110 | local function find_providers(file, root) |
| 468 | assert(type(file) == "string") | 111 | assert(type(file) == "string") |
| 469 | root = root or cfg.root_dir | 112 | root = root or cfg.root_dir |
| 470 | 113 | ||
| 471 | local manifest, err = manif_core.load_local_manifest(path.rocks_dir(root)) | 114 | local manifest, err = manif.load_local_manifest(path.rocks_dir(root)) |
| 472 | if not manifest then | 115 | if not manifest then |
| 473 | return nil, "untracked" | 116 | return nil, "untracked" |
| 474 | end | 117 | end |
diff --git a/src/luarocks/manif/writer.lua b/src/luarocks/manif/writer.lua new file mode 100644 index 00000000..75ea3b81 --- /dev/null +++ b/src/luarocks/manif/writer.lua | |||
| @@ -0,0 +1,360 @@ | |||
| 1 | |||
| 2 | local writer = {} | ||
| 3 | |||
| 4 | local cfg = require("luarocks.core.cfg") | ||
| 5 | local search = require("luarocks.search") | ||
| 6 | local repos = require("luarocks.repos") | ||
| 7 | local deps = require("luarocks.deps") | ||
| 8 | local fs = require("luarocks.fs") | ||
| 9 | local util = require("luarocks.util") | ||
| 10 | local dir = require("luarocks.dir") | ||
| 11 | local fetch = require("luarocks.fetch") | ||
| 12 | local path = require("luarocks.path") | ||
| 13 | local persist = require("luarocks.persist") | ||
| 14 | local manif = require("luarocks.manif") | ||
| 15 | |||
| 16 | --- Output a table listing items of a package. | ||
| 17 | -- @param itemsfn function: a function for obtaining items of a package. | ||
| 18 | -- pkg and version will be passed to it; it should return a table with | ||
| 19 | -- items as keys. | ||
| 20 | -- @param pkg string: package name | ||
| 21 | -- @param version string: package version | ||
| 22 | -- @param tbl table: the package matching table: keys should be item names | ||
| 23 | -- and values arrays of strings with packages names in "name/version" format. | ||
| 24 | local function store_package_items(itemsfn, pkg, version, tbl) | ||
| 25 | assert(type(itemsfn) == "function") | ||
| 26 | assert(type(pkg) == "string") | ||
| 27 | assert(type(version) == "string") | ||
| 28 | assert(type(tbl) == "table") | ||
| 29 | |||
| 30 | local pkg_version = pkg.."/"..version | ||
| 31 | local result = {} | ||
| 32 | |||
| 33 | for item, path in pairs(itemsfn(pkg, version)) do | ||
| 34 | result[item] = path | ||
| 35 | if not tbl[item] then | ||
| 36 | tbl[item] = {} | ||
| 37 | end | ||
| 38 | table.insert(tbl[item], pkg_version) | ||
| 39 | end | ||
| 40 | return result | ||
| 41 | end | ||
| 42 | |||
| 43 | |||
| 44 | --- Process the dependencies of a manifest table to determine its dependency | ||
| 45 | -- chains for loading modules. The manifest dependencies information is filled | ||
| 46 | -- and any dependency inconsistencies or missing dependencies are reported to | ||
| 47 | -- standard error. | ||
| 48 | -- @param manifest table: a manifest table. | ||
| 49 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 50 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 51 | -- "none" for no trees. | ||
| 52 | local function update_dependencies(manifest, deps_mode) | ||
| 53 | assert(type(manifest) == "table") | ||
| 54 | assert(type(deps_mode) == "string") | ||
| 55 | |||
| 56 | for pkg, versions in pairs(manifest.repository) do | ||
| 57 | for version, repositories in pairs(versions) do | ||
| 58 | local current = pkg.." "..version | ||
| 59 | for _, repo in ipairs(repositories) do | ||
| 60 | if repo.arch == "installed" then | ||
| 61 | local missing | ||
| 62 | repo.dependencies, missing = deps.scan_deps({}, {}, manifest, pkg, version, deps_mode) | ||
| 63 | repo.dependencies[pkg] = nil | ||
| 64 | if missing then | ||
| 65 | for miss, err in pairs(missing) do | ||
| 66 | if miss == current then | ||
| 67 | util.printerr("Tree inconsistency detected: "..current.." has no rockspec. "..err) | ||
| 68 | elseif deps_mode ~= "none" then | ||
| 69 | util.printerr("Missing dependency for "..pkg.." "..version..": "..miss) | ||
| 70 | end | ||
| 71 | end | ||
| 72 | end | ||
| 73 | end | ||
| 74 | end | ||
| 75 | end | ||
| 76 | end | ||
| 77 | end | ||
| 78 | |||
| 79 | --- Sort function for ordering rock identifiers in a manifest's | ||
| 80 | -- modules table. Rocks are ordered alphabetically by name, and then | ||
| 81 | -- by version which greater first. | ||
| 82 | -- @param a string: Version to compare. | ||
| 83 | -- @param b string: Version to compare. | ||
| 84 | -- @return boolean: The comparison result, according to the | ||
| 85 | -- rule outlined above. | ||
| 86 | local function sort_pkgs(a, b) | ||
| 87 | assert(type(a) == "string") | ||
| 88 | assert(type(b) == "string") | ||
| 89 | |||
| 90 | local na, va = a:match("(.*)/(.*)$") | ||
| 91 | local nb, vb = b:match("(.*)/(.*)$") | ||
| 92 | |||
| 93 | return (na == nb) and deps.compare_versions(va, vb) or na < nb | ||
| 94 | end | ||
| 95 | |||
| 96 | --- Sort items of a package matching table by version number (higher versions first). | ||
| 97 | -- @param tbl table: the package matching table: keys should be strings | ||
| 98 | -- and values arrays of strings with packages names in "name/version" format. | ||
| 99 | local function sort_package_matching_table(tbl) | ||
| 100 | assert(type(tbl) == "table") | ||
| 101 | |||
| 102 | if next(tbl) then | ||
| 103 | for item, pkgs in pairs(tbl) do | ||
| 104 | if #pkgs > 1 then | ||
| 105 | table.sort(pkgs, sort_pkgs) | ||
| 106 | -- Remove duplicates from the sorted array. | ||
| 107 | local prev = nil | ||
| 108 | local i = 1 | ||
| 109 | while pkgs[i] do | ||
| 110 | local curr = pkgs[i] | ||
| 111 | if curr == prev then | ||
| 112 | table.remove(pkgs, i) | ||
| 113 | else | ||
| 114 | prev = curr | ||
| 115 | i = i + 1 | ||
| 116 | end | ||
| 117 | end | ||
| 118 | end | ||
| 119 | end | ||
| 120 | end | ||
| 121 | end | ||
| 122 | |||
| 123 | --- Filter manifest table by Lua version, removing rockspecs whose Lua version | ||
| 124 | -- does not match. | ||
| 125 | -- @param manifest table: a manifest table. | ||
| 126 | -- @param lua_version string or nil: filter by Lua version | ||
| 127 | -- @param repodir string: directory of repository being scanned | ||
| 128 | -- @param cache table: temporary rockspec cache table | ||
| 129 | local function filter_by_lua_version(manifest, lua_version, repodir, cache) | ||
| 130 | assert(type(manifest) == "table") | ||
| 131 | assert(type(repodir) == "string") | ||
| 132 | assert((not cache) or type(cache) == "table") | ||
| 133 | |||
| 134 | cache = cache or {} | ||
| 135 | lua_version = deps.parse_version(lua_version) | ||
| 136 | for pkg, versions in pairs(manifest.repository) do | ||
| 137 | local to_remove = {} | ||
| 138 | for version, repositories in pairs(versions) do | ||
| 139 | for _, repo in ipairs(repositories) do | ||
| 140 | if repo.arch == "rockspec" then | ||
| 141 | local pathname = dir.path(repodir, pkg.."-"..version..".rockspec") | ||
| 142 | local rockspec, err = cache[pathname] | ||
| 143 | if not rockspec then | ||
| 144 | rockspec, err = fetch.load_local_rockspec(pathname, true) | ||
| 145 | end | ||
| 146 | if rockspec then | ||
| 147 | cache[pathname] = rockspec | ||
| 148 | for _, dep in ipairs(rockspec.dependencies) do | ||
| 149 | if dep.name == "lua" then | ||
| 150 | if not deps.match_constraints(lua_version, dep.constraints) then | ||
| 151 | table.insert(to_remove, version) | ||
| 152 | end | ||
| 153 | break | ||
| 154 | end | ||
| 155 | end | ||
| 156 | else | ||
| 157 | util.printerr("Error loading rockspec for "..pkg.." "..version..": "..err) | ||
| 158 | end | ||
| 159 | end | ||
| 160 | end | ||
| 161 | end | ||
| 162 | if next(to_remove) then | ||
| 163 | for _, incompat in ipairs(to_remove) do | ||
| 164 | versions[incompat] = nil | ||
| 165 | end | ||
| 166 | if not next(versions) then | ||
| 167 | manifest.repository[pkg] = nil | ||
| 168 | end | ||
| 169 | end | ||
| 170 | end | ||
| 171 | end | ||
| 172 | |||
| 173 | --- Store search results in a manifest table. | ||
| 174 | -- @param results table: The search results as returned by search.disk_search. | ||
| 175 | -- @param manifest table: A manifest table (must contain repository, modules, commands tables). | ||
| 176 | -- It will be altered to include the search results. | ||
| 177 | -- @param dep_handler: dependency handler function | ||
| 178 | -- @return boolean or (nil, string): true in case of success, or nil followed by an error message. | ||
| 179 | local function store_results(results, manifest, dep_handler) | ||
| 180 | assert(type(results) == "table") | ||
| 181 | assert(type(manifest) == "table") | ||
| 182 | assert((not dep_handler) or type(dep_handler) == "function") | ||
| 183 | |||
| 184 | for name, versions in pairs(results) do | ||
| 185 | local pkgtable = manifest.repository[name] or {} | ||
| 186 | for version, entries in pairs(versions) do | ||
| 187 | local versiontable = {} | ||
| 188 | for _, entry in ipairs(entries) do | ||
| 189 | local entrytable = {} | ||
| 190 | entrytable.arch = entry.arch | ||
| 191 | if entry.arch == "installed" then | ||
| 192 | local rock_manifest = manif.load_rock_manifest(name, version) | ||
| 193 | if not rock_manifest then | ||
| 194 | return nil, "rock_manifest file not found for "..name.." "..version.." - not a LuaRocks 2 tree?" | ||
| 195 | end | ||
| 196 | entrytable.modules = store_package_items(repos.package_modules, name, version, manifest.modules) | ||
| 197 | entrytable.commands = store_package_items(repos.package_commands, name, version, manifest.commands) | ||
| 198 | end | ||
| 199 | table.insert(versiontable, entrytable) | ||
| 200 | end | ||
| 201 | pkgtable[version] = versiontable | ||
| 202 | end | ||
| 203 | manifest.repository[name] = pkgtable | ||
| 204 | end | ||
| 205 | if dep_handler then | ||
| 206 | dep_handler(manifest) | ||
| 207 | end | ||
| 208 | sort_package_matching_table(manifest.modules) | ||
| 209 | sort_package_matching_table(manifest.commands) | ||
| 210 | return true | ||
| 211 | end | ||
| 212 | |||
| 213 | --- Commit a table to disk in given local path. | ||
| 214 | -- @param where string: The directory where the table should be saved. | ||
| 215 | -- @param name string: The filename. | ||
| 216 | -- @param tbl table: The table to be saved. | ||
| 217 | -- @return boolean or (nil, string): true if successful, or nil and a | ||
| 218 | -- message in case of errors. | ||
| 219 | local function save_table(where, name, tbl) | ||
| 220 | assert(type(where) == "string") | ||
| 221 | assert(type(name) == "string") | ||
| 222 | assert(type(tbl) == "table") | ||
| 223 | |||
| 224 | local filename = dir.path(where, name) | ||
| 225 | local ok, err = persist.save_from_table(filename..".tmp", tbl) | ||
| 226 | if ok then | ||
| 227 | ok, err = fs.replace_file(filename, filename..".tmp") | ||
| 228 | end | ||
| 229 | return ok, err | ||
| 230 | end | ||
| 231 | |||
| 232 | function writer.make_rock_manifest(name, version) | ||
| 233 | local install_dir = path.install_dir(name, version) | ||
| 234 | local tree = {} | ||
| 235 | for _, file in ipairs(fs.find(install_dir)) do | ||
| 236 | local full_path = dir.path(install_dir, file) | ||
| 237 | local walk = tree | ||
| 238 | local last | ||
| 239 | local last_name | ||
| 240 | for filename in file:gmatch("[^/]+") do | ||
| 241 | local next = walk[filename] | ||
| 242 | if not next then | ||
| 243 | next = {} | ||
| 244 | walk[filename] = next | ||
| 245 | end | ||
| 246 | last = walk | ||
| 247 | last_name = filename | ||
| 248 | walk = next | ||
| 249 | end | ||
| 250 | if fs.is_file(full_path) then | ||
| 251 | local sum, err = fs.get_md5(full_path) | ||
| 252 | if not sum then | ||
| 253 | return nil, "Failed producing checksum: "..tostring(err) | ||
| 254 | end | ||
| 255 | last[last_name] = sum | ||
| 256 | end | ||
| 257 | end | ||
| 258 | local rock_manifest = { rock_manifest=tree } | ||
| 259 | manif.rock_manifest_cache[name.."/"..version] = rock_manifest | ||
| 260 | save_table(install_dir, "rock_manifest", rock_manifest ) | ||
| 261 | end | ||
| 262 | |||
| 263 | --- Scan a LuaRocks repository and output a manifest file. | ||
| 264 | -- A file called 'manifest' will be written in the root of the given | ||
| 265 | -- repository directory. | ||
| 266 | -- @param repo A local repository directory. | ||
| 267 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 268 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 269 | -- "none" for the default dependency mode from the configuration. | ||
| 270 | -- @param versioned boolean: if versioned versions of the manifest should be created. | ||
| 271 | -- @return boolean or (nil, string): True if manifest was generated, | ||
| 272 | -- or nil and an error message. | ||
| 273 | function writer.make_manifest(repo, deps_mode, remote) | ||
| 274 | assert(type(repo) == "string") | ||
| 275 | assert(type(deps_mode) == "string") | ||
| 276 | |||
| 277 | if deps_mode == "none" then deps_mode = cfg.deps_mode end | ||
| 278 | |||
| 279 | if not fs.is_dir(repo) then | ||
| 280 | return nil, "Cannot access repository at "..repo | ||
| 281 | end | ||
| 282 | |||
| 283 | local query = search.make_query("") | ||
| 284 | query.exact_name = false | ||
| 285 | query.arch = "any" | ||
| 286 | local results = search.disk_search(repo, query) | ||
| 287 | local manifest = { repository = {}, modules = {}, commands = {} } | ||
| 288 | |||
| 289 | manif.cache_manifest(repo, nil, manifest) | ||
| 290 | |||
| 291 | local dep_handler = nil | ||
| 292 | if not remote then | ||
| 293 | dep_handler = function(manifest) | ||
| 294 | update_dependencies(manifest, deps_mode) | ||
| 295 | end | ||
| 296 | end | ||
| 297 | local ok, err = store_results(results, manifest, dep_handler) | ||
| 298 | if not ok then return nil, err end | ||
| 299 | |||
| 300 | if remote then | ||
| 301 | local cache = {} | ||
| 302 | for luaver in util.lua_versions() do | ||
| 303 | local vmanifest = { repository = {}, modules = {}, commands = {} } | ||
| 304 | local dep_handler = function(manifest) | ||
| 305 | filter_by_lua_version(manifest, luaver, repo, cache) | ||
| 306 | end | ||
| 307 | store_results(results, vmanifest, dep_handler) | ||
| 308 | save_table(repo, "manifest-"..luaver, vmanifest) | ||
| 309 | end | ||
| 310 | end | ||
| 311 | |||
| 312 | return save_table(repo, "manifest", manifest) | ||
| 313 | end | ||
| 314 | |||
| 315 | --- Load a manifest file from a local repository and add to the repository | ||
| 316 | -- information with regard to the given name and version. | ||
| 317 | -- A file called 'manifest' will be written in the root of the given | ||
| 318 | -- repository directory. | ||
| 319 | -- @param name string: Name of a package from the repository. | ||
| 320 | -- @param version string: Version of a package from the repository. | ||
| 321 | -- @param repo string or nil: Pathname of a local repository. If not given, | ||
| 322 | -- the default local repository is used. | ||
| 323 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 324 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 325 | -- "none" for using the default dependency mode from the configuration. | ||
| 326 | -- @return boolean or (nil, string): True if manifest was generated, | ||
| 327 | -- or nil and an error message. | ||
| 328 | function writer.update_manifest(name, version, repo, deps_mode) | ||
| 329 | assert(type(name) == "string") | ||
| 330 | assert(type(version) == "string") | ||
| 331 | repo = path.rocks_dir(repo or cfg.root_dir) | ||
| 332 | assert(type(deps_mode) == "string") | ||
| 333 | |||
| 334 | if deps_mode == "none" then deps_mode = cfg.deps_mode end | ||
| 335 | |||
| 336 | local manifest, err = manif.load_manifest(repo) | ||
| 337 | if not manifest then | ||
| 338 | util.printerr("No existing manifest. Attempting to rebuild...") | ||
| 339 | local ok, err = writer.make_manifest(repo, deps_mode) | ||
| 340 | if not ok then | ||
| 341 | return nil, err | ||
| 342 | end | ||
| 343 | manifest, err = manif.load_manifest(repo) | ||
| 344 | if not manifest then | ||
| 345 | return nil, err | ||
| 346 | end | ||
| 347 | end | ||
| 348 | |||
| 349 | local results = {[name] = {[version] = {{arch = "installed", repo = repo}}}} | ||
| 350 | |||
| 351 | local dep_handler = function(manifest) | ||
| 352 | update_dependencies(manifest, deps_mode) | ||
| 353 | end | ||
| 354 | local ok, err = store_results(results, manifest, dep_handler) | ||
| 355 | if not ok then return nil, err end | ||
| 356 | |||
| 357 | return save_table(repo, "manifest", manifest) | ||
| 358 | end | ||
| 359 | |||
| 360 | return writer | ||
diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua index 3a163e92..b85653e9 100644 --- a/src/luarocks/pack.lua +++ b/src/luarocks/pack.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "pack" command. | 2 | --- Module implementing the LuaRocks "pack" command. |
| 3 | -- Creates a rock, packing sources or binaries. | 3 | -- Creates a rock, packing sources or binaries. |
| 4 | local pack = {} | 4 | local pack = {} |
| 5 | package.loaded["luarocks.pack"] = pack | ||
| 6 | 5 | ||
| 7 | local unpack = unpack or table.unpack | 6 | local unpack = unpack or table.unpack |
| 8 | 7 | ||
| @@ -10,7 +9,7 @@ local path = require("luarocks.path") | |||
| 10 | local repos = require("luarocks.repos") | 9 | local repos = require("luarocks.repos") |
| 11 | local fetch = require("luarocks.fetch") | 10 | local fetch = require("luarocks.fetch") |
| 12 | local fs = require("luarocks.fs") | 11 | local fs = require("luarocks.fs") |
| 13 | local cfg = require("luarocks.cfg") | 12 | local cfg = require("luarocks.core.cfg") |
| 14 | local util = require("luarocks.util") | 13 | local util = require("luarocks.util") |
| 15 | local dir = require("luarocks.dir") | 14 | local dir = require("luarocks.dir") |
| 16 | local manif = require("luarocks.manif") | 15 | local manif = require("luarocks.manif") |
diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua index 6219d8c6..83e9c295 100644 --- a/src/luarocks/path.lua +++ b/src/luarocks/path.lua | |||
| @@ -3,9 +3,10 @@ | |||
| 3 | -- All paths are configured in this module, making it a single | 3 | -- All paths are configured in this module, making it a single |
| 4 | -- point where the layout of the local installation is defined in LuaRocks. | 4 | -- point where the layout of the local installation is defined in LuaRocks. |
| 5 | local path = {} | 5 | local path = {} |
| 6 | setmetatable(path, { __index = require("luarocks.core.path") }) | ||
| 6 | 7 | ||
| 7 | local dir = require("luarocks.dir") | 8 | local dir = require("luarocks.dir") |
| 8 | local cfg = require("luarocks.cfg") | 9 | local cfg = require("luarocks.core.cfg") |
| 9 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
| 10 | 11 | ||
| 11 | --- Infer rockspec filename from a rock filename. | 12 | --- Infer rockspec filename from a rock filename. |
| @@ -17,29 +18,11 @@ function path.rockspec_name_from_rock(rock_name) | |||
| 17 | return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec" | 18 | return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec" |
| 18 | end | 19 | end |
| 19 | 20 | ||
| 20 | function path.rocks_dir(tree) | ||
| 21 | if type(tree) == "string" then | ||
| 22 | return dir.path(tree, cfg.rocks_subdir) | ||
| 23 | else | ||
| 24 | assert(type(tree) == "table") | ||
| 25 | return tree.rocks_dir or dir.path(tree.root, cfg.rocks_subdir) | ||
| 26 | end | ||
| 27 | end | ||
| 28 | |||
| 29 | function path.root_dir(rocks_dir) | 21 | function path.root_dir(rocks_dir) |
| 30 | assert(type(rocks_dir) == "string") | 22 | assert(type(rocks_dir) == "string") |
| 31 | return rocks_dir:match("(.*)" .. util.matchquote(cfg.rocks_subdir) .. ".*$") | 23 | return rocks_dir:match("(.*)" .. util.matchquote(cfg.rocks_subdir) .. ".*$") |
| 32 | end | 24 | end |
| 33 | 25 | ||
| 34 | function path.rocks_tree_to_string(tree) | ||
| 35 | if type(tree) == "string" then | ||
| 36 | return tree | ||
| 37 | else | ||
| 38 | assert(type(tree) == "table") | ||
| 39 | return tree.root | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | function path.deploy_bin_dir(tree) | 26 | function path.deploy_bin_dir(tree) |
| 44 | if type(tree) == "string" then | 27 | if type(tree) == "string" then |
| 45 | return dir.path(tree, "bin") | 28 | return dir.path(tree, "bin") |
| @@ -49,24 +32,6 @@ function path.deploy_bin_dir(tree) | |||
| 49 | end | 32 | end |
| 50 | end | 33 | end |
| 51 | 34 | ||
| 52 | function path.deploy_lua_dir(tree) | ||
| 53 | if type(tree) == "string" then | ||
| 54 | return dir.path(tree, cfg.lua_modules_path) | ||
| 55 | else | ||
| 56 | assert(type(tree) == "table") | ||
| 57 | return tree.lua_dir or dir.path(tree.root, cfg.lua_modules_path) | ||
| 58 | end | ||
| 59 | end | ||
| 60 | |||
| 61 | function path.deploy_lib_dir(tree) | ||
| 62 | if type(tree) == "string" then | ||
| 63 | return dir.path(tree, cfg.lib_modules_path) | ||
| 64 | else | ||
| 65 | assert(type(tree) == "table") | ||
| 66 | return tree.lib_dir or dir.path(tree.root, cfg.lib_modules_path) | ||
| 67 | end | ||
| 68 | end | ||
| 69 | |||
| 70 | function path.manifest_file(tree) | 35 | function path.manifest_file(tree) |
| 71 | if type(tree) == "string" then | 36 | if type(tree) == "string" then |
| 72 | return dir.path(tree, cfg.rocks_subdir, "manifest") | 37 | return dir.path(tree, cfg.rocks_subdir, "manifest") |
| @@ -229,39 +194,6 @@ function path.make_url(pathname, name, version, arch) | |||
| 229 | return dir.path(pathname, filename) | 194 | return dir.path(pathname, filename) |
| 230 | end | 195 | end |
| 231 | 196 | ||
| 232 | --- Convert a pathname to a module identifier. | ||
| 233 | -- In Unix, for example, a path "foo/bar/baz.lua" is converted to | ||
| 234 | -- "foo.bar.baz"; "bla/init.lua" returns "bla"; "foo.so" returns "foo". | ||
| 235 | -- @param file string: Pathname of module | ||
| 236 | -- @return string: The module identifier, or nil if given path is | ||
| 237 | -- not a conformant module path (the function does not check if the | ||
| 238 | -- path actually exists). | ||
| 239 | function path.path_to_module(file) | ||
| 240 | assert(type(file) == "string") | ||
| 241 | |||
| 242 | local name = file:match("(.*)%."..cfg.lua_extension.."$") | ||
| 243 | if name then | ||
| 244 | name = name:gsub(dir.separator, ".") | ||
| 245 | local init = name:match("(.*)%.init$") | ||
| 246 | if init then | ||
| 247 | name = init | ||
| 248 | end | ||
| 249 | else | ||
| 250 | name = file:match("(.*)%."..cfg.lib_extension.."$") | ||
| 251 | if name then | ||
| 252 | name = name:gsub(dir.separator, ".") | ||
| 253 | else | ||
| 254 | name = file:match("(.*)%."..cfg.static_lib_extension.."$") | ||
| 255 | if name then | ||
| 256 | name = name:gsub(dir.separator, ".") | ||
| 257 | end | ||
| 258 | end | ||
| 259 | end | ||
| 260 | if not name then name = file end | ||
| 261 | name = name:gsub("^%.+", ""):gsub("%.+$", "") | ||
| 262 | return name | ||
| 263 | end | ||
| 264 | |||
| 265 | --- Obtain the directory name where a module should be stored. | 197 | --- Obtain the directory name where a module should be stored. |
| 266 | -- For example, on Unix, "foo.bar.baz" will return "foo/bar". | 198 | -- For example, on Unix, "foo.bar.baz" will return "foo/bar". |
| 267 | -- @param mod string: A module name in Lua dot-separated format. | 199 | -- @param mod string: A module name in Lua dot-separated format. |
| @@ -291,22 +223,6 @@ function path.configure_paths(rockspec) | |||
| 291 | rockspec.variables = vars | 223 | rockspec.variables = vars |
| 292 | end | 224 | end |
| 293 | 225 | ||
| 294 | --- Produce a versioned version of a filename. | ||
| 295 | -- @param file string: filename (must start with prefix) | ||
| 296 | -- @param prefix string: Path prefix for file | ||
| 297 | -- @param name string: Rock name | ||
| 298 | -- @param version string: Rock version | ||
| 299 | -- @return string: a pathname with the same directory parts and a versioned basename. | ||
| 300 | function path.versioned_name(file, prefix, name, version) | ||
| 301 | assert(type(file) == "string") | ||
| 302 | assert(type(name) == "string") | ||
| 303 | assert(type(version) == "string") | ||
| 304 | |||
| 305 | local rest = file:sub(#prefix+1):gsub("^/*", "") | ||
| 306 | local name_version = (name.."_"..version):gsub("%-", "_"):gsub("%.", "_") | ||
| 307 | return dir.path(prefix, name_version.."-"..rest) | ||
| 308 | end | ||
| 309 | |||
| 310 | function path.use_tree(tree) | 226 | function path.use_tree(tree) |
| 311 | cfg.root_dir = tree | 227 | cfg.root_dir = tree |
| 312 | cfg.rocks_dir = path.rocks_dir(tree) | 228 | cfg.rocks_dir = path.rocks_dir(tree) |
| @@ -315,60 +231,6 @@ function path.use_tree(tree) | |||
| 315 | cfg.deploy_lib_dir = path.deploy_lib_dir(tree) | 231 | cfg.deploy_lib_dir = path.deploy_lib_dir(tree) |
| 316 | end | 232 | end |
| 317 | 233 | ||
| 318 | --- Apply a given function to the active rocks trees based on chosen dependency mode. | ||
| 319 | -- @param deps_mode string: Dependency mode: "one" for the current default tree, | ||
| 320 | -- "all" for all trees, "order" for all trees with priority >= the current default, | ||
| 321 | -- "none" for no trees (this function becomes a nop). | ||
| 322 | -- @param fn function: function to be applied, with the tree dir (string) as the first | ||
| 323 | -- argument and the remaining varargs of map_trees as the following arguments. | ||
| 324 | -- @return a table with all results of invocations of fn collected. | ||
| 325 | function path.map_trees(deps_mode, fn, ...) | ||
| 326 | local result = {} | ||
| 327 | if deps_mode == "one" then | ||
| 328 | table.insert(result, (fn(cfg.root_dir, ...)) or 0) | ||
| 329 | elseif deps_mode == "all" or deps_mode == "order" then | ||
| 330 | local use = false | ||
| 331 | if deps_mode == "all" then | ||
| 332 | use = true | ||
| 333 | end | ||
| 334 | for _, tree in ipairs(cfg.rocks_trees) do | ||
| 335 | if dir.normalize(path.rocks_tree_to_string(tree)) == dir.normalize(path.rocks_tree_to_string(cfg.root_dir)) then | ||
| 336 | use = true | ||
| 337 | end | ||
| 338 | if use then | ||
| 339 | table.insert(result, (fn(tree, ...)) or 0) | ||
| 340 | end | ||
| 341 | end | ||
| 342 | end | ||
| 343 | return result | ||
| 344 | end | ||
| 345 | |||
| 346 | local is_src_extension = { [".lua"] = true, [".tl"] = true, [".tld"] = true, [".moon"] = true } | ||
| 347 | |||
| 348 | --- Return the pathname of the file that would be loaded for a module, indexed. | ||
| 349 | -- @param file_name string: module file name as in manifest (eg. "socket/core.so") | ||
| 350 | -- @param name string: name of the package (eg. "luasocket") | ||
| 351 | -- @param version string: version number (eg. "2.0.2-1") | ||
| 352 | -- @param tree string: repository path (eg. "/usr/local") | ||
| 353 | -- @param i number: the index, 1 if version is the current default, > 1 otherwise. | ||
| 354 | -- This is done this way for use by select_module in luarocks.loader. | ||
| 355 | -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so") | ||
| 356 | function path.which_i(file_name, name, version, tree, i) | ||
| 357 | local deploy_dir | ||
| 358 | local extension = file_name:match("%.[a-z]+$") | ||
| 359 | if is_src_extension[extension] then | ||
| 360 | deploy_dir = path.deploy_lua_dir(tree) | ||
| 361 | file_name = dir.path(deploy_dir, file_name) | ||
| 362 | else | ||
| 363 | deploy_dir = path.deploy_lib_dir(tree) | ||
| 364 | file_name = dir.path(deploy_dir, file_name) | ||
| 365 | end | ||
| 366 | if i > 1 then | ||
| 367 | file_name = path.versioned_name(file_name, deploy_dir, name, version) | ||
| 368 | end | ||
| 369 | return file_name | ||
| 370 | end | ||
| 371 | |||
| 372 | --- Return the pathname of the file that would be loaded for a module, | 234 | --- Return the pathname of the file that would be loaded for a module, |
| 373 | -- returning the versioned pathname if given version is not the default version | 235 | -- returning the versioned pathname if given version is not the default version |
| 374 | -- in the given manifest. | 236 | -- in the given manifest. |
diff --git a/src/luarocks/path_cmd.lua b/src/luarocks/path_cmd.lua index c0329977..1f5bb07f 100644 --- a/src/luarocks/path_cmd.lua +++ b/src/luarocks/path_cmd.lua | |||
| @@ -5,7 +5,7 @@ local path_cmd = {} | |||
| 5 | 5 | ||
| 6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 7 | local deps = require("luarocks.deps") | 7 | local deps = require("luarocks.deps") |
| 8 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.core.cfg") |
| 9 | 9 | ||
| 10 | path_cmd.help_summary = "Return the currently configured package path." | 10 | path_cmd.help_summary = "Return the currently configured package path." |
| 11 | path_cmd.help_arguments = "" | 11 | path_cmd.help_arguments = "" |
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index c2adb570..16ff5065 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua | |||
| @@ -4,83 +4,10 @@ | |||
| 4 | -- Implemented separately to avoid interdependencies, | 4 | -- Implemented separately to avoid interdependencies, |
| 5 | -- as it is used in the bootstrapping stage of the cfg module. | 5 | -- as it is used in the bootstrapping stage of the cfg module. |
| 6 | local persist = {} | 6 | local persist = {} |
| 7 | package.loaded["luarocks.persist"] = persist | 7 | setmetatable(persist, { __index = require("luarocks.core.persist") }) |
| 8 | 8 | ||
| 9 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
| 10 | 10 | ||
| 11 | --- Load and run a Lua file in an environment. | ||
| 12 | -- @param filename string: the name of the file. | ||
| 13 | -- @param env table: the environment table. | ||
| 14 | -- @return (true, any) or (nil, string, string): true and the return value | ||
| 15 | -- of the file, or nil, an error message and an error code ("open", "load" | ||
| 16 | -- or "run") in case of errors. | ||
| 17 | local function run_file(filename, env) | ||
| 18 | local fd, err = io.open(filename) | ||
| 19 | if not fd then | ||
| 20 | return nil, err, "open" | ||
| 21 | end | ||
| 22 | local str, err = fd:read("*a") | ||
| 23 | fd:close() | ||
| 24 | if not str then | ||
| 25 | return nil, err, "open" | ||
| 26 | end | ||
| 27 | str = str:gsub("^#![^\n]*\n", "") | ||
| 28 | local chunk, ran | ||
| 29 | if _VERSION == "Lua 5.1" then -- Lua 5.1 | ||
| 30 | chunk, err = loadstring(str, filename) | ||
| 31 | if chunk then | ||
| 32 | setfenv(chunk, env) | ||
| 33 | ran, err = pcall(chunk) | ||
| 34 | end | ||
| 35 | else -- Lua 5.2 | ||
| 36 | chunk, err = load(str, filename, "t", env) | ||
| 37 | if chunk then | ||
| 38 | ran, err = pcall(chunk) | ||
| 39 | end | ||
| 40 | end | ||
| 41 | if not chunk then | ||
| 42 | return nil, "Error loading file: "..err, "load" | ||
| 43 | end | ||
| 44 | if not ran then | ||
| 45 | return nil, "Error running file: "..err, "run" | ||
| 46 | end | ||
| 47 | return true, err | ||
| 48 | end | ||
| 49 | |||
| 50 | --- Load a Lua file containing assignments, storing them in a table. | ||
| 51 | -- The global environment is not propagated to the loaded file. | ||
| 52 | -- @param filename string: the name of the file. | ||
| 53 | -- @param tbl table or nil: if given, this table is used to store | ||
| 54 | -- loaded values. | ||
| 55 | -- @return (table, table) or (nil, string, string): a table with the file's assignments | ||
| 56 | -- as fields and set of undefined globals accessed in file, | ||
| 57 | -- or nil, an error message and an error code ("open"; couldn't open the file, | ||
| 58 | -- "load"; compile-time error, or "run"; run-time error) | ||
| 59 | -- in case of errors. | ||
| 60 | function persist.load_into_table(filename, tbl) | ||
| 61 | assert(type(filename) == "string") | ||
| 62 | assert(type(tbl) == "table" or not tbl) | ||
| 63 | |||
| 64 | local result = tbl or {} | ||
| 65 | local globals = {} | ||
| 66 | local globals_mt = { | ||
| 67 | __index = function(t, k) | ||
| 68 | globals[k] = true | ||
| 69 | end | ||
| 70 | } | ||
| 71 | local save_mt = getmetatable(result) | ||
| 72 | setmetatable(result, globals_mt) | ||
| 73 | |||
| 74 | local ok, err, errcode = run_file(filename, result) | ||
| 75 | |||
| 76 | setmetatable(result, save_mt) | ||
| 77 | |||
| 78 | if not ok then | ||
| 79 | return nil, err, errcode | ||
| 80 | end | ||
| 81 | return result, globals | ||
| 82 | end | ||
| 83 | |||
| 84 | local write_table | 11 | local write_table |
| 85 | 12 | ||
| 86 | --- Write a value as Lua code. | 13 | --- Write a value as Lua code. |
diff --git a/src/luarocks/purge.lua b/src/luarocks/purge.lua index 18043cc3..7647a243 100644 --- a/src/luarocks/purge.lua +++ b/src/luarocks/purge.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "purge" command. | 2 | --- Module implementing the LuaRocks "purge" command. |
| 3 | -- Remove all rocks from a given tree. | 3 | -- Remove all rocks from a given tree. |
| 4 | local purge = {} | 4 | local purge = {} |
| 5 | package.loaded["luarocks.purge"] = purge | ||
| 6 | 5 | ||
| 7 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 8 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| @@ -10,8 +9,8 @@ local path = require("luarocks.path") | |||
| 10 | local search = require("luarocks.search") | 9 | local search = require("luarocks.search") |
| 11 | local deps = require("luarocks.deps") | 10 | local deps = require("luarocks.deps") |
| 12 | local repos = require("luarocks.repos") | 11 | local repos = require("luarocks.repos") |
| 13 | local manif = require("luarocks.manif") | 12 | local writer = require("luarocks.manif.writer") |
| 14 | local cfg = require("luarocks.cfg") | 13 | local cfg = require("luarocks.core.cfg") |
| 15 | local remove = require("luarocks.remove") | 14 | local remove = require("luarocks.remove") |
| 16 | 15 | ||
| 17 | purge.help_summary = "Remove all installed rocks from a tree." | 16 | purge.help_summary = "Remove all installed rocks from a tree." |
| @@ -55,7 +54,7 @@ function purge.command(flags) | |||
| 55 | end | 54 | end |
| 56 | 55 | ||
| 57 | for package, versions in util.sortedpairs(results) do | 56 | for package, versions in util.sortedpairs(results) do |
| 58 | for version, repositories in util.sortedpairs(versions, sort) do | 57 | for version, _ in util.sortedpairs(versions, sort) do |
| 59 | if flags["old-versions"] then | 58 | if flags["old-versions"] then |
| 60 | util.printout("Keeping "..package.." "..version.."...") | 59 | util.printout("Keeping "..package.." "..version.."...") |
| 61 | local ok, err = remove.remove_other_versions(package, version, flags["force"], flags["force-fast"]) | 60 | local ok, err = remove.remove_other_versions(package, version, flags["force"], flags["force-fast"]) |
| @@ -72,7 +71,7 @@ function purge.command(flags) | |||
| 72 | end | 71 | end |
| 73 | end | 72 | end |
| 74 | end | 73 | end |
| 75 | return manif.make_manifest(cfg.rocks_dir, "one") | 74 | return writer.make_manifest(cfg.rocks_dir, "one") |
| 76 | end | 75 | end |
| 77 | 76 | ||
| 78 | return purge | 77 | return purge |
diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua index 3f62e89e..e2c05176 100644 --- a/src/luarocks/remove.lua +++ b/src/luarocks/remove.lua | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | --- Module implementing the LuaRocks "remove" command. | 2 | --- Module implementing the LuaRocks "remove" command. |
| 3 | -- Uninstalls rocks. | 3 | -- Uninstalls rocks. |
| 4 | local remove = {} | 4 | local remove = {} |
| 5 | package.loaded["luarocks.remove"] = remove | ||
| 6 | 5 | ||
| 7 | local search = require("luarocks.search") | 6 | local search = require("luarocks.search") |
| 8 | local deps = require("luarocks.deps") | 7 | local deps = require("luarocks.deps") |
| @@ -10,8 +9,8 @@ local fetch = require("luarocks.fetch") | |||
| 10 | local repos = require("luarocks.repos") | 9 | local repos = require("luarocks.repos") |
| 11 | local path = require("luarocks.path") | 10 | local path = require("luarocks.path") |
| 12 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
| 13 | local cfg = require("luarocks.cfg") | 12 | local cfg = require("luarocks.core.cfg") |
| 14 | local manif = require("luarocks.manif") | 13 | local writer = require("luarocks.manif.writer") |
| 15 | local fs = require("luarocks.fs") | 14 | local fs = require("luarocks.fs") |
| 16 | 15 | ||
| 17 | remove.help_summary = "Uninstall a rock." | 16 | remove.help_summary = "Uninstall a rock." |
| @@ -113,7 +112,7 @@ function remove.remove_search_results(results, name, deps_mode, force, fast) | |||
| 113 | 112 | ||
| 114 | local ok, err = delete_versions(name, versions) | 113 | local ok, err = delete_versions(name, versions) |
| 115 | if not ok then return nil, err end | 114 | if not ok then return nil, err end |
| 116 | ok, err = manif.make_manifest(cfg.rocks_dir, deps_mode) | 115 | ok, err = writer.make_manifest(cfg.rocks_dir, deps_mode) |
| 117 | if not ok then return nil, err end | 116 | if not ok then return nil, err end |
| 118 | 117 | ||
| 119 | util.printout("Removal successful.") | 118 | util.printout("Removal successful.") |
diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua index 86126a13..7acb00b9 100644 --- a/src/luarocks/repos.lua +++ b/src/luarocks/repos.lua | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | 1 | ||
| 2 | --- Functions for managing the repository on disk. | 2 | --- Functions for managing the repository on disk. |
| 3 | local repos = {} | 3 | local repos = {} |
| 4 | package.loaded["luarocks.repos"] = repos | ||
| 5 | 4 | ||
| 6 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 7 | local path = require("luarocks.path") | 6 | local path = require("luarocks.path") |
| 8 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 9 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
| 10 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
| 11 | local manif = require("luarocks.manif") | 10 | local manif = require("luarocks.manif") |
diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index c3f00a7c..7d4f3e81 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua | |||
| @@ -2,13 +2,13 @@ | |||
| 2 | --- Module implementing the LuaRocks "search" command. | 2 | --- Module implementing the LuaRocks "search" command. |
| 3 | -- Queries LuaRocks servers. | 3 | -- Queries LuaRocks servers. |
| 4 | local search = {} | 4 | local search = {} |
| 5 | package.loaded["luarocks.search"] = search | 5 | |
| 6 | 6 | ||
| 7 | local dir = require("luarocks.dir") | 7 | local dir = require("luarocks.dir") |
| 8 | local path = require("luarocks.path") | 8 | local path = require("luarocks.path") |
| 9 | local manif = require("luarocks.manif") | 9 | local manif = require("luarocks.manif") |
| 10 | local deps = require("luarocks.deps") | 10 | local deps = require("luarocks.deps") |
| 11 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.core.cfg") |
| 12 | local util = require("luarocks.util") | 12 | local util = require("luarocks.util") |
| 13 | 13 | ||
| 14 | search.help_summary = "Query the LuaRocks servers." | 14 | search.help_summary = "Query the LuaRocks servers." |
diff --git a/src/luarocks/show.lua b/src/luarocks/show.lua index df992f5c..f0bf2164 100644 --- a/src/luarocks/show.lua +++ b/src/luarocks/show.lua | |||
| @@ -1,10 +1,9 @@ | |||
| 1 | --- Module implementing the LuaRocks "show" command. | 1 | --- Module implementing the LuaRocks "show" command. |
| 2 | -- Shows information about an installed rock. | 2 | -- Shows information about an installed rock. |
| 3 | local show = {} | 3 | local show = {} |
| 4 | package.loaded["luarocks.show"] = show | ||
| 5 | 4 | ||
| 6 | local search = require("luarocks.search") | 5 | local search = require("luarocks.search") |
| 7 | local cfg = require("luarocks.cfg") | 6 | local cfg = require("luarocks.core.cfg") |
| 8 | local util = require("luarocks.util") | 7 | local util = require("luarocks.util") |
| 9 | local path = require("luarocks.path") | 8 | local path = require("luarocks.path") |
| 10 | local deps = require("luarocks.deps") | 9 | local deps = require("luarocks.deps") |
diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua index 287d8151..382d3f0a 100644 --- a/src/luarocks/type_check.lua +++ b/src/luarocks/type_check.lua | |||
| @@ -2,16 +2,12 @@ | |||
| 2 | -- Functions and definitions for doing a basic lint check on files | 2 | -- Functions and definitions for doing a basic lint check on files |
| 3 | -- loaded by LuaRocks. | 3 | -- loaded by LuaRocks. |
| 4 | local type_check = {} | 4 | local type_check = {} |
| 5 | package.loaded["luarocks.type_check"] = type_check | 5 | setmetatable(type_check, { __index = require("luarocks.core.type_check") }) |
| 6 | |||
| 7 | local cfg = require("luarocks.cfg") | ||
| 8 | local deps = require("luarocks.deps") | ||
| 9 | 6 | ||
| 10 | type_check.rockspec_format = "3.0" | 7 | type_check.rockspec_format = "3.0" |
| 11 | 8 | ||
| 12 | local string_1 = { _type = "string" } | 9 | local string_1 = type_check.string_1 |
| 13 | local number_1 = { _type = "number" } | 10 | local mandatory_string_1 = type_check.mandatory_string_1 |
| 14 | local mandatory_string_1 = { _type = "string", _mandatory = true } | ||
| 15 | 11 | ||
| 16 | -- Syntax for type-checking tables: | 12 | -- Syntax for type-checking tables: |
| 17 | -- | 13 | -- |
| @@ -112,203 +108,6 @@ rockspec_types.external_dependencies.platforms._any = rockspec_types.external_de | |||
| 112 | rockspec_types.source.platforms._any = rockspec_types.source | 108 | rockspec_types.source.platforms._any = rockspec_types.source |
| 113 | rockspec_types.hooks.platforms._any = rockspec_types.hooks | 109 | rockspec_types.hooks.platforms._any = rockspec_types.hooks |
| 114 | 110 | ||
| 115 | local manifest_types = { | ||
| 116 | repository = { | ||
| 117 | _mandatory = true, | ||
| 118 | -- packages | ||
| 119 | _any = { | ||
| 120 | -- versions | ||
| 121 | _any = { | ||
| 122 | -- items | ||
| 123 | _any = { | ||
| 124 | arch = mandatory_string_1, | ||
| 125 | modules = { _any = string_1 }, | ||
| 126 | commands = { _any = string_1 }, | ||
| 127 | dependencies = { _any = string_1 }, | ||
| 128 | -- TODO: to be extended with more metadata. | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } | ||
| 132 | }, | ||
| 133 | modules = { | ||
| 134 | _mandatory = true, | ||
| 135 | -- modules | ||
| 136 | _any = { | ||
| 137 | -- providers | ||
| 138 | _any = string_1 | ||
| 139 | } | ||
| 140 | }, | ||
| 141 | commands = { | ||
| 142 | _mandatory = true, | ||
| 143 | -- modules | ||
| 144 | _any = { | ||
| 145 | -- commands | ||
| 146 | _any = string_1 | ||
| 147 | } | ||
| 148 | }, | ||
| 149 | dependencies = { | ||
| 150 | -- each module | ||
| 151 | _any = { | ||
| 152 | -- each version | ||
| 153 | _any = { | ||
| 154 | -- each dependency | ||
| 155 | _any = { | ||
| 156 | name = string_1, | ||
| 157 | constraints = { | ||
| 158 | _any = { | ||
| 159 | no_upgrade = { _type = "boolean" }, | ||
| 160 | op = string_1, | ||
| 161 | version = { | ||
| 162 | string = string_1, | ||
| 163 | _any = number_1, | ||
| 164 | } | ||
| 165 | } | ||
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | local function check_version(version, typetbl, context) | ||
| 174 | local typetbl_version = typetbl._version or "1.0" | ||
| 175 | if deps.compare_versions(typetbl_version, version) then | ||
| 176 | if context == "" then | ||
| 177 | return nil, "Invalid rockspec_format version number in rockspec? Please fix rockspec accordingly." | ||
| 178 | else | ||
| 179 | return nil, context.." is not supported in rockspec format "..version.." (requires version "..typetbl_version.."), please fix the rockspec_format field accordingly." | ||
| 180 | end | ||
| 181 | end | ||
| 182 | return true | ||
| 183 | end | ||
| 184 | |||
| 185 | local type_check_table | ||
| 186 | |||
| 187 | --- Type check an object. | ||
| 188 | -- The object is compared against an archetypical value | ||
| 189 | -- matching the expected type -- the actual values don't matter, | ||
| 190 | -- only their types. Tables are type checked recursively. | ||
| 191 | -- @param version string: The version of the item. | ||
| 192 | -- @param item any: The object being checked. | ||
| 193 | -- @param typetbl any: The type-checking table for the object. | ||
| 194 | -- @param context string: A string indicating the "context" where the | ||
| 195 | -- error occurred (the full table path), for error messages. | ||
| 196 | -- @return boolean or (nil, string): true if type checking | ||
| 197 | -- succeeded, or nil and an error message if it failed. | ||
| 198 | -- @see type_check_table | ||
| 199 | local function type_check_item(version, item, typetbl, context) | ||
| 200 | assert(type(version) == "string") | ||
| 201 | |||
| 202 | local ok, err = check_version(version, typetbl, context) | ||
| 203 | if not ok then | ||
| 204 | return nil, err | ||
| 205 | end | ||
| 206 | |||
| 207 | local item_type = type(item) or "nil" | ||
| 208 | local expected_type = typetbl._type or "table" | ||
| 209 | |||
| 210 | if expected_type == "number" then | ||
| 211 | if not tonumber(item) then | ||
| 212 | return nil, "Type mismatch on field "..context..": expected a number" | ||
| 213 | end | ||
| 214 | elseif expected_type == "string" then | ||
| 215 | if item_type ~= "string" then | ||
| 216 | return nil, "Type mismatch on field "..context..": expected a string, got "..item_type | ||
| 217 | end | ||
| 218 | if typetbl._pattern then | ||
| 219 | if not item:match("^"..typetbl._pattern.."$") then | ||
| 220 | return nil, "Type mismatch on field "..context..": invalid value "..item.." does not match '"..typetbl._pattern.."'" | ||
| 221 | end | ||
| 222 | end | ||
| 223 | elseif expected_type == "table" then | ||
| 224 | if item_type ~= expected_type then | ||
| 225 | return nil, "Type mismatch on field "..context..": expected a table" | ||
| 226 | else | ||
| 227 | return type_check_table(version, item, typetbl, context) | ||
| 228 | end | ||
| 229 | elseif item_type ~= expected_type then | ||
| 230 | return nil, "Type mismatch on field "..context..": expected "..expected_type | ||
| 231 | end | ||
| 232 | return true | ||
| 233 | end | ||
| 234 | |||
| 235 | local function mkfield(context, field) | ||
| 236 | if context == "" then | ||
| 237 | return field | ||
| 238 | end | ||
| 239 | return context.."."..field | ||
| 240 | end | ||
| 241 | |||
| 242 | --- Type check the contents of a table. | ||
| 243 | -- The table's contents are compared against a reference table, | ||
| 244 | -- which contains the recognized fields, with archetypical values | ||
| 245 | -- matching the expected types -- the actual values of items in the | ||
| 246 | -- reference table don't matter, only their types (ie, for field x | ||
| 247 | -- in tbl that is correctly typed, type(tbl.x) == type(types.x)). | ||
| 248 | -- If the reference table contains a field called MORE, then | ||
| 249 | -- unknown fields in the checked table are accepted. | ||
| 250 | -- If it contains a field called ANY, then its type will be | ||
| 251 | -- used to check any unknown fields. If a field is prefixed | ||
| 252 | -- with MUST_, it is mandatory; its absence from the table is | ||
| 253 | -- a type error. | ||
| 254 | -- Tables are type checked recursively. | ||
| 255 | -- @param version string: The version of tbl. | ||
| 256 | -- @param tbl table: The table to be type checked. | ||
| 257 | -- @param typetbl table: The type-checking table, containing | ||
| 258 | -- values for recognized fields in the checked table. | ||
| 259 | -- @param context string: A string indicating the "context" where the | ||
| 260 | -- error occurred (such as the name of the table the item is a part of), | ||
| 261 | -- to be used by error messages. | ||
| 262 | -- @return boolean or (nil, string): true if type checking | ||
| 263 | -- succeeded, or nil and an error message if it failed. | ||
| 264 | type_check_table = function(version, tbl, typetbl, context) | ||
| 265 | assert(type(version) == "string") | ||
| 266 | assert(type(tbl) == "table") | ||
| 267 | assert(type(typetbl) == "table") | ||
| 268 | |||
| 269 | local ok, err = check_version(version, typetbl, context) | ||
| 270 | if not ok then | ||
| 271 | return nil, err | ||
| 272 | end | ||
| 273 | |||
| 274 | for k, v in pairs(tbl) do | ||
| 275 | local t = typetbl[k] or typetbl._any | ||
| 276 | if t then | ||
| 277 | local ok, err = type_check_item(version, v, t, mkfield(context, k)) | ||
| 278 | if not ok then return nil, err end | ||
| 279 | elseif typetbl._more then | ||
| 280 | -- Accept unknown field | ||
| 281 | else | ||
| 282 | if not cfg.accept_unknown_fields then | ||
| 283 | return nil, "Unknown field "..k | ||
| 284 | end | ||
| 285 | end | ||
| 286 | end | ||
| 287 | for k, v in pairs(typetbl) do | ||
| 288 | if k:sub(1,1) ~= "_" and v._mandatory then | ||
| 289 | if not tbl[k] then | ||
| 290 | return nil, "Mandatory field "..mkfield(context, k).." is missing." | ||
| 291 | end | ||
| 292 | end | ||
| 293 | end | ||
| 294 | return true | ||
| 295 | end | ||
| 296 | |||
| 297 | local function check_undeclared_globals(globals, typetbl) | ||
| 298 | local undeclared = {} | ||
| 299 | for glob, _ in pairs(globals) do | ||
| 300 | if not (typetbl[glob] or typetbl["MUST_"..glob]) then | ||
| 301 | table.insert(undeclared, glob) | ||
| 302 | end | ||
| 303 | end | ||
| 304 | if #undeclared == 1 then | ||
| 305 | return nil, "Unknown variable: "..undeclared[1] | ||
| 306 | elseif #undeclared > 1 then | ||
| 307 | return nil, "Unknown variables: "..table.concat(undeclared, ", ") | ||
| 308 | end | ||
| 309 | return true | ||
| 310 | end | ||
| 311 | |||
| 312 | --- Type check a rockspec table. | 111 | --- Type check a rockspec table. |
| 313 | -- Verify the correctness of elements from a | 112 | -- Verify the correctness of elements from a |
| 314 | -- rockspec table, reporting on unknown fields and type | 113 | -- rockspec table, reporting on unknown fields and type |
| @@ -320,22 +119,9 @@ function type_check.type_check_rockspec(rockspec, globals) | |||
| 320 | if not rockspec.rockspec_format then | 119 | if not rockspec.rockspec_format then |
| 321 | rockspec.rockspec_format = "1.0" | 120 | rockspec.rockspec_format = "1.0" |
| 322 | end | 121 | end |
| 323 | local ok, err = check_undeclared_globals(globals, rockspec_types) | 122 | local ok, err = type_check.check_undeclared_globals(globals, rockspec_types) |
| 324 | if not ok then return nil, err end | ||
| 325 | return type_check_table(rockspec.rockspec_format, rockspec, rockspec_types, "") | ||
| 326 | end | ||
| 327 | |||
| 328 | --- Type check a manifest table. | ||
| 329 | -- Verify the correctness of elements from a | ||
| 330 | -- manifest table, reporting on unknown fields and type | ||
| 331 | -- mismatches. | ||
| 332 | -- @return boolean or (nil, string): true if type checking | ||
| 333 | -- succeeded, or nil and an error message if it failed. | ||
| 334 | function type_check.type_check_manifest(manifest, globals) | ||
| 335 | assert(type(manifest) == "table") | ||
| 336 | local ok, err = check_undeclared_globals(globals, manifest_types) | ||
| 337 | if not ok then return nil, err end | 123 | if not ok then return nil, err end |
| 338 | return type_check_table("1.0", manifest, manifest_types, "") | 124 | return type_check.type_check_table(rockspec.rockspec_format, rockspec, rockspec_types, "") |
| 339 | end | 125 | end |
| 340 | 126 | ||
| 341 | return type_check | 127 | return type_check |
diff --git a/src/luarocks/unpack.lua b/src/luarocks/unpack.lua index 4e4d9a06..22b3f49b 100644 --- a/src/luarocks/unpack.lua +++ b/src/luarocks/unpack.lua | |||
| @@ -2,14 +2,13 @@ | |||
| 2 | --- Module implementing the LuaRocks "unpack" command. | 2 | --- Module implementing the LuaRocks "unpack" command. |
| 3 | -- Unpack the contents of a rock. | 3 | -- Unpack the contents of a rock. |
| 4 | local unpack = {} | 4 | local unpack = {} |
| 5 | package.loaded["luarocks.unpack"] = unpack | ||
| 6 | 5 | ||
| 7 | local fetch = require("luarocks.fetch") | 6 | local fetch = require("luarocks.fetch") |
| 8 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
| 9 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
| 10 | local build = require("luarocks.build") | 9 | local build = require("luarocks.build") |
| 11 | local dir = require("luarocks.dir") | 10 | local dir = require("luarocks.dir") |
| 12 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.core.cfg") |
| 13 | 12 | ||
| 14 | unpack.help_summary = "Unpack the contents of a rock." | 13 | unpack.help_summary = "Unpack the contents of a rock." |
| 15 | unpack.help_arguments = "[--force] {<rock>|<name> [<version>]}" | 14 | unpack.help_arguments = "[--force] {<rock>|<name> [<version>]}" |
diff --git a/src/luarocks/upload.lua b/src/luarocks/upload.lua index 5031b1ef..4bda4303 100644 --- a/src/luarocks/upload.lua +++ b/src/luarocks/upload.lua | |||
| @@ -4,7 +4,7 @@ local upload = {} | |||
| 4 | local util = require("luarocks.util") | 4 | local util = require("luarocks.util") |
| 5 | local fetch = require("luarocks.fetch") | 5 | local fetch = require("luarocks.fetch") |
| 6 | local pack = require("luarocks.pack") | 6 | local pack = require("luarocks.pack") |
| 7 | local cfg = require("luarocks.cfg") | 7 | local cfg = require("luarocks.core.cfg") |
| 8 | local Api = require("luarocks.upload.api") | 8 | local Api = require("luarocks.upload.api") |
| 9 | 9 | ||
| 10 | upload.help_summary = "Upload a rockspec to the public rocks repository." | 10 | upload.help_summary = "Upload a rockspec to the public rocks repository." |
diff --git a/src/luarocks/upload/api.lua b/src/luarocks/upload/api.lua index 6df24569..3e28bbda 100644 --- a/src/luarocks/upload/api.lua +++ b/src/luarocks/upload/api.lua | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | 1 | ||
| 2 | local api = {} | 2 | local api = {} |
| 3 | 3 | ||
| 4 | local cfg = require("luarocks.cfg") | 4 | local cfg = require("luarocks.core.cfg") |
| 5 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
| 6 | local util = require("luarocks.util") | 6 | local util = require("luarocks.util") |
| 7 | local persist = require("luarocks.persist") | 7 | local persist = require("luarocks.persist") |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index d27710c1..f41b1c38 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
| @@ -2,26 +2,13 @@ | |||
| 2 | --- Assorted utilities for managing tables, plus a scheduler for rollback functions. | 2 | --- Assorted utilities for managing tables, plus a scheduler for rollback functions. |
| 3 | -- Does not requires modules directly (only as locals | 3 | -- Does not requires modules directly (only as locals |
| 4 | -- inside specific functions) to avoid interdependencies, | 4 | -- inside specific functions) to avoid interdependencies, |
| 5 | -- as this is used in the bootstrapping stage of luarocks.cfg. | 5 | -- as this is used in the bootstrapping stage of luarocks.core.cfg. |
| 6 | 6 | ||
| 7 | local util = {} | 7 | local util = {} |
| 8 | setmetatable(util, { __index = require("luarocks.core.util") }) | ||
| 8 | 9 | ||
| 9 | local unpack = unpack or table.unpack | 10 | local unpack = unpack or table.unpack |
| 10 | 11 | ||
| 11 | --- Run a process and read a its output. | ||
| 12 | -- Equivalent to io.popen(cmd):read("*l"), except that it | ||
| 13 | -- closes the fd right away. | ||
| 14 | -- @param cmd string: The command to execute | ||
| 15 | -- @param spec string: "*l" by default, to read a single line. | ||
| 16 | -- May be used to read more, passing, for instance, "*a". | ||
| 17 | -- @return string: the output of the program. | ||
| 18 | function util.popen_read(cmd, spec) | ||
| 19 | local fd = io.popen(cmd) | ||
| 20 | local out = fd:read(spec or "*l") | ||
| 21 | fd:close() | ||
| 22 | return out | ||
| 23 | end | ||
| 24 | |||
| 25 | local scheduled_functions = {} | 12 | local scheduled_functions = {} |
| 26 | local debug = require("debug") | 13 | local debug = require("debug") |
| 27 | 14 | ||
| @@ -210,27 +197,6 @@ function util.parse_flags(...) | |||
| 210 | return flags, unpack(out) | 197 | return flags, unpack(out) |
| 211 | end | 198 | end |
| 212 | 199 | ||
| 213 | --- Merges contents of src on top of dst's contents. | ||
| 214 | -- @param dst Destination table, which will receive src's contents. | ||
| 215 | -- @param src Table which provides new contents to dst. | ||
| 216 | -- @see platform_overrides | ||
| 217 | function util.deep_merge(dst, src) | ||
| 218 | for k, v in pairs(src) do | ||
| 219 | if type(v) == "table" then | ||
| 220 | if not dst[k] then | ||
| 221 | dst[k] = {} | ||
| 222 | end | ||
| 223 | if type(dst[k]) == "table" then | ||
| 224 | util.deep_merge(dst[k], v) | ||
| 225 | else | ||
| 226 | dst[k] = v | ||
| 227 | end | ||
| 228 | else | ||
| 229 | dst[k] = v | ||
| 230 | end | ||
| 231 | end | ||
| 232 | end | ||
| 233 | |||
| 234 | --- Perform platform-specific overrides on a table. | 200 | --- Perform platform-specific overrides on a table. |
| 235 | -- Overrides values of table with the contents of the appropriate | 201 | -- Overrides values of table with the contents of the appropriate |
| 236 | -- subset of its "platforms" field. The "platforms" field should | 202 | -- subset of its "platforms" field. The "platforms" field should |
| @@ -247,7 +213,7 @@ end | |||
| 247 | function util.platform_overrides(tbl) | 213 | function util.platform_overrides(tbl) |
| 248 | assert(type(tbl) == "table" or not tbl) | 214 | assert(type(tbl) == "table" or not tbl) |
| 249 | 215 | ||
| 250 | local cfg = require("luarocks.cfg") | 216 | local cfg = require("luarocks.core.cfg") |
| 251 | 217 | ||
| 252 | if not tbl then return end | 218 | if not tbl then return end |
| 253 | 219 | ||
| @@ -264,19 +230,6 @@ end | |||
| 264 | 230 | ||
| 265 | local var_format_pattern = "%$%((%a[%a%d_]+)%)" | 231 | local var_format_pattern = "%$%((%a[%a%d_]+)%)" |
| 266 | 232 | ||
| 267 | --- Create a new shallow copy of a table: a new table with | ||
| 268 | -- the same keys and values. Keys point to the same objects as | ||
| 269 | -- the original table (ie, does not copy recursively). | ||
| 270 | -- @param tbl table: the input table | ||
| 271 | -- @return table: a new table with the same contents. | ||
| 272 | function util.make_shallow_copy(tbl) | ||
| 273 | local copy = {} | ||
| 274 | for k,v in pairs(tbl) do | ||
| 275 | copy[k] = v | ||
| 276 | end | ||
| 277 | return copy | ||
| 278 | end | ||
| 279 | |||
| 280 | -- Check if a set of needed variables are referenced | 233 | -- Check if a set of needed variables are referenced |
| 281 | -- somewhere in a list of definitions, warning the user | 234 | -- somewhere in a list of definitions, warning the user |
| 282 | -- about any unused ones. Each key in needed_set should | 235 | -- about any unused ones. Each key in needed_set should |
| @@ -339,17 +292,6 @@ function util.variable_substitutions(tbl, vars) | |||
| 339 | end | 292 | end |
| 340 | end | 293 | end |
| 341 | 294 | ||
| 342 | --- Return an array of keys of a table. | ||
| 343 | -- @param tbl table: The input table. | ||
| 344 | -- @return table: The array of keys. | ||
| 345 | function util.keys(tbl) | ||
| 346 | local ks = {} | ||
| 347 | for k,_ in pairs(tbl) do | ||
| 348 | table.insert(ks, k) | ||
| 349 | end | ||
| 350 | return ks | ||
| 351 | end | ||
| 352 | |||
| 353 | local function default_sort(a, b) | 295 | local function default_sort(a, b) |
| 354 | local ta = type(a) | 296 | local ta = type(a) |
| 355 | local tb = type(b) | 297 | local tb = type(b) |
| @@ -431,12 +373,6 @@ function util.printout(...) | |||
| 431 | io.stdout:write("\n") | 373 | io.stdout:write("\n") |
| 432 | end | 374 | end |
| 433 | 375 | ||
| 434 | --- Print a line to standard error | ||
| 435 | function util.printerr(...) | ||
| 436 | io.stderr:write(table.concat({...},"\t")) | ||
| 437 | io.stderr:write("\n") | ||
| 438 | end | ||
| 439 | |||
| 440 | --- Display a warning message. | 376 | --- Display a warning message. |
| 441 | -- @param msg string: the warning message | 377 | -- @param msg string: the warning message |
| 442 | function util.warning(msg) | 378 | function util.warning(msg) |
| @@ -465,7 +401,7 @@ function util.this_program(default) | |||
| 465 | end | 401 | end |
| 466 | 402 | ||
| 467 | function util.deps_mode_help(program) | 403 | function util.deps_mode_help(program) |
| 468 | local cfg = require("luarocks.cfg") | 404 | local cfg = require("luarocks.core.cfg") |
| 469 | return [[ | 405 | return [[ |
| 470 | --deps-mode=<mode> How to handle dependencies. Four modes are supported: | 406 | --deps-mode=<mode> How to handle dependencies. Four modes are supported: |
| 471 | * all - use all trees from the rocks_trees list | 407 | * all - use all trees from the rocks_trees list |
| @@ -488,7 +424,7 @@ function util.see_help(command, program) | |||
| 488 | end | 424 | end |
| 489 | 425 | ||
| 490 | function util.announce_install(rockspec) | 426 | function util.announce_install(rockspec) |
| 491 | local cfg = require("luarocks.cfg") | 427 | local cfg = require("luarocks.core.cfg") |
| 492 | local path = require("luarocks.path") | 428 | local path = require("luarocks.path") |
| 493 | 429 | ||
| 494 | local suffix = "" | 430 | local suffix = "" |
| @@ -566,135 +502,6 @@ function util.get_default_rockspec() | |||
| 566 | end | 502 | end |
| 567 | end | 503 | end |
| 568 | 504 | ||
| 569 | -- from http://lua-users.org/wiki/SplitJoin | ||
| 570 | -- by PhilippeLhoste | ||
| 571 | function util.split_string(str, delim, maxNb) | ||
| 572 | -- Eliminate bad cases... | ||
| 573 | if string.find(str, delim) == nil then | ||
| 574 | return { str } | ||
| 575 | end | ||
| 576 | if maxNb == nil or maxNb < 1 then | ||
| 577 | maxNb = 0 -- No limit | ||
| 578 | end | ||
| 579 | local result = {} | ||
| 580 | local pat = "(.-)" .. delim .. "()" | ||
| 581 | local nb = 0 | ||
| 582 | local lastPos | ||
| 583 | for part, pos in string.gmatch(str, pat) do | ||
| 584 | nb = nb + 1 | ||
| 585 | result[nb] = part | ||
| 586 | lastPos = pos | ||
| 587 | if nb == maxNb then break end | ||
| 588 | end | ||
| 589 | -- Handle the last field | ||
| 590 | if nb ~= maxNb then | ||
| 591 | result[nb + 1] = string.sub(str, lastPos) | ||
| 592 | end | ||
| 593 | return result | ||
| 594 | end | ||
| 595 | |||
| 596 | --- Remove repeated entries from a path-style string. | ||
| 597 | -- Example: given ("a;b;c;a;b;d", ";"), returns "a;b;c;d". | ||
| 598 | -- @param list string: A path string (from $PATH or package.path) | ||
| 599 | -- @param sep string: The separator | ||
| 600 | function util.remove_path_dupes(list, sep) | ||
| 601 | assert(type(list) == "string") | ||
| 602 | assert(type(sep) == "string") | ||
| 603 | local parts = util.split_string(list, sep) | ||
| 604 | local final, entries = {}, {} | ||
| 605 | for _, part in ipairs(parts) do | ||
| 606 | part = part:gsub("//", "/") | ||
| 607 | if not entries[part] then | ||
| 608 | table.insert(final, part) | ||
| 609 | entries[part] = true | ||
| 610 | end | ||
| 611 | end | ||
| 612 | return table.concat(final, sep) | ||
| 613 | end | ||
| 614 | |||
| 615 | --- | ||
| 616 | -- Formats tables with cycles recursively to any depth. | ||
| 617 | -- References to other tables are shown as values. | ||
| 618 | -- Self references are indicated. | ||
| 619 | -- The string returned is "Lua code", which can be procesed | ||
| 620 | -- (in the case in which indent is composed by spaces or "--"). | ||
| 621 | -- Userdata and function keys and values are shown as strings, | ||
| 622 | -- which logically are exactly not equivalent to the original code. | ||
| 623 | -- This routine can serve for pretty formating tables with | ||
| 624 | -- proper indentations, apart from printing them: | ||
| 625 | -- io.write(table.show(t, "t")) -- a typical use | ||
| 626 | -- Written by Julio Manuel Fernandez-Diaz, | ||
| 627 | -- Heavily based on "Saving tables with cycles", PIL2, p. 113. | ||
| 628 | -- @param t table: is the table. | ||
| 629 | -- @param name string: is the name of the table (optional) | ||
| 630 | -- @param indent string: is a first indentation (optional). | ||
| 631 | -- @return string: the pretty-printed table | ||
| 632 | function util.show_table(t, name, indent) | ||
| 633 | local cart -- a container | ||
| 634 | local autoref -- for self references | ||
| 635 | |||
| 636 | local function isemptytable(t) return next(t) == nil end | ||
| 637 | |||
| 638 | local function basicSerialize (o) | ||
| 639 | local so = tostring(o) | ||
| 640 | if type(o) == "function" then | ||
| 641 | local info = debug.getinfo(o, "S") | ||
| 642 | -- info.name is nil because o is not a calling level | ||
| 643 | if info.what == "C" then | ||
| 644 | return ("%q"):format(so .. ", C function") | ||
| 645 | else | ||
| 646 | -- the information is defined through lines | ||
| 647 | return ("%q"):format(so .. ", defined in (" .. info.linedefined .. "-" .. info.lastlinedefined .. ")" .. info.source) | ||
| 648 | end | ||
| 649 | elseif type(o) == "number" then | ||
| 650 | return so | ||
| 651 | else | ||
| 652 | return ("%q"):format(so) | ||
| 653 | end | ||
| 654 | end | ||
| 655 | |||
| 656 | local function addtocart (value, name, indent, saved, field) | ||
| 657 | indent = indent or "" | ||
| 658 | saved = saved or {} | ||
| 659 | field = field or name | ||
| 660 | |||
| 661 | cart = cart .. indent .. field | ||
| 662 | |||
| 663 | if type(value) ~= "table" then | ||
| 664 | cart = cart .. " = " .. basicSerialize(value) .. ";\n" | ||
| 665 | else | ||
| 666 | if saved[value] then | ||
| 667 | cart = cart .. " = {}; -- " .. saved[value] .. " (self reference)\n" | ||
| 668 | autoref = autoref .. name .. " = " .. saved[value] .. ";\n" | ||
| 669 | else | ||
| 670 | saved[value] = name | ||
| 671 | --if tablecount(value) == 0 then | ||
| 672 | if isemptytable(value) then | ||
| 673 | cart = cart .. " = {};\n" | ||
| 674 | else | ||
| 675 | cart = cart .. " = {\n" | ||
| 676 | for k, v in pairs(value) do | ||
| 677 | k = basicSerialize(k) | ||
| 678 | local fname = ("%s[%s]"):format(name, k) | ||
| 679 | field = ("[%s]"):format(k) | ||
| 680 | -- three spaces between levels | ||
| 681 | addtocart(v, fname, indent .. " ", saved, field) | ||
| 682 | end | ||
| 683 | cart = cart .. indent .. "};\n" | ||
| 684 | end | ||
| 685 | end | ||
| 686 | end | ||
| 687 | end | ||
| 688 | |||
| 689 | name = name or "__unnamed__" | ||
| 690 | if type(t) ~= "table" then | ||
| 691 | return name .. " = " .. basicSerialize(t) | ||
| 692 | end | ||
| 693 | cart, autoref = "", "" | ||
| 694 | addtocart(t, name, indent) | ||
| 695 | return cart .. autoref | ||
| 696 | end | ||
| 697 | |||
| 698 | function util.array_contains(tbl, value) | 505 | function util.array_contains(tbl, value) |
| 699 | for _, v in ipairs(tbl) do | 506 | for _, v in ipairs(tbl) do |
| 700 | if v == value then | 507 | if v == value then |
diff --git a/src/luarocks/validate.lua b/src/luarocks/validate.lua deleted file mode 100644 index f0452bbd..00000000 --- a/src/luarocks/validate.lua +++ /dev/null | |||
| @@ -1,158 +0,0 @@ | |||
| 1 | |||
| 2 | --- Sandboxed test of build/install of all packages in a repository (unfinished and disabled). | ||
| 3 | local validate = {} | ||
| 4 | package.loaded["luarocks.validate"] = validate | ||
| 5 | |||
| 6 | local fs = require("luarocks.fs") | ||
| 7 | local dir = require("luarocks.dir") | ||
| 8 | local path = require("luarocks.path") | ||
| 9 | local cfg = require("luarocks.cfg") | ||
| 10 | local build = require("luarocks.build") | ||
| 11 | local install = require("luarocks.install") | ||
| 12 | local util = require("luarocks.util") | ||
| 13 | |||
| 14 | validate.help_summary = "Sandboxed test of build/install of all packages in a repository." | ||
| 15 | |||
| 16 | validate.help = [[ | ||
| 17 | <argument>, if given, is a local repository pathname. | ||
| 18 | ]] | ||
| 19 | |||
| 20 | local function save_settings(repo) | ||
| 21 | local protocol, path = dir.split_url(repo) | ||
| 22 | table.insert(cfg.rocks_servers, 1, protocol.."://"..path) | ||
| 23 | return { | ||
| 24 | root_dir = cfg.root_dir, | ||
| 25 | rocks_dir = cfg.rocks_dir, | ||
| 26 | deploy_bin_dir = cfg.deploy_bin_dir, | ||
| 27 | deploy_lua_dir = cfg.deploy_lua_dir, | ||
| 28 | deploy_lib_dir = cfg.deploy_lib_dir, | ||
| 29 | } | ||
| 30 | end | ||
| 31 | |||
| 32 | local function restore_settings(settings) | ||
| 33 | cfg.root_dir = settings.root_dir | ||
| 34 | cfg.rocks_dir = settings.rocks_dir | ||
| 35 | cfg.deploy_bin_dir = settings.deploy_bin_dir | ||
| 36 | cfg.deploy_lua_dir = settings.deploy_lua_dir | ||
| 37 | cfg.deploy_lib_dir = settings.deploy_lib_dir | ||
| 38 | cfg.variables.ROCKS_TREE = settings.rocks_dir | ||
| 39 | cfg.variables.SCRIPTS_DIR = settings.deploy_bin_dir | ||
| 40 | table.remove(cfg.rocks_servers, 1) | ||
| 41 | end | ||
| 42 | |||
| 43 | local function prepare_sandbox(file) | ||
| 44 | local root_dir = fs.make_temp_dir(file):gsub("/+$", "") | ||
| 45 | cfg.root_dir = root_dir | ||
| 46 | cfg.rocks_dir = path.rocks_dir(root_dir) | ||
| 47 | cfg.deploy_bin_dir = path.deploy_bin_dir(root_dir) | ||
| 48 | cfg.variables.ROCKS_TREE = cfg.rocks_dir | ||
| 49 | cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir | ||
| 50 | return root_dir | ||
| 51 | end | ||
| 52 | |||
| 53 | local function validate_rockspec(file) | ||
| 54 | local ok, err, errcode = build.build_rockspec(file, true, "one") | ||
| 55 | if not ok then | ||
| 56 | util.printerr(err) | ||
| 57 | end | ||
| 58 | return ok, err, errcode | ||
| 59 | end | ||
| 60 | |||
| 61 | local function validate_src_rock(file) | ||
| 62 | local ok, err, errcode = build.build_rock(file, false, "one") | ||
| 63 | if not ok then | ||
| 64 | util.printerr(err) | ||
| 65 | end | ||
| 66 | return ok, err, errcode | ||
| 67 | end | ||
| 68 | |||
| 69 | local function validate_rock(file) | ||
| 70 | local ok, err, errcode = install.install_binary_rock(file, "one") | ||
| 71 | if not ok then | ||
| 72 | util.printerr(err) | ||
| 73 | end | ||
| 74 | return ok, err, errcode | ||
| 75 | end | ||
| 76 | |||
| 77 | function validate.command(flags, repo) | ||
| 78 | repo = repo or cfg.rocks_dir | ||
| 79 | |||
| 80 | util.printout("Verifying contents of "..repo) | ||
| 81 | |||
| 82 | local results = { | ||
| 83 | ok = {} | ||
| 84 | } | ||
| 85 | local settings = save_settings(repo) | ||
| 86 | local sandbox | ||
| 87 | if flags["quick"] then | ||
| 88 | sandbox = prepare_sandbox("luarocks_validate") | ||
| 89 | end | ||
| 90 | if not fs.exists(repo) then | ||
| 91 | return nil, repo.." is not a local repository." | ||
| 92 | end | ||
| 93 | for file in fs.dir(repo) do for _=1,1 do | ||
| 94 | if file == "manifest" or file == "index.html" then | ||
| 95 | break -- continue for | ||
| 96 | end | ||
| 97 | local pathname = fs.absolute_name(dir.path(repo, file)) | ||
| 98 | if not flags["quick"] then | ||
| 99 | sandbox = prepare_sandbox(file) | ||
| 100 | end | ||
| 101 | local ok, err, errcode | ||
| 102 | util.printout() | ||
| 103 | util.printout("Verifying "..pathname) | ||
| 104 | if file:match("%.rockspec$") then | ||
| 105 | ok, err, errcode = validate_rockspec(pathname, "one") | ||
| 106 | elseif file:match("%.src%.rock$") then | ||
| 107 | ok, err, errcode = validate_src_rock(pathname) | ||
| 108 | elseif file:match("%.rock$") then | ||
| 109 | ok, err, errcode = validate_rock(pathname) | ||
| 110 | end | ||
| 111 | if ok then | ||
| 112 | table.insert(results.ok, {file=file} ) | ||
| 113 | else | ||
| 114 | if not errcode then | ||
| 115 | errcode = "misc" | ||
| 116 | end | ||
| 117 | if not results[errcode] then | ||
| 118 | results[errcode] = {} | ||
| 119 | end | ||
| 120 | table.insert(results[errcode], {file=file, err=err} ) | ||
| 121 | end | ||
| 122 | util.run_scheduled_functions() | ||
| 123 | if not flags["quick"] then | ||
| 124 | fs.delete(sandbox) | ||
| 125 | end | ||
| 126 | repeat until not fs.pop_dir() | ||
| 127 | end end | ||
| 128 | if flags["quick"] then | ||
| 129 | fs.delete(sandbox) | ||
| 130 | end | ||
| 131 | restore_settings(settings) | ||
| 132 | util.title("Results:") | ||
| 133 | util.printout("OK: "..tostring(#results.ok)) | ||
| 134 | for _, entry in ipairs(results.ok) do | ||
| 135 | util.printout(entry.file) | ||
| 136 | end | ||
| 137 | for errcode, errors in pairs(results) do | ||
| 138 | if errcode ~= "ok" then | ||
| 139 | util.printout() | ||
| 140 | util.printout(errcode.." errors: "..tostring(#errors)) | ||
| 141 | for _, entry in ipairs(errors) do | ||
| 142 | util.printout(entry.file, entry.err) | ||
| 143 | end | ||
| 144 | end | ||
| 145 | end | ||
| 146 | |||
| 147 | util.title("Summary:") | ||
| 148 | local total = 0 | ||
| 149 | for errcode, errors in pairs(results) do | ||
| 150 | util.printout(errcode..": "..tostring(#errors)) | ||
| 151 | total = total + #errors | ||
| 152 | end | ||
| 153 | util.printout("Total: "..total) | ||
| 154 | return true | ||
| 155 | end | ||
| 156 | |||
| 157 | |||
| 158 | return validate | ||
diff --git a/src/luarocks/write_rockspec.lua b/src/luarocks/write_rockspec.lua index 68c00cce..d6075dbd 100644 --- a/src/luarocks/write_rockspec.lua +++ b/src/luarocks/write_rockspec.lua | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | 1 | ||
| 2 | local write_rockspec = {} | 2 | local write_rockspec = {} |
| 3 | package.loaded["luarocks.write_rockspec"] = write_rockspec | ||
| 4 | 3 | ||
| 5 | local cfg = require("luarocks.cfg") | 4 | local cfg = require("luarocks.core.cfg") |
| 6 | local dir = require("luarocks.dir") | 5 | local dir = require("luarocks.dir") |
| 7 | local fetch = require("luarocks.fetch") | 6 | local fetch = require("luarocks.fetch") |
| 8 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
