PageRenderTime 57ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/exe/luarocks/src/luarocks/path.lua

https://github.com/torch/torch7-distro
Lua | 395 lines | 254 code | 36 blank | 105 comment | 74 complexity | 6c6d34391b6cf50f177eb641ea808b09 MD5 | raw file
  1. --- LuaRocks-specific path handling functions.
  2. -- All paths are configured in this module, making it a single
  3. -- point where the layout of the local installation is defined in LuaRocks.
  4. module("luarocks.path", package.seeall)
  5. local dir = require("luarocks.dir")
  6. local cfg = require("luarocks.cfg")
  7. local util = require("luarocks.util")
  8. local deps = require("luarocks.deps")
  9. help_summary = "Return the currently configured package path."
  10. help_arguments = ""
  11. help = [[
  12. Returns the package path currently configured for this installation
  13. of LuaRocks, formatted as shell commands to update LUA_PATH and
  14. LUA_CPATH. (On Unix systems, you may run: eval `luarocks path`)
  15. ]]
  16. --- Infer rockspec filename from a rock filename.
  17. -- @param rock_name string: Pathname of a rock file.
  18. -- @return string: Filename of the rockspec, without path.
  19. function rockspec_name_from_rock(rock_name)
  20. assert(type(rock_name) == "string")
  21. local base_name = dir.base_name(rock_name)
  22. return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec"
  23. end
  24. function rocks_dir(tree)
  25. if type(tree) == "string" then
  26. return dir.path(tree, cfg.rocks_subdir)
  27. else
  28. assert(type(tree) == "table")
  29. return tree.rocks_dir or dir.path(tree.root, cfg.rocks_subdir)
  30. end
  31. end
  32. function root_dir(rocks_dir)
  33. assert(type(rocks_dir) == "string")
  34. return rocks_dir:match("(.*)" .. util.matchquote(cfg.rocks_subdir) .. ".*$")
  35. end
  36. function rocks_tree_to_string(tree)
  37. if type(tree) == "string" then
  38. return tree
  39. else
  40. assert(type(tree) == "table")
  41. return tree.root
  42. end
  43. end
  44. function deploy_bin_dir(tree)
  45. if type(tree) == "string" then
  46. return dir.path(tree, "bin")
  47. else
  48. assert(type(tree) == "table")
  49. return tree.bin_dir or dir.path(tree.root, "bin")
  50. end
  51. end
  52. function 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. function deploy_lib_dir(tree)
  61. if type(tree) == "string" then
  62. return dir.path(tree, cfg.lib_modules_path)
  63. else
  64. assert(type(tree) == "table")
  65. return tree.lib_dir or dir.path(tree.root, cfg.lib_modules_path)
  66. end
  67. end
  68. function manifest_file(tree)
  69. if type(tree) == "string" then
  70. return dir.path(tree, cfg.rocks_subdir, "manifest")
  71. else
  72. assert(type(tree) == "table")
  73. return (tree.rocks_dir and dir.path(tree.rocks_dir, "manifest")) or dir.path(tree.root, cfg.rocks_subdir, "manifest")
  74. end
  75. end
  76. --- Get the directory for all versions of a package in a tree.
  77. -- @param name string: The package name.
  78. -- @return string: The resulting path -- does not guarantee that
  79. -- @param tree string or nil: If given, specifies the local tree to use.
  80. -- the package (and by extension, the path) exists.
  81. function versions_dir(name, tree)
  82. assert(type(name) == "string")
  83. tree = tree or cfg.root_dir
  84. return dir.path(rocks_dir(tree), name)
  85. end
  86. --- Get the local installation directory (prefix) for a package.
  87. -- @param name string: The package name.
  88. -- @param version string: The package version.
  89. -- @param tree string or nil: If given, specifies the local tree to use.
  90. -- @return string: The resulting path -- does not guarantee that
  91. -- the package (and by extension, the path) exists.
  92. function install_dir(name, version, tree)
  93. assert(type(name) == "string")
  94. assert(type(version) == "string")
  95. tree = tree or cfg.root_dir
  96. return dir.path(rocks_dir(tree), name, version)
  97. end
  98. --- Get the local filename of the rockspec of an installed rock.
  99. -- @param name string: The package name.
  100. -- @param version string: The package version.
  101. -- @param tree string or nil: If given, specifies the local tree to use.
  102. -- @return string: The resulting path -- does not guarantee that
  103. -- the package (and by extension, the file) exists.
  104. function rockspec_file(name, version, tree)
  105. assert(type(name) == "string")
  106. assert(type(version) == "string")
  107. tree = tree or cfg.root_dir
  108. return dir.path(rocks_dir(tree), name, version, name.."-"..version..".rockspec")
  109. end
  110. --- Get the local filename of the rock_manifest file of an installed rock.
  111. -- @param name string: The package name.
  112. -- @param version string: The package version.
  113. -- @param tree string or nil: If given, specifies the local tree to use.
  114. -- @return string: The resulting path -- does not guarantee that
  115. -- the package (and by extension, the file) exists.
  116. function rock_manifest_file(name, version, tree)
  117. assert(type(name) == "string")
  118. assert(type(version) == "string")
  119. tree = tree or cfg.root_dir
  120. return dir.path(rocks_dir(tree), name, version, "rock_manifest")
  121. end
  122. --- Get the local installation directory for C libraries of a package.
  123. -- @param name string: The package name.
  124. -- @param version string: The package version.
  125. -- @param tree string or nil: If given, specifies the local tree to use.
  126. -- @return string: The resulting path -- does not guarantee that
  127. -- the package (and by extension, the path) exists.
  128. function lib_dir(name, version, tree)
  129. assert(type(name) == "string")
  130. assert(type(version) == "string")
  131. tree = tree or cfg.root_dir
  132. return dir.path(rocks_dir(tree), name, version, "lib")
  133. end
  134. --- Get the local installation directory for Lua modules of a package.
  135. -- @param name string: The package name.
  136. -- @param version string: The package version.
  137. -- @param tree string or nil: If given, specifies the local tree to use.
  138. -- @return string: The resulting path -- does not guarantee that
  139. -- the package (and by extension, the path) exists.
  140. function lua_dir(name, version, tree)
  141. assert(type(name) == "string")
  142. assert(type(version) == "string")
  143. tree = tree or cfg.root_dir
  144. return dir.path(rocks_dir(tree), name, version, "lua")
  145. end
  146. --- Get the local installation directory for documentation of a package.
  147. -- @param name string: The package name.
  148. -- @param version string: The package version.
  149. -- @param tree string or nil: If given, specifies the local tree to use.
  150. -- @return string: The resulting path -- does not guarantee that
  151. -- the package (and by extension, the path) exists.
  152. function doc_dir(name, version, tree)
  153. assert(type(name) == "string")
  154. assert(type(version) == "string")
  155. tree = tree or cfg.root_dir
  156. return dir.path(rocks_dir(tree), name, version, "doc")
  157. end
  158. --- Get the local installation directory for configuration files of a package.
  159. -- @param name string: The package name.
  160. -- @param version string: The package version.
  161. -- @param tree string or nil: If given, specifies the local tree to use.
  162. -- @return string: The resulting path -- does not guarantee that
  163. -- the package (and by extension, the path) exists.
  164. function conf_dir(name, version, tree)
  165. assert(type(name) == "string")
  166. assert(type(version) == "string")
  167. tree = tree or cfg.root_dir
  168. return dir.path(rocks_dir(tree), name, version, "conf")
  169. end
  170. --- Get the local installation directory for command-line scripts
  171. -- of a package.
  172. -- @param name string: The package name.
  173. -- @param version string: The package version.
  174. -- @param tree string or nil: If given, specifies the local tree to use.
  175. -- @return string: The resulting path -- does not guarantee that
  176. -- the package (and by extension, the path) exists.
  177. function bin_dir(name, version, tree)
  178. assert(type(name) == "string")
  179. assert(type(version) == "string")
  180. tree = tree or cfg.root_dir
  181. return dir.path(rocks_dir(tree), name, version, "bin")
  182. end
  183. --- Extract name, version and arch of a rock filename,
  184. -- or name, version and "rockspec" from a rockspec name.
  185. -- @param file_name string: pathname of a rock or rockspec
  186. -- @return (string, string, string) or nil: name, version and arch
  187. -- or nil if name could not be parsed
  188. function parse_name(file_name)
  189. assert(type(file_name) == "string")
  190. if file_name:match("%.rock$") then
  191. return dir.base_name(file_name):match("(.*)-([^-]+-%d+)%.([^.]+)%.rock$")
  192. else
  193. return dir.base_name(file_name):match("(.*)-([^-]+-%d+)%.(rockspec)")
  194. end
  195. end
  196. --- Make a rockspec or rock URL.
  197. -- @param pathname string: Base URL or pathname.
  198. -- @param name string: Package name.
  199. -- @param version string: Package version.
  200. -- @param arch string: Architecture identifier, or "rockspec" or "installed".
  201. -- @return string: A URL or pathname following LuaRocks naming conventions.
  202. function make_url(pathname, name, version, arch)
  203. assert(type(pathname) == "string")
  204. assert(type(name) == "string")
  205. assert(type(version) == "string")
  206. assert(type(arch) == "string")
  207. local filename = name.."-"..version
  208. if arch == "installed" then
  209. filename = dir.path(name, version, filename..".rockspec")
  210. elseif arch == "rockspec" then
  211. filename = filename..".rockspec"
  212. else
  213. filename = filename.."."..arch..".rock"
  214. end
  215. return dir.path(pathname, filename)
  216. end
  217. --- Convert a pathname to a module identifier.
  218. -- In Unix, for example, a path "foo/bar/baz.lua" is converted to
  219. -- "foo.bar.baz"; "bla/init.lua" returns "bla"; "foo.so" returns "foo".
  220. -- @param file string: Pathname of module
  221. -- @return string: The module identifier, or nil if given path is
  222. -- not a conformant module path (the function does not check if the
  223. -- path actually exists).
  224. function path_to_module(file)
  225. assert(type(file) == "string")
  226. local name = file:match("(.*)%."..cfg.lua_extension.."$")
  227. if name then
  228. name = name:gsub(dir.separator, ".")
  229. local init = name:match("(.*)%.init$")
  230. if init then
  231. name = init
  232. end
  233. else
  234. name = file:match("(.*)%."..cfg.lib_extension.."$")
  235. if name then
  236. name = name:gsub(dir.separator, ".")
  237. end
  238. end
  239. if not name then name = file end
  240. name = name:gsub("^%.+", ""):gsub("%.+$", "")
  241. return name
  242. end
  243. --- Obtain the directory name where a module should be stored.
  244. -- For example, on Unix, "foo.bar.baz" will return "foo/bar".
  245. -- @param mod string: A module name in Lua dot-separated format.
  246. -- @return string: A directory name using the platform's separator.
  247. function module_to_path(mod)
  248. assert(type(mod) == "string")
  249. return (mod:gsub("[^.]*$", ""):gsub("%.", dir.separator))
  250. end
  251. --- Set up path-related variables for a given rock.
  252. -- Create a "variables" table in the rockspec table, containing
  253. -- adjusted variables according to the configuration file.
  254. -- @param rockspec table: The rockspec table.
  255. function configure_paths(rockspec)
  256. assert(type(rockspec) == "table")
  257. local vars = {}
  258. for k,v in pairs(cfg.variables) do
  259. vars[k] = v
  260. end
  261. local name, version = rockspec.name, rockspec.version
  262. vars.PREFIX = install_dir(name, version)
  263. vars.LUADIR = lua_dir(name, version)
  264. vars.LIBDIR = lib_dir(name, version)
  265. vars.CONFDIR = conf_dir(name, version)
  266. vars.BINDIR = bin_dir(name, version)
  267. vars.DOCDIR = doc_dir(name, version)
  268. rockspec.variables = vars
  269. end
  270. function versioned_name(file, prefix, name, version)
  271. assert(type(file) == "string")
  272. assert(type(name) == "string")
  273. assert(type(version) == "string")
  274. local rest = file:sub(#prefix+1):gsub("^/*", "")
  275. local name_version = (name.."_"..version):gsub("%-", "_"):gsub("%.", "_")
  276. return dir.path(prefix, name_version.."-"..rest)
  277. end
  278. function use_tree(tree)
  279. cfg.root_dir = tree
  280. cfg.rocks_dir = rocks_dir(tree)
  281. cfg.deploy_bin_dir = deploy_bin_dir(tree)
  282. cfg.deploy_lua_dir = deploy_lua_dir(tree)
  283. cfg.deploy_lib_dir = deploy_lib_dir(tree)
  284. end
  285. function map_trees(deps_mode, fn, ...)
  286. local result = {}
  287. if deps_mode == "one" then
  288. table.insert(result, (fn(cfg.root_dir, ...)) or 0)
  289. elseif deps_mode == "all" or deps_mode == "order" then
  290. local use = false
  291. if deps_mode == "all" then
  292. use = true
  293. end
  294. for _, tree in ipairs(cfg.rocks_trees) do
  295. if dir.normalize(tree) == dir.normalize(cfg.root_dir) then
  296. use = true
  297. end
  298. if use then
  299. table.insert(result, (fn(tree, ...)) or 0)
  300. end
  301. end
  302. end
  303. return result
  304. end
  305. --- Return the pathname of the file that would be loaded for a module, indexed.
  306. -- @param module_name string: module name (eg. "socket.core")
  307. -- @param name string: name of the package (eg. "luasocket")
  308. -- @param version string: version number (eg. "2.0.2-1")
  309. -- @param tree string: repository path (eg. "/usr/local")
  310. -- @param i number: the index, 1 if version is the current default, > 1 otherwise.
  311. -- This is done this way for use by select_module in luarocks.loader.
  312. -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
  313. function which_i(module_name, name, version, tree, i)
  314. local deploy_dir
  315. if module_name:match("%.lua$") then
  316. deploy_dir = deploy_lua_dir(tree)
  317. module_name = dir.path(deploy_dir, module_name)
  318. else
  319. deploy_dir = deploy_lib_dir(tree)
  320. module_name = dir.path(deploy_dir, module_name)
  321. end
  322. if i > 1 then
  323. module_name = versioned_name(module_name, deploy_dir, name, version)
  324. end
  325. return module_name
  326. end
  327. --- Return the pathname of the file that would be loaded for a module,
  328. -- returning the versioned pathname if given version is not the default version
  329. -- in the given manifest.
  330. -- @param module_name string: module name (eg. "socket.core")
  331. -- @param name string: name of the package (eg. "luasocket")
  332. -- @param version string: version number (eg. "2.0.2-1")
  333. -- @param tree string: repository path (eg. "/usr/local")
  334. -- @param manifest table: the manifest table for the tree.
  335. -- @return string: filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
  336. function which(module_name, filename, name, version, tree, manifest)
  337. local versions = manifest.modules[module_name]
  338. assert(versions)
  339. for i, name_version in ipairs(versions) do
  340. if name_version == name.."/"..version then
  341. return which_i(filename, name, version, tree, i):gsub("//", "/")
  342. end
  343. end
  344. assert(false)
  345. end
  346. --- Driver function for "path" command.
  347. -- @return boolean This function always succeeds.
  348. function run(...)
  349. local flags = util.parse_flags(...)
  350. local deps_mode = deps.get_deps_mode(flags)
  351. util.printout(cfg.export_lua_path:format(util.remove_path_dupes(package.path, ';')))
  352. util.printout(cfg.export_lua_cpath:format(util.remove_path_dupes(package.cpath, ';')))
  353. if flags["bin"] then
  354. local bin_dirs = map_trees(deps_mode, deploy_bin_dir)
  355. table.insert(bin_dirs, 1, os.getenv("PATH"))
  356. util.printout(cfg.export_path:format(util.remove_path_dupes(table.concat(bin_dirs, cfg.export_path_separator), cfg.export_path_separator)))
  357. end
  358. return true
  359. end