aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/luarocks/cfg.lua19
-rw-r--r--src/luarocks/deps.lua2
-rw-r--r--src/luarocks/download.lua7
-rw-r--r--src/luarocks/fs/lua.lua30
-rw-r--r--src/luarocks/fs/unix.lua2
-rw-r--r--src/luarocks/fs/unix/tools.lua18
-rw-r--r--src/luarocks/fs/win32.lua19
-rw-r--r--src/luarocks/list.lua4
-rw-r--r--src/luarocks/manif.lua20
-rw-r--r--src/luarocks/manif_core.lua49
-rw-r--r--src/luarocks/path_cmd.lua2
-rw-r--r--src/luarocks/search.lua54
-rw-r--r--test/testing.lua1
-rwxr-xr-xtest/testing.sh13
14 files changed, 178 insertions, 62 deletions
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua
index 60239d3f..e7356c16 100644
--- a/src/luarocks/cfg.lua
+++ b/src/luarocks/cfg.lua
@@ -362,6 +362,7 @@ local defaults = {
362 FIND = "find", 362 FIND = "find",
363 TEST = "test", 363 TEST = "test",
364 CHMOD = "chmod", 364 CHMOD = "chmod",
365 MKTEMP = "mktemp",
365 366
366 ZIP = "zip", 367 ZIP = "zip",
367 UNZIP = "unzip -n", 368 UNZIP = "unzip -n",
@@ -604,13 +605,11 @@ defaults.variables.LUA = site_config.LUA_DIR_SET and (defaults.variables.LUA_BIN
604-- Add built-in modules to rocks_provided 605-- Add built-in modules to rocks_provided
605defaults.rocks_provided["lua"] = cfg.lua_version.."-1" 606defaults.rocks_provided["lua"] = cfg.lua_version.."-1"
606 607
607if cfg.lua_version >= "5.2" then 608if bit32 then -- Lua 5.2+
608 -- Lua 5.2+
609 defaults.rocks_provided["bit32"] = cfg.lua_version.."-1" 609 defaults.rocks_provided["bit32"] = cfg.lua_version.."-1"
610end 610end
611 611
612if cfg.lua_version >= "5.3" then 612if utf8 then -- Lua 5.3+
613 -- Lua 5.3+
614 defaults.rocks_provided["utf8"] = cfg.lua_version.."-1" 613 defaults.rocks_provided["utf8"] = cfg.lua_version.."-1"
615end 614end
616 615
@@ -668,17 +667,23 @@ function cfg.make_paths_from_tree(tree)
668 return lua_path, lib_path, bin_path 667 return lua_path, lib_path, bin_path
669end 668end
670 669
671function cfg.package_paths() 670function cfg.package_paths(current)
672 local new_path, new_cpath, new_bin = {}, {}, {} 671 local new_path, new_cpath, new_bin = {}, {}, {}
673 for _,tree in ipairs(cfg.rocks_trees) do 672 local function add_tree_to_paths(tree)
674 local lua_path, lib_path, bin_path = cfg.make_paths_from_tree(tree) 673 local lua_path, lib_path, bin_path = cfg.make_paths_from_tree(tree)
675 table.insert(new_path, lua_path.."/?.lua") 674 table.insert(new_path, lua_path.."/?.lua")
676 table.insert(new_path, lua_path.."/?/init.lua") 675 table.insert(new_path, lua_path.."/?/init.lua")
677 table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension) 676 table.insert(new_cpath, lib_path.."/?."..cfg.lib_extension)
678 table.insert(new_bin, bin_path) 677 table.insert(new_bin, bin_path)
679 end 678 end
679 if current then
680 add_tree_to_paths(current)
681 end
682 for _,tree in ipairs(cfg.rocks_trees) do
683 add_tree_to_paths(tree)
684 end
680 if extra_luarocks_module_dir then 685 if extra_luarocks_module_dir then
681 table.insert(new_path, extra_luarocks_module_dir) 686 table.insert(new_path, extra_luarocks_module_dir)
682 end 687 end
683 return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator) 688 return table.concat(new_path, ";"), table.concat(new_cpath, ";"), table.concat(new_bin, cfg.export_path_separator)
684end 689end
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua
index b9eda6e6..2a458b23 100644
--- a/src/luarocks/deps.lua
+++ b/src/luarocks/deps.lua
@@ -499,7 +499,7 @@ function deps.fulfill_dependencies(rockspec, deps_mode)
499 if not match_dep(dep, nil, deps_mode, rockspec.rocks_provided) then 499 if not match_dep(dep, nil, deps_mode, rockspec.rocks_provided) then
500 local url, err = search.find_suitable_rock(dep) 500 local url, err = search.find_suitable_rock(dep)
501 if not url then 501 if not url then
502 return nil, "Could not satisfy dependency: "..deps.show_dep(dep) 502 return nil, "Could not satisfy dependency "..deps.show_dep(dep)..": "..err
503 end 503 end
504 local ok, err, errcode = install.run(url, deps.deps_mode_to_flag(deps_mode)) 504 local ok, err, errcode = install.run(url, deps.deps_mode_to_flag(deps_mode))
505 if not ok then 505 if not ok then
diff --git a/src/luarocks/download.lua b/src/luarocks/download.lua
index f08ba7fe..090f49aa 100644
--- a/src/luarocks/download.lua
+++ b/src/luarocks/download.lua
@@ -39,6 +39,7 @@ end
39function download.download(arch, name, version, all) 39function download.download(arch, name, version, all)
40 local query = search.make_query(name, version) 40 local query = search.make_query(name, version)
41 if arch then query.arch = arch end 41 if arch then query.arch = arch end
42 local search_err
42 43
43 if all then 44 if all then
44 if name == "" then query.exact_name = false end 45 if name == "" then query.exact_name = false end
@@ -67,12 +68,14 @@ function download.download(arch, name, version, all)
67 return all_ok, any_err 68 return all_ok, any_err
68 end 69 end
69 else 70 else
70 local url = search.find_suitable_rock(query) 71 local url
72 url, search_err = search.find_suitable_rock(query)
71 if url then 73 if url then
72 return get_file(url) 74 return get_file(url)
73 end 75 end
74 end 76 end
75 return nil, "Could not find a result named "..name..(version and " "..version or "").."." 77 return nil, "Could not find a result named "..name..(version and " "..version or "")..
78 (search_err and ": "..search_err or ".")
76end 79end
77 80
78--- Driver function for the "download" command. 81--- Driver function for the "download" command.
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua
index 1d303c67..483b3e3c 100644
--- a/src/luarocks/fs/lua.lua
+++ b/src/luarocks/fs/lua.lua
@@ -28,8 +28,6 @@ local patch = require("luarocks.tools.patch")
28 28
29local dir_stack = {} 29local dir_stack = {}
30 30
31math.randomseed(os.time())
32
33local dir_separator = "/" 31local dir_separator = "/"
34 32
35--- Quote argument for shell processing. 33--- Quote argument for shell processing.
@@ -67,23 +65,6 @@ function fs_lua.is_writable(file)
67 return result 65 return result
68end 66end
69 67
70--- Create a temporary directory.
71-- @param name string: name pattern to use for avoiding conflicts
72-- when creating temporary directory.
73-- @return string or (nil, string): name of temporary directory or (nil, error message) on failure.
74function fs_lua.make_temp_dir(name)
75 assert(type(name) == "string")
76 name = dir.normalize(name)
77
78 local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000))
79 local ok, err = fs.make_dir(temp_dir)
80 if ok then
81 return temp_dir
82 else
83 return nil, err
84 end
85end
86
87local function quote_args(command, ...) 68local function quote_args(command, ...)
88 local out = { command } 69 local out = { command }
89 for _, arg in ipairs({...}) do 70 for _, arg in ipairs({...}) do
@@ -785,6 +766,17 @@ function fs_lua.get_permissions(file)
785 return posix.stat(file, "mode") 766 return posix.stat(file, "mode")
786end 767end
787 768
769--- Create a temporary directory.
770-- @param name string: name pattern to use for avoiding conflicts
771-- when creating temporary directory.
772-- @return string or (nil, string): name of temporary directory or (nil, error message) on failure.
773function fs_lua.make_temp_dir(name)
774 assert(type(name) == "string")
775 name = dir.normalize(name)
776
777 return posix.mkdtemp((os.getenv("TMPDIR") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-XXXXXX")
778end
779
788end 780end
789 781
790--------------------------------------------------------------------- 782---------------------------------------------------------------------
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua
index 8eb3386a..570b26e4 100644
--- a/src/luarocks/fs/unix.lua
+++ b/src/luarocks/fs/unix.lua
@@ -9,8 +9,6 @@ local cfg = require("luarocks.cfg")
9local dir = require("luarocks.dir") 9local dir = require("luarocks.dir")
10local util = require("luarocks.util") 10local util = require("luarocks.util")
11 11
12math.randomseed(os.time())
13
14--- Annotate command string for quiet execution. 12--- Annotate command string for quiet execution.
15-- @param cmd string: A command-line string. 13-- @param cmd string: A command-line string.
16-- @return string: The command-line, with silencing annotation. 14-- @return string: The command-line, with silencing annotation.
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua
index 767bae4d..ab55897e 100644
--- a/src/luarocks/fs/unix/tools.lua
+++ b/src/luarocks/fs/unix/tools.lua
@@ -357,4 +357,22 @@ function tools.set_time(file, time)
357 return fs.execute(vars.TOUCH, "-d", "@"..tostring(time), file) 357 return fs.execute(vars.TOUCH, "-d", "@"..tostring(time), file)
358end 358end
359 359
360--- Create a temporary directory.
361-- @param name string: name pattern to use for avoiding conflicts
362-- when creating temporary directory.
363-- @return string or (nil, string): name of temporary directory or (nil, error message) on failure.
364function tools.make_temp_dir(name)
365 assert(type(name) == "string")
366 name = dir.normalize(name)
367
368 local template = (os.getenv("TMPDIR") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-XXXXXX"
369 local pipe = io.popen(vars.MKTEMP.." -d "..fs.Q(template))
370 local dirname = pipe:read("*l")
371 pipe:close()
372 if dirname and dirname:match("^/") then
373 return dirname
374 end
375 return nil, "Failed to create temporary directory "..tostring(dirname)
376end
377
360return tools 378return tools
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua
index 0c8cc9e9..c14c421b 100644
--- a/src/luarocks/fs/win32.lua
+++ b/src/luarocks/fs/win32.lua
@@ -10,6 +10,8 @@ local cfg = require("luarocks.cfg")
10local dir = require("luarocks.dir") 10local dir = require("luarocks.dir")
11local util = require("luarocks.util") 11local util = require("luarocks.util")
12 12
13math.randomseed(os.time())
14
13-- Monkey patch io.popen and os.execute to make sure quoting 15-- Monkey patch io.popen and os.execute to make sure quoting
14-- works as expected. 16-- works as expected.
15-- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html 17-- See http://lua-users.org/lists/lua-l/2013-11/msg00367.html
@@ -221,6 +223,23 @@ function win32.is_writable(file)
221 return result 223 return result
222end 224end
223 225
226--- Create a temporary directory.
227-- @param name string: name pattern to use for avoiding conflicts
228-- when creating temporary directory.
229-- @return string or (nil, string): name of temporary directory or (nil, error message) on failure.
230function win32.make_temp_dir(name)
231 assert(type(name) == "string")
232 name = dir.normalize(name)
233
234 local temp_dir = os.getenv("TMP") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000))
235 local ok, err = fs.make_dir(temp_dir)
236 if ok then
237 return temp_dir
238 else
239 return nil, err
240 end
241end
242
224function win32.tmpname() 243function win32.tmpname()
225 return os.getenv("TMP")..os.tmpname() 244 return os.getenv("TMP")..os.tmpname()
226end 245end
diff --git a/src/luarocks/list.lua b/src/luarocks/list.lua
index fddded03..99868028 100644
--- a/src/luarocks/list.lua
+++ b/src/luarocks/list.lua
@@ -93,8 +93,8 @@ function list.run(...)
93 93
94 local results = {} 94 local results = {}
95 for _, tree in ipairs(trees) do 95 for _, tree in ipairs(trees) do
96 local ok, err = search.manifest_search(results, path.rocks_dir(tree), query) 96 local ok, err, errcode = search.manifest_search(results, path.rocks_dir(tree), query)
97 if not ok then 97 if not ok and errcode ~= "open" then
98 util.warning(err) 98 util.warning(err)
99 end 99 end
100 end 100 end
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua
index f53f8dca..05621315 100644
--- a/src/luarocks/manif.lua
+++ b/src/luarocks/manif.lua
@@ -105,18 +105,22 @@ end
105-- All functions that use manifest tables assume they were obtained 105-- All functions that use manifest tables assume they were obtained
106-- through either this function or load_local_manifest. 106-- through either this function or load_local_manifest.
107-- @param repo_url string: URL or pathname for the repository. 107-- @param repo_url string: URL or pathname for the repository.
108-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
108-- @return table or (nil, string, [string]): A table representing the manifest, 109-- @return table or (nil, string, [string]): A table representing the manifest,
109-- or nil followed by an error message and an optional error code. 110-- or nil followed by an error message and an optional error code.
110function manif.load_manifest(repo_url) 111function manif.load_manifest(repo_url, lua_version)
111 assert(type(repo_url) == "string") 112 assert(type(repo_url) == "string")
113 assert(type(lua_version) == "string" or not lua_version)
114 lua_version = lua_version or cfg.lua_version
112 115
113 if manif_core.manifest_cache[repo_url] then 116 local cached_manifest = manif_core.get_cached_manifest(repo_url, lua_version)
114 return manif_core.manifest_cache[repo_url] 117 if cached_manifest then
118 return cached_manifest
115 end 119 end
116 120
117 local filenames = { 121 local filenames = {
118 "manifest-"..cfg.lua_version..".zip", 122 "manifest-"..lua_version..".zip",
119 "manifest-"..cfg.lua_version, 123 "manifest-"..lua_version,
120 "manifest", 124 "manifest",
121 } 125 }
122 126
@@ -156,7 +160,7 @@ function manif.load_manifest(repo_url)
156 end 160 end
157 pathname = nozip 161 pathname = nozip
158 end 162 end
159 return manif_core.manifest_loader(pathname, repo_url) 163 return manif_core.manifest_loader(pathname, repo_url, lua_version)
160end 164end
161 165
162--- Output a table listing items of a package. 166--- Output a table listing items of a package.
@@ -381,7 +385,7 @@ function manif.make_manifest(repo, deps_mode, remote)
381 local results = search.disk_search(repo, query) 385 local results = search.disk_search(repo, query)
382 local manifest = { repository = {}, modules = {}, commands = {} } 386 local manifest = { repository = {}, modules = {}, commands = {} }
383 387
384 manif_core.manifest_cache[repo] = manifest 388 manif_core.cache_manifest(repo, nil, manifest)
385 389
386 local dep_handler = nil 390 local dep_handler = nil
387 if not remote then 391 if not remote then
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua
index d719caa2..610f9860 100644
--- a/src/luarocks/manif_core.lua
+++ b/src/luarocks/manif_core.lua
@@ -7,31 +7,56 @@ package.loaded["luarocks.manif_core"] = manif_core
7 7
8local persist = require("luarocks.persist") 8local persist = require("luarocks.persist")
9local type_check = require("luarocks.type_check") 9local type_check = require("luarocks.type_check")
10local cfg = require("luarocks.cfg")
10local dir = require("luarocks.dir") 11local dir = require("luarocks.dir")
11local util = require("luarocks.util") 12local util = require("luarocks.util")
12local path = require("luarocks.path") 13local path = require("luarocks.path")
13 14
14manif_core.manifest_cache = {} 15-- Table with repository identifiers as keys and tables mapping
16-- Lua versions to cached loaded manifests as values.
17local manifest_cache = {}
18
19--- Cache a loaded manifest.
20-- @param repo_url string: The repository identifier.
21-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
22-- @param manifest table: the manifest to be cached.
23function manif_core.cache_manifest(repo_url, lua_version, manifest)
24 lua_version = lua_version or cfg.lua_version
25 manifest_cache[repo_url] = manifest_cache[repo_url] or {}
26 manifest_cache[repo_url][lua_version] = manifest
27end
28
29--- Attempt to get cached loaded manifest.
30-- @param repo_url string: The repository identifier.
31-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
32-- @return table or nil: loaded manifest or nil if cache is empty.
33function manif_core.get_cached_manifest(repo_url, lua_version)
34 lua_version = lua_version or cfg.lua_version
35 return manifest_cache[repo_url] and manifest_cache[repo_url][lua_version]
36end
15 37
16--- Back-end function that actually loads the manifest 38--- Back-end function that actually loads the manifest
17-- and stores it in the manifest cache. 39-- and stores it in the manifest cache.
18-- @param file string: The local filename of the manifest file. 40-- @param file string: The local filename of the manifest file.
19-- @param repo_url string: The repository identifier. 41-- @param repo_url string: The repository identifier.
42-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
20-- @param quick boolean: If given, skips type checking. 43-- @param quick boolean: If given, skips type checking.
21function manif_core.manifest_loader(file, repo_url, quick) 44-- @return table or (nil, string, string): the manifest or nil,
22 local manifest, err = persist.load_into_table(file) 45-- error message and error code ("open", "load", "run" or "type").
46function manif_core.manifest_loader(file, repo_url, lua_version, quick)
47 local manifest, err, errcode = persist.load_into_table(file)
23 if not manifest then 48 if not manifest then
24 return nil, "Failed loading manifest for "..repo_url..": "..err 49 return nil, "Failed loading manifest for "..repo_url..": "..err, errcode
25 end 50 end
26 local globals = err 51 local globals = err
27 if not quick then 52 if not quick then
28 local ok, err = type_check.type_check_manifest(manifest, globals) 53 local ok, err = type_check.type_check_manifest(manifest, globals)
29 if not ok then 54 if not ok then
30 return nil, "Error checking manifest: "..err 55 return nil, "Error checking manifest: "..err, "type"
31 end 56 end
32 end 57 end
33 58
34 manif_core.manifest_cache[repo_url] = manifest 59 manif_core.cache_manifest(repo_url, lua_version, manifest)
35 return manifest 60 return manifest
36end 61end
37 62
@@ -39,18 +64,18 @@ end
39-- All functions that use manifest tables assume they were obtained 64-- All functions that use manifest tables assume they were obtained
40-- through either this function or load_manifest. 65-- through either this function or load_manifest.
41-- @param repo_url string: URL or pathname for the repository. 66-- @param repo_url string: URL or pathname for the repository.
42-- @return table or (nil, string): A table representing the manifest, 67-- @return table or (nil, string, string): A table representing the manifest,
43-- or nil followed by an error message. 68-- or nil followed by an error message and an error code, see manifest_loader.
44function manif_core.load_local_manifest(repo_url) 69function manif_core.load_local_manifest(repo_url)
45 assert(type(repo_url) == "string") 70 assert(type(repo_url) == "string")
46 71
47 if manif_core.manifest_cache[repo_url] then 72 local cached_manifest = manif_core.get_cached_manifest(repo_url)
48 return manif_core.manifest_cache[repo_url] 73 if cached_manifest then
74 return cached_manifest
49 end 75 end
50 76
51 local pathname = dir.path(repo_url, "manifest") 77 local pathname = dir.path(repo_url, "manifest")
52 78 return manif_core.manifest_loader(pathname, repo_url, nil, true)
53 return manif_core.manifest_loader(pathname, repo_url, true)
54end 79end
55 80
56--- Get all versions of a package listed in a manifest file. 81--- Get all versions of a package listed in a manifest file.
diff --git a/src/luarocks/path_cmd.lua b/src/luarocks/path_cmd.lua
index 2bee4cb5..ecd6d4b1 100644
--- a/src/luarocks/path_cmd.lua
+++ b/src/luarocks/path_cmd.lua
@@ -37,7 +37,7 @@ function path_cmd.run(...)
37 local flags = util.parse_flags(...) 37 local flags = util.parse_flags(...)
38 local deps_mode = deps.get_deps_mode(flags) 38 local deps_mode = deps.get_deps_mode(flags)
39 39
40 local lr_path, lr_cpath, lr_bin = cfg.package_paths() 40 local lr_path, lr_cpath, lr_bin = cfg.package_paths(flags["tree"])
41 local path_sep = cfg.export_path_separator 41 local path_sep = cfg.export_path_separator
42 42
43 if flags["lr-path"] then 43 if flags["lr-path"] then
diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua
index 5e6cf50e..6c0020c0 100644
--- a/src/luarocks/search.lua
+++ b/src/luarocks/search.lua
@@ -170,14 +170,15 @@ end
170-- If the arch field is omitted, the local architecture (cfg.arch) 170-- If the arch field is omitted, the local architecture (cfg.arch)
171-- is used. The special value "any" is also recognized, returning all 171-- is used. The special value "any" is also recognized, returning all
172-- matches regardless of architecture. 172-- matches regardless of architecture.
173-- @return true or, in case of errors, nil and an error message. 173-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
174function search.manifest_search(results, repo, query) 174-- @return true or, in case of errors, nil, an error message and an optional error code.
175function search.manifest_search(results, repo, query, lua_version)
175 assert(type(results) == "table") 176 assert(type(results) == "table")
176 assert(type(repo) == "string") 177 assert(type(repo) == "string")
177 assert(type(query) == "table") 178 assert(type(query) == "table")
178 179
179 query_arch_as_table(query) 180 query_arch_as_table(query)
180 local manifest, err, errcode = manif.load_manifest(repo) 181 local manifest, err, errcode = manif.load_manifest(repo, lua_version)
181 if not manifest then 182 if not manifest then
182 return nil, err, errcode 183 return nil, err, errcode
183 end 184 end
@@ -193,10 +194,11 @@ end
193 194
194--- Search on all configured rocks servers. 195--- Search on all configured rocks servers.
195-- @param query table: A dependency query. 196-- @param query table: A dependency query.
197-- @param lua_version string: Lua version in "5.x" format, defaults to installed version.
196-- @return table: A table where keys are package names 198-- @return table: A table where keys are package names
197-- and values are tables matching version strings to arrays of 199-- and values are tables matching version strings to arrays of
198-- tables with fields "arch" and "repo". 200-- tables with fields "arch" and "repo".
199function search.search_repos(query) 201function search.search_repos(query, lua_version)
200 assert(type(query) == "table") 202 assert(type(query) == "table")
201 203
202 local results = {} 204 local results = {}
@@ -210,7 +212,7 @@ function search.search_repos(query)
210 if protocol == "file" then 212 if protocol == "file" then
211 mirror = pathname 213 mirror = pathname
212 end 214 end
213 local ok, err, errcode = search.manifest_search(results, mirror, query) 215 local ok, err, errcode = search.manifest_search(results, mirror, query, lua_version)
214 if errcode == "network" then 216 if errcode == "network" then
215 cfg.disabled_servers[repo] = true 217 cfg.disabled_servers[repo] = true
216 end 218 end
@@ -278,6 +280,23 @@ local function pick_latest_version(name, versions)
278 return nil 280 return nil
279end 281end
280 282
283-- Find out which other Lua versions provide rock versions matching a query,
284-- @param query table: A dependency query matching a single rock.
285-- @return table: array of Lua versions supported, in "5.x" format.
286local function supported_lua_versions(query)
287 local results = {}
288
289 for lua_version in util.lua_versions() do
290 if lua_version ~= cfg.lua_version then
291 if search.search_repos(query, lua_version)[query.name] then
292 table.insert(results, lua_version)
293 end
294 end
295 end
296
297 return results
298end
299
281--- Attempt to get a single URL for a given search for a rock. 300--- Attempt to get a single URL for a given search for a rock.
282-- @param query table: A dependency query matching a single rock. 301-- @param query table: A dependency query matching a single rock.
283-- @return string or (nil, string): URL for latest matching version 302-- @return string or (nil, string): URL for latest matching version
@@ -288,6 +307,29 @@ function search.find_suitable_rock(query)
288 local results = search.search_repos(query) 307 local results = search.search_repos(query)
289 local first_rock = next(results) 308 local first_rock = next(results)
290 if not first_rock then 309 if not first_rock then
310 if cfg.rocks_provided[query.name] == nil then
311 -- Check if constraints are satisfiable with other Lua versions.
312 local lua_versions = supported_lua_versions(query)
313
314 if #lua_versions ~= 0 then
315 -- Build a nice message in "only Lua 5.x and 5.y but not 5.z." format
316 for i, lua_version in ipairs(lua_versions) do
317 lua_versions[i] = "Lua "..lua_version
318 end
319
320 local versions_message = "only "..table.concat(lua_versions, " and ")..
321 " but not Lua "..cfg.lua_version.."."
322
323 if #query.constraints == 0 then
324 return nil, query.name.." supports "..versions_message
325 elseif #query.constraints == 1 and query.constraints[1].op == "==" then
326 return nil, query.name.." "..query.constraints[1].version.string.." supports "..versions_message
327 else
328 return nil, "Matching "..query.name.." versions support "..versions_message
329 end
330 end
331 end
332
291 return nil, "No results matching query were found." 333 return nil, "No results matching query were found."
292 elseif next(results, first_rock) then 334 elseif next(results, first_rock) then
293 -- Shouldn't happen as query must match only one package. 335 -- Shouldn't happen as query must match only one package.
@@ -369,7 +411,7 @@ function search.act_on_src_or_rockspec(action, name, version, ...)
369 query.arch = "src|rockspec" 411 query.arch = "src|rockspec"
370 local url, err = search.find_suitable_rock(query) 412 local url, err = search.find_suitable_rock(query)
371 if not url then 413 if not url then
372 return nil, "Could not find a result named "..name..(version and " "..version or "").."." 414 return nil, "Could not find a result named "..name..(version and " "..version or "")..": "..err
373 end 415 end
374 return action(url, ...) 416 return action(url, ...)
375end 417end
diff --git a/test/testing.lua b/test/testing.lua
index 6d4b4b05..c37293ee 100644
--- a/test/testing.lua
+++ b/test/testing.lua
@@ -266,6 +266,7 @@ local tests = {
266 test_path_lr_path = function() return run "$luarocks path --lr-path" end, 266 test_path_lr_path = function() return run "$luarocks path --lr-path" end,
267 test_path_lr_cpath = function() return run "$luarocks path --lr-cpath" end, 267 test_path_lr_cpath = function() return run "$luarocks path --lr-cpath" end,
268 test_path_lr_bin = function() return run "$luarocks path --lr-bin" end, 268 test_path_lr_bin = function() return run "$luarocks path --lr-bin" end,
269 test_path_with_tree = function() return run "$luarocks path --tree=lua_modules" end,
269 fail_purge_missing_tree = function() return run '$luarocks purge --tree="$testing_tree"' end, 270 fail_purge_missing_tree = function() return run '$luarocks purge --tree="$testing_tree"' end,
270 test_purge = function() return run '$luarocks purge --tree="$testing_sys_tree"' end, 271 test_purge = function() return run '$luarocks purge --tree="$testing_sys_tree"' end,
271 test_remove = function() 272 test_remove = function()
diff --git a/test/testing.sh b/test/testing.sh
index 92c6ab5d..dbc1249e 100755
--- a/test/testing.sh
+++ b/test/testing.sh
@@ -213,7 +213,7 @@ srcdir_luasocket=luasocket-3.0-rc1
213version_cprint=0.1 213version_cprint=0.1
214verrev_cprint=0.1-2 214verrev_cprint=0.1-2
215 215
216version_luacov=0.9.1 216version_luacov=0.11.0
217verrev_luacov=${version_luacov}-1 217verrev_luacov=${version_luacov}-1
218version_lxsh=0.8.6 218version_lxsh=0.8.6
219version_validate_args=1.5.4 219version_validate_args=1.5.4
@@ -364,7 +364,6 @@ need() {
364need_luasocket() { need luasocket $verrev_luasocket; } 364need_luasocket() { need luasocket $verrev_luasocket; }
365 365
366# Tests ######################################### 366# Tests #########################################
367
368test_version() { $luarocks --version; } 367test_version() { $luarocks --version; }
369 368
370fail_unknown_command() { $luarocks unknown_command; } 369fail_unknown_command() { $luarocks unknown_command; }
@@ -445,6 +444,7 @@ test_download_rockspecversion() { $luarocks download --rockspec validate-args ${
445test_help() { $luarocks help; } 444test_help() { $luarocks help; }
446fail_help_invalid() { $luarocks help invalid; } 445fail_help_invalid() { $luarocks help invalid; }
447 446
447test_install_only_deps() { $luarocks install --only-deps "$testing_cache/luasocket-$verrev_luasocket.$platform.rock"; }
448test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; } 448test_install_binaryrock() { $luarocks build --pack-binary-rock cprint && $luarocks install ./cprint-${verrev_cprint}.${platform}.rock && rm ./cprint-${verrev_cprint}.${platform}.rock; }
449test_install_with_bin() { $luarocks install wsapi; } 449test_install_with_bin() { $luarocks install wsapi; }
450fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; } 450fail_install_notazipfile() { $luarocks install "$testing_dir/testfiles/not_a_zipfile-1.0-1.src.rock"; }
@@ -484,9 +484,12 @@ test_path() { $luarocks path --bin; }
484test_path_lr_path() { $luarocks path --lr-path; } 484test_path_lr_path() { $luarocks path --lr-path; }
485test_path_lr_cpath() { $luarocks path --lr-cpath; } 485test_path_lr_cpath() { $luarocks path --lr-cpath; }
486test_path_lr_bin() { $luarocks path --lr-bin; } 486test_path_lr_bin() { $luarocks path --lr-bin; }
487test_path_with_tree() { $luarocks path --tree=lua_modules; }
487 488
488fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; } 489fail_purge_missing_tree() { $luarocks purge --tree="$testing_tree"; }
490fail_purge_tree_notstring() { $luarocks purge --tree=1; }
489test_purge() { $luarocks purge --tree="$testing_sys_tree"; } 491test_purge() { $luarocks purge --tree="$testing_sys_tree"; }
492test_purge_oldversions() { $luarocks purge --old-versions --tree="$testing_sys_tree"; }
490 493
491test_remove() { $luarocks build abelhas ${version_abelhas} && $luarocks remove abelhas ${version_abelhas}; } 494test_remove() { $luarocks build abelhas ${version_abelhas} && $luarocks remove abelhas ${version_abelhas}; }
492test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; } 495test_remove_force() { need_luasocket; $luarocks build lualogging && $luarocks remove --force luasocket; }
@@ -520,6 +523,9 @@ fail_unpack_invalidrockspec() { need_luasocket; $luarocks unpack "invalid.rocksp
520 523
521fail_upload_invalidrockspec() { $luarocks upload "invalid.rockspec"; } 524fail_upload_invalidrockspec() { $luarocks upload "invalid.rockspec"; }
522fail_upload_invalidkey() { $luarocks upload --api-key="invalid" "invalid.rockspec"; } 525fail_upload_invalidkey() { $luarocks upload --api-key="invalid" "invalid.rockspec"; }
526fail_upload_skippack() { $luarocks upload --api-key="invalid" --skip-pack "luacov-${verrev_luacov}.rockspec"; }
527fail_upload_force() { $luarocks install lua-cjson && $luarocks upload --api-key="invalid" --force "luacov-${verrev_luacov}.rockspec" && $luarocks remove lua-cjson; }
528
523 529
524test_admin_help() { $luarocks_admin help; } 530test_admin_help() { $luarocks_admin help; }
525 531
@@ -595,6 +601,9 @@ fail_luajit_dependency() {
595test_doc() { $luarocks install luarepl; $luarocks doc luarepl; } 601test_doc() { $luarocks install luarepl; $luarocks doc luarepl; }
596test_doc_home() { $luarocks install luacov; $luarocks doc luacov --home; } 602test_doc_home() { $luarocks install luacov; $luarocks doc luacov --home; }
597fail_doc_invalid() { $luarocks doc invalid; } 603fail_doc_invalid() { $luarocks doc invalid; }
604test_doc_list() { $luarocks install luacov; $luarocks doc luacov --list; }
605test_doc_local() { $luarocks install luacov; $luarocks doc luacov --local; }
606test_doc_porcelain() { $luarocks install luacov; $luarocks doc luacov --porcelain; }
598 607
599# Driver ######################################### 608# Driver #########################################
600 609