From 91c1f20bbafdee236f78a93a78c233c833f413e9 Mon Sep 17 00:00:00 2001
From: Peter Melnichenko <mpeterval@gmail.com>
Date: Sat, 12 Nov 2016 00:35:46 +0300
Subject: Fix module paths `luarocks show` displays for "asset" files

Remove path.which that produced incorrect results for files
with no .lua/.so/.dll extension, reimplement similar functionality
in luarocks.repos (with support for commands as well) and use that instead.

Ref #424.
---
 src/luarocks/cmd/show.lua |  5 +++--
 src/luarocks/path.lua     | 21 ---------------------
 src/luarocks/repos.lua    | 27 +++++++++++++++++++++++++--
 3 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua
index 1ff81e08..ebb515c0 100644
--- a/src/luarocks/cmd/show.lua
+++ b/src/luarocks/cmd/show.lua
@@ -9,6 +9,7 @@ local path = require("luarocks.path")
 local deps = require("luarocks.deps")
 local fetch = require("luarocks.fetch")
 local manif = require("luarocks.manif")
+local repos = require("luarocks.repos")
 
 show.help_summary = "Show information about an installed rock."
 
@@ -124,8 +125,8 @@ function show.command(flags, name, version)
       if next(minfo.modules) then
          util.printout()
          util.printout("Modules:")
-         for mod, filename in util.sortedpairs(minfo.modules) do
-            util.printout("\t"..mod.." ("..path.which(mod, filename, name, version, repo, manifest)..")")
+         for mod in util.sortedpairs(minfo.modules) do
+            util.printout("\t"..mod.." ("..repos.which(name, version, "module", mod, repo)..")")
          end
       end
       local direct_deps = {}
diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua
index 83e9c295..71893cf1 100644
--- a/src/luarocks/path.lua
+++ b/src/luarocks/path.lua
@@ -231,25 +231,4 @@ function path.use_tree(tree)
    cfg.deploy_lib_dir = path.deploy_lib_dir(tree)
 end
 
---- Return the pathname of the file that would be loaded for a module, 
--- returning the versioned pathname if given version is not the default version
--- in the given manifest.
--- @param module_name string: module name (eg. "socket.core")
--- @param file_name string: module file name as in manifest (eg. "socket/core.so")
--- @param name string: name of the package (eg. "luasocket")
--- @param version string: version number (eg. "2.0.2-1")
--- @param tree string: repository path (eg. "/usr/local")
--- @param manifest table: the manifest table for the tree.
--- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
-function path.which(module_name, file_name, name, version, tree, manifest)
-   local versions = manifest.modules[module_name]
-   assert(versions)
-   for i, name_version in ipairs(versions) do
-      if name_version == name.."/"..version then
-         return path.which_i(file_name, name, version, tree, i):gsub("//", "/")
-      end
-   end
-   assert(false)
-end
-
 return path
diff --git a/src/luarocks/repos.lua b/src/luarocks/repos.lua
index 7c3251b9..5d5dedd6 100644
--- a/src/luarocks/repos.lua
+++ b/src/luarocks/repos.lua
@@ -231,8 +231,9 @@ end
 -- item from the newest version of lexicographically smallest package
 -- is deployed using non-versioned name and others use versioned names.
 
-local function get_deploy_paths(name, version, deploy_type, file_path)
-   local deploy_dir = cfg["deploy_" .. deploy_type .. "_dir"]
+local function get_deploy_paths(name, version, deploy_type, file_path, repo)
+   repo = repo or cfg.root_dir
+   local deploy_dir = path["deploy_" .. deploy_type .. "_dir"](repo)
    local non_versioned = dir.path(deploy_dir, file_path)
    local versioned = path.versioned_name(non_versioned, deploy_dir, name, version)
    return non_versioned, versioned
@@ -423,4 +424,26 @@ function repos.delete_version(name, version, deps_mode, quick)
    return writer.remove_from_manifest(name, version, nil, deps_mode)
 end
 
+--- Find full path to a file providing a module or a command
+-- in a package.
+-- @param name string: name of package.
+-- @param version string: exact package version in string format.
+-- @param item_type string: "module" or "command".
+-- @param item_name string: module or command name.
+-- @param root string or nil: A local root dir for a rocks tree. If not given, the default is used.
+-- @return string: absolute path to the file providing given module
+-- or command.
+function repos.which(name, version, item_type, item_name, repo)
+   local deploy_type, file_path = manif.get_providing_file(name, version, item_type, item_name, repo)
+   local non_versioned, versioned = get_deploy_paths(name, version, deploy_type, file_path, repo)
+   local cur_name, cur_version = manif.get_current_provider(item_type, item_name)
+   local deploy_path = (name == cur_name and version == cur_version) and non_versioned or versioned
+
+   if deploy_type == "bin" and cfg.wrapper_suffix and cfg.wrapper_suffix ~= "" then
+      deploy_path = find_suffixed(deploy_path, cfg.wrapper_suffix) or deploy_path
+   end
+
+   return deploy_path
+end
+
 return repos
-- 
cgit v1.2.3-55-g6feb