aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/add.lua6
-rw-r--r--src/luarocks/admin_remove.lua2
-rw-r--r--src/luarocks/build.lua43
-rw-r--r--src/luarocks/build/builtin.lua12
-rw-r--r--src/luarocks/build/cmake.lua6
-rw-r--r--src/luarocks/build/make.lua3
-rw-r--r--src/luarocks/cfg.lua114
-rw-r--r--src/luarocks/command_line.lua40
-rw-r--r--src/luarocks/deps.lua11
-rw-r--r--src/luarocks/dir.lua3
-rw-r--r--src/luarocks/download.lua5
-rw-r--r--src/luarocks/fetch.lua24
-rw-r--r--src/luarocks/fetch/git.lua3
-rw-r--r--src/luarocks/fetch/git_file.lua17
-rw-r--r--src/luarocks/fs.lua5
-rw-r--r--src/luarocks/fs/lua.lua57
-rw-r--r--src/luarocks/fs/unix.lua62
-rw-r--r--src/luarocks/fs/unix/tools.lua66
-rw-r--r--src/luarocks/fs/win32.lua6
-rw-r--r--src/luarocks/fs/win32/tools.lua51
-rw-r--r--src/luarocks/help.lua80
-rw-r--r--src/luarocks/index.lua10
-rw-r--r--src/luarocks/install.lua8
-rw-r--r--src/luarocks/loader.lua46
-rw-r--r--src/luarocks/make.lua23
-rw-r--r--src/luarocks/manif.lua21
-rw-r--r--src/luarocks/manif_core.lua1
-rw-r--r--src/luarocks/pack.lua37
-rw-r--r--src/luarocks/path.lua128
-rw-r--r--src/luarocks/persist.lua28
-rw-r--r--src/luarocks/refresh_cache.lua3
-rw-r--r--src/luarocks/remove.lua8
-rw-r--r--src/luarocks/rep.lua29
-rw-r--r--src/luarocks/search.lua4
-rw-r--r--src/luarocks/show.lua4
-rw-r--r--src/luarocks/tools/patch.lua2
-rw-r--r--src/luarocks/tools/tar.lua1
-rw-r--r--src/luarocks/tools/zip.lua2
-rw-r--r--src/luarocks/type_check.lua38
-rw-r--r--src/luarocks/unpack.lua2
-rw-r--r--src/luarocks/util.lua15
-rw-r--r--src/luarocks/validate.lua1
42 files changed, 667 insertions, 360 deletions
diff --git a/src/luarocks/add.lua b/src/luarocks/add.lua
index 6edfea35..bf3f8979 100644
--- a/src/luarocks/add.lua
+++ b/src/luarocks/add.lua
@@ -13,10 +13,10 @@ local fs = require("luarocks.fs")
13local cache = require("luarocks.cache") 13local cache = require("luarocks.cache")
14 14
15help_summary = "Add a rock or rockspec to a rocks server." 15help_summary = "Add a rock or rockspec to a rocks server."
16help_arguments = "[--to=<server>] [--no-refresh] {<rockspec>|<rock>...}" 16help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}"
17help = [[ 17help = [[
18Arguments are local files, which may be rockspecs or rocks. 18Arguments are local files, which may be rockspecs or rocks.
19The flag --to indicates which server to use. 19The flag --server indicates which server to use.
20If not given, the default server set in the upload_server variable 20If not given, the default server set in the upload_server variable
21from the configuration file is used instead. 21from the configuration file is used instead.
22The flag --no-refresh indicates the local cache should not be refreshed 22The flag --no-refresh indicates the local cache should not be refreshed
@@ -101,7 +101,7 @@ function run(...)
101 if #files < 1 then 101 if #files < 1 then
102 return nil, "Argument missing, see help." 102 return nil, "Argument missing, see help."
103 end 103 end
104 local server, server_table = cache.get_upload_server(flags["to"]) 104 local server, server_table = cache.get_upload_server(flags["server"])
105 if not server then return nil, server_table end 105 if not server then return nil, server_table end
106 return add_files_to_server(not flags["no-refresh"], files, server, server_table) 106 return add_files_to_server(not flags["no-refresh"], files, server, server_table)
107end 107end
diff --git a/src/luarocks/admin_remove.lua b/src/luarocks/admin_remove.lua
index 1b897e7d..f1268576 100644
--- a/src/luarocks/admin_remove.lua
+++ b/src/luarocks/admin_remove.lua
@@ -80,7 +80,7 @@ function run(...)
80 if #files < 1 then 80 if #files < 1 then
81 return nil, "Argument missing, see help." 81 return nil, "Argument missing, see help."
82 end 82 end
83 local server, server_table = cache.get_upload_server(flags["from"]) 83 local server, server_table = cache.get_upload_server(flags["server"])
84 if not server then return nil, server_table end 84 if not server then return nil, server_table end
85 return remove_files_from_server(not flags["no-refresh"], files, server, server_table) 85 return remove_files_from_server(not flags["no-refresh"], files, server, server_table)
86end 86end
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua
index 77dd1dad..9a67f00b 100644
--- a/src/luarocks/build.lua
+++ b/src/luarocks/build.lua
@@ -3,6 +3,7 @@
3-- Builds a rock, compiling its C parts if any. 3-- Builds a rock, compiling its C parts if any.
4module("luarocks.build", package.seeall) 4module("luarocks.build", package.seeall)
5 5
6local pack = require("luarocks.pack")
6local path = require("luarocks.path") 7local path = require("luarocks.path")
7local util = require("luarocks.util") 8local util = require("luarocks.util")
8local rep = require("luarocks.rep") 9local rep = require("luarocks.rep")
@@ -46,9 +47,17 @@ local function install_files(files, location, is_module_path)
46 for k, file in pairs(files) do 47 for k, file in pairs(files) do
47 local dest = location 48 local dest = location
48 if type(k) == "string" then 49 if type(k) == "string" then
49 dest = is_module_path and dir.path(location, path.module_to_path(k)) or k 50 if is_module_path then
51 dest = dir.path(location, path.module_to_path(k))
52 fs.make_dir(dest)
53 else
54 dest = dir.path(location, dir.dir_name(k))
55 fs.make_dir(dest)
56 dest = dir.path(dest, dir.base_name(k))
57 end
58 else
59 fs.make_dir(dest)
50 end 60 end
51 fs.make_dir(dest)
52 local ok = fs.copy(dir.path(file), dest) 61 local ok = fs.copy(dir.path(file), dest)
53 if not ok then 62 if not ok then
54 return nil, "Failed copying "..file 63 return nil, "Failed copying "..file
@@ -225,7 +234,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode)
225 ok, err = manif.make_rock_manifest(name, version) 234 ok, err = manif.make_rock_manifest(name, version)
226 if err then return nil, err end 235 if err then return nil, err end
227 236
228 ok, err = rep.deploy_files(name, version) 237 ok, err = rep.deploy_files(name, version, rep.should_wrap_bin_scripts(rockspec))
229 if err then return nil, err end 238 if err then return nil, err end
230 239
231 util.remove_scheduled_function(rollback) 240 util.remove_scheduled_function(rollback)
@@ -240,7 +249,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode)
240 if err then return nil, err end 249 if err then return nil, err end
241 250
242 local license = "" 251 local license = ""
243 if rockspec.description.license then 252 if rockspec.description and rockspec.description.license then
244 license = ("(license: "..rockspec.description.license..")") 253 license = ("(license: "..rockspec.description.license..")")
245 end 254 end
246 255
@@ -290,25 +299,6 @@ local function do_build(name, version)
290 return nil, "Don't know what to do with "..name 299 return nil, "Don't know what to do with "..name
291end 300end
292 301
293local function pack_binary_rock(name, version)
294 local temp_dir = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name))
295 if not temp_dir then
296 return nil, "Failed creating temporary directory."
297 end
298 util.schedule_function(fs.delete, temp_dir)
299
300 path.use_tree(temp_dir)
301 local ok, err = do_build(name, version)
302 if not ok then
303 return nil, err
304 end
305 local rname, rversion = path.parse_name(name)
306 if not rname then
307 rname, rversion = name, version
308 end
309 return pack.pack_binary_rock(rname, rversion)
310end
311
312--- Driver function for "build" command. 302--- Driver function for "build" command.
313-- @param name string: A local or remote rockspec or rock file. 303-- @param name string: A local or remote rockspec or rock file.
314-- If a package name is given, forwards the request to "search" and, 304-- If a package name is given, forwards the request to "search" and,
@@ -324,12 +314,11 @@ function run(...)
324 end 314 end
325 assert(type(version) == "string" or not version) 315 assert(type(version) == "string" or not version)
326 316
327 local ok, err = fs.check_command_permissions(flags)
328 if not ok then return nil, err end
329
330 if flags["pack-binary-rock"] then 317 if flags["pack-binary-rock"] then
331 return pack_binary_rock(name, version) 318 return pack.pack_binary_rock(name, version, do_build, name, version)
332 else 319 else
320 local ok, err = fs.check_command_permissions(flags)
321 if not ok then return nil, err end
333 return do_build(name, version) 322 return do_build(name, version)
334 end 323 end
335end 324end
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua
index 7b550bff..aea8b853 100644
--- a/src/luarocks/build/builtin.lua
+++ b/src/luarocks/build/builtin.lua
@@ -46,7 +46,7 @@ end
46-- nil and an error message otherwise. 46-- nil and an error message otherwise.
47function run(rockspec) 47function run(rockspec)
48 assert(type(rockspec) == "table") 48 assert(type(rockspec) == "table")
49 local compile_object, compile_library 49 local compile_object, compile_library, compile_wrapper_binary
50 50
51 local build = rockspec.build 51 local build = rockspec.build
52 local variables = rockspec.variables 52 local variables = rockspec.variables
@@ -74,7 +74,7 @@ function run(rockspec)
74 local extras = { unpack(objects) } 74 local extras = { unpack(objects) }
75 add_flags(extras, "-L%s", libdirs) 75 add_flags(extras, "-L%s", libdirs)
76 add_flags(extras, "%s.lib", libraries) 76 add_flags(extras, "%s.lib", libraries)
77 extras[#extras+1] = dir.path(variables.LUA_LIBDIR, "lua5.1.lib") 77 extras[#extras+1] = dir.path(variables.LUA_LIBDIR, variables.LUALIB)
78 extras[#extras+1] = "-l" .. (variables.MSVCRT or "msvcr80") 78 extras[#extras+1] = "-l" .. (variables.MSVCRT or "msvcr80")
79 local ok = execute(variables.LD.." "..variables.LIBFLAG, "-o", library, unpack(extras)) 79 local ok = execute(variables.LD.." "..variables.LIBFLAG, "-o", library, unpack(extras))
80 return ok 80 return ok
@@ -89,7 +89,7 @@ function run(rockspec)
89 local ok = execute(variables.RC, "-o", resname, rcname) 89 local ok = execute(variables.RC, "-o", resname, rcname)
90 if not ok then return ok end 90 if not ok then return ok end
91 ok = execute(variables.LD, "-o", wrapname, resname, variables.WRAPPER, 91 ok = execute(variables.LD, "-o", wrapname, resname, variables.WRAPPER,
92 dir.path(variables.LUA_LIBDIR, "lua5.1.lib"), "-l" .. (variables.MSVCRT or "msvcr80"), "-luser32") 92 dir.path(variables.LUA_LIBDIR, variables.LUALIB), "-l" .. (variables.MSVCRT or "msvcr80"), "-luser32")
93 return ok, wrapname 93 return ok, wrapname
94 end 94 end
95 elseif cfg.is_platform("win32") then 95 elseif cfg.is_platform("win32") then
@@ -109,7 +109,7 @@ function run(rockspec)
109 def:write("EXPORTS\n") 109 def:write("EXPORTS\n")
110 def:write("luaopen_"..name:gsub("%.", "_").."\n") 110 def:write("luaopen_"..name:gsub("%.", "_").."\n")
111 def:close() 111 def:close()
112 local ok = execute(variables.LD, "-dll", "-def:"..deffile, "-out:"..library, dir.path(variables.LUA_LIBDIR, "lua5.1.lib"), unpack(extras)) 112 local ok = execute(variables.LD, "-dll", "-def:"..deffile, "-out:"..library, dir.path(variables.LUA_LIBDIR, variables.LUALIB), unpack(extras))
113 local manifestfile = basename..".dll.manifest" 113 local manifestfile = basename..".dll.manifest"
114 if ok and fs.exists(manifestfile) then 114 if ok and fs.exists(manifestfile) then
115 ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basename..".dll;2") 115 ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basename..".dll;2")
@@ -126,7 +126,7 @@ function run(rockspec)
126 local ok = execute(variables.RC, "-r", "-fo"..resname, rcname) 126 local ok = execute(variables.RC, "-r", "-fo"..resname, rcname)
127 if not ok then return ok end 127 if not ok then return ok end
128 ok = execute(variables.LD, "-out:"..wrapname, resname, variables.WRAPPER, 128 ok = execute(variables.LD, "-out:"..wrapname, resname, variables.WRAPPER,
129 dir.path(variables.LUA_LIBDIR, "lua5.1.lib"), "user32.lib") 129 dir.path(variables.LUA_LIBDIR, variables.LUALIB), "user32.lib")
130 local manifestfile = wrapname..".manifest" 130 local manifestfile = wrapname..".manifest"
131 if ok and fs.exists(manifestfile) then 131 if ok and fs.exists(manifestfile) then
132 ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..wrapname..";1") 132 ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..wrapname..";1")
@@ -187,7 +187,7 @@ function run(rockspec)
187 if type(info) == "string" then 187 if type(info) == "string" then
188 local ext = info:match(".([^.]+)$") 188 local ext = info:match(".([^.]+)$")
189 if ext == "lua" then 189 if ext == "lua" then
190 if info:match("init.lua$") then 190 if info:match("init%.lua$") and not name:match("%.init$") then
191 moddir = path.module_to_path(name..".init") 191 moddir = path.module_to_path(name..".init")
192 end 192 end
193 local dest = dir.path(luadir, moddir) 193 local dest = dir.path(luadir, moddir)
diff --git a/src/luarocks/build/cmake.lua b/src/luarocks/build/cmake.lua
index 295f5df6..2d9abf9e 100644
--- a/src/luarocks/build/cmake.lua
+++ b/src/luarocks/build/cmake.lua
@@ -16,9 +16,9 @@ function run(rockspec)
16 local variables = build.variables or {} 16 local variables = build.variables or {}
17 17
18 -- Pass Env variables 18 -- Pass Env variables
19 build.variables.CMAKE_MODULE_PATH=os.getenv("CMAKE_MODULE_PATH") 19 variables.CMAKE_MODULE_PATH=os.getenv("CMAKE_MODULE_PATH")
20 build.variables.CMAKE_LIBRARY_PATH=os.getenv("CMAKE_LIBRARY_PATH") 20 variables.CMAKE_LIBRARY_PATH=os.getenv("CMAKE_LIBRARY_PATH")
21 build.variables.CMAKE_INCLUDE_PATH=os.getenv("CMAKE_INCLUDE_PATH") 21 variables.CMAKE_INCLUDE_PATH=os.getenv("CMAKE_INCLUDE_PATH")
22 22
23 util.variable_substitutions(variables, rockspec.variables) 23 util.variable_substitutions(variables, rockspec.variables)
24 24
diff --git a/src/luarocks/build/make.lua b/src/luarocks/build/make.lua
index 80c0d4f4..c4b21578 100644
--- a/src/luarocks/build/make.lua
+++ b/src/luarocks/build/make.lua
@@ -7,6 +7,9 @@ local util = require("luarocks.util")
7local cfg = require("luarocks.cfg") 7local cfg = require("luarocks.cfg")
8 8
9--- Call "make" with given target and variables 9--- Call "make" with given target and variables
10-- @param make_cmd string: the make command to be used (typically
11-- configured through variables.MAKE in the config files, or
12-- the appropriate platform-specific default).
10-- @param pass boolean: If true, run make; if false, do nothing. 13-- @param pass boolean: If true, run make; if false, do nothing.
11-- @param target string: The make target; an empty string indicates 14-- @param target string: The make target; an empty string indicates
12-- the default target. 15-- the default target.
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua
index 2b48d576..1147d725 100644
--- a/src/luarocks/cfg.lua
+++ b/src/luarocks/cfg.lua
@@ -1,7 +1,4 @@
1 1
2local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, type, assert =
3 rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, type, assert
4
5--- Configuration for LuaRocks. 2--- Configuration for LuaRocks.
6-- Tries to load the user's configuration file and 3-- Tries to load the user's configuration file and
7-- defines defaults for unset values. See the 4-- defines defaults for unset values. See the
@@ -10,21 +7,26 @@ local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs,
10-- 7--
11-- End-users shouldn't edit this file. They can override any defaults 8-- End-users shouldn't edit this file. They can override any defaults
12-- set in this file using their system-wide $LUAROCKS_SYSCONFIG file 9-- set in this file using their system-wide $LUAROCKS_SYSCONFIG file
13-- (see luarocks.config) or their user-specific configuration file 10-- (see luarocks.site_config) or their user-specific configuration file
14-- (~/.luarocks/config.lua on Unix or %APPDATA%/luarocks/config.lua on 11-- (~/.luarocks/config.lua on Unix or %APPDATA%/luarocks/config.lua on
15-- Windows). 12-- Windows).
13
14local rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, type, assert, _VERSION =
15 rawset, next, table, pairs, require, io, os, setmetatable, pcall, ipairs, package, type, assert, _VERSION
16
16module("luarocks.cfg") 17module("luarocks.cfg")
17 18
18-- Load site-local global configurations 19-- Load site-local global configurations
19local ok, config = pcall(require, "luarocks.config") 20local ok, site_config = pcall(require, "luarocks.site_config")
20if not ok then 21if not ok then
21 io.stderr:write("Site-local luarocks/config.lua file not found. Incomplete installation?\n") 22 io.stderr:write("Site-local luarocks/site_config.lua file not found. Incomplete installation?\n")
22 config = {} 23 site_config = {}
23end 24end
24 25
25_M.config = config 26_M.site_config = site_config
26 27
27program_version = "2.0.5" 28lua_version = _VERSION:sub(5)
29program_version = "2.0.8"
28user_agent = "LuaRocks/"..program_version 30user_agent = "LuaRocks/"..program_version
29 31
30local persist = require("luarocks.persist") 32local persist = require("luarocks.persist")
@@ -46,12 +48,12 @@ local detected = {}
46local system,proc 48local system,proc
47 49
48-- A proper installation of LuaRocks will hardcode the system 50-- A proper installation of LuaRocks will hardcode the system
49-- and proc values with config.LUAROCKS_UNAME_S and config.LUAROCKS_UNAME_M, 51-- and proc values with site_config.LUAROCKS_UNAME_S and site_config.LUAROCKS_UNAME_M,
50-- so that this detection does not run every time. When it is 52-- so that this detection does not run every time. When it is
51-- performed, we use the Unix way to identify the system, 53-- performed, we use the Unix way to identify the system,
52-- even on Windows (assuming UnxUtils or Cygwin). 54-- even on Windows (assuming UnxUtils or Cygwin).
53system = config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") 55system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l")
54proc = config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") 56proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l")
55if proc:match("i[%d]86") then 57if proc:match("i[%d]86") then
56 proc = "x86" 58 proc = "x86"
57elseif proc:match("amd64") or proc:match("x86_64") then 59elseif proc:match("amd64") or proc:match("x86_64") then
@@ -75,6 +77,9 @@ elseif system == "Darwin" then
75elseif system == "Linux" then 77elseif system == "Linux" then
76 detected.unix = true 78 detected.unix = true
77 detected.linux = true 79 detected.linux = true
80elseif system == "SunOS" then
81 detected.unix = true
82 detected.solaris = true
78elseif system and system:match("^CYGWIN") then 83elseif system and system:match("^CYGWIN") then
79 detected.unix = true 84 detected.unix = true
80 detected.cygwin = true 85 detected.cygwin = true
@@ -90,6 +95,7 @@ end
90-- Path configuration: 95-- Path configuration:
91 96
92local sys_config_file, home_config_file 97local sys_config_file, home_config_file
98local sys_config_ok, home_config_ok = false, false
93if detected.windows or detected.mingw32 then 99if detected.windows or detected.mingw32 then
94 home = os.getenv("APPDATA") or "c:" 100 home = os.getenv("APPDATA") or "c:"
95 sys_config_file = "c:/luarocks/config.lua" 101 sys_config_file = "c:/luarocks/config.lua"
@@ -105,14 +111,34 @@ end
105variables = {} 111variables = {}
106rocks_trees = {} 112rocks_trees = {}
107 113
108persist.load_into_table(config.LUAROCKS_SYSCONFIG or sys_config_file, _M) 114local ok, err = persist.load_into_table(site_config.LUAROCKS_SYSCONFIG or sys_config_file, _M)
115if ok then
116 sys_config_ok = true
117else -- nil or false
118 sys_config_ok = ok
119 if err and ok == nil then
120 io.stderr:write(err.."\n")
121 end
122end
109 123
110if not config.LUAROCKS_FORCE_CONFIG then 124if not site_config.LUAROCKS_FORCE_CONFIG then
111 home_config_file = os.getenv("LUAROCKS_CONFIG") or home_config_file 125 home_config_file = os.getenv("LUAROCKS_CONFIG") or home_config_file
112 local home_overrides = persist.load_into_table(home_config_file, { home = home }) 126 local home_overrides, err = persist.load_into_table(home_config_file, { home = home })
113 if home_overrides then 127 if home_overrides then
128 home_config_ok = true
114 local util = require("luarocks.util") 129 local util = require("luarocks.util")
130 if home_overrides.rocks_trees then
131 _M.rocks_trees = nil
132 end
133 if home_overrides.rocks_servers then
134 _M.rocks_servers = nil
135 end
115 util.deep_merge(_M, home_overrides) 136 util.deep_merge(_M, home_overrides)
137 else -- nil or false
138 home_config_ok = home_overrides
139 if err and home_config_ok == nil then
140 io.stderr:write(err.."\n")
141 end
116 end 142 end
117end 143end
118 144
@@ -120,8 +146,8 @@ if not next(rocks_trees) then
120 if home_tree then 146 if home_tree then
121 table.insert(rocks_trees, home_tree) 147 table.insert(rocks_trees, home_tree)
122 end 148 end
123 if config.LUAROCKS_ROCKS_TREE then 149 if site_config.LUAROCKS_ROCKS_TREE then
124 table.insert(rocks_trees, config.LUAROCKS_ROCKS_TREE) 150 table.insert(rocks_trees, site_config.LUAROCKS_ROCKS_TREE)
125 end 151 end
126end 152end
127 153
@@ -129,8 +155,13 @@ end
129 155
130local root = rocks_trees[#rocks_trees] 156local root = rocks_trees[#rocks_trees]
131local defaults = { 157local defaults = {
132 lua_modules_path = "/share/lua/5.1/", 158
133 lib_modules_path = "/lib/lua/5.1/", 159 local_by_default = false,
160 use_extensions = false,
161 accept_unknown_fields = false,
162
163 lua_modules_path = "/share/lua/"..lua_version,
164 lib_modules_path = "/lib/lua/"..lua_version,
134 165
135 arch = "unknown", 166 arch = "unknown",
136 lib_extension = "unknown", 167 lib_extension = "unknown",
@@ -141,9 +172,9 @@ local defaults = {
141 }, 172 },
142 173
143 lua_extension = "lua", 174 lua_extension = "lua",
144 lua_interpreter = config.LUA_INTERPRETER or "lua", 175 lua_interpreter = site_config.LUA_INTERPRETER or "lua",
145 downloader = config.LUAROCKS_DOWNLOADER or "wget", 176 downloader = site_config.LUAROCKS_DOWNLOADER or "wget",
146 md5checker = config.LUAROCKS_MD5CHECKER or "md5sum", 177 md5checker = site_config.LUAROCKS_MD5CHECKER or "md5sum",
147 178
148 variables = { 179 variables = {
149 MAKE = "make", 180 MAKE = "make",
@@ -183,6 +214,7 @@ local defaults = {
183 MD5 = "md5", 214 MD5 = "md5",
184 STAT = "stat", 215 STAT = "stat",
185 216
217 CMAKE = "cmake",
186 SEVENZ = "7z", 218 SEVENZ = "7z",
187 219
188 STATFLAG = "-c '%a'", 220 STATFLAG = "-c '%a'",
@@ -208,19 +240,21 @@ if detected.windows then
208 defaults.external_lib_extension = "dll" 240 defaults.external_lib_extension = "dll"
209 defaults.obj_extension = "obj" 241 defaults.obj_extension = "obj"
210 defaults.external_deps_dirs = { "c:/external/" } 242 defaults.external_deps_dirs = { "c:/external/" }
211 defaults.variables.LUA_BINDIR = config.LUA_BINDIR and config.LUA_BINDIR:gsub("\\", "/") or "c:/lua5.1/bin" 243 defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/bin"
212 defaults.variables.LUA_INCDIR = config.LUA_INCDIR and config.LUA_INCDIR:gsub("\\", "/") or "c:/lua5.1/include" 244 defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/include"
213 defaults.variables.LUA_LIBDIR = config.LUA_LIBDIR and config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua5.1/lib" 245 defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/lib"
214 defaults.cmake_generator = "MinGW Makefiles" 246 defaults.cmake_generator = "MinGW Makefiles"
215 defaults.makefile = "Makefile.win" 247 defaults.makefile = "Makefile.win"
216 defaults.variables.MAKE = "nmake" -- TODO: Split Windows flavors between mingw and msvc 248 defaults.variables.MAKE = "nmake" -- TODO: Split Windows flavors between mingw and msvc
217 defaults.variables.CC = "cl" 249 defaults.variables.CC = "cl"
218 defaults.variables.RC = "rc" 250 defaults.variables.RC = "rc"
219 defaults.variables.WRAPPER = config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.obj" 251 defaults.variables.WRAPPER = site_config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.obj"
220 defaults.variables.LD = "link" 252 defaults.variables.LD = "link"
221 defaults.variables.MT = "mt" 253 defaults.variables.MT = "mt"
254 defaults.variables.LUALIB = "lua"..lua_version..".lib"
222 defaults.variables.CFLAGS = "/MD /O2" 255 defaults.variables.CFLAGS = "/MD /O2"
223 defaults.variables.LIBFLAG = "/dll" 256 defaults.variables.LIBFLAG = "/dll"
257 defaults.variables.LUALIB = "lua"..lua_version..".lib"
224 defaults.external_deps_patterns = { 258 defaults.external_deps_patterns = {
225 bin = { "?.exe", "?.bat" }, 259 bin = { "?.exe", "?.bat" },
226 lib = { "?.lib", "?.dll", "lib?.dll" }, 260 lib = { "?.lib", "?.dll", "lib?.dll" },
@@ -244,15 +278,15 @@ if detected.mingw32 then
244 defaults.external_lib_extension = "dll" 278 defaults.external_lib_extension = "dll"
245 defaults.obj_extension = "o" 279 defaults.obj_extension = "o"
246 defaults.external_deps_dirs = { "c:/external/" } 280 defaults.external_deps_dirs = { "c:/external/" }
247 defaults.variables.LUA_BINDIR = config.LUA_BINDIR and config.LUA_BINDIR:gsub("\\", "/") or "c:/lua5.1/bin" 281 defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR and site_config.LUA_BINDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/bin"
248 defaults.variables.LUA_INCDIR = config.LUA_INCDIR and config.LUA_INCDIR:gsub("\\", "/") or "c:/lua5.1/include" 282 defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR and site_config.LUA_INCDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/include"
249 defaults.variables.LUA_LIBDIR = config.LUA_LIBDIR and config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua5.1/lib" 283 defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR and site_config.LUA_LIBDIR:gsub("\\", "/") or "c:/lua"..lua_version.."/lib"
250 defaults.cmake_generator = "MinGW Makefiles" 284 defaults.cmake_generator = "MinGW Makefiles"
251 defaults.make = "mingw32-make" -- TODO: Split Windows flavors between mingw and msvc 285 defaults.make = "mingw32-make" -- TODO: Split Windows flavors between mingw and msvc
252 defaults.makefile = "Makefile.win" 286 defaults.makefile = "Makefile.win"
253 defaults.variables.CC = "mingw32-gcc" 287 defaults.variables.CC = "mingw32-gcc"
254 defaults.variables.RC = "windres" 288 defaults.variables.RC = "windres"
255 defaults.variables.WRAPPER = config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.o" 289 defaults.variables.WRAPPER = site_config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.o"
256 defaults.variables.LD = "mingw32-gcc" 290 defaults.variables.LD = "mingw32-gcc"
257 defaults.variables.CFLAGS = "-O2" 291 defaults.variables.CFLAGS = "-O2"
258 defaults.variables.LIBFLAG = "-shared" 292 defaults.variables.LIBFLAG = "-shared"
@@ -276,9 +310,9 @@ if detected.unix then
276 defaults.external_lib_extension = "so" 310 defaults.external_lib_extension = "so"
277 defaults.obj_extension = "o" 311 defaults.obj_extension = "o"
278 defaults.external_deps_dirs = { "/usr/local", "/usr" } 312 defaults.external_deps_dirs = { "/usr/local", "/usr" }
279 defaults.variables.LUA_BINDIR = config.LUA_BINDIR or "/usr/local/bin" 313 defaults.variables.LUA_BINDIR = site_config.LUA_BINDIR or "/usr/local/bin"
280 defaults.variables.LUA_INCDIR = config.LUA_INCDIR or "/usr/local/include" 314 defaults.variables.LUA_INCDIR = site_config.LUA_INCDIR or "/usr/local/include"
281 defaults.variables.LUA_LIBDIR = config.LUA_LIBDIR or "/usr/local/lib" 315 defaults.variables.LUA_LIBDIR = site_config.LUA_LIBDIR or "/usr/local/lib"
282 defaults.variables.CFLAGS = "-O2" 316 defaults.variables.CFLAGS = "-O2"
283 defaults.cmake_generator = "Unix Makefiles" 317 defaults.cmake_generator = "Unix Makefiles"
284 defaults.platforms = { "unix" } 318 defaults.platforms = { "unix" }
@@ -347,11 +381,19 @@ if detected.openbsd then
347 defaults.variables.STATFLAG = "-f '%Op'" 381 defaults.variables.STATFLAG = "-f '%Op'"
348end 382end
349 383
384if detected.solaris then
385 defaults.arch = "solaris-"..proc
386 defaults.platforms = {"unix", "solaris"}
387 defaults.variables.MAKE = "gmake"
388 defaults.variables.CC = "gcc"
389 defaults.variables.LD = "gcc"
390end
391
350-- Expose some more values detected by LuaRocks for use by rockspec authors. 392-- Expose some more values detected by LuaRocks for use by rockspec authors.
351defaults.variables.LUA = defaults.lua_interpreter 393defaults.variables.LUA = defaults.lua_interpreter
352defaults.variables.LIB_EXTENSION = defaults.lib_extension 394defaults.variables.LIB_EXTENSION = defaults.lib_extension
353defaults.variables.OBJ_EXTENSION = defaults.obj_extension 395defaults.variables.OBJ_EXTENSION = defaults.obj_extension
354defaults.variables.LUAROCKS_PREFIX = config.LUAROCKS_PREFIX 396defaults.variables.LUAROCKS_PREFIX = site_config.LUAROCKS_PREFIX
355 397
356-- Use defaults: 398-- Use defaults:
357 399
@@ -389,6 +431,10 @@ for _,tree in ipairs(rocks_trees) do
389 end 431 end
390end 432end
391 433
434function which_config()
435 return sys_config_file, sys_config_ok, home_config_file, home_config_ok
436end
437
392--- Check if platform was detected 438--- Check if platform was detected
393-- @param query string: The platform name to check. 439-- @param query string: The platform name to check.
394-- @return boolean: true if LuaRocks is currently running on queried platform. 440-- @return boolean: true if LuaRocks is currently running on queried platform.
diff --git a/src/luarocks/command_line.lua b/src/luarocks/command_line.lua
index 02793c5a..8fa9073c 100644
--- a/src/luarocks/command_line.lua
+++ b/src/luarocks/command_line.lua
@@ -57,6 +57,12 @@ function run_command(...)
57 end 57 end
58 local nonflags = { util.parse_flags(unpack(args)) } 58 local nonflags = { util.parse_flags(unpack(args)) }
59 local flags = table.remove(nonflags, 1) 59 local flags = table.remove(nonflags, 1)
60
61 if flags["from"] then flags["server"] = flags["from"] end
62 if flags["only-from"] then flags["only-server"] = flags["only-from"] end
63 if flags["only-sources-from"] then flags["only-sources"] = flags["only-sources-from"] end
64 if flags["to"] then flags["tree"] = flags["to"] end
65
60 cfg.flags = flags 66 cfg.flags = flags
61 67
62 local command 68 local command
@@ -79,16 +85,22 @@ function run_command(...)
79 end 85 end
80 end 86 end
81 command = command:gsub("-", "_") 87 command = command:gsub("-", "_")
88
89 if flags["extensions"] then
90 cfg.use_extensions = true
91 local type_check = require("luarocks.type_check")
92 type_check.load_extensions()
93 end
82 94
83 if cfg.local_by_default then 95 if cfg.local_by_default then
84 flags["local"] = true 96 flags["local"] = true
85 end 97 end
86 98
87 if flags["to"] then 99 if flags["tree"] then
88 if flags["to"] == true then 100 if flags["tree"] == true then
89 die("Argument error: use --to=<path>") 101 die("Argument error: use --tree=<path>")
90 end 102 end
91 local root_dir = fs.absolute_name(flags["to"]) 103 local root_dir = fs.absolute_name(flags["tree"])
92 path.use_tree(root_dir) 104 path.use_tree(root_dir)
93 elseif flags["local"] then 105 elseif flags["local"] then
94 path.use_tree(cfg.home_tree) 106 path.use_tree(cfg.home_tree)
@@ -110,19 +122,23 @@ function run_command(...)
110 cfg.variables.ROCKS_TREE = cfg.rocks_dir 122 cfg.variables.ROCKS_TREE = cfg.rocks_dir
111 cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir 123 cfg.variables.SCRIPTS_DIR = cfg.deploy_bin_dir
112 124
113 if flags["from"] then 125 if flags["server"] then
114 if flags["from"] == true then 126 if flags["server"] == true then
115 die("Argument error: use --from=<url>") 127 die("Argument error: use --server=<url>")
116 end 128 end
117 local protocol, path = dir.split_url(flags["from"]) 129 local protocol, path = dir.split_url(flags["server"])
118 table.insert(cfg.rocks_servers, 1, protocol.."://"..path) 130 table.insert(cfg.rocks_servers, 1, protocol.."://"..path)
119 end 131 end
120 132
121 if flags["only-from"] then 133 if flags["only-server"] then
122 if flags["only-from"] == true then 134 if flags["only-server"] == true then
123 die("Argument error: use --only-from=<url>") 135 die("Argument error: use --only-server=<url>")
124 end 136 end
125 cfg.rocks_servers = { flags["only-from"] } 137 cfg.rocks_servers = { flags["only-server"] }
138 end
139
140 if flags["only-sources"] then
141 cfg.only_sources_from = flags["only-sources"]
126 end 142 end
127 143
128 if command ~= "help" then 144 if command ~= "help" then
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua
index 27062cbb..194e0e7e 100644
--- a/src/luarocks/deps.lua
+++ b/src/luarocks/deps.lua
@@ -317,7 +317,7 @@ local function match_dep(dep, blacklist)
317 317
318 local versions 318 local versions
319 if dep.name == "lua" then 319 if dep.name == "lua" then
320 versions = { "5.1" } 320 versions = { cfg.lua_version }
321 else 321 else
322 versions = manif_core.get_versions(dep.name) 322 versions = manif_core.get_versions(dep.name)
323 end 323 end
@@ -470,7 +470,7 @@ function fulfill_dependencies(rockspec)
470 if not match_dep(dep) then 470 if not match_dep(dep) then
471 local rock = search.find_suitable_rock(dep) 471 local rock = search.find_suitable_rock(dep)
472 if not rock then 472 if not rock then
473 return nil, "Could not find a rock to satisfy dependency: "..show_dep(dep) 473 return nil, "Could not satisfy dependency: "..show_dep(dep)
474 end 474 end
475 local ok, err, errcode = install.run(rock) 475 local ok, err, errcode = install.run(rock)
476 if not ok then 476 if not ok then
@@ -606,12 +606,15 @@ end
606--- Recursively scan dependencies, to build a transitive closure of all 606--- Recursively scan dependencies, to build a transitive closure of all
607-- dependent packages. 607-- dependent packages.
608-- @param results table: The results table being built. 608-- @param results table: The results table being built.
609-- @param missing table: The table of missing dependencies being recursively built.
610-- @param manifest table: The manifest table containing dependencies.
609-- @param name string: Package name. 611-- @param name string: Package name.
610-- @param version string: Package version. 612-- @param version string: Package version.
611-- @return (table, table): The results and a table of missing dependencies. 613-- @return (table, table): The results and a table of missing dependencies.
612function scan_deps(results, missing, manifest, name, version) 614function scan_deps(results, missing, manifest, name, version)
613 assert(type(results) == "table") 615 assert(type(results) == "table")
614 assert(type(missing) == "table") 616 assert(type(missing) == "table")
617 assert(type(manifest) == "table")
615 assert(type(name) == "string") 618 assert(type(name) == "string")
616 assert(type(version) == "string") 619 assert(type(version) == "string")
617 620
@@ -630,7 +633,7 @@ function scan_deps(results, missing, manifest, name, version)
630 if not deplist then 633 if not deplist then
631 rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version)) 634 rockspec, err = fetch.load_local_rockspec(path.rockspec_file(name, version))
632 if err then 635 if err then
633 missing[name.." "..version] = true 636 missing[name.." "..version] = err
634 return results, missing 637 return results, missing
635 end 638 end
636 dependencies_name[version] = rockspec.dependencies 639 dependencies_name[version] = rockspec.dependencies
@@ -643,7 +646,7 @@ function scan_deps(results, missing, manifest, name, version)
643 end 646 end
644 if next(failures) then 647 if next(failures) then
645 for _, failure in pairs(failures) do 648 for _, failure in pairs(failures) do
646 missing[show_dep(failure)] = true 649 missing[show_dep(failure)] = "failed"
647 end 650 end
648 end 651 end
649 results[name] = version 652 results[name] = version
diff --git a/src/luarocks/dir.lua b/src/luarocks/dir.lua
index 5a8058dc..69968917 100644
--- a/src/luarocks/dir.lua
+++ b/src/luarocks/dir.lua
@@ -1,4 +1,5 @@
1 1
2--- Generic utilities for handling pathnames.
2module("luarocks.dir", package.seeall) 3module("luarocks.dir", package.seeall)
3 4
4separator = "/" 5separator = "/"
@@ -10,7 +11,7 @@ separator = "/"
10function base_name(pathname) 11function base_name(pathname)
11 assert(type(pathname) == "string") 12 assert(type(pathname) == "string")
12 13
13 local base = pathname:match(".*[/\\]([^/\\]*)") 14 local base = pathname:gsub("[/\\]*$", ""):match(".*[/\\]([^/\\]*)")
14 return base or pathname 15 return base or pathname
15end 16end
16 17
diff --git a/src/luarocks/download.lua b/src/luarocks/download.lua
index 6ae5f7af..268dc113 100644
--- a/src/luarocks/download.lua
+++ b/src/luarocks/download.lua
@@ -9,11 +9,12 @@ local fetch = require("luarocks.fetch")
9local search = require("luarocks.search") 9local search = require("luarocks.search")
10 10
11help_summary = "Download a specific rock file from a rocks server." 11help_summary = "Download a specific rock file from a rocks server."
12help_arguments = "[--all] [--source] [--arch=<arch>] [<name> [<version>]]" 12help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]"
13 13
14help = [[ 14help = [[
15--all Download multiple rock files if there is more than one match. 15--all Download all files if there are multiple matches.
16--source Download .src.rock if available. 16--source Download .src.rock if available.
17--rockspec Download .rockspec if available.
17--arch=<arch> Download rock for a specific architecture. 18--arch=<arch> Download rock for a specific architecture.
18]] 19]]
19 20
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua
index 2ea2c906..b835b20e 100644
--- a/src/luarocks/fetch.lua
+++ b/src/luarocks/fetch.lua
@@ -9,6 +9,7 @@ local path = require("luarocks.path")
9local deps = require("luarocks.deps") 9local deps = require("luarocks.deps")
10local persist = require("luarocks.persist") 10local persist = require("luarocks.persist")
11local util = require("luarocks.util") 11local util = require("luarocks.util")
12local cfg = require("luarocks.cfg")
12 13
13--- Fetch a local or remote file. 14--- Fetch a local or remote file.
14-- Make a remote or local URL/pathname local, fetching the file if necessary. 15-- Make a remote or local URL/pathname local, fetching the file if necessary.
@@ -59,7 +60,11 @@ function fetch_url_at_temp_dir(url, tmpname, filename)
59 60
60 local protocol, pathname = dir.split_url(url) 61 local protocol, pathname = dir.split_url(url)
61 if protocol == "file" then 62 if protocol == "file" then
62 return pathname, dir.dir_name(fs.absolute_name(pathname)) 63 if fs.exists(pathname) then
64 return pathname, dir.dir_name(fs.absolute_name(pathname))
65 else
66 return nil, "File not found: "..pathname
67 end
63 else 68 else
64 local temp_dir = fs.make_temp_dir(tmpname) 69 local temp_dir = fs.make_temp_dir(tmpname)
65 if not temp_dir then 70 if not temp_dir then
@@ -117,7 +122,7 @@ end
117 122
118--- Back-end function that actually loads the local rockspec. 123--- Back-end function that actually loads the local rockspec.
119-- Performs some validation and postprocessing of the rockspec contents. 124-- Performs some validation and postprocessing of the rockspec contents.
120-- @param file string: The local filename of the rockspec file. 125-- @param filename string: The local filename of the rockspec file.
121-- @return table or (nil, string): A table representing the rockspec 126-- @return table or (nil, string): A table representing the rockspec
122-- or nil followed by an error message. 127-- or nil followed by an error message.
123function load_local_rockspec(filename) 128function load_local_rockspec(filename)
@@ -162,8 +167,8 @@ function load_local_rockspec(filename)
162 rockspec.source.protocol, rockspec.source.pathname = protocol, pathname 167 rockspec.source.protocol, rockspec.source.pathname = protocol, pathname
163 168
164 -- Temporary compatibility 169 -- Temporary compatibility
165 if not rockspec.source.cvs_module then rockspec.source.module = rockspec.source.cvs_module end 170 if rockspec.source.cvs_module then rockspec.source.module = rockspec.source.cvs_module end
166 if not rockspec.source.cvs_tag then rockspec.source.tag = rockspec.source.cvs_tag end 171 if rockspec.source.cvs_tag then rockspec.source.tag = rockspec.source.cvs_tag end
167 172
168 local name_version = rockspec.package:lower() .. "-" .. rockspec.version 173 local name_version = rockspec.package:lower() .. "-" .. rockspec.version
169 if basename ~= "rockspec" and basename ~= name_version .. ".rockspec" then 174 if basename ~= "rockspec" and basename ~= name_version .. ".rockspec" then
@@ -297,11 +302,20 @@ function fetch_sources(rockspec, extract, dest_dir)
297 if protocol == "http" or protocol == "https" or protocol == "ftp" or protocol == "file" then 302 if protocol == "http" or protocol == "https" or protocol == "ftp" or protocol == "file" then
298 proto = require("luarocks.fetch") 303 proto = require("luarocks.fetch")
299 else 304 else
300 ok, proto = pcall(require, "luarocks.fetch."..protocol) 305 ok, proto = pcall(require, "luarocks.fetch."..protocol:gsub("[+-]", "_"))
301 if not ok then 306 if not ok then
302 return nil, "Unknown protocol "..protocol 307 return nil, "Unknown protocol "..protocol
303 end 308 end
304 end 309 end
305 310
311 if cfg.only_sources_from
312 and rockspec.source.pathname
313 and #rockspec.source.pathname > 0 then
314 if #cfg.only_sources_from == 0 then
315 return nil, "Can't download "..rockspec.source.url.." -- download from remote servers disabled"
316 elseif rockspec.source.pathname:find(cfg.only_sources_from, 1, true) ~= 1 then
317 return nil, "Can't download "..rockspec.source.url.." -- only downloading from "..cfg.only_sources_from
318 end
319 end
306 return proto.get_sources(rockspec, extract, dest_dir) 320 return proto.get_sources(rockspec, extract, dest_dir)
307end 321end
diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua
index 7db74c26..f8c0f2c8 100644
--- a/src/luarocks/fetch/git.lua
+++ b/src/luarocks/fetch/git.lua
@@ -26,7 +26,7 @@ function get_sources(rockspec, extract, dest_dir)
26 local checkout_command 26 local checkout_command
27 local tag_or_branch = rockspec.source.tag or rockspec.source.branch 27 local tag_or_branch = rockspec.source.tag or rockspec.source.branch
28 if tag_or_branch then 28 if tag_or_branch then
29 checkout_command = {git_cmd, "checkout", tag_or_branch} 29 checkout_command = {git_cmd, "checkout", "-q", tag_or_branch}
30 end 30 end
31 local store_dir 31 local store_dir
32 if not dest_dir then 32 if not dest_dir then
@@ -38,6 +38,7 @@ function get_sources(rockspec, extract, dest_dir)
38 else 38 else
39 store_dir = dest_dir 39 store_dir = dest_dir
40 end 40 end
41 store_dir = fs.absolute_name(store_dir)
41 fs.change_dir(store_dir) 42 fs.change_dir(store_dir)
42 if not fs.execute(unpack(command)) then 43 if not fs.execute(unpack(command)) then
43 return nil, "Failed cloning git repository." 44 return nil, "Failed cloning git repository."
diff --git a/src/luarocks/fetch/git_file.lua b/src/luarocks/fetch/git_file.lua
new file mode 100644
index 00000000..1b18d0fa
--- /dev/null
+++ b/src/luarocks/fetch/git_file.lua
@@ -0,0 +1,17 @@
1
2--- Fetch back-end for retrieving sources from local Git repositories.
3module("luarocks.fetch.git_file", package.seeall)
4
5local git = require("luarocks.fetch.git")
6
7--- Fetch sources for building a rock from a local Git repository.
8-- @param rockspec table: The rockspec table
9-- @param extract boolean: Unused in this module (required for API purposes.)
10-- @param dest_dir string or nil: If set, will extract to the given directory.
11-- @return (string, string) or (nil, string): The absolute pathname of
12-- the fetched source tarball and the temporary directory created to
13-- store it; or nil and an error message.
14function get_sources(rockspec, extract, dest_dir)
15 rockspec.source.url = rockspec.source.url:gsub("^git.file://", "")
16 return git.get_sources(rockspec, extract, dest_dir)
17end
diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua
index d2cb3ddb..467b1943 100644
--- a/src/luarocks/fs.lua
+++ b/src/luarocks/fs.lua
@@ -1,11 +1,12 @@
1 1
2local pairs = pairs
3
4--- Proxy module for filesystem and platform abstractions. 2--- Proxy module for filesystem and platform abstractions.
5-- All code using "fs" code should require "luarocks.fs", 3-- All code using "fs" code should require "luarocks.fs",
6-- and not the various platform-specific implementations. 4-- and not the various platform-specific implementations.
7-- However, see the documentation of the implementation 5-- However, see the documentation of the implementation
8-- for the API reference. 6-- for the API reference.
7
8local pairs = pairs
9
9module("luarocks.fs", package.seeall) 10module("luarocks.fs", package.seeall)
10 11
11local cfg = require("luarocks.cfg") 12local cfg = require("luarocks.cfg")
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua
index 1a7e4eff..67c3ce0f 100644
--- a/src/luarocks/fs/lua.lua
+++ b/src/luarocks/fs/lua.lua
@@ -59,7 +59,7 @@ function is_writable(file)
59 if fh then fh:close() end 59 if fh then fh:close() end
60 os.remove(file2) 60 os.remove(file2)
61 else 61 else
62 local fh = io.open(file, 'rb+') 62 local fh = io.open(file, 'r+b')
63 result = fh ~= nil 63 result = fh ~= nil
64 if fh then fh:close() end 64 if fh then fh:close() end
65 end 65 end
@@ -129,7 +129,8 @@ if lfs_ok then
129-- @return boolean: true if command succeeds (status code 0), false 129-- @return boolean: true if command succeeds (status code 0), false
130-- otherwise. 130-- otherwise.
131function execute_string(cmd) 131function execute_string(cmd)
132 if os.execute(cmd) == 0 then 132 local code = os.execute(cmd)
133 if code == 0 or code == true then
133 return true 134 return true
134 else 135 else
135 return false 136 return false
@@ -159,7 +160,7 @@ end
159-- a crossplatform way. 160-- a crossplatform way.
160function change_dir_to_root() 161function change_dir_to_root()
161 table.insert(dir_stack, lfs.currentdir()) 162 table.insert(dir_stack, lfs.currentdir())
162 lfs.chdir("/") -- works on Windows too 163 lfs.chdir("/") -- works on Windows too
163end 164end
164 165
165--- Change working directory to the previous in the dir stack. 166--- Change working directory to the previous in the dir stack.
@@ -231,9 +232,11 @@ end
231--- Copy a file. 232--- Copy a file.
232-- @param src string: Pathname of source 233-- @param src string: Pathname of source
233-- @param dest string: Pathname of destination 234-- @param dest string: Pathname of destination
235-- @param perms string or nil: Permissions for destination file,
236-- or nil to use the source filename permissions
234-- @return boolean or (boolean, string): true on success, false on failure, 237-- @return boolean or (boolean, string): true on success, false on failure,
235-- plus an error message. 238-- plus an error message.
236function copy(src, dest) 239function copy(src, dest, perms)
237 assert(src and dest) 240 assert(src and dest)
238 src = normalize(src) 241 src = normalize(src)
239 dest = normalize(dest) 242 dest = normalize(dest)
@@ -241,7 +244,7 @@ function copy(src, dest)
241 if destmode == "directory" then 244 if destmode == "directory" then
242 dest = dir.path(dest, dir.base_name(src)) 245 dest = dir.path(dest, dir.base_name(src))
243 end 246 end
244 local perms = fs.get_permissions(src) 247 if not perms then perms = fs.get_permissions(src) end
245 local src_h, err = io.open(src, "rb") 248 local src_h, err = io.open(src, "rb")
246 if not src_h then return nil, err end 249 if not src_h then return nil, err end
247 local dest_h, err = io.open(dest, "wb+") 250 local dest_h, err = io.open(dest, "wb+")
@@ -540,7 +543,7 @@ function download(url, filename)
540 err = "Unsupported protocol" 543 err = "Unsupported protocol"
541 end 544 end
542 if not content then 545 if not content then
543 return false, err 546 return false, tostring(err)
544 end 547 end
545 local file = io.open(filename, "wb") 548 local file = io.open(filename, "wb")
546 if not file then return false end 549 if not file then return false end
@@ -576,7 +579,26 @@ end
576 579
577if posix_ok then 580if posix_ok then
578 581
582local octal_to_rwx = {
583 ["0"] = "---",
584 ["1"] = "--x",
585 ["2"] = "-w-",
586 ["3"] = "-wx",
587 ["4"] = "r--",
588 ["5"] = "r-x",
589 ["6"] = "rw-",
590 ["7"] = "rwx",
591}
592
579function chmod(file, mode) 593function chmod(file, mode)
594 -- LuaPosix (as of 5.1.15) does not support octal notation...
595 if mode:sub(1,1) == "0" then
596 local new_mode = {}
597 for c in mode:sub(2):gmatch(".") do
598 table.insert(new_mode, octal_to_rwx[c])
599 end
600 mode = table.concat(new_mode)
601 end
580 local err = posix.chmod(file, mode) 602 local err = posix.chmod(file, mode)
581 return err == 0 603 return err == 0
582end 604end
@@ -593,6 +615,7 @@ end
593 615
594--- Apply a patch. 616--- Apply a patch.
595-- @param patchname string: The filename of the patch. 617-- @param patchname string: The filename of the patch.
618-- @param patchdata string or nil: The actual patch as a string.
596function apply_patch(patchname, patchdata) 619function apply_patch(patchname, patchdata)
597 local p, all_ok = patch.read_patch(patchname, patchdata) 620 local p, all_ok = patch.read_patch(patchname, patchdata)
598 if not all_ok then 621 if not all_ok then
@@ -631,9 +654,23 @@ end
631-- plus an error message. 654-- plus an error message.
632function check_command_permissions(flags) 655function check_command_permissions(flags)
633 local root_dir = path.root_dir(cfg.rocks_dir) 656 local root_dir = path.root_dir(cfg.rocks_dir)
634 if not flags["local"] and not fs.is_writable(root_dir) then 657 local ok = true
635 return nil, "Your user does not have write permissions in " .. root_dir .. 658 local err = ""
636 " \n-- you may want to run as a privileged user or use your local tree with --local." 659 for _, dir in ipairs { cfg.rocks_dir, root_dir, dir.dir_name(root_dir) } do
660 if fs.exists(dir) and not fs.is_writable(dir) then
661 ok = false
662 err = "Your user does not have write permissions in " .. dir
663 break
664 end
665 end
666 if ok then
667 return true
668 else
669 if flags["local"] then
670 err = err .. " \n-- please check your permissions."
671 else
672 err = err .. " \n-- you may want to run as a privileged user or use your local tree with --local."
673 end
674 return nil, err
637 end 675 end
638 return true
639end 676end
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua
index 0930cadb..88bafaf6 100644
--- a/src/luarocks/fs/unix.lua
+++ b/src/luarocks/fs/unix.lua
@@ -1,8 +1,9 @@
1 1
2--- Unix implementation of filesystem and platform abstractions.
3
2local assert, type, table, io, package, math, os, ipairs = 4local assert, type, table, io, package, math, os, ipairs =
3 assert, type, table, io, package, math, os, ipairs 5 assert, type, table, io, package, math, os, ipairs
4 6
5--- Unix implementation of filesystem and platform abstractions.
6module("luarocks.fs.unix", package.seeall) 7module("luarocks.fs.unix", package.seeall)
7 8
8local fs = require("luarocks.fs") 9local fs = require("luarocks.fs")
@@ -53,7 +54,7 @@ function wrap_script(file, dest)
53 wrapper:write('export LUA_PATH LUA_CPATH\n') 54 wrapper:write('export LUA_PATH LUA_CPATH\n')
54 wrapper:write('exec "'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.loader "'..file..'" "$@"\n') 55 wrapper:write('exec "'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.loader "'..file..'" "$@"\n')
55 wrapper:close() 56 wrapper:close()
56 if fs.execute("chmod +x",wrapname) then 57 if fs.chmod(wrapname, "0755") then
57 return true 58 return true
58 else 59 else
59 return nil, "Could not make "..wrapname.." executable." 60 return nil, "Could not make "..wrapname.." executable."
@@ -70,61 +71,18 @@ function is_actual_binary(filename)
70 return false 71 return false
71 end 72 end
72 local file = io.open(filename) 73 local file = io.open(filename)
73 if file then 74 if not file then
74 local found = false
75 local first = file:read()
76 if first:match("#!.*lua") then
77 found = true
78 elseif first:match("#!/bin/sh") then
79 local line = file:read()
80 line = file:read()
81 if not(line and line:match("LUA_PATH")) then
82 found = true
83 end
84 end
85 file:close()
86 if found then
87 return false
88 else
89 return true
90 end
91 else
92 return true 75 return true
93 end 76 end
94 return false 77 local first = file:read(2)
95end 78 file:close()
96 79 if not first then
97function is_actual_binary(filename) 80 util.printerr("Warning: could not read "..filename)
98 if filename:match("%.lua$") then
99 return false
100 end
101 local file = io.open(filename)
102 if file then
103 local found = false
104 local first = file:read()
105 if not first then
106 file:close()
107 util.printerr("Warning: could not read "..filename)
108 return false
109 end
110 if first:match("#!.*lua") then
111 file:close()
112 return true
113 elseif first:match("#!/bin/sh") then
114 local line = file:read()
115 line = file:read()
116 if not(line and line:match("LUA_PATH")) then
117 file:close()
118 return true
119 end
120 end
121 file:close()
122 else
123 return true 81 return true
124 end 82 end
125 return false 83 return first ~= "#!"
126end 84end
127 85
128function copy_binary(filename, dest) 86function copy_binary(filename, dest)
129 return fs.copy(filename, dest) 87 return fs.copy(filename, dest, "0755")
130end 88end
diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua
index d1722f4b..37efcf66 100644
--- a/src/luarocks/fs/unix/tools.lua
+++ b/src/luarocks/fs/unix/tools.lua
@@ -11,13 +11,14 @@ local dir_stack = {}
11local vars = cfg.variables 11local vars = cfg.variables
12 12
13--- Run the given command. 13--- Run the given command.
14-- The command is executed in the current directory in the dir stack. 14-- The command is executed in the current directory in the directory stack.
15-- @param cmd string: No quoting/escaping is applied to the command. 15-- @param cmd string: No quoting/escaping is applied to the command.
16-- @return boolean: true if command succeeds (status code 0), false 16-- @return boolean: true if command succeeds (status code 0), false
17-- otherwise. 17-- otherwise.
18function execute_string(cmd) 18function execute_string(cmd)
19 local actual_cmd = "cd " .. fs.Q(fs.current_dir()) .. " && " .. cmd 19 local actual_cmd = "cd " .. fs.Q(fs.current_dir()) .. " && " .. cmd
20 if os.execute(actual_cmd) == 0 then 20 local code = os.execute(actual_cmd)
21 if code == 0 or code == true then
21 return true 22 return true
22 else 23 else
23 return false 24 return false
@@ -25,26 +26,26 @@ function execute_string(cmd)
25end 26end
26 27
27--- Obtain current directory. 28--- Obtain current directory.
28-- Uses the module's internal dir stack. 29-- Uses the module's internal directory stack.
29-- @return string: the absolute pathname of the current directory. 30-- @return string: the absolute pathname of the current directory.
30function current_dir() 31function current_dir()
31 local pipe = io.popen(vars.PWD) 32 local pipe = io.popen(vars.PWD)
32 local current = pipe:read("*l") 33 local current = pipe:read("*l")
33 pipe:close() 34 pipe:close()
34 for _, d in ipairs(dir_stack) do 35 for _, directory in ipairs(dir_stack) do
35 current = fs.absolute_name(d, current) 36 current = fs.absolute_name(directory, current)
36 end 37 end
37 return current 38 return current
38end 39end
39 40
40--- Change the current directory. 41--- Change the current directory.
41-- Uses the module's internal dir stack. This does not have exact 42-- Uses the module's internal directory stack. This does not have exact
42-- semantics of chdir, as it does not handle errors the same way, 43-- semantics of chdir, as it does not handle errors the same way,
43-- but works well for our purposes for now. 44-- but works well for our purposes for now.
44-- @param d string: The directory to switch to. 45-- @param directory string: The directory to switch to.
45function change_dir(d) 46function change_dir(directory)
46 assert(type(d) == "string") 47 assert(type(directory) == "string")
47 table.insert(dir_stack, d) 48 table.insert(dir_stack, directory)
48end 49end
49 50
50--- Change directory to root. 51--- Change directory to root.
@@ -54,48 +55,59 @@ function change_dir_to_root()
54 table.insert(dir_stack, "/") 55 table.insert(dir_stack, "/")
55end 56end
56 57
57--- Change working directory to the previous in the dir stack. 58--- Change working directory to the previous in the directory stack.
58function pop_dir() 59function pop_dir()
59 local d = table.remove(dir_stack) 60 local directory = table.remove(dir_stack)
60 return d ~= nil 61 return directory ~= nil
61end 62end
62 63
63--- Create a directory if it does not already exist. 64--- Create a directory if it does not already exist.
64-- If any of the higher levels in the path name does not exist 65-- If any of the higher levels in the path name does not exist
65-- too, they are created as well. 66-- too, they are created as well.
66-- @param d string: pathname of directory to create. 67-- @param directory string: pathname of directory to create.
67-- @return boolean: true on success, false on failure. 68-- @return boolean: true on success, false on failure.
68function make_dir(d) 69function make_dir(directory)
69 assert(d) 70 assert(directory)
70 return fs.execute(vars.MKDIR.." -p", d) 71 return fs.execute(vars.MKDIR.." -p", directory)
71end 72end
72 73
73--- Remove a directory if it is empty. 74--- Remove a directory if it is empty.
74-- Does not return errors (for example, if directory is not empty or 75-- Does not return errors (for example, if directory is not empty or
75-- if already does not exist) 76-- if already does not exist)
76-- @param dir string: pathname of directory to remove. 77-- @param directory string: pathname of directory to remove.
77function remove_dir_if_empty(d) 78function remove_dir_if_empty(directory)
78 assert(d) 79 assert(directory)
79 fs.execute_string(vars.RMDIR.." "..fs.Q(d).." 1> /dev/null 2> /dev/null") 80 fs.execute_string(vars.RMDIR.." "..fs.Q(directory).." 1> /dev/null 2> /dev/null")
80end 81end
81 82
82--- Remove a directory if it is empty. 83--- Remove a directory if it is empty.
83-- Does not return errors (for example, if directory is not empty or 84-- Does not return errors (for example, if directory is not empty or
84-- if already does not exist) 85-- if already does not exist)
85-- @param dir string: pathname of directory to remove. 86-- @param directory string: pathname of directory to remove.
86function remove_dir_tree_if_empty(d) 87function remove_dir_tree_if_empty(directory)
87 assert(d) 88 assert(directory)
88 fs.execute_string(vars.RMDIR.." -p "..fs.Q(d).." 1> /dev/null 2> /dev/null") 89 fs.execute_string(vars.RMDIR.." -p "..fs.Q(directory).." 1> /dev/null 2> /dev/null")
89end 90end
90 91
91--- Copy a file. 92--- Copy a file.
92-- @param src string: Pathname of source 93-- @param src string: Pathname of source
93-- @param dest string: Pathname of destination 94-- @param dest string: Pathname of destination
95-- @param perm string or nil: Permissions for destination file,
94-- @return boolean or (boolean, string): true on success, false on failure, 96-- @return boolean or (boolean, string): true on success, false on failure,
95-- plus an error message. 97-- plus an error message.
96function copy(src, dest) 98function copy(src, dest, perm)
97 assert(src and dest) 99 assert(src and dest)
98 if fs.execute(vars.CP, src, dest) then 100 if fs.execute(vars.CP, src, dest) then
101 if perm then
102 if fs.is_dir(dest) then
103 dest = dir.path(dest, dir.base_name(src))
104 end
105 if fs.chmod(dest, perm) then
106 return true
107 else
108 return false, "Failed setting permissions of "..dest
109 end
110 end
99 return true 111 return true
100 else 112 else
101 return false, "Failed copying "..src.." to "..dest 113 return false, "Failed copying "..src.." to "..dest
@@ -194,7 +206,7 @@ function exists(file)
194 return fs.execute(vars.TEST, "-r", file) 206 return fs.execute(vars.TEST, "-r", file)
195end 207end
196 208
197--- Test is file/dir is writable. 209--- Test is file/directory is writable.
198-- @param file string: filename to test 210-- @param file string: filename to test
199-- @return boolean: true if file exists, false otherwise. 211-- @return boolean: true if file exists, false otherwise.
200function is_writable(file) 212function is_writable(file)
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua
index 44740850..98daf13f 100644
--- a/src/luarocks/fs/win32.lua
+++ b/src/luarocks/fs/win32.lua
@@ -15,7 +15,7 @@ local dir = require("luarocks.dir")
15function Q(arg) 15function Q(arg)
16 assert(type(arg) == "string") 16 assert(type(arg) == "string")
17 -- Quote DIR for Windows 17 -- Quote DIR for Windows
18 if arg:match("^[\.a-zA-Z]?:?[\\/]") then 18 if arg:match("^[%.a-zA-Z]?:?[\\/]") then
19 return '"' .. arg:gsub("/", "\\"):gsub('"', '\\"') .. '"' 19 return '"' .. arg:gsub("/", "\\"):gsub('"', '\\"') .. '"'
20 end 20 end
21 -- URLs and anything else 21 -- URLs and anything else
@@ -33,7 +33,9 @@ function absolute_name(pathname, relative_to)
33 assert(type(relative_to) == "string" or not relative_to) 33 assert(type(relative_to) == "string" or not relative_to)
34 34
35 relative_to = relative_to or fs.current_dir() 35 relative_to = relative_to or fs.current_dir()
36 if pathname:match("^[\.a-zA-Z]?:?[\\/]") then 36 -- FIXME I'm not sure this first \\ should be there at all.
37 -- What are the Windows rules for drive letters?
38 if pathname:match("^[\\.a-zA-Z]?:?[\\/]") then
37 return pathname 39 return pathname
38 else 40 else
39 return relative_to .. "/" .. pathname 41 return relative_to .. "/" .. pathname
diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua
index 5b7634cf..6115f382 100644
--- a/src/luarocks/fs/win32/tools.lua
+++ b/src/luarocks/fs/win32/tools.lua
@@ -42,14 +42,14 @@ function exists(file)
42end 42end
43 43
44--- Obtain current directory. 44--- Obtain current directory.
45-- Uses the module's internal dir stack. 45-- Uses the module's internal directory stack.
46-- @return string: the absolute pathname of the current directory. 46-- @return string: the absolute pathname of the current directory.
47function current_dir() 47function current_dir()
48 local pipe = io.popen(vars.PWD) 48 local pipe = io.popen(vars.PWD)
49 local current = pipe:read("*l") 49 local current = pipe:read("*l")
50 pipe:close() 50 pipe:close()
51 for _, d in ipairs(dir_stack) do 51 for _, directory in ipairs(dir_stack) do
52 current = fs.absolute_name(d, current) 52 current = fs.absolute_name(directory, current)
53 end 53 end
54 return current 54 return current
55end 55end
@@ -82,13 +82,13 @@ function get_md5(file)
82end 82end
83 83
84--- Change the current directory. 84--- Change the current directory.
85-- Uses the module's internal dir stack. This does not have exact 85-- Uses the module's internal directory stack. This does not have exact
86-- semantics of chdir, as it does not handle errors the same way, 86-- semantics of chdir, as it does not handle errors the same way,
87-- but works well for our purposes for now. 87-- but works well for our purposes for now.
88-- @param d string: The directory to switch to. 88-- @param directory string: The directory to switch to.
89function change_dir(d) 89function change_dir(directory)
90 assert(type(d) == "string") 90 assert(type(directory) == "string")
91 table.insert(dir_stack, d) 91 table.insert(dir_stack, directory)
92end 92end
93 93
94--- Change directory to root. 94--- Change directory to root.
@@ -98,19 +98,20 @@ function change_dir_to_root()
98 table.insert(dir_stack, "/") 98 table.insert(dir_stack, "/")
99end 99end
100 100
101--- Change working directory to the previous in the dir stack. 101--- Change working directory to the previous in the directory stack.
102function pop_dir() 102function pop_dir()
103 local d = table.remove(dir_stack) 103 local directory = table.remove(dir_stack)
104 return d ~= nil 104 return directory ~= nil
105end 105end
106 106
107--- Run the given command. 107--- Run the given command.
108-- The command is executed in the current directory in the dir stack. 108-- The command is executed in the current directory in the directory stack.
109-- @param cmd string: No quoting/escaping is applied to the command. 109-- @param cmd string: No quoting/escaping is applied to the command.
110-- @return boolean: true if command succeeds (status code 0), false 110-- @return boolean: true if command succeeds (status code 0), false
111-- otherwise. 111-- otherwise.
112function execute_string(cmd) 112function execute_string(cmd)
113 if os.execute(command_at(fs.current_dir(), cmd)) == 0 then 113 local code = os.execute(command_at(fs.current_dir(), cmd))
114 if code == 0 or code == true then
114 return true 115 return true
115 else 116 else
116 return false 117 return false
@@ -128,30 +129,30 @@ end
128--- Create a directory if it does not already exist. 129--- Create a directory if it does not already exist.
129-- If any of the higher levels in the path name does not exist 130-- If any of the higher levels in the path name does not exist
130-- too, they are created as well. 131-- too, they are created as well.
131-- @param d string: pathname of directory to create. 132-- @param directory string: pathname of directory to create.
132-- @return boolean: true on success, false on failure. 133-- @return boolean: true on success, false on failure.
133function make_dir(d) 134function make_dir(directory)
134 assert(d) 135 assert(directory)
135 fs.execute(vars.MKDIR.." "..fs.Q(d).." 1> NUL 2> NUL") 136 fs.execute(vars.MKDIR.." "..fs.Q(directory).." 1> NUL 2> NUL")
136 return 1 137 return 1
137end 138end
138 139
139--- Remove a directory if it is empty. 140--- Remove a directory if it is empty.
140-- Does not return errors (for example, if directory is not empty or 141-- Does not return errors (for example, if directory is not empty or
141-- if already does not exist) 142-- if already does not exist)
142-- @param d string: pathname of directory to remove. 143-- @param directory string: pathname of directory to remove.
143function remove_dir_if_empty(d) 144function remove_dir_if_empty(directory)
144 assert(d) 145 assert(directory)
145 fs.execute_string(vars.RMDIR.." "..fs.Q(d).." 1> NUL 2> NUL") 146 fs.execute_string(vars.RMDIR.." "..fs.Q(directory).." 1> NUL 2> NUL")
146end 147end
147 148
148--- Remove a directory if it is empty. 149--- Remove a directory if it is empty.
149-- Does not return errors (for example, if directory is not empty or 150-- Does not return errors (for example, if directory is not empty or
150-- if already does not exist) 151-- if already does not exist)
151-- @param dir string: pathname of directory to remove. 152-- @param directory string: pathname of directory to remove.
152function remove_dir_tree_if_empty(d) 153function remove_dir_tree_if_empty(directory)
153 assert(d) 154 assert(directory)
154 fs.execute_string(vars.RMDIR.." "..fs.Q(d).." 1> NUL 2> NUL") 155 fs.execute_string(vars.RMDIR.." "..fs.Q(directory).." 1> NUL 2> NUL")
155end 156end
156 157
157--- Copy a file. 158--- Copy a file.
diff --git a/src/luarocks/help.lua b/src/luarocks/help.lua
index a2e64b5d..19cd7914 100644
--- a/src/luarocks/help.lua
+++ b/src/luarocks/help.lua
@@ -9,13 +9,31 @@ module("luarocks.help", package.seeall)
9local util = require("luarocks.util") 9local util = require("luarocks.util")
10local cfg = require("luarocks.cfg") 10local cfg = require("luarocks.cfg")
11 11
12help_summary = "Help on commands." 12help_summary = "Help on commands. Type '"..program_name.." help <command>' for more."
13 13
14help_arguments = "[<command>]" 14help_arguments = "[<command>]"
15help = [[ 15help = [[
16<command> is the command to show help for. 16<command> is the command to show help for.
17]] 17]]
18 18
19local function print_banner()
20 util.printout("\nLuaRocks "..cfg.program_version..", a module deployment system for Lua")
21end
22
23local function print_section(section)
24 util.printout("\n"..section)
25end
26
27local function get_status(status)
28 if status then
29 return "ok"
30 elseif status == false then
31 return "not found"
32 else
33 return "failed"
34 end
35end
36
19--- Driver function for the "help" command. 37--- Driver function for the "help" command.
20-- @param command string or nil: command to show help for; if not 38-- @param command string or nil: command to show help for; if not
21-- given, help summaries for all commands are shown. 39-- given, help summaries for all commands are shown.
@@ -25,25 +43,29 @@ function run(...)
25 local flags, command = util.parse_flags(...) 43 local flags, command = util.parse_flags(...)
26 44
27 if not command then 45 if not command then
46 local sys_file, sys_ok, home_file, home_ok = cfg.which_config()
47 print_banner()
48 print_section("NAME")
49 util.printout("\t"..program_name..[[ - ]]..program_description)
50 print_section("SYNOPSIS")
51 util.printout("\t"..program_name..[[ [--from=<server> | --only-from=<server>] [--to=<tree>] [VAR=VALUE]... <command> [<argument>] ]])
52 print_section("GENERAL OPTIONS")
28 util.printout([[ 53 util.printout([[
29LuaRocks ]]..cfg.program_version..[[, a module deployment system for Lua 54 These apply to all commands, as appropriate:
30
31]]..program_name..[[ - ]]..program_description..[[
32
33usage: ]]..program_name..[[ [--from=<server> | --only-from=<server>] [--to=<tree>] [VAR=VALUE]... <command> [<argument>]
34
35Variables from the "variables" table of the configuration file
36can be overriden with VAR=VALUE assignments.
37 55
38--from=<server> Fetch rocks/rockspecs from this server 56 --server=<server> Fetch rocks/rockspecs from this server
39 (takes priority over config file) 57 (takes priority over config file)
40--only-from=<server> Fetch rocks/rockspecs from this server only 58 --only-server=<server> Fetch rocks/rockspecs from this server only
41 (overrides any entries in the config file) 59 (overrides any entries in the config file)
42--to=<tree> Which tree to operate on. 60 --only-sources=<url> Restrict downloads to paths matching the
43--local Use the tree in the user's home directory. 61 given URL.
44 62 --tree=<tree> Which tree to operate on.
45Supported commands: 63 --local Use the tree in the user's home directory.]])
46]]) 64 print_section("VARIABLES")
65 util.printout([[
66 Variables from the "variables" table of the configuration file
67 can be overriden with VAR=VALUE assignments.]])
68 print_section("COMMANDS")
47 local names = {} 69 local names = {}
48 for name, command in pairs(commands) do 70 for name, command in pairs(commands) do
49 table.insert(names, name) 71 table.insert(names, name)
@@ -51,18 +73,26 @@ Supported commands:
51 table.sort(names) 73 table.sort(names)
52 for _, name in ipairs(names) do 74 for _, name in ipairs(names) do
53 local command = commands[name] 75 local command = commands[name]
54 util.printout(name, command.help_summary) 76 util.printout("", name)
77 util.printout("\t", command.help_summary)
55 end 78 end
79 print_section("CONFIGURATION")
80 util.printout([[
81 System configuration file: ]]..sys_file .. " (" .. get_status(sys_ok) ..[[)
82 User configuration file: ]]..home_file .. " (" .. get_status(home_ok) ..")\n")
56 else 83 else
57 command = command:gsub("-", "_") 84 command = command:gsub("-", "_")
58 if commands[command] then 85 if commands[command] then
59 local arguments = commands[command].help_arguments or "<argument>" 86 local arguments = commands[command].help_arguments or "<argument>"
60 util.printout() 87 print_banner()
61 util.printout(program_name.." "..command.." "..arguments) 88 print_section("NAME")
62 util.printout() 89 util.printout("\t"..program_name.." "..command.." - "..commands[command].help_summary)
63 util.printout(command.." - "..commands[command].help_summary) 90 print_section("SYNOPSIS")
64 util.printout() 91 util.printout("\t"..program_name.." "..command.." "..arguments)
65 util.printout(commands[command].help) 92 print_section("DESCRIPTION")
93 util.printout("",(commands[command].help:gsub("\n","\n\t"):gsub("\n\t$","")))
94 print_section("SEE ALSO")
95 util.printout("","'luarocks help' for general options and configuration.\n")
66 else 96 else
67 return nil, "Unknown command '"..command.."'" 97 return nil, "Unknown command '"..command.."'"
68 end 98 end
diff --git a/src/luarocks/index.lua b/src/luarocks/index.lua
index 570db431..6aa7c831 100644
--- a/src/luarocks/index.lua
+++ b/src/luarocks/index.lua
@@ -1,4 +1,5 @@
1 1
2--- Module which builds the index.html page to be used in rocks servers.
2module("luarocks.index", package.seeall) 3module("luarocks.index", package.seeall)
3 4
4local util = require("luarocks.util") 5local util = require("luarocks.util")
@@ -143,14 +144,15 @@ function make_index(repo)
143 output = output .. index_package_end 144 output = output .. index_package_end
144 if latest_rockspec then 145 if latest_rockspec then
145 local rockspec = persist.load_into_table(dir.path(repo, latest_rockspec)) 146 local rockspec = persist.load_into_table(dir.path(repo, latest_rockspec))
147 local descript = rockspec.description or {}
146 local vars = { 148 local vars = {
147 anchor = package, 149 anchor = package,
148 package = rockspec.package, 150 package = rockspec.package,
149 original = rockspec.source.url, 151 original = rockspec.source.url,
150 summary = rockspec.description.summary or "", 152 summary = descript.summary or "",
151 detailed = rockspec.description.detailed or "", 153 detailed = descript.detailed or "",
152 license = rockspec.description.license or "N/A", 154 license = descript.license or "N/A",
153 homepage = rockspec.description.homepage and ("| <a href="..rockspec.description.homepage..">project homepage</a>") or "", 155 homepage = descript.homepage and ("| <a href="..descript.homepage..">project homepage</a>") or "",
154 externaldependencies = format_external_dependencies(rockspec) 156 externaldependencies = format_external_dependencies(rockspec)
155 } 157 }
156 vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ") 158 vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ")
diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua
index e99b4ce0..0ae163f8 100644
--- a/src/luarocks/install.lua
+++ b/src/luarocks/install.lua
@@ -65,7 +65,12 @@ function install_binary_rock(rock_file)
65 ok, err, errcode = deps.fulfill_dependencies(rockspec) 65 ok, err, errcode = deps.fulfill_dependencies(rockspec)
66 if err then return nil, err, errcode end 66 if err then return nil, err, errcode end
67 67
68 ok, err = rep.deploy_files(name, version) 68 local wrap_bin_scripts = true
69 if rockspec.deploy and rockspec.deploy.wrap_bin_scripts == false then
70 wrap_bin_scripts = false
71 end
72
73 ok, err = rep.deploy_files(name, version, rep.should_wrap_bin_scripts(rockspec))
69 if err then return nil, err end 74 if err then return nil, err end
70 75
71 util.remove_scheduled_function(rollback) 76 util.remove_scheduled_function(rollback)
@@ -112,6 +117,7 @@ function run(...)
112 if not ok then return nil, err end 117 if not ok then return nil, err end
113 118
114 if name:match("%.rockspec$") or name:match("%.src%.rock$") then 119 if name:match("%.rockspec$") or name:match("%.src%.rock$") then
120 util.printout("Using "..name.."... switching to 'build' mode")
115 local build = require("luarocks.build") 121 local build = require("luarocks.build")
116 return build.run(name, flags["local"] and "--local") 122 return build.run(name, flags["local"] and "--local")
117 elseif name:match("%.rock$") then 123 elseif name:match("%.rock$") then
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua
index c3cba55a..362a986a 100644
--- a/src/luarocks/loader.lua
+++ b/src/luarocks/loader.lua
@@ -1,4 +1,10 @@
1 1
2--- A module which installs a Lua package loader that is LuaRocks-aware.
3-- This loader uses dependency information from the LuaRocks tree to load
4-- correct versions of modules. It does this by constructing a "context"
5-- table in the environment, which records which versions of packages were
6-- used to load previous modules, so that the loader chooses versions
7-- that are declared to be compatible with the ones loaded earlier.
2local global_env = _G 8local global_env = _G
3local package, require, ipairs, pairs, table, type, next, unpack = 9local package, require, ipairs, pairs, table, type, next, unpack =
4 package, require, ipairs, pairs, table, type, next, unpack 10 package, require, ipairs, pairs, table, type, next, unpack
@@ -88,8 +94,20 @@ local function sort_versions(a,b)
88 return a.version > b.version 94 return a.version > b.version
89end 95end
90 96
97--- Request module to be loaded through other loaders,
98-- once the proper name of the module has been determined.
99-- For example, in case the module "socket.core" has been requested
100-- to the LuaRocks loader and it determined based on context that
101-- the version 2.0.2 needs to be loaded and it is not the current
102-- version, the module requested for the other loaders will be
103-- "socket.core_2_0_2".
104-- @param module The module name requested by the user, such as "socket.core"
105-- @param name The rock name, such as "luasocket"
106-- @param version The rock version, such as "2.0.2-1"
107-- @param module_name The actual module name, such as "socket.core" or "socket.core_2_0_2".
108-- @return table or (nil, string): The module table as returned by some other loader,
109-- or nil followed by an error message if no other loader managed to load the module.
91local function call_other_loaders(module, name, version, module_name) 110local function call_other_loaders(module, name, version, module_name)
92
93 for i, loader in pairs(package.loaders) do 111 for i, loader in pairs(package.loaders) do
94 if loader ~= luarocks_loader then 112 if loader ~= luarocks_loader then
95 local results = { loader(module_name) } 113 local results = { loader(module_name) }
@@ -101,6 +119,17 @@ local function call_other_loaders(module, name, version, module_name)
101 return nil, "Failed loading module "..module.." in LuaRocks rock "..name.." "..version 119 return nil, "Failed loading module "..module.." in LuaRocks rock "..name.." "..version
102end 120end
103 121
122--- Search for a module in the rocks trees
123-- @param module string: module name (eg. "socket.core")
124-- @param filter_module_name function(string, string, string, string, number):
125-- a function that takes the module name (eg "socket.core"), the rock name
126-- (eg "luasocket"), the version (eg "2.0.2-1"), the path of the rocks tree
127-- (eg "/usr/local"), and the numeric index of the matching entry, so the
128-- filter function can know if the matching module was the first entry or not.
129-- @return string, string, string: name of the rock containing the module
130-- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"),
131-- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is
132-- stored versioned).
104local function select_module(module, filter_module_name) 133local function select_module(module, filter_module_name)
105 --assert(type(module) == "string") 134 --assert(type(module) == "string")
106 --assert(type(filter_module_name) == "function") 135 --assert(type(filter_module_name) == "function")
@@ -116,6 +145,9 @@ local function select_module(module, filter_module_name)
116 for i, entry in ipairs(entries) do 145 for i, entry in ipairs(entries) do
117 local name, version = entry:match("^([^/]*)/(.*)$") 146 local name, version = entry:match("^([^/]*)/(.*)$")
118 local module_name = tree.manifest.repository[name][version][1].modules[module] 147 local module_name = tree.manifest.repository[name][version][1].modules[module]
148 if not type(module_name) == "string" then
149 error("Invalid format in manifest file (invalid data for "..tostring(name).." "..tostring(version)..")")
150 end
119 module_name = filter_module_name(module_name, name, version, tree.tree, i) 151 module_name = filter_module_name(module_name, name, version, tree.tree, i)
120 if context[name] == version then 152 if context[name] == version then
121 return name, version, module_name 153 return name, version, module_name
@@ -133,6 +165,12 @@ local function select_module(module, filter_module_name)
133 end 165 end
134end 166end
135 167
168--- Search for a module
169-- @param module string: module name (eg. "socket.core")
170-- @return string, string, string: name of the rock containing the module
171-- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"),
172-- name of the module (eg. "socket.core", or "socket.core_2_0_2" if file is
173-- stored versioned).
136local function pick_module(module) 174local function pick_module(module)
137 return 175 return
138 select_module(module, function(module_name, name, version, tree, i) 176 select_module(module, function(module_name, name, version, tree, i)
@@ -144,6 +182,11 @@ local function pick_module(module)
144 end) 182 end)
145end 183end
146 184
185--- Return the pathname of the file that would be loaded for a module.
186-- @param module string: module name (eg. "socket.core")
187-- @return string, string, string: name of the rock containing the module
188-- (eg. "luasocket"), version of the rock (eg. "2.0.2-1"),
189-- filename of the module (eg. "/usr/local/lib/lua/5.1/socket/core.so")
147function which(module) 190function which(module)
148 local name, version, module_name = 191 local name, version, module_name =
149 select_module(module, function(module_name, name, version, tree, i) 192 select_module(module, function(module_name, name, version, tree, i)
@@ -172,7 +215,6 @@ end
172-- @return table: The module table (typically), like in plain 215-- @return table: The module table (typically), like in plain
173-- require(). See <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require">require()</a> 216-- require(). See <a href="http://www.lua.org/manual/5.1/manual.html#pdf-require">require()</a>
174-- in the Lua reference manual for details. 217-- in the Lua reference manual for details.
175
176function luarocks_loader(module) 218function luarocks_loader(module)
177 local name, version, module_name = pick_module(module) 219 local name, version, module_name = pick_module(module)
178 if not name then 220 if not name then
diff --git a/src/luarocks/make.lua b/src/luarocks/make.lua
index 4af5a16c..fe8f7645 100644
--- a/src/luarocks/make.lua
+++ b/src/luarocks/make.lua
@@ -9,9 +9,11 @@ local build = require("luarocks.build")
9local fs = require("luarocks.fs") 9local fs = require("luarocks.fs")
10local util = require("luarocks.util") 10local util = require("luarocks.util")
11local cfg = require("luarocks.cfg") 11local cfg = require("luarocks.cfg")
12local fetch = require("luarocks.fetch")
13local pack = require("luarocks.pack")
12 14
13help_summary = "Compile package in current directory using a rockspec." 15help_summary = "Compile package in current directory using a rockspec."
14help_arguments = "[<rockspec>]" 16help_arguments = "[--pack-binary-rock] [<rockspec>]"
15help = [[ 17help = [[
16Builds sources in the current directory, but unlike "build", 18Builds sources in the current directory, but unlike "build",
17it does not fetch sources, etc., assuming everything is 19it does not fetch sources, etc., assuming everything is
@@ -22,6 +24,10 @@ is found, you must specify which to use, through the command-line.
22This command is useful as a tool for debugging rockspecs. 24This command is useful as a tool for debugging rockspecs.
23To install rocks, you'll normally want to use the "install" and 25To install rocks, you'll normally want to use the "install" and
24"build" commands. See the help on those for details. 26"build" commands. See the help on those for details.
27
28If --pack-binary-rock is passed, the rock is not installed;
29instead, a .rock file with the contents of compilation is produced
30in the current directory.
25]] 31]]
26 32
27--- Driver function for "make" command. 33--- Driver function for "make" command.
@@ -31,9 +37,6 @@ To install rocks, you'll normally want to use the "install" and
31function run(...) 37function run(...)
32 local flags, rockspec = util.parse_flags(...) 38 local flags, rockspec = util.parse_flags(...)
33 assert(type(rockspec) == "string" or not rockspec) 39 assert(type(rockspec) == "string" or not rockspec)
34
35 local ok, err = fs.check_command_permissions(flags)
36 if not ok then return nil, err end
37 40
38 if not rockspec then 41 if not rockspec then
39 local files = fs.list_dir(fs.current_dir()) 42 local files = fs.list_dir(fs.current_dir())
@@ -54,5 +57,15 @@ function run(...)
54 return nil, "Invalid argument: 'make' takes a rockspec as a parameter. See help." 57 return nil, "Invalid argument: 'make' takes a rockspec as a parameter. See help."
55 end 58 end
56 59
57 return build.build_rockspec(rockspec, false, true) 60 if flags["pack-binary-rock"] then
61 local rspec, err, errcode = fetch.load_rockspec(rockspec)
62 if not rspec then
63 return nil, err
64 end
65 return pack.pack_binary_rock(rspec.name, rspec.version, build.build_rockspec, rockspec, false, true)
66 else
67 local ok, err = fs.check_command_permissions(flags)
68 if not ok then return nil, err end
69 return build.build_rockspec(rockspec, false, true)
70 end
58end 71end
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua
index 8ce555d8..f09abf45 100644
--- a/src/luarocks/manif.lua
+++ b/src/luarocks/manif.lua
@@ -1,4 +1,8 @@
1 1
2--- Module for handling manifest files and tables.
3-- Manifest files describe the contents of a LuaRocks tree or server.
4-- They are loaded into manifest tables, which are then used for
5-- performing searches, matching dependencies, etc.
2module("luarocks.manif", package.seeall) 6module("luarocks.manif", package.seeall)
3 7
4local manif_core = require("luarocks.manif_core") 8local manif_core = require("luarocks.manif_core")
@@ -172,12 +176,11 @@ local function sort_package_matching_table(tbl)
172 end 176 end
173end 177end
174 178
175--- Process the dependencies of a package to determine its dependency 179--- Process the dependencies of a manifest table to determine its dependency
176-- chain for loading modules. 180-- chains for loading modules. The manifest dependencies information is filled
177-- @param name string: Package name. 181-- and any dependency inconsistencies or missing dependencies are reported to
178-- @param version string: Package version. 182-- standard error.
179-- @return (table, table): A table listing dependencies as string-string pairs 183-- @param manifest table: a manifest table.
180-- of names and versions, and a similar table of missing dependencies.
181local function update_dependencies(manifest) 184local function update_dependencies(manifest)
182 for pkg, versions in pairs(manifest.repository) do 185 for pkg, versions in pairs(manifest.repository) do
183 for version, repos in pairs(versions) do 186 for version, repos in pairs(versions) do
@@ -188,9 +191,9 @@ local function update_dependencies(manifest)
188 repo.dependencies, missing = deps.scan_deps({}, {}, manifest, pkg, version) 191 repo.dependencies, missing = deps.scan_deps({}, {}, manifest, pkg, version)
189 repo.dependencies[pkg] = nil 192 repo.dependencies[pkg] = nil
190 if missing then 193 if missing then
191 for miss, _ in pairs(missing) do 194 for miss, err in pairs(missing) do
192 if miss == current then 195 if miss == current then
193 util.printerr("Tree inconsistency detected: "..current.." has no rockspec.") 196 util.printerr("Tree inconsistency detected: "..current.." has no rockspec. "..err)
194 else 197 else
195 util.printerr("Missing dependency for "..pkg.." "..version..": "..miss) 198 util.printerr("Missing dependency for "..pkg.." "..version..": "..miss)
196 end 199 end
@@ -205,6 +208,8 @@ end
205--- Store search results in a manifest table. 208--- Store search results in a manifest table.
206-- @param results table: The search results as returned by search.disk_search. 209-- @param results table: The search results as returned by search.disk_search.
207-- @param manifest table: A manifest table (must contain repository, modules, commands tables). 210-- @param manifest table: A manifest table (must contain repository, modules, commands tables).
211-- It will be altered to include the search results.
212-- @return boolean or (nil, string): true in case of success, or nil followed by an error message.
208local function store_results(results, manifest) 213local function store_results(results, manifest)
209 assert(type(results) == "table") 214 assert(type(results) == "table")
210 assert(type(manifest) == "table") 215 assert(type(manifest) == "table")
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua
index 2e1a9518..40f16898 100644
--- a/src/luarocks/manif_core.lua
+++ b/src/luarocks/manif_core.lua
@@ -15,6 +15,7 @@ manifest_cache = {}
15-- and stores it in the manifest cache. 15-- and stores it in the manifest cache.
16-- @param file string: The local filename of the manifest file. 16-- @param file string: The local filename of the manifest file.
17-- @param repo_url string: The repository identifier. 17-- @param repo_url string: The repository identifier.
18-- @param quick boolean: If given, skips type checking.
18function manifest_loader(file, repo_url, quick) 19function manifest_loader(file, repo_url, quick)
19 local manifest, err = persist.load_into_table(file) 20 local manifest, err = persist.load_into_table(file)
20 if not manifest then 21 if not manifest then
diff --git a/src/luarocks/pack.lua b/src/luarocks/pack.lua
index b85b7460..f7a7ad12 100644
--- a/src/luarocks/pack.lua
+++ b/src/luarocks/pack.lua
@@ -80,16 +80,16 @@ end
80-- @param version string or nil: A version number may also be passed. 80-- @param version string or nil: A version number may also be passed.
81-- @return string or (nil, string): The filename of the resulting 81-- @return string or (nil, string): The filename of the resulting
82-- .src.rock file; or nil and an error message. 82-- .src.rock file; or nil and an error message.
83function pack_binary_rock(name, version) 83local function do_pack_binary_rock(name, version)
84 assert(type(name) == "string") 84 assert(type(name) == "string")
85 assert(type(version) == "string" or not version) 85 assert(type(version) == "string" or not version)
86 86
87 local query = search.make_query(name, version) 87 local query = search.make_query(name, version)
88 query.exact_name = true 88 query.exact_name = true
89 local results = {} 89 local results = {}
90 for _, tree in ipairs(cfg.rocks_trees) do 90
91 search.manifest_search(results, path.rocks_dir(tree), query) 91 search.manifest_search(results, cfg.rocks_dir, query)
92 end 92
93 if not next(results) then 93 if not next(results) then
94 return nil, "'"..name.."' does not seem to be an installed rock." 94 return nil, "'"..name.."' does not seem to be an installed rock."
95 end 95 end
@@ -149,6 +149,33 @@ function pack_binary_rock(name, version)
149 return rock_file 149 return rock_file
150end 150end
151 151
152function pack_binary_rock(name, version, cmd, ...)
153
154 -- The --pack-binary-rock option for "luarocks build" basically performs
155 -- "luarocks build" on a temporary tree and then "luarocks pack". The
156 -- alternative would require refactoring parts of luarocks.build and
157 -- luarocks.pack, which would save a few file operations: the idea would be
158 -- to shave off the final deploy steps from the build phase and the initial
159 -- collect steps from the pack phase.
160
161 local temp_dir = fs.make_temp_dir("luarocks-build-pack-"..dir.base_name(name))
162 if not temp_dir then
163 return nil, "Failed creating temporary directory."
164 end
165 util.schedule_function(fs.delete, temp_dir)
166
167 path.use_tree(temp_dir)
168 local ok, err = cmd(...)
169 if not ok then
170 return nil, err
171 end
172 local rname, rversion = path.parse_name(name)
173 if not rname then
174 rname, rversion = name, version
175 end
176 return do_pack_binary_rock(rname, rversion)
177end
178
152--- Driver function for the "pack" command. 179--- Driver function for the "pack" command.
153-- @param arg string: may be a rockspec file, for creating a source rock, 180-- @param arg string: may be a rockspec file, for creating a source rock,
154-- or the name of an installed package, for creating a binary rock. 181-- or the name of an installed package, for creating a binary rock.
@@ -167,7 +194,7 @@ function run(...)
167 if arg:match(".*%.rockspec") then 194 if arg:match(".*%.rockspec") then
168 file, err = pack_source_rock(arg) 195 file, err = pack_source_rock(arg)
169 else 196 else
170 file, err = pack_binary_rock(arg, version) 197 file, err = do_pack_binary_rock(arg, version)
171 end 198 end
172 if err then 199 if err then
173 return nil, err 200 return nil, err
diff --git a/src/luarocks/path.lua b/src/luarocks/path.lua
index 8c795e8b..03ed1b90 100644
--- a/src/luarocks/path.lua
+++ b/src/luarocks/path.lua
@@ -1,5 +1,5 @@
1 1
2--- Path and filename handling functions. 2--- LuaRocks-specific path handling functions.
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.
5module("luarocks.path", package.seeall) 5module("luarocks.path", package.seeall)
@@ -25,12 +25,12 @@ function rockspec_name_from_rock(rock_name)
25 return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec" 25 return base_name:match("(.*)%.[^.]*.rock") .. ".rockspec"
26end 26end
27 27
28function rocks_dir(repo) 28function rocks_dir(tree)
29 if type(repo) == "string" then 29 if type(tree) == "string" then
30 return dir.path(repo, "lib", "luarocks", "rocks") 30 return dir.path(tree, "lib", "luarocks", "rocks")
31 else 31 else
32 assert(type(repo) == "table") 32 assert(type(tree) == "table")
33 return repo.rocks_dir or dir.path(repo.root, "lib", "luarocks", "rocks") 33 return tree.rocks_dir or dir.path(tree.root, "lib", "luarocks", "rocks")
34 end 34 end
35end 35end
36 36
@@ -41,156 +41,156 @@ function root_dir(rocks_dir)
41 return rocks_dir:match("(.*)" .. suffix .. "$") 41 return rocks_dir:match("(.*)" .. suffix .. "$")
42end 42end
43 43
44function deploy_bin_dir(repo) 44function deploy_bin_dir(tree)
45 if type(repo) == "string" then 45 if type(tree) == "string" then
46 return dir.path(repo, "bin") 46 return dir.path(tree, "bin")
47 else 47 else
48 assert(type(repo) == "table") 48 assert(type(tree) == "table")
49 return repo.bin_dir or dir.path(repo.root, "bin") 49 return tree.bin_dir or dir.path(tree.root, "bin")
50 end 50 end
51end 51end
52 52
53function deploy_lua_dir(repo) 53function deploy_lua_dir(tree)
54 if type(repo) == "string" then 54 if type(tree) == "string" then
55 return dir.path(repo, "share", "lua", "5.1") 55 return dir.path(tree, cfg.lua_modules_path)
56 else 56 else
57 assert(type(repo) == "table") 57 assert(type(tree) == "table")
58 return repo.lua_dir or dir.path(repo.root, "share", "lua", "5.1") 58 return tree.lua_dir or dir.path(tree.root, cfg.lua_modules_path)
59 end 59 end
60end 60end
61 61
62function deploy_lib_dir(repo) 62function deploy_lib_dir(tree)
63 if type(repo) == "string" then 63 if type(tree) == "string" then
64 return dir.path(repo, "lib", "lua", "5.1") 64 return dir.path(tree, cfg.lib_modules_path)
65 else 65 else
66 assert(type(repo) == "table") 66 assert(type(tree) == "table")
67 return repo.lib_dir or dir.path(repo.root, "lib", "lua", "5.1") 67 return tree.lib_dir or dir.path(tree.root, cfg.lib_modules_path)
68 end 68 end
69end 69end
70 70
71function manifest_file(repo) 71function manifest_file(tree)
72 if type(repo) == "string" then 72 if type(tree) == "string" then
73 return dir.path(repo, "lib", "luarocks", "rocks", "manifest") 73 return dir.path(tree, "lib", "luarocks", "rocks", "manifest")
74 else 74 else
75 assert(type(repo) == "table") 75 assert(type(tree) == "table")
76 return (repo.rocks_dir and dir.path(repo.rocks_dir, "manifest")) or dir.path(repo.root, "lib", "luarocks", "rocks", "manifest") 76 return (tree.rocks_dir and dir.path(tree.rocks_dir, "manifest")) or dir.path(tree.root, "lib", "luarocks", "rocks", "manifest")
77 end 77 end
78end 78end
79 79
80--- Get the repository directory for all versions of a package. 80--- Get the directory for all versions of a package in a tree.
81-- @param name string: The package name. 81-- @param name string: The package name.
82-- @return string: The resulting path -- does not guarantee that 82-- @return string: The resulting path -- does not guarantee that
83-- @param rocks_dir string or nil: If given, specifies the local repository to use. 83-- @param tree string or nil: If given, specifies the local tree to use.
84-- the package (and by extension, the path) exists. 84-- the package (and by extension, the path) exists.
85function versions_dir(name, repo) 85function versions_dir(name, tree)
86 assert(type(name) == "string") 86 assert(type(name) == "string")
87 repo = repo or cfg.root_dir 87 tree = tree or cfg.root_dir
88 return dir.path(rocks_dir(repo), name) 88 return dir.path(rocks_dir(tree), name)
89end 89end
90 90
91--- Get the local installation directory (prefix) for a package. 91--- Get the local installation directory (prefix) for a package.
92-- @param name string: The package name. 92-- @param name string: The package name.
93-- @param version string: The package version. 93-- @param version string: The package version.
94-- @param rocks_dir string or nil: If given, specifies the local repository to use. 94-- @param tree string or nil: If given, specifies the local tree to use.
95-- @return string: The resulting path -- does not guarantee that 95-- @return string: The resulting path -- does not guarantee that
96-- the package (and by extension, the path) exists. 96-- the package (and by extension, the path) exists.
97function install_dir(name, version, repo) 97function install_dir(name, version, tree)
98 assert(type(name) == "string") 98 assert(type(name) == "string")
99 assert(type(version) == "string") 99 assert(type(version) == "string")
100 repo = repo or cfg.root_dir 100 tree = tree or cfg.root_dir
101 return dir.path(rocks_dir(repo), name, version) 101 return dir.path(rocks_dir(tree), name, version)
102end 102end
103 103
104--- Get the local filename of the rockspec of an installed rock. 104--- Get the local filename of the rockspec of an installed rock.
105-- @param name string: The package name. 105-- @param name string: The package name.
106-- @param version string: The package version. 106-- @param version string: The package version.
107-- @param rocks_dir string or nil: If given, specifies the local repository to use. 107-- @param tree string or nil: If given, specifies the local tree to use.
108-- @return string: The resulting path -- does not guarantee that 108-- @return string: The resulting path -- does not guarantee that
109-- the package (and by extension, the file) exists. 109-- the package (and by extension, the file) exists.
110function rockspec_file(name, version, repo) 110function rockspec_file(name, version, tree)
111 assert(type(name) == "string") 111 assert(type(name) == "string")
112 assert(type(version) == "string") 112 assert(type(version) == "string")
113 repo = repo or cfg.root_dir 113 tree = tree or cfg.root_dir
114 return dir.path(rocks_dir(repo), name, version, name.."-"..version..".rockspec") 114 return dir.path(rocks_dir(tree), name, version, name.."-"..version..".rockspec")
115end 115end
116 116
117--- Get the local filename of the rock_manifest file of an installed rock. 117--- Get the local filename of the rock_manifest file of an installed rock.
118-- @param name string: The package name. 118-- @param name string: The package name.
119-- @param version string: The package version. 119-- @param version string: The package version.
120-- @param rocks_dir string or nil: If given, specifies the local repository to use. 120-- @param tree string or nil: If given, specifies the local tree to use.
121-- @return string: The resulting path -- does not guarantee that 121-- @return string: The resulting path -- does not guarantee that
122-- the package (and by extension, the file) exists. 122-- the package (and by extension, the file) exists.
123function rock_manifest_file(name, version, repo) 123function rock_manifest_file(name, version, tree)
124 assert(type(name) == "string") 124 assert(type(name) == "string")
125 assert(type(version) == "string") 125 assert(type(version) == "string")
126 repo = repo or cfg.root_dir 126 tree = tree or cfg.root_dir
127 return dir.path(rocks_dir(repo), name, version, "rock_manifest") 127 return dir.path(rocks_dir(tree), name, version, "rock_manifest")
128end 128end
129 129
130--- Get the local installation directory for C libraries of a package. 130--- Get the local installation directory for C libraries of a package.
131-- @param name string: The package name. 131-- @param name string: The package name.
132-- @param version string: The package version. 132-- @param version string: The package version.
133-- @param rocks_dir string or nil: If given, specifies the local repository to use. 133-- @param tree string or nil: If given, specifies the local tree to use.
134-- @return string: The resulting path -- does not guarantee that 134-- @return string: The resulting path -- does not guarantee that
135-- the package (and by extension, the path) exists. 135-- the package (and by extension, the path) exists.
136function lib_dir(name, version, repo) 136function lib_dir(name, version, tree)
137 assert(type(name) == "string") 137 assert(type(name) == "string")
138 assert(type(version) == "string") 138 assert(type(version) == "string")
139 repo = repo or cfg.root_dir 139 tree = tree or cfg.root_dir
140 return dir.path(rocks_dir(repo), name, version, "lib") 140 return dir.path(rocks_dir(tree), name, version, "lib")
141end 141end
142 142
143--- Get the local installation directory for Lua modules of a package. 143--- Get the local installation directory for Lua modules of a package.
144-- @param name string: The package name. 144-- @param name string: The package name.
145-- @param version string: The package version. 145-- @param version string: The package version.
146-- @param rocks_dir string or nil: If given, specifies the local repository to use. 146-- @param tree string or nil: If given, specifies the local tree to use.
147-- @return string: The resulting path -- does not guarantee that 147-- @return string: The resulting path -- does not guarantee that
148-- the package (and by extension, the path) exists. 148-- the package (and by extension, the path) exists.
149function lua_dir(name, version, repo) 149function lua_dir(name, version, tree)
150 assert(type(name) == "string") 150 assert(type(name) == "string")
151 assert(type(version) == "string") 151 assert(type(version) == "string")
152 repo = repo or cfg.root_dir 152 tree = tree or cfg.root_dir
153 return dir.path(rocks_dir(repo), name, version, "lua") 153 return dir.path(rocks_dir(tree), name, version, "lua")
154end 154end
155 155
156--- Get the local installation directory for documentation of a package. 156--- Get the local installation directory for documentation of a package.
157-- @param name string: The package name. 157-- @param name string: The package name.
158-- @param version string: The package version. 158-- @param version string: The package version.
159-- @param rocks_dir string or nil: If given, specifies the local repository to use. 159-- @param tree string or nil: If given, specifies the local tree to use.
160-- @return string: The resulting path -- does not guarantee that 160-- @return string: The resulting path -- does not guarantee that
161-- the package (and by extension, the path) exists. 161-- the package (and by extension, the path) exists.
162function doc_dir(name, version, repo) 162function doc_dir(name, version, tree)
163 assert(type(name) == "string") 163 assert(type(name) == "string")
164 assert(type(version) == "string") 164 assert(type(version) == "string")
165 repo = repo or cfg.root_dir 165 tree = tree or cfg.root_dir
166 return dir.path(rocks_dir(repo), name, version, "doc") 166 return dir.path(rocks_dir(tree), name, version, "doc")
167end 167end
168 168
169--- Get the local installation directory for configuration files of a package. 169--- Get the local installation directory for configuration files of a package.
170-- @param name string: The package name. 170-- @param name string: The package name.
171-- @param version string: The package version. 171-- @param version string: The package version.
172-- @param rocks_dir string or nil: If given, specifies the local repository to use. 172-- @param tree string or nil: If given, specifies the local tree to use.
173-- @return string: The resulting path -- does not guarantee that 173-- @return string: The resulting path -- does not guarantee that
174-- the package (and by extension, the path) exists. 174-- the package (and by extension, the path) exists.
175function conf_dir(name, version, repo) 175function conf_dir(name, version, tree)
176 assert(type(name) == "string") 176 assert(type(name) == "string")
177 assert(type(version) == "string") 177 assert(type(version) == "string")
178 repo = repo or cfg.root_dir 178 tree = tree or cfg.root_dir
179 return dir.path(rocks_dir(repo), name, version, "conf") 179 return dir.path(rocks_dir(tree), name, version, "conf")
180end 180end
181 181
182--- Get the local installation directory for command-line scripts 182--- Get the local installation directory for command-line scripts
183-- of a package. 183-- of a package.
184-- @param name string: The package name. 184-- @param name string: The package name.
185-- @param version string: The package version. 185-- @param version string: The package version.
186-- @param rocks_dir string or nil: If given, specifies the local repository to use. 186-- @param tree string or nil: If given, specifies the local tree to use.
187-- @return string: The resulting path -- does not guarantee that 187-- @return string: The resulting path -- does not guarantee that
188-- the package (and by extension, the path) exists. 188-- the package (and by extension, the path) exists.
189function bin_dir(name, version, repo) 189function bin_dir(name, version, tree)
190 assert(type(name) == "string") 190 assert(type(name) == "string")
191 assert(type(version) == "string") 191 assert(type(version) == "string")
192 repo = repo or cfg.root_dir 192 tree = tree or cfg.root_dir
193 return dir.path(rocks_dir(repo), name, version, "bin") 193 return dir.path(rocks_dir(tree), name, version, "bin")
194end 194end
195 195
196--- Extract name, version and arch of a rock filename, 196--- Extract name, version and arch of a rock filename,
@@ -309,7 +309,7 @@ end
309-- @return boolean This function always succeeds. 309-- @return boolean This function always succeeds.
310function run(...) 310function run(...)
311 util.printout(cfg.export_lua_path:format(package.path)) 311 util.printout(cfg.export_lua_path:format(package.path))
312 util.printout(cfg.export_lua_cpath:format(package.path)) 312 util.printout(cfg.export_lua_cpath:format(package.cpath))
313 return true 313 return true
314end 314end
315 315
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua
index c809b51c..182b3da6 100644
--- a/src/luarocks/persist.lua
+++ b/src/luarocks/persist.lua
@@ -18,13 +18,30 @@ function load_into_table(filename, tbl)
18 assert(type(filename) == "string") 18 assert(type(filename) == "string")
19 assert(type(tbl) == "table" or not tbl) 19 assert(type(tbl) == "table" or not tbl)
20 20
21 local chunk, err = loadfile(filename) 21 local result, chunk, ran, err
22 local result = tbl or {}
23 if setfenv then -- Lua 5.1
24 chunk, err = loadfile(filename)
25 if chunk then
26 setfenv(chunk, result)
27 ran, err = pcall(chunk)
28 end
29 else -- Lua 5.2
30 chunk, err = loadfile(filename, "t", result)
31 if chunk then
32 ran, err = pcall(chunk)
33 end
34 end
35
22 if not chunk then 36 if not chunk then
23 return nil, err 37 if err:sub(1,5) ~= filename:sub(1,5) then
38 return false, err
39 end
40 return nil, "Error loading file: "..err
41 end
42 if not ran then
43 return nil, "Error running file: "..err
24 end 44 end
25 local result = tbl or {}
26 setfenv(chunk, result)
27 chunk()
28 return result 45 return result
29end 46end
30 47
@@ -34,6 +51,7 @@ end
34-- are keys (tables are handled recursively). 51-- are keys (tables are handled recursively).
35-- @param out userdata: a file object, open for writing. 52-- @param out userdata: a file object, open for writing.
36-- @param tbl table: the table to be written. 53-- @param tbl table: the table to be written.
54-- @param level number: the indentation level
37local function write_table(out, tbl, level) 55local function write_table(out, tbl, level)
38 out:write("{") 56 out:write("{")
39 local sep = "\n" 57 local sep = "\n"
diff --git a/src/luarocks/refresh_cache.lua b/src/luarocks/refresh_cache.lua
index 23f86a13..80730375 100644
--- a/src/luarocks/refresh_cache.lua
+++ b/src/luarocks/refresh_cache.lua
@@ -1,4 +1,5 @@
1 1
2--- Module implementing the luarocks-admin "refresh_cache" command.
2module("luarocks.refresh_cache", package.seeall) 3module("luarocks.refresh_cache", package.seeall)
3 4
4local util = require("luarocks.util") 5local util = require("luarocks.util")
@@ -15,7 +16,7 @@ from the configuration file is used instead.
15 16
16function run(...) 17function run(...)
17 local flags = util.parse_flags(...) 18 local flags = util.parse_flags(...)
18 local server, upload_server = cache.get_upload_server(flags["from"]) 19 local server, upload_server = cache.get_upload_server(flags["server"])
19 if not server then return nil, upload_server end 20 if not server then return nil, upload_server end
20 local download_url = cache.get_server_urls(server, upload_server) 21 local download_url = cache.get_server_urls(server, upload_server)
21 22
diff --git a/src/luarocks/remove.lua b/src/luarocks/remove.lua
index caa683ee..b22d1ab6 100644
--- a/src/luarocks/remove.lua
+++ b/src/luarocks/remove.lua
@@ -82,11 +82,9 @@ function run(...)
82 if type(name) ~= "string" then 82 if type(name) ~= "string" then
83 return nil, "Argument missing, see help." 83 return nil, "Argument missing, see help."
84 end 84 end
85 85
86 if not flags["local"] and not fs.is_writable(cfg.rocks_dir) then 86 local ok, err = fs.check_command_permissions(flags)
87 return nil, "Your user does not have write permissions in " .. cfg.rocks_dir .. 87 if not ok then return nil, err end
88 " \n-- you may want to run as a privileged user or use your local tree with --local."
89 end
90 88
91 local results = {} 89 local results = {}
92 search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version)) 90 search.manifest_search(results, cfg.rocks_dir, search.make_query(name, version))
diff --git a/src/luarocks/rep.lua b/src/luarocks/rep.lua
index 8bbc1b52..5bb5fed5 100644
--- a/src/luarocks/rep.lua
+++ b/src/luarocks/rep.lua
@@ -194,9 +194,22 @@ local function resolve_conflict(target, deploy_dir, name, version)
194 end 194 end
195end 195end
196 196
197function deploy_files(name, version) 197function should_wrap_bin_scripts(rockspec)
198 assert(type(rockspec) == "table")
199
200 if cfg.wrap_bin_scripts ~= nil then
201 return cfg.wrap_bin_scripts
202 end
203 if rockspec.deploy and rockspec.deploy.wrap_bin_scripts == false then
204 return false
205 end
206 return true
207end
208
209function deploy_files(name, version, wrap_bin_scripts)
198 assert(type(name) == "string") 210 assert(type(name) == "string")
199 assert(type(version) == "string") 211 assert(type(version) == "string")
212 assert(type(wrap_bin_scripts) == "boolean")
200 213
201 local function deploy_file_tree(file_tree, source_dir, deploy_dir, move_fn) 214 local function deploy_file_tree(file_tree, source_dir, deploy_dir, move_fn)
202 if not move_fn then 215 if not move_fn then
@@ -209,10 +222,13 @@ function deploy_files(name, version)
209 local ok, err 222 local ok, err
210 if fs.exists(target) then 223 if fs.exists(target) then
211 local new_target, err = resolve_conflict(target, deploy_dir, name, version) 224 local new_target, err = resolve_conflict(target, deploy_dir, name, version)
212 if err == "untracked" then 225 if err == "untracked" then
213 fs.delete(target) 226 fs.delete(target)
214 elseif err then return nil, err.." Cannot install new version." 227 elseif err then
215 else target = new_target end 228 return nil, err.." Cannot install new version."
229 else
230 target = new_target
231 end
216 end 232 end
217 fs.make_dir(dir.dir_name(target)) 233 fs.make_dir(dir.dir_name(target))
218 ok, err = move_fn(source, target) 234 ok, err = move_fn(source, target)
@@ -227,7 +243,8 @@ function deploy_files(name, version)
227 243
228 local ok, err = true 244 local ok, err = true
229 if rock_manifest.bin then 245 if rock_manifest.bin then
230 ok, err = deploy_file_tree(rock_manifest.bin, path.bin_dir(name, version), cfg.deploy_bin_dir, install_binary) 246 local move_bin_fn = wrap_bin_scripts and install_binary or fs.copy_binary
247 ok, err = deploy_file_tree(rock_manifest.bin, path.bin_dir(name, version), cfg.deploy_bin_dir, move_bin_fn)
231 end 248 end
232 if ok and rock_manifest.lua then 249 if ok and rock_manifest.lua then
233 ok, err = deploy_file_tree(rock_manifest.lua, path.lua_dir(name, version), cfg.deploy_lua_dir) 250 ok, err = deploy_file_tree(rock_manifest.lua, path.lua_dir(name, version), cfg.deploy_lua_dir)
diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua
index 127bba19..9671d15b 100644
--- a/src/luarocks/search.lua
+++ b/src/luarocks/search.lua
@@ -331,8 +331,8 @@ end
331-- user possibilities if it couldn't narrow down a single match. 331-- user possibilities if it couldn't narrow down a single match.
332-- @param action function: A function that takes a .src.rock or 332-- @param action function: A function that takes a .src.rock or
333-- .rockspec URL as a parameter. 333-- .rockspec URL as a parameter.
334-- @string name string: A rock name 334-- @param name string: A rock name
335-- @string version string or nil: A version number may also be given. 335-- @param version string or nil: A version number may also be given.
336-- @return The result of the action function, or nil and an error message. 336-- @return The result of the action function, or nil and an error message.
337function act_on_src_or_rockspec(action, name, version) 337function act_on_src_or_rockspec(action, name, version)
338 assert(type(action) == "function") 338 assert(type(action) == "function")
diff --git a/src/luarocks/show.lua b/src/luarocks/show.lua
index f968bec8..7255ea63 100644
--- a/src/luarocks/show.lua
+++ b/src/luarocks/show.lua
@@ -94,7 +94,7 @@ function run(...)
94 local rockspec, err = fetch.load_local_rockspec(rockspec_file) 94 local rockspec, err = fetch.load_local_rockspec(rockspec_file)
95 if not rockspec then return nil,err end 95 if not rockspec then return nil,err end
96 96
97 local descript = rockspec.description 97 local descript = rockspec.description or {}
98 local manifest, err = manif.load_manifest(repo_url) 98 local manifest, err = manif.load_manifest(repo_url)
99 if not manifest then return nil,err end 99 if not manifest then return nil,err end
100 local minfo = manifest.repository[name][version][1] 100 local minfo = manifest.repository[name][version][1]
@@ -108,7 +108,7 @@ function run(...)
108 elseif flags["mversion"] then util.printout(version) 108 elseif flags["mversion"] then util.printout(version)
109 else 109 else
110 util.printout() 110 util.printout()
111 util.printout(rockspec.package.." "..rockspec.version.." - "..descript.summary) 111 util.printout(rockspec.package.." "..rockspec.version.." - "..(descript.summary or ""))
112 util.printout() 112 util.printout()
113 if descript.detailed then 113 if descript.detailed then
114 util.printout(format_text(descript.detailed)) 114 util.printout(format_text(descript.detailed))
diff --git a/src/luarocks/tools/patch.lua b/src/luarocks/tools/patch.lua
index a2b76954..9a89aa48 100644
--- a/src/luarocks/tools/patch.lua
+++ b/src/luarocks/tools/patch.lua
@@ -1,4 +1,4 @@
1--- Patch utility to apply unified diffs 1--- Patch utility to apply unified diffs.
2-- 2--
3-- http://lua-users.org/wiki/LuaPatch 3-- http://lua-users.org/wiki/LuaPatch
4-- 4--
diff --git a/src/luarocks/tools/tar.lua b/src/luarocks/tools/tar.lua
index e47172fa..ba01a413 100644
--- a/src/luarocks/tools/tar.lua
+++ b/src/luarocks/tools/tar.lua
@@ -1,4 +1,5 @@
1 1
2--- A pure-Lua implementation of untar (unpacking .tar archives)
2module("luarocks.tools.tar", package.seeall) 3module("luarocks.tools.tar", package.seeall)
3 4
4local fs = require("luarocks.fs") 5local fs = require("luarocks.fs")
diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua
index 19f6af85..7534f097 100644
--- a/src/luarocks/tools/zip.lua
+++ b/src/luarocks/tools/zip.lua
@@ -1,4 +1,6 @@
1 1
2--- A Lua implementation of .zip file archiving (used for creating .rock files),
3-- using only lua-zlib.
2module("luarocks.tools.zip", package.seeall) 4module("luarocks.tools.zip", package.seeall)
3 5
4local zlib = require("zlib") 6local zlib = require("zlib")
diff --git a/src/luarocks/type_check.lua b/src/luarocks/type_check.lua
index 0e4a73af..282198f6 100644
--- a/src/luarocks/type_check.lua
+++ b/src/luarocks/type_check.lua
@@ -4,12 +4,14 @@
4-- loaded by LuaRocks. 4-- loaded by LuaRocks.
5module("luarocks.type_check", package.seeall) 5module("luarocks.type_check", package.seeall)
6 6
7local cfg = require("luarocks.cfg")
8
7rockspec_format = "1.0" 9rockspec_format = "1.0"
8 10
9rockspec_types = { 11rockspec_types = {
10 rockspec_format = "string", 12 rockspec_format = "string",
11 MUST_package = "string", 13 MUST_package = "string",
12 MUST_version = "string", 14 MUST_version = "[%w.]+-[%d]+",
13 description = { 15 description = {
14 summary = "string", 16 summary = "string",
15 detailed = "string", 17 detailed = "string",
@@ -72,6 +74,17 @@ rockspec_types = {
72 } 74 }
73} 75}
74 76
77function load_extensions()
78 rockspec_format = "1.1"
79 rockspec_types.deploy = {
80 wrap_bin_scripts = true,
81 }
82end
83
84if cfg.use_extensions then
85 load_extensions()
86end
87
75rockspec_types.build.platforms.ANY = rockspec_types.build 88rockspec_types.build.platforms.ANY = rockspec_types.build
76rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies 89rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies
77rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dependencies 90rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dependencies
@@ -143,6 +156,9 @@ local type_check_table
143-- @param item any: The object being checked. 156-- @param item any: The object being checked.
144-- @param expected any: The reference object. In case of a table, 157-- @param expected any: The reference object. In case of a table,
145-- its is structured as a type reference table. 158-- its is structured as a type reference 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.
146-- @return boolean or (nil, string): true if type checking 162-- @return boolean or (nil, string): true if type checking
147-- succeeded, or nil and an error message if it failed. 163-- succeeded, or nil and an error message if it failed.
148-- @see type_check_table 164-- @see type_check_table
@@ -155,6 +171,15 @@ local function type_check_item(name, item, expected, context)
155 if not tonumber(item) then 171 if not tonumber(item) then
156 return nil, "Type mismatch on field "..context..name..": expected a number" 172 return nil, "Type mismatch on field "..context..name..": expected a number"
157 end 173 end
174 elseif expected_type == "string" then
175 if not tostring(item) then
176 return nil, "Type mismatch on field "..context..name..": expected a value convertible to string"
177 end
178 if expected ~= "string" then
179 if not item:match("^"..expected.."$") then
180 return nil, "Type mismatch on field "..context..name..": invalid value "..item
181 end
182 end
158 elseif expected_type == "table" then 183 elseif expected_type == "table" then
159 if item_type ~= expected_type then 184 if item_type ~= expected_type then
160 return nil, "Type mismatch on field "..context..name..": expected a table" 185 return nil, "Type mismatch on field "..context..name..": expected a table"
@@ -183,6 +208,9 @@ end
183-- @param tbl table: The table to be type checked. 208-- @param tbl table: The table to be type checked.
184-- @param types table: The reference table, containing 209-- @param types table: The reference table, containing
185-- values for recognized fields in the checked table. 210-- values for recognized fields in the checked table.
211-- @param context string: A string indicating the "context" where the
212-- error occurred (such as the name of the table the item is a part of),
213-- to be used by error messages.
186-- @return boolean or (nil, string): true if type checking 214-- @return boolean or (nil, string): true if type checking
187-- succeeded, or nil and an error message if it failed. 215-- succeeded, or nil and an error message if it failed.
188type_check_table = function(tbl, types, context) 216type_check_table = function(tbl, types, context)
@@ -196,7 +224,9 @@ type_check_table = function(tbl, types, context)
196 elseif types.MORE then 224 elseif types.MORE then
197 -- Accept unknown field 225 -- Accept unknown field
198 else 226 else
199 return nil, "Unknown field "..k 227 if not cfg.accept_unknown_fields then
228 return nil, "Unknown field "..k
229 end
200 end 230 end
201 end 231 end
202 for k, v in pairs(types) do 232 for k, v in pairs(types) do
@@ -218,6 +248,10 @@ end
218-- succeeded, or nil and an error message if it failed. 248-- succeeded, or nil and an error message if it failed.
219function type_check_rockspec(rockspec) 249function type_check_rockspec(rockspec)
220 assert(type(rockspec) == "table") 250 assert(type(rockspec) == "table")
251 if rockspec.rockspec_format then
252 -- relies on global state
253 load_extensions()
254 end
221 return type_check_table(rockspec, rockspec_types, "") 255 return type_check_table(rockspec, rockspec_types, "")
222end 256end
223 257
diff --git a/src/luarocks/unpack.lua b/src/luarocks/unpack.lua
index dacafa31..6ea7353d 100644
--- a/src/luarocks/unpack.lua
+++ b/src/luarocks/unpack.lua
@@ -45,6 +45,8 @@ end
45--- Load a .rock file to the given directory and unpack it inside it. 45--- Load a .rock file to the given directory and unpack it inside it.
46-- @param rock_file string: The URL for a .rock file. 46-- @param rock_file string: The URL for a .rock file.
47-- @param dir_name string: The directory where to unpack. 47-- @param dir_name string: The directory where to unpack.
48-- @param kind string: the kind of rock file, as in the second-level
49-- extension in the rock filename (eg. "src", "all", "linux-x86")
48-- @return table or (nil, string): the loaded rockspec table or 50-- @return table or (nil, string): the loaded rockspec table or
49-- nil and an error message. 51-- nil and an error message.
50local function unpack_rock(rock_file, dir_name, kind) 52local function unpack_rock(rock_file, dir_name, kind)
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua
index 3fea9a13..96ea03b8 100644
--- a/src/luarocks/util.lua
+++ b/src/luarocks/util.lua
@@ -1,10 +1,11 @@
1 1
2local global_env = _G 2--- Assorted utilities for managing tables, plus a scheduler for rollback functions.
3
4--- Utility functions shared by other modules.
5-- Does not requires modules directly (only as locals 3-- Does not requires modules directly (only as locals
6-- inside specific functions) to avoid interdependencies, 4-- inside specific functions) to avoid interdependencies,
7-- as this is used in the bootstrapping stage of luarocks.cfg. 5-- as this is used in the bootstrapping stage of luarocks.cfg.
6
7local global_env = _G
8
8module("luarocks.util", package.seeall) 9module("luarocks.util", package.seeall)
9 10
10local scheduled_functions = {} 11local scheduled_functions = {}
@@ -26,7 +27,7 @@ end
26 27
27--- Unschedule a function. 28--- Unschedule a function.
28-- This is useful for cancelling a rollback of a completed operation. 29-- This is useful for cancelling a rollback of a completed operation.
29-- @param table: The token representing the scheduled function that was 30-- @param item table: The token representing the scheduled function that was
30-- returned from the schedule_function call. 31-- returned from the schedule_function call.
31function remove_scheduled_function(item) 32function remove_scheduled_function(item)
32 for k, v in pairs(scheduled_functions) do 33 for k, v in pairs(scheduled_functions) do
@@ -84,7 +85,11 @@ function deep_merge(dst, src)
84 if not dst[k] then 85 if not dst[k] then
85 dst[k] = {} 86 dst[k] = {}
86 end 87 end
87 deep_merge(dst[k], v) 88 if type(dst[k]) == "table" then
89 deep_merge(dst[k], v)
90 else
91 dst[k] = v
92 end
88 else 93 else
89 dst[k] = v 94 dst[k] = v
90 end 95 end
diff --git a/src/luarocks/validate.lua b/src/luarocks/validate.lua
index fbffadc7..03e90ecf 100644
--- a/src/luarocks/validate.lua
+++ b/src/luarocks/validate.lua
@@ -1,4 +1,5 @@
1 1
2--- Sandboxed test of build/install of all packages in a repository (unfinished and disabled).
2module("luarocks.validate", package.seeall) 3module("luarocks.validate", package.seeall)
3 4
4local fs = require("luarocks.fs") 5local fs = require("luarocks.fs")