From 5cdc22fb3c3a85160cd7c2d49ba10ab113e4a784 Mon Sep 17 00:00:00 2001 From: Hisham Date: Thu, 11 Aug 2016 20:55:08 -0300 Subject: Make behavior of config files on Windows more consistent with that on Unix. This was detected during the port of the new testsuite to Windows by @robooo. --- src/luarocks/cfg.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index d58c7407..d84ebc6e 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua @@ -5,10 +5,9 @@ -- file format documentation for details. -- -- End-users shouldn't edit this file. They can override any defaults --- set in this file using their system-wide $LUAROCKS_SYSCONFIG file --- (see luarocks.site_config) or their user-specific configuration file --- (~/.luarocks/config.lua on Unix or %APPDATA%/luarocks/config.lua on --- Windows). +-- set in this file using their system-wide or user-specific configuration +-- files. Run `luarocks` with no arguments to see the locations of +-- these files in your platform. local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION = rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, tonumber, type, assert, _VERSION -- cgit v1.2.3-55-g6feb From af41c31d62c4e44c9f5c12a8ce10d6d49aa05347 Mon Sep 17 00:00:00 2001 From: Hisham Date: Mon, 22 Aug 2016 18:36:30 -0300 Subject: Use Unix makefile by default on MinGW; Makefile.win is a leftover from Kepler days, and those are usually NMAKE makefiles for MSVC. --- src/luarocks/cfg.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index d84ebc6e..bcb30342 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua @@ -468,6 +468,7 @@ if cfg.platforms.mingw32 then defaults.variables.LD = "mingw32-gcc" defaults.variables.CFLAGS = "-O2" defaults.variables.LIBFLAG = "-shared" + defaults.makefile = "Makefile" defaults.external_deps_patterns = { bin = { "?.exe", "?.bat" }, -- mingw lookup list from http://stackoverflow.com/a/15853231/1793220 -- cgit v1.2.3-55-g6feb From c53a3c84000cfeaa5749abe3a5917b55f74c21de Mon Sep 17 00:00:00 2001 From: Hisham Date: Thu, 8 Sep 2016 11:28:52 -0300 Subject: Make `pack` use the same logic as `show` for finding a rock. --- src/luarocks/doc.lua | 4 ++-- src/luarocks/pack.lua | 36 +++++++++--------------------------- src/luarocks/search.lua | 33 +++++++++++++++++++++++++++++++++ src/luarocks/show.lua | 37 ++----------------------------------- 4 files changed, 46 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/luarocks/doc.lua b/src/luarocks/doc.lua index ec2b1110..15460b31 100644 --- a/src/luarocks/doc.lua +++ b/src/luarocks/doc.lua @@ -5,7 +5,7 @@ local doc = {} package.loaded["luarocks.doc"] = doc local util = require("luarocks.util") -local show = require("luarocks.show") +local search = require("luarocks.search") local path = require("luarocks.path") local dir = require("luarocks.dir") local fetch = require("luarocks.fetch") @@ -63,7 +63,7 @@ function doc.command(flags, name, version) return nil, "Argument missing. "..util.see_help("doc") end - local iname, iversion, repo = show.pick_installed_rock(name, version, flags["tree"]) + local iname, iversion, repo = search.pick_installed_rock(name, version, flags["tree"]) if not iname then util.printout(name..(version and " "..version or "").." is not installed. Looking for it in the rocks servers...") return try_to_open_homepage(name, version) diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua index 277cf246..fb40a576 100644 --- a/src/luarocks/pack.lua +++ b/src/luarocks/pack.lua @@ -85,38 +85,20 @@ end -- @param name string: Name of package to pack. -- @param version string or nil: A version number may also be passed. +-- @param tree string or nil: An optional tree to pick the package from. -- @return string or (nil, string): The filename of the resulting -- .src.rock file; or nil and an error message. -local function do_pack_binary_rock(name, version) +local function do_pack_binary_rock(name, version, tree) assert(type(name) == "string") assert(type(version) == "string" or not version) - local query = search.make_query(name, version) - query.exact_name = true - local results = {} - - search.manifest_search(results, cfg.rocks_dir, query) - - if not next(results) then - return nil, "'"..name.."' does not seem to be an installed rock." - end - - local versions = results[name] - - if not version then - local first = next(versions) - if next(versions, first) then - return nil, "Please specify which version of '"..name.."' to pack." - end - version = first - end - if not version:match("[^-]+%-%d+") then - return nil, "Expected version "..version.." in version-revision format." + local repo, repo_url + name, version, repo, repo_url = search.pick_installed_rock(name, version, tree) + if not name then + return nil, version end - - local info = versions[version][1] - - local root = path.root_dir(info.repo) + + local root = path.root_dir(repo_url) local prefix = path.install_dir(name, version, root) if not fs.exists(prefix) then return nil, "'"..name.." "..version.."' does not seem to be an installed rock." @@ -202,7 +184,7 @@ function pack.command(flags, arg, version) if arg:match(".*%.rockspec") then file, err = pack.pack_source_rock(arg) else - file, err = do_pack_binary_rock(arg, version) + file, err = do_pack_binary_rock(arg, version, flags["tree"]) end if err then return nil, err diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index eaa321d5..d22c2a18 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua @@ -416,6 +416,39 @@ function search.act_on_src_or_rockspec(action, name, version, ...) return action(url, ...) end +function search.pick_installed_rock(name, version, given_tree) + local results = {} + local query = search.make_query(name, version) + query.exact_name = true + local tree_map = {} + local trees = cfg.rocks_trees + if given_tree then + trees = { given_tree } + end + for _, tree in ipairs(trees) do + local rocks_dir = path.rocks_dir(tree) + tree_map[rocks_dir] = tree + search.manifest_search(results, rocks_dir, query) + end + + if not next(results) then -- + return nil,"cannot find package "..name.." "..(version or "").."\nUse 'list' to find installed rocks." + end + + version = nil + local repo_url + local package, versions = util.sortedpairs(results)() + --question: what do we do about multiple versions? This should + --give us the latest version on the last repo (which is usually the global one) + for vs, repositories in util.sortedpairs(versions, deps.compare_versions) do + if not version then version = vs end + for _, rp in ipairs(repositories) do repo_url = rp.repo end + end + + local repo = tree_map[repo_url] + return name, version, repo, repo_url +end + --- Driver function for "search" command. -- @param name string: A substring of a rock name to search. -- @param version string or nil: a version may also be passed. diff --git a/src/luarocks/show.lua b/src/luarocks/show.lua index 01860e78..88f9512d 100644 --- a/src/luarocks/show.lua +++ b/src/luarocks/show.lua @@ -58,45 +58,12 @@ local function format_text(text) return (table.concat(paragraphs, "\n\n"):gsub("%s$", "")) end -function show.pick_installed_rock(name, version, tree) - local results = {} - local query = search.make_query(name, version) - query.exact_name = true - local tree_map = {} - local trees = cfg.rocks_trees - if tree then - trees = { tree } - end - for _, tree in ipairs(trees) do - local rocks_dir = path.rocks_dir(tree) - tree_map[rocks_dir] = tree - search.manifest_search(results, rocks_dir, query) - end - - if not next(results) then -- - return nil,"cannot find package "..name.." "..(version or "").."\nUse 'list' to find installed rocks." - end - - version = nil - local repo_url - local package, versions = util.sortedpairs(results)() - --question: what do we do about multiple versions? This should - --give us the latest version on the last repo (which is usually the global one) - for vs, repositories in util.sortedpairs(versions, deps.compare_versions) do - if not version then version = vs end - for _, rp in ipairs(repositories) do repo_url = rp.repo end - end - - local repo = tree_map[repo_url] - return name, version, repo, repo_url -end - local function installed_rock_label(name, tree) local installed, version if cfg.rocks_provided[name] then installed, version = true, cfg.rocks_provided[name] else - installed, version = show.pick_installed_rock(name, nil, tree) + installed, version = search.pick_installed_rock(name, nil, tree) end return installed and "(using "..version..")" or "(missing)" end @@ -111,7 +78,7 @@ function show.command(flags, name, version) end local repo, repo_url - name, version, repo, repo_url = show.pick_installed_rock(name, version, flags["tree"]) + name, version, repo, repo_url = search.pick_installed_rock(name, version, flags["tree"]) if not name then return nil, version end -- cgit v1.2.3-55-g6feb From c6d48427430b6b96f88b249dee1533fb5e6ff681 Mon Sep 17 00:00:00 2001 From: Hisham Date: Thu, 8 Sep 2016 13:10:40 -0300 Subject: Fix pack-binary-rock operation. --- src/luarocks/pack.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua index fb40a576..932ff0d5 100644 --- a/src/luarocks/pack.lua +++ b/src/luarocks/pack.lua @@ -164,7 +164,7 @@ function pack.pack_binary_rock(name, version, cmd, ...) if not rname then rname, rversion = name, version end - return do_pack_binary_rock(rname, rversion) + return do_pack_binary_rock(rname, rversion, temp_dir) end --- Driver function for the "pack" command. -- cgit v1.2.3-55-g6feb From 34963cbc145f9ea1521c24919a9c2c38ee24a7d8 Mon Sep 17 00:00:00 2001 From: Hisham Date: Wed, 5 Oct 2016 03:18:26 -0300 Subject: Simulate module() for older wrappers. Older versions of LuaRocks (e.g. 2.1.0) install script wrappers that assume that `luarocks.loader` is available in the global namespace (this is from the module() era). This workaround detects this (because site_config.lua files written by these old versions use module(), and therefore create a `luarocks` global. To reproduce this issue, make a clean install of LuaRocks 2.1.0, then run `luarocks install luarocks`. Installation succeds, but running `luarocks` produces `attempt to index field 'loader' (a nil value)`. Bug reported by @tomasguisasola. --- src/luarocks/loader.lua | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index 26280e94..06a0cfda 100644 --- a/src/luarocks/loader.lua +++ b/src/luarocks/loader.lua @@ -22,6 +22,11 @@ local manif_core = require("luarocks.manif_core") local deps = require("luarocks.deps") local util = require("luarocks.util") +-- Workaround for wrappers produced by older versions of LuaRocks +if luarocks then + luarocks.loader = loader +end + loader.context = {} -- Contains a table when rocks trees are loaded, -- cgit v1.2.3-55-g6feb From eb7427676a2f09556f9d5f19a1a6392fd945e8bc Mon Sep 17 00:00:00 2001 From: Peter Melnichenko Date: Thu, 6 Oct 2016 16:51:04 +0300 Subject: Rewrite util.sortedpairs to avoid using coroutines util.sortedpairs is used in luarocks loader since @6dc745a. Openresty does not like coroutines being used from inside `require`, resulting in "attempt to yield across C-call boundary" error. New version of util.sortedpairs uses a prepared array of ordered keys instead of coroutines. Ref #620. --- src/luarocks/util.lua | 79 ++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 532bea8b..c9fb7d63 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -357,52 +357,59 @@ local function default_sort(a, b) end end --- The iterator function used internally by util.sortedpairs. +--- A table iterator generator that returns elements sorted by key, +-- to be used in "for" loops. -- @param tbl table: The table to be iterated. --- @param sort_function function or nil: An optional comparison function --- to be used by table.sort when sorting keys. --- @see sortedpairs -local function sortedpairs_iterator(tbl, sort_function) - local ks = util.keys(tbl) - if not sort_function or type(sort_function) == "function" then - table.sort(ks, sort_function or default_sort) - for _, k in ipairs(ks) do - coroutine.yield(k, tbl[k]) - end +-- @param sort_function function or table or nil: An optional comparison function +-- to be used by table.sort when sorting keys, or an array listing an explicit order +-- for keys. If a value itself is an array, it is taken so that the first element +-- is a string representing the field name, and the second element is a priority table +-- for that key, which is returned by the iterator as the third value after the key +-- and the value. +-- @return function: the iterator function. +function util.sortedpairs(tbl, sort_function) + sort_function = sort_function or default_sort + local keys = util.keys(tbl) + local sub_orders = {} + + if type(sort_function) == "function" then + table.sort(keys, sort_function) else local order = sort_function - local done = {} - for _, k in ipairs(order) do - local sub_order - if type(k) == "table" then - sub_order = k[2] - k = k[1] + local ordered_keys = {} + local all_keys = keys + keys = {} + + for _, order_entry in ipairs(order) do + local key, sub_order + if type(order_entry) == "table" then + key = order_entry[1] + sub_order = order_entry[2] + else + key = order_entry end - if tbl[k] then - done[k] = true - coroutine.yield(k, tbl[k], sub_order) + + if tbl[key] then + ordered_keys[key] = true + sub_orders[key] = sub_order + table.insert(keys, key) end end - table.sort(ks, default_sort) - for _, k in ipairs(ks) do - if not done[k] then - coroutine.yield(k, tbl[k]) + + table.sort(all_keys, default_sort) + for _, key in ipairs(all_keys) do + if not ordered_keys[key] then + table.insert(keys, key) end end end -end ---- A table iterator generator that returns elements sorted by key, --- to be used in "for" loops. --- @param tbl table: The table to be iterated. --- @param sort_function function or table or nil: An optional comparison function --- to be used by table.sort when sorting keys, or an array listing an explicit order --- for keys. If a value itself is an array, it is taken so that the first element --- is a string representing the field name, and the second element is a priority table --- for that key. --- @return function: the iterator function. -function util.sortedpairs(tbl, sort_function) - return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end) + local i = 1 + return function() + local key = keys[i] + i = i + 1 + return key, tbl[key], sub_orders[key] + end end function util.lua_versions() -- cgit v1.2.3-55-g6feb From 67a7d4faee164903769d001abbebd1073ad87e01 Mon Sep 17 00:00:00 2001 From: Hisham Date: Thu, 6 Oct 2016 11:51:31 -0300 Subject: Make the workaround for older LuaRocks versions more robust. --- src/luarocks/loader.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index 06a0cfda..874bc10c 100644 --- a/src/luarocks/loader.lua +++ b/src/luarocks/loader.lua @@ -23,8 +23,25 @@ local deps = require("luarocks.deps") local util = require("luarocks.util") -- Workaround for wrappers produced by older versions of LuaRocks +local temporary_global = false if luarocks then + -- The site_config.lua file generated by old versions uses module(), + -- so it produces a global `luarocks` table. Since we have the table, + -- add the `loader` field to make the old wrappers happy. luarocks.loader = loader +else + -- When a new version is installed on top of an old version, + -- site_config.lua may be replaced, and then it no longer creates + -- a global. + -- Detect when being called via -lluarocks.loader; this is + -- most likely a wrapper. + local info = debug.getinfo(2, "nS") + if info.what == "C" and not info.name then + luarocks = { loader = loader } + temporary_global = true + -- For the other half of this hack, + -- see the next use of `temporary_global` below. + end end loader.context = {} @@ -60,6 +77,13 @@ function loader.add_context(name, version) -- assert(type(name) == "string") -- assert(type(version) == "string") + if temporary_global then + -- The first thing a wrapper does is to call add_context. + -- From here on, it's safe to clean the global environment. + luarocks = nil + temporary_global = false + end + if loader.context[name] then return end -- cgit v1.2.3-55-g6feb