diff options
author | Hisham <hisham@gobolinux.org> | 2016-06-30 01:15:01 -0300 |
---|---|---|
committer | Hisham <hisham@gobolinux.org> | 2016-06-30 01:15:01 -0300 |
commit | f2beb5ee1fd2c54d59a43f4f2a8fe0f7a1701daa (patch) | |
tree | 46f958aa7efb4d6b31612178026228ba49e612f5 /src | |
parent | 6b38323d10743c83e377d9be2fa734a3a3d5a300 (diff) | |
download | luarocks-f2beb5ee1fd2c54d59a43f4f2a8fe0f7a1701daa.tar.gz luarocks-f2beb5ee1fd2c54d59a43f4f2a8fe0f7a1701daa.tar.bz2 luarocks-f2beb5ee1fd2c54d59a43f4f2a8fe0f7a1701daa.zip |
Core modules reorganization.
Isolate all modules used by luarocks.loader in a
luarocks.core.* namespace. Core modules can only require
other core modules, and they only use require() at the
top-level chunk. In other words, after luarocks.loader
is setup, package.path can be altered at will and it
should not affect the ability of luarocks.loader to run,
and the luarocks.loader modules should not interfere
with modules loaded later.
This was motivated by @robooo's GSoC work on porting
the LuaRocks test suite to Lua using Busted. Busted itself
runs using luarocks.loader, and we need to ensure that
the modules loaded by the tests do not conflict with
the ones used by luarocks.loader.
A circular dependency between luarocks.manif and
luarocks.search was removed by creating a separate
luarocks.manif.writer module.
Also, luarocks-admin commands were moved to a
luarocks.admin.* namespace.
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") |