diff options
Diffstat (limited to 'src')
44 files changed, 973 insertions, 450 deletions
diff --git a/src/bin/luarocks b/src/bin/luarocks index 5da4bc25..1397bbd0 100755 --- a/src/bin/luarocks +++ b/src/bin/luarocks | |||
@@ -18,5 +18,6 @@ commands.make = require("luarocks.make") | |||
18 | commands.download = require("luarocks.download") | 18 | commands.download = require("luarocks.download") |
19 | commands.path = require("luarocks.path") | 19 | commands.path = require("luarocks.path") |
20 | commands.show = require("luarocks.show") | 20 | commands.show = require("luarocks.show") |
21 | commands.new_version = require("luarocks.new_version") | ||
21 | 22 | ||
22 | command_line.run_command(...) | 23 | command_line.run_command(...) |
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") | |||
13 | local cache = require("luarocks.cache") | 13 | local cache = require("luarocks.cache") |
14 | 14 | ||
15 | help_summary = "Add a rock or rockspec to a rocks server." | 15 | help_summary = "Add a rock or rockspec to a rocks server." |
16 | help_arguments = "[--to=<server>] [--no-refresh] {<rockspec>|<rock>...}" | 16 | help_arguments = "[--server=<server>] [--no-refresh] {<rockspec>|<rock>...}" |
17 | help = [[ | 17 | help = [[ |
18 | Arguments are local files, which may be rockspecs or rocks. | 18 | Arguments are local files, which may be rockspecs or rocks. |
19 | The flag --to indicates which server to use. | 19 | The flag --server indicates which server to use. |
20 | If not given, the default server set in the upload_server variable | 20 | If not given, the default server set in the upload_server variable |
21 | from the configuration file is used instead. | 21 | from the configuration file is used instead. |
22 | The flag --no-refresh indicates the local cache should not be refreshed | 22 | The 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) |
107 | end | 107 | end |
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) |
86 | end | 86 | end |
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 77dd1dad..42ae3fd7 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. |
4 | module("luarocks.build", package.seeall) | 4 | module("luarocks.build", package.seeall) |
5 | 5 | ||
6 | local pack = require("luarocks.pack") | ||
6 | local path = require("luarocks.path") | 7 | local path = require("luarocks.path") |
7 | local util = require("luarocks.util") | 8 | local util = require("luarocks.util") |
8 | local rep = require("luarocks.rep") | 9 | local 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 |
@@ -102,9 +111,10 @@ end | |||
102 | -- @param minimal_mode boolean: true if there's no need to fetch, | 111 | -- @param minimal_mode boolean: true if there's no need to fetch, |
103 | -- unpack or change dir (this is used by "luarocks make"). Implies | 112 | -- unpack or change dir (this is used by "luarocks make"). Implies |
104 | -- need_to_fetch = false. | 113 | -- need_to_fetch = false. |
114 | -- @param no_deps boolean: true if dependency check needs to be skipped | ||
105 | -- @return boolean or (nil, string, [string]): True if succeeded or | 115 | -- @return boolean or (nil, string, [string]): True if succeeded or |
106 | -- nil and an error message followed by an error code. | 116 | -- nil and an error message followed by an error code. |
107 | function build_rockspec(rockspec_file, need_to_fetch, minimal_mode) | 117 | function build_rockspec(rockspec_file, need_to_fetch, minimal_mode, no_deps) |
108 | assert(type(rockspec_file) == "string") | 118 | assert(type(rockspec_file) == "string") |
109 | assert(type(need_to_fetch) == "boolean") | 119 | assert(type(need_to_fetch) == "boolean") |
110 | 120 | ||
@@ -117,10 +127,15 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode) | |||
117 | return nil, "Rockspec error: build type not specified" | 127 | return nil, "Rockspec error: build type not specified" |
118 | end | 128 | end |
119 | 129 | ||
120 | local ok, err, errcode = deps.fulfill_dependencies(rockspec) | 130 | if no_deps then |
121 | if err then | 131 | util.printerr("Warning: skipping dependency checks.") |
122 | return nil, err, errcode | 132 | else |
133 | local ok, err, errcode = deps.fulfill_dependencies(rockspec) | ||
134 | if err then | ||
135 | return nil, err, errcode | ||
136 | end | ||
123 | end | 137 | end |
138 | |||
124 | ok, err, errcode = deps.check_external_deps(rockspec, "build") | 139 | ok, err, errcode = deps.check_external_deps(rockspec, "build") |
125 | if err then | 140 | if err then |
126 | return nil, err, errcode | 141 | return nil, err, errcode |
@@ -225,7 +240,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode) | |||
225 | ok, err = manif.make_rock_manifest(name, version) | 240 | ok, err = manif.make_rock_manifest(name, version) |
226 | if err then return nil, err end | 241 | if err then return nil, err end |
227 | 242 | ||
228 | ok, err = rep.deploy_files(name, version) | 243 | ok, err = rep.deploy_files(name, version, rep.should_wrap_bin_scripts(rockspec)) |
229 | if err then return nil, err end | 244 | if err then return nil, err end |
230 | 245 | ||
231 | util.remove_scheduled_function(rollback) | 246 | util.remove_scheduled_function(rollback) |
@@ -240,7 +255,7 @@ function build_rockspec(rockspec_file, need_to_fetch, minimal_mode) | |||
240 | if err then return nil, err end | 255 | if err then return nil, err end |
241 | 256 | ||
242 | local license = "" | 257 | local license = "" |
243 | if rockspec.description.license then | 258 | if rockspec.description and rockspec.description.license then |
244 | license = ("(license: "..rockspec.description.license..")") | 259 | license = ("(license: "..rockspec.description.license..")") |
245 | end | 260 | end |
246 | 261 | ||
@@ -258,7 +273,7 @@ end | |||
258 | -- false if the rockspec was obtained from inside a source rock. | 273 | -- false if the rockspec was obtained from inside a source rock. |
259 | -- @return boolean or (nil, string, [string]): True if build was successful, | 274 | -- @return boolean or (nil, string, [string]): True if build was successful, |
260 | -- or false and an error message and an optional error code. | 275 | -- or false and an error message and an optional error code. |
261 | function build_rock(rock_file, need_to_fetch) | 276 | function build_rock(rock_file, need_to_fetch, no_deps) |
262 | assert(type(rock_file) == "string") | 277 | assert(type(rock_file) == "string") |
263 | assert(type(need_to_fetch) == "boolean") | 278 | assert(type(need_to_fetch) == "boolean") |
264 | 279 | ||
@@ -268,47 +283,28 @@ function build_rock(rock_file, need_to_fetch) | |||
268 | end | 283 | end |
269 | local rockspec_file = path.rockspec_name_from_rock(rock_file) | 284 | local rockspec_file = path.rockspec_name_from_rock(rock_file) |
270 | fs.change_dir(unpack_dir) | 285 | fs.change_dir(unpack_dir) |
271 | local ok, err, errcode = build_rockspec(rockspec_file, need_to_fetch) | 286 | local ok, err, errcode = build_rockspec(rockspec_file, need_to_fetch, false, no_deps) |
272 | fs.pop_dir() | 287 | fs.pop_dir() |
273 | return ok, err, errcode | 288 | return ok, err, errcode |
274 | end | 289 | end |
275 | 290 | ||
276 | local function do_build(name, version) | 291 | local function do_build(name, version, no_deps) |
277 | if name:match("%.rockspec$") then | 292 | if name:match("%.rockspec$") then |
278 | return build_rockspec(name, true) | 293 | return build_rockspec(name, true, false, no_deps) |
279 | elseif name:match("%.src%.rock$") then | 294 | elseif name:match("%.src%.rock$") then |
280 | return build_rock(name, false) | 295 | return build_rock(name, false, no_deps) |
281 | elseif name:match("%.all%.rock$") then | 296 | elseif name:match("%.all%.rock$") then |
282 | local install = require("luarocks.install") | 297 | local install = require("luarocks.install") |
283 | return install.install_binary_rock(name) | 298 | return install.install_binary_rock(name, no_deps) |
284 | elseif name:match("%.rock$") then | 299 | elseif name:match("%.rock$") then |
285 | return build_rock(name, true) | 300 | return build_rock(name, true, no_deps) |
286 | elseif not name:match(dir.separator) then | 301 | elseif not name:match(dir.separator) then |
287 | local search = require("luarocks.search") | 302 | local search = require("luarocks.search") |
288 | return search.act_on_src_or_rockspec(run, name:lower(), version) | 303 | return search.act_on_src_or_rockspec(run, name:lower(), version, no_deps and "--nodeps") |
289 | end | 304 | end |
290 | return nil, "Don't know what to do with "..name | 305 | return nil, "Don't know what to do with "..name |
291 | end | 306 | end |
292 | 307 | ||
293 | local 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) | ||
310 | end | ||
311 | |||
312 | --- Driver function for "build" command. | 308 | --- Driver function for "build" command. |
313 | -- @param name string: A local or remote rockspec or rock file. | 309 | -- @param name string: A local or remote rockspec or rock file. |
314 | -- If a package name is given, forwards the request to "search" and, | 310 | -- If a package name is given, forwards the request to "search" and, |
@@ -324,12 +320,11 @@ function run(...) | |||
324 | end | 320 | end |
325 | assert(type(version) == "string" or not version) | 321 | assert(type(version) == "string" or not version) |
326 | 322 | ||
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 | 323 | if flags["pack-binary-rock"] then |
331 | return pack_binary_rock(name, version) | 324 | return pack.pack_binary_rock(name, version, do_build, name, version, flags["nodeps"]) |
332 | else | 325 | else |
333 | return do_build(name, version) | 326 | local ok, err = fs.check_command_permissions(flags) |
327 | if not ok then return nil, err end | ||
328 | return do_build(name, version, flags["nodeps"]) | ||
334 | end | 329 | end |
335 | end | 330 | end |
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. |
47 | function run(rockspec) | 47 | function 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") | |||
7 | local cfg = require("luarocks.cfg") | 7 | local 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..56a9a965 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua | |||
@@ -1,7 +1,4 @@ | |||
1 | 1 | ||
2 | local 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 | |||
14 | local 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 | |||
16 | module("luarocks.cfg") | 17 | module("luarocks.cfg") |
17 | 18 | ||
18 | -- Load site-local global configurations | 19 | -- Load site-local global configurations |
19 | local ok, config = pcall(require, "luarocks.config") | 20 | local ok, site_config = pcall(require, "luarocks.site_config") |
20 | if not ok then | 21 | if 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 = {} |
23 | end | 24 | end |
24 | 25 | ||
25 | _M.config = config | 26 | _M.site_config = site_config |
26 | 27 | ||
27 | program_version = "2.0.5" | 28 | lua_version = _VERSION:sub(5) |
29 | program_version = "2.0.8" | ||
28 | user_agent = "LuaRocks/"..program_version | 30 | user_agent = "LuaRocks/"..program_version |
29 | 31 | ||
30 | local persist = require("luarocks.persist") | 32 | local persist = require("luarocks.persist") |
@@ -46,12 +48,12 @@ local detected = {} | |||
46 | local system,proc | 48 | local 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). |
53 | system = config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") | 55 | system = site_config.LUAROCKS_UNAME_S or io.popen("uname -s"):read("*l") |
54 | proc = config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") | 56 | proc = site_config.LUAROCKS_UNAME_M or io.popen("uname -m"):read("*l") |
55 | if proc:match("i[%d]86") then | 57 | if proc:match("i[%d]86") then |
56 | proc = "x86" | 58 | proc = "x86" |
57 | elseif proc:match("amd64") or proc:match("x86_64") then | 59 | elseif proc:match("amd64") or proc:match("x86_64") then |
@@ -75,6 +77,9 @@ elseif system == "Darwin" then | |||
75 | elseif system == "Linux" then | 77 | elseif system == "Linux" then |
76 | detected.unix = true | 78 | detected.unix = true |
77 | detected.linux = true | 79 | detected.linux = true |
80 | elseif system == "SunOS" then | ||
81 | detected.unix = true | ||
82 | detected.solaris = true | ||
78 | elseif system and system:match("^CYGWIN") then | 83 | elseif system and system:match("^CYGWIN") then |
79 | detected.unix = true | 84 | detected.unix = true |
80 | detected.cygwin = true | 85 | detected.cygwin = true |
@@ -90,14 +95,15 @@ end | |||
90 | -- Path configuration: | 95 | -- Path configuration: |
91 | 96 | ||
92 | local sys_config_file, home_config_file | 97 | local sys_config_file, home_config_file |
98 | local sys_config_ok, home_config_ok = false, false | ||
93 | if detected.windows or detected.mingw32 then | 99 | if 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 = site_config.LUAROCKS_SYSCONFIG or "c:/luarocks/config.lua" |
96 | home_config_file = home.."/luarocks/config.lua" | 102 | home_config_file = home.."/luarocks/config.lua" |
97 | home_tree = home.."/luarocks/" | 103 | home_tree = home.."/luarocks/" |
98 | else | 104 | else |
99 | home = os.getenv("HOME") or "" | 105 | home = os.getenv("HOME") or "" |
100 | sys_config_file = "/etc/luarocks/config.lua" | 106 | sys_config_file = site_config.LUAROCKS_SYSCONFIG or "/etc/luarocks/config.lua" |
101 | home_config_file = home.."/.luarocks/config.lua" | 107 | home_config_file = home.."/.luarocks/config.lua" |
102 | home_tree = home.."/.luarocks/" | 108 | home_tree = home.."/.luarocks/" |
103 | end | 109 | end |
@@ -105,14 +111,34 @@ end | |||
105 | variables = {} | 111 | variables = {} |
106 | rocks_trees = {} | 112 | rocks_trees = {} |
107 | 113 | ||
108 | persist.load_into_table(config.LUAROCKS_SYSCONFIG or sys_config_file, _M) | 114 | local ok, err = persist.load_into_table(sys_config_file, _M) |
115 | if ok then | ||
116 | sys_config_ok = true | ||
117 | else -- nil or false | ||
118 | sys_config_ok = ok | ||
119 | if err and ok == nil then | ||
120 | io.stderr:write(err.."\n") | ||
121 | end | ||
122 | end | ||
109 | 123 | ||
110 | if not config.LUAROCKS_FORCE_CONFIG then | 124 | if 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 |
117 | end | 143 | end |
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 |
126 | end | 152 | end |
127 | 153 | ||
@@ -129,8 +155,13 @@ end | |||
129 | 155 | ||
130 | local root = rocks_trees[#rocks_trees] | 156 | local root = rocks_trees[#rocks_trees] |
131 | local defaults = { | 157 | local 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" } |
@@ -311,6 +345,10 @@ if detected.cygwin then | |||
311 | defaults.variables.LIBFLAG = "-shared" | 345 | defaults.variables.LIBFLAG = "-shared" |
312 | end | 346 | end |
313 | 347 | ||
348 | if detected.bsd then | ||
349 | defaults.variables.STATFLAG = "-f '%Op'" | ||
350 | end | ||
351 | |||
314 | if detected.macosx then | 352 | if detected.macosx then |
315 | defaults.external_lib_extension = "dylib" | 353 | defaults.external_lib_extension = "dylib" |
316 | defaults.arch = "macosx-"..proc | 354 | defaults.arch = "macosx-"..proc |
@@ -318,9 +356,6 @@ if detected.macosx then | |||
318 | defaults.variables.CC = "export MACOSX_DEPLOYMENT_TARGET=10.3; gcc" | 356 | defaults.variables.CC = "export MACOSX_DEPLOYMENT_TARGET=10.3; gcc" |
319 | defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10.3; gcc" | 357 | defaults.variables.LD = "export MACOSX_DEPLOYMENT_TARGET=10.3; gcc" |
320 | defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" | 358 | defaults.variables.LIBFLAG = "-bundle -undefined dynamic_lookup -all_load" |
321 | end | ||
322 | |||
323 | if detected.bsd then | ||
324 | defaults.variables.STATFLAG = "-f '%A'" | 359 | defaults.variables.STATFLAG = "-f '%A'" |
325 | end | 360 | end |
326 | 361 | ||
@@ -344,14 +379,21 @@ end | |||
344 | if detected.openbsd then | 379 | if detected.openbsd then |
345 | defaults.arch = "openbsd-"..proc | 380 | defaults.arch = "openbsd-"..proc |
346 | defaults.platforms = {"unix", "bsd", "openbsd"} | 381 | defaults.platforms = {"unix", "bsd", "openbsd"} |
347 | defaults.variables.STATFLAG = "-f '%Op'" | 382 | end |
383 | |||
384 | if 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" | ||
348 | end | 390 | end |
349 | 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. |
351 | defaults.variables.LUA = defaults.lua_interpreter | 393 | defaults.variables.LUA = defaults.lua_interpreter |
352 | defaults.variables.LIB_EXTENSION = defaults.lib_extension | 394 | defaults.variables.LIB_EXTENSION = defaults.lib_extension |
353 | defaults.variables.OBJ_EXTENSION = defaults.obj_extension | 395 | defaults.variables.OBJ_EXTENSION = defaults.obj_extension |
354 | defaults.variables.LUAROCKS_PREFIX = config.LUAROCKS_PREFIX | 396 | defaults.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 |
390 | end | 432 | end |
391 | 433 | ||
434 | function which_config() | ||
435 | return sys_config_file, sys_config_ok, home_config_file, home_config_ok | ||
436 | end | ||
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..a669ad66 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 |
@@ -568,7 +568,7 @@ function check_external_deps(rockspec, mode) | |||
568 | end | 568 | end |
569 | end | 569 | end |
570 | else | 570 | else |
571 | found = fs.exists(dir.path(dirdata.dir, f)) | 571 | found = fs.is_file(dir.path(dirdata.dir, f)) |
572 | end | 572 | end |
573 | if found then | 573 | if found then |
574 | break | 574 | break |
@@ -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. |
612 | function scan_deps(results, missing, manifest, name, version) | 614 | function 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. | ||
2 | module("luarocks.dir", package.seeall) | 3 | module("luarocks.dir", package.seeall) |
3 | 4 | ||
4 | separator = "/" | 5 | separator = "/" |
@@ -10,7 +11,7 @@ separator = "/" | |||
10 | function base_name(pathname) | 11 | function 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 |
15 | end | 16 | end |
16 | 17 | ||
diff --git a/src/luarocks/download.lua b/src/luarocks/download.lua index 6ae5f7af..474e4d39 100644 --- a/src/luarocks/download.lua +++ b/src/luarocks/download.lua | |||
@@ -9,60 +9,37 @@ local fetch = require("luarocks.fetch") | |||
9 | local search = require("luarocks.search") | 9 | local search = require("luarocks.search") |
10 | 10 | ||
11 | help_summary = "Download a specific rock file from a rocks server." | 11 | help_summary = "Download a specific rock file from a rocks server." |
12 | help_arguments = "[--all] [--source] [--arch=<arch>] [<name> [<version>]]" | 12 | help_arguments = "[--all] [--arch=<arch> | --source | --rockspec] [<name> [<version>]]" |
13 | 13 | ||
14 | help = [[ | 14 | help = [[ |
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 | ||
20 | local function download(rock_file) | 21 | function download(arch, name, version, all) |
21 | local rock = fetch.fetch_url(rock_file) | ||
22 | return rock ~= nil | ||
23 | end | ||
24 | |||
25 | --- Driver function for the "download" command. | ||
26 | -- @param name string: a rock name. | ||
27 | -- @param version string or nil: if the name of a package is given, a | ||
28 | -- version may also be passed. | ||
29 | -- @return boolean or (nil, string): true if successful or nil followed | ||
30 | -- by an error message. | ||
31 | function run(...) | ||
32 | local flags, name, version = util.parse_flags(...) | ||
33 | |||
34 | assert(type(version) == "string" or not version) | ||
35 | if type(name) ~= "string" and not flags["all"] then | ||
36 | return nil, "Argument missing, see help." | ||
37 | end | ||
38 | if not name then name, version = "", "" end | ||
39 | |||
40 | local query = search.make_query(name, version) | ||
41 | if flags["source"] then | ||
42 | query.arch = "src" | ||
43 | elseif flags["rockspec"] then | ||
44 | query.arch = "rockspec" | ||
45 | elseif flags["arch"] then | ||
46 | query.arch = flags["arch"] | ||
47 | end | ||
48 | local results, err | 22 | local results, err |
49 | if flags["all"] then | 23 | local query = search.make_query(name, version) |
24 | if arch then query.arch = arch end | ||
25 | if all then | ||
50 | if name == "" then query.exact_name = false end | 26 | if name == "" then query.exact_name = false end |
51 | results, err = search.search_repos(query) | 27 | results, err = search.search_repos(query) |
52 | else | 28 | else |
53 | results, err = search.find_suitable_rock(query) | 29 | results, err = search.find_suitable_rock(query) |
54 | end | 30 | end |
55 | if type(results) == "string" then | 31 | if type(results) == "string" then |
56 | return download(results) | 32 | local file = fetch.fetch_url(results) |
33 | return file | ||
57 | elseif type(results) == "table" and next(results) then | 34 | elseif type(results) == "table" and next(results) then |
58 | if flags["all"] then | 35 | if all then |
59 | local all_ok = true | 36 | local all_ok = true |
60 | local any_err = "" | 37 | local any_err = "" |
61 | for name, result in pairs(results) do | 38 | for name, result in pairs(results) do |
62 | for version, versions in pairs(result) do | 39 | for version, versions in pairs(result) do |
63 | for _,items in pairs(versions) do | 40 | for _,items in pairs(versions) do |
64 | local filename = path.make_url(items.repo, name, version, items.arch) | 41 | local filename = path.make_url(items.repo, name, version, items.arch) |
65 | local ok, err = download(filename) | 42 | local ok, err = fetch.fetch_url(filename) |
66 | if not ok then | 43 | if not ok then |
67 | all_ok = false | 44 | all_ok = false |
68 | any_err = any_err .. "\n" .. err | 45 | any_err = any_err .. "\n" .. err |
@@ -79,7 +56,35 @@ function run(...) | |||
79 | search.print_results(results) | 56 | search.print_results(results) |
80 | return nil, "Please narrow your query or use --all." | 57 | return nil, "Please narrow your query or use --all." |
81 | end | 58 | end |
82 | else | ||
83 | return nil, "Could not find a result named "..name..(version and " "..version or "").."." | ||
84 | end | 59 | end |
60 | return nil, "Could not find a result named "..name..(version and " "..version or "").."." | ||
61 | end | ||
62 | |||
63 | --- Driver function for the "download" command. | ||
64 | -- @param name string: a rock name. | ||
65 | -- @param version string or nil: if the name of a package is given, a | ||
66 | -- version may also be passed. | ||
67 | -- @return boolean or (nil, string): true if successful or nil followed | ||
68 | -- by an error message. | ||
69 | function run(...) | ||
70 | local flags, name, version = util.parse_flags(...) | ||
71 | |||
72 | assert(type(version) == "string" or not version) | ||
73 | if type(name) ~= "string" and not flags["all"] then | ||
74 | return nil, "Argument missing, see help." | ||
75 | end | ||
76 | if not name then name, version = "", "" end | ||
77 | |||
78 | local arch | ||
79 | |||
80 | if flags["source"] then | ||
81 | arch = "src" | ||
82 | elseif flags["rockspec"] then | ||
83 | arch = "rockspec" | ||
84 | elseif flags["arch"] then | ||
85 | arch = flags["arch"] | ||
86 | end | ||
87 | |||
88 | local dl, err = download(arch, name, version, flags["all"]) | ||
89 | return dl and true, err | ||
85 | end | 90 | end |
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") | |||
9 | local deps = require("luarocks.deps") | 9 | local deps = require("luarocks.deps") |
10 | local persist = require("luarocks.persist") | 10 | local persist = require("luarocks.persist") |
11 | local util = require("luarocks.util") | 11 | local util = require("luarocks.util") |
12 | local 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. |
123 | function load_local_rockspec(filename) | 128 | function 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) |
307 | end | 321 | end |
diff --git a/src/luarocks/fetch/git.lua b/src/luarocks/fetch/git.lua index 42129b22..e5f1ad4d 100644 --- a/src/luarocks/fetch/git.lua +++ b/src/luarocks/fetch/git.lua | |||
@@ -25,7 +25,6 @@ function get_sources(rockspec, extract, dest_dir) | |||
25 | local command = {git_cmd, "clone", "--depth=1", rockspec.source.url, module} | 25 | local command = {git_cmd, "clone", "--depth=1", rockspec.source.url, module} |
26 | local tag_or_branch = rockspec.source.tag or rockspec.source.branch | 26 | local tag_or_branch = rockspec.source.tag or rockspec.source.branch |
27 | if tag_or_branch then | 27 | if tag_or_branch then |
28 | -- ensure the branch (or tag) is available | ||
29 | table.insert(command, 4, "--branch=" .. tag_or_branch) | 28 | table.insert(command, 4, "--branch=" .. tag_or_branch) |
30 | end | 29 | end |
31 | local store_dir | 30 | local store_dir |
@@ -38,6 +37,7 @@ function get_sources(rockspec, extract, dest_dir) | |||
38 | else | 37 | else |
39 | store_dir = dest_dir | 38 | store_dir = dest_dir |
40 | end | 39 | end |
40 | store_dir = fs.absolute_name(store_dir) | ||
41 | fs.change_dir(store_dir) | 41 | fs.change_dir(store_dir) |
42 | if not fs.execute(unpack(command)) then | 42 | if not fs.execute(unpack(command)) then |
43 | return nil, "Failed cloning git repository." | 43 | 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. | ||
3 | module("luarocks.fetch.git_file", package.seeall) | ||
4 | |||
5 | local 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. | ||
14 | function 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) | ||
17 | end | ||
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 | ||
2 | local 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 | |||
8 | local pairs = pairs | ||
9 | |||
9 | module("luarocks.fs", package.seeall) | 10 | module("luarocks.fs", package.seeall) |
10 | 11 | ||
11 | local cfg = require("luarocks.cfg") | 12 | local 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. |
131 | function execute_string(cmd) | 131 | function 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. |
160 | function change_dir_to_root() | 161 | function 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 |
163 | end | 164 | end |
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. |
236 | function copy(src, dest) | 239 | function 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 | ||
577 | if posix_ok then | 580 | if posix_ok then |
578 | 581 | ||
582 | local 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 | |||
579 | function chmod(file, mode) | 593 | function 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 |
582 | end | 604 | end |
@@ -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. | ||
596 | function apply_patch(patchname, patchdata) | 619 | function 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. |
632 | function check_command_permissions(flags) | 655 | function 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 | ||
639 | end | 676 | end |
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 | |||
2 | local assert, type, table, io, package, math, os, ipairs = | 4 | local 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. | ||
6 | module("luarocks.fs.unix", package.seeall) | 7 | module("luarocks.fs.unix", package.seeall) |
7 | 8 | ||
8 | local fs = require("luarocks.fs") | 9 | local 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) |
95 | end | 78 | file:close() |
96 | 79 | if not first then | |
97 | function 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 ~= "#!" |
126 | end | 84 | end |
127 | 85 | ||
128 | function copy_binary(filename, dest) | 86 | function copy_binary(filename, dest) |
129 | return fs.copy(filename, dest) | 87 | return fs.copy(filename, dest, "0755") |
130 | end | 88 | end |
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 = {} | |||
11 | local vars = cfg.variables | 11 | local 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. |
18 | function execute_string(cmd) | 18 | function 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) | |||
25 | end | 26 | end |
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. |
30 | function current_dir() | 31 | function 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 |
38 | end | 39 | end |
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. |
45 | function change_dir(d) | 46 | function 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) |
48 | end | 49 | end |
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, "/") |
55 | end | 56 | end |
56 | 57 | ||
57 | --- Change working directory to the previous in the dir stack. | 58 | --- Change working directory to the previous in the directory stack. |
58 | function pop_dir() | 59 | function pop_dir() |
59 | local d = table.remove(dir_stack) | 60 | local directory = table.remove(dir_stack) |
60 | return d ~= nil | 61 | return directory ~= nil |
61 | end | 62 | end |
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. |
68 | function make_dir(d) | 69 | function 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) |
71 | end | 72 | end |
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. |
77 | function remove_dir_if_empty(d) | 78 | function 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") |
80 | end | 81 | end |
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. |
86 | function remove_dir_tree_if_empty(d) | 87 | function 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") |
89 | end | 90 | end |
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. |
96 | function copy(src, dest) | 98 | function 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) |
195 | end | 207 | end |
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. |
200 | function is_writable(file) | 212 | function 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") | |||
15 | function Q(arg) | 15 | function 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) | |||
42 | end | 42 | end |
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. |
47 | function current_dir() | 47 | function 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 |
55 | end | 55 | end |
@@ -82,13 +82,13 @@ function get_md5(file) | |||
82 | end | 82 | end |
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. |
89 | function change_dir(d) | 89 | function 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) |
92 | end | 92 | end |
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, "/") |
99 | end | 99 | end |
100 | 100 | ||
101 | --- Change working directory to the previous in the dir stack. | 101 | --- Change working directory to the previous in the directory stack. |
102 | function pop_dir() | 102 | function pop_dir() |
103 | local d = table.remove(dir_stack) | 103 | local directory = table.remove(dir_stack) |
104 | return d ~= nil | 104 | return directory ~= nil |
105 | end | 105 | end |
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. |
112 | function execute_string(cmd) | 112 | function 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. |
133 | function make_dir(d) | 134 | function 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 |
137 | end | 138 | end |
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. |
143 | function remove_dir_if_empty(d) | 144 | function 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") |
146 | end | 147 | end |
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. |
152 | function remove_dir_tree_if_empty(d) | 153 | function 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") |
155 | end | 156 | end |
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) | |||
9 | local util = require("luarocks.util") | 9 | local util = require("luarocks.util") |
10 | local cfg = require("luarocks.cfg") | 10 | local cfg = require("luarocks.cfg") |
11 | 11 | ||
12 | help_summary = "Help on commands." | 12 | help_summary = "Help on commands. Type '"..program_name.." help <command>' for more." |
13 | 13 | ||
14 | help_arguments = "[<command>]" | 14 | help_arguments = "[<command>]" |
15 | help = [[ | 15 | help = [[ |
16 | <command> is the command to show help for. | 16 | <command> is the command to show help for. |
17 | ]] | 17 | ]] |
18 | 18 | ||
19 | local function print_banner() | ||
20 | util.printout("\nLuaRocks "..cfg.program_version..", a module deployment system for Lua") | ||
21 | end | ||
22 | |||
23 | local function print_section(section) | ||
24 | util.printout("\n"..section) | ||
25 | end | ||
26 | |||
27 | local 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 | ||
35 | end | ||
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([[ |
29 | LuaRocks ]]..cfg.program_version..[[, a module deployment system for Lua | 54 | These apply to all commands, as appropriate: |
30 | |||
31 | ]]..program_name..[[ - ]]..program_description..[[ | ||
32 | |||
33 | usage: ]]..program_name..[[ [--from=<server> | --only-from=<server>] [--to=<tree>] [VAR=VALUE]... <command> [<argument>] | ||
34 | |||
35 | Variables from the "variables" table of the configuration file | ||
36 | can 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. | |
45 | Supported 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..ba55f3b1 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. | ||
2 | module("luarocks.index", package.seeall) | 3 | module("luarocks.index", package.seeall) |
3 | 4 | ||
4 | local util = require("luarocks.util") | 5 | local util = require("luarocks.util") |
@@ -8,6 +9,8 @@ local persist = require("luarocks.persist") | |||
8 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
9 | local manif = require("luarocks.manif") | 10 | local manif = require("luarocks.manif") |
10 | 11 | ||
12 | local ext_url_target = ' target="_blank"' | ||
13 | |||
11 | local index_header = [[ | 14 | local index_header = [[ |
12 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | 15 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
13 | <html> | 16 | <html> |
@@ -143,17 +146,19 @@ function make_index(repo) | |||
143 | output = output .. index_package_end | 146 | output = output .. index_package_end |
144 | if latest_rockspec then | 147 | if latest_rockspec then |
145 | local rockspec = persist.load_into_table(dir.path(repo, latest_rockspec)) | 148 | local rockspec = persist.load_into_table(dir.path(repo, latest_rockspec)) |
149 | local descript = rockspec.description or {} | ||
146 | local vars = { | 150 | local vars = { |
147 | anchor = package, | 151 | anchor = package, |
148 | package = rockspec.package, | 152 | package = rockspec.package, |
149 | original = rockspec.source.url, | 153 | original = rockspec.source.url, |
150 | summary = rockspec.description.summary or "", | 154 | summary = descript.summary or "", |
151 | detailed = rockspec.description.detailed or "", | 155 | detailed = descript.detailed or "", |
152 | license = rockspec.description.license or "N/A", | 156 | license = descript.license or "N/A", |
153 | homepage = rockspec.description.homepage and ("| <a href="..rockspec.description.homepage..">project homepage</a>") or "", | 157 | homepage = descript.homepage and ('| <a href="'..descript.homepage..'"'..ext_url_target..'>project homepage</a>') or "", |
154 | externaldependencies = format_external_dependencies(rockspec) | 158 | externaldependencies = format_external_dependencies(rockspec) |
155 | } | 159 | } |
156 | vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ") | 160 | vars.detailed = vars.detailed:gsub("\n\n", "</p><p>"):gsub("%s+", " ") |
161 | vars.detailed = vars.detailed:gsub("(https?://[a-zA-Z0-9%.%%-_%+%[%]=%?&/$@;:]+)", '<a href="%1"'..ext_url_target..'>%1</a>') | ||
157 | output = output:gsub("$(%w+)", vars) | 162 | output = output:gsub("$(%w+)", vars) |
158 | else | 163 | else |
159 | output = output:gsub("$anchor", package) | 164 | output = output:gsub("$anchor", package) |
diff --git a/src/luarocks/install.lua b/src/luarocks/install.lua index e99b4ce0..0a779b86 100644 --- a/src/luarocks/install.lua +++ b/src/luarocks/install.lua | |||
@@ -23,9 +23,10 @@ or a filename of a locally available rock. | |||
23 | 23 | ||
24 | --- Install a binary rock. | 24 | --- Install a binary rock. |
25 | -- @param rock_file string: local or remote filename of a rock. | 25 | -- @param rock_file string: local or remote filename of a rock. |
26 | -- @param no_deps boolean: true if dependency check needs to be skipped | ||
26 | -- @return boolean or (nil, string, [string]): True if succeeded or | 27 | -- @return boolean or (nil, string, [string]): True if succeeded or |
27 | -- nil and an error message and an optional error code. | 28 | -- nil and an error message and an optional error code. |
28 | function install_binary_rock(rock_file) | 29 | function install_binary_rock(rock_file, no_deps) |
29 | assert(type(rock_file) == "string") | 30 | assert(type(rock_file) == "string") |
30 | 31 | ||
31 | local name, version, arch = path.parse_name(rock_file) | 32 | local name, version, arch = path.parse_name(rock_file) |
@@ -53,8 +54,12 @@ function install_binary_rock(rock_file) | |||
53 | return nil, "Failed loading rockspec for installed package: "..err, errcode | 54 | return nil, "Failed loading rockspec for installed package: "..err, errcode |
54 | end | 55 | end |
55 | 56 | ||
56 | ok, err, errcode = deps.check_external_deps(rockspec, "install") | 57 | if no_deps then |
57 | if err then return nil, err, errcode end | 58 | util.printerr("Warning: skipping dependency checks.") |
59 | else | ||
60 | ok, err, errcode = deps.check_external_deps(rockspec, "install") | ||
61 | if err then return nil, err, errcode end | ||
62 | end | ||
58 | 63 | ||
59 | -- For compatibility with .rock files built with LuaRocks 1 | 64 | -- For compatibility with .rock files built with LuaRocks 1 |
60 | if not fs.exists(path.rock_manifest_file(name, version)) then | 65 | if not fs.exists(path.rock_manifest_file(name, version)) then |
@@ -62,10 +67,17 @@ function install_binary_rock(rock_file) | |||
62 | if err then return nil, err end | 67 | if err then return nil, err end |
63 | end | 68 | end |
64 | 69 | ||
65 | ok, err, errcode = deps.fulfill_dependencies(rockspec) | 70 | if not no_deps then |
66 | if err then return nil, err, errcode end | 71 | ok, err, errcode = deps.fulfill_dependencies(rockspec) |
72 | if err then return nil, err, errcode end | ||
73 | end | ||
74 | |||
75 | local wrap_bin_scripts = true | ||
76 | if rockspec.deploy and rockspec.deploy.wrap_bin_scripts == false then | ||
77 | wrap_bin_scripts = false | ||
78 | end | ||
67 | 79 | ||
68 | ok, err = rep.deploy_files(name, version) | 80 | ok, err = rep.deploy_files(name, version, rep.should_wrap_bin_scripts(rockspec)) |
69 | if err then return nil, err end | 81 | if err then return nil, err end |
70 | 82 | ||
71 | util.remove_scheduled_function(rollback) | 83 | util.remove_scheduled_function(rollback) |
@@ -112,10 +124,11 @@ function run(...) | |||
112 | if not ok then return nil, err end | 124 | if not ok then return nil, err end |
113 | 125 | ||
114 | if name:match("%.rockspec$") or name:match("%.src%.rock$") then | 126 | if name:match("%.rockspec$") or name:match("%.src%.rock$") then |
127 | util.printout("Using "..name.."... switching to 'build' mode") | ||
115 | local build = require("luarocks.build") | 128 | local build = require("luarocks.build") |
116 | return build.run(name, flags["local"] and "--local") | 129 | return build.run(name, flags["local"] and "--local") |
117 | elseif name:match("%.rock$") then | 130 | elseif name:match("%.rock$") then |
118 | return install_binary_rock(name) | 131 | return install_binary_rock(name, flags["nodeps"]) |
119 | else | 132 | else |
120 | local search = require("luarocks.search") | 133 | local search = require("luarocks.search") |
121 | local results, err = search.find_suitable_rock(search.make_query(name:lower(), version)) | 134 | local results, err = search.find_suitable_rock(search.make_query(name:lower(), version)) |
diff --git a/src/luarocks/loader.lua b/src/luarocks/loader.lua index c3cba55a..ac694124 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. | ||
2 | local global_env = _G | 8 | local global_env = _G |
3 | local package, require, ipairs, pairs, table, type, next, unpack = | 9 | local 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 |
89 | end | 95 | end |
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. | ||
91 | local function call_other_loaders(module, name, version, module_name) | 110 | local 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 |
102 | end | 120 | end |
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). | ||
104 | local function select_module(module, filter_module_name) | 133 | local 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 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 |
134 | end | 166 | end |
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). | ||
136 | local function pick_module(module) | 174 | local 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) |
145 | end | 183 | end |
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") | ||
147 | function which(module) | 190 | function 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 | |||
176 | function luarocks_loader(module) | 218 | function 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..769db2f7 100644 --- a/src/luarocks/make.lua +++ b/src/luarocks/make.lua | |||
@@ -9,9 +9,11 @@ local build = require("luarocks.build") | |||
9 | local fs = require("luarocks.fs") | 9 | local fs = require("luarocks.fs") |
10 | local util = require("luarocks.util") | 10 | local util = require("luarocks.util") |
11 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.cfg") |
12 | local fetch = require("luarocks.fetch") | ||
13 | local pack = require("luarocks.pack") | ||
12 | 14 | ||
13 | help_summary = "Compile package in current directory using a rockspec." | 15 | help_summary = "Compile package in current directory using a rockspec." |
14 | help_arguments = "[<rockspec>]" | 16 | help_arguments = "[--pack-binary-rock] [<rockspec>]" |
15 | help = [[ | 17 | help = [[ |
16 | Builds sources in the current directory, but unlike "build", | 18 | Builds sources in the current directory, but unlike "build", |
17 | it does not fetch sources, etc., assuming everything is | 19 | it does not fetch sources, etc., assuming everything is |
@@ -22,6 +24,10 @@ is found, you must specify which to use, through the command-line. | |||
22 | This command is useful as a tool for debugging rockspecs. | 24 | This command is useful as a tool for debugging rockspecs. |
23 | To install rocks, you'll normally want to use the "install" and | 25 | To 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 | |||
28 | If --pack-binary-rock is passed, the rock is not installed; | ||
29 | instead, a .rock file with the contents of compilation is produced | ||
30 | in 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 | |||
31 | function run(...) | 37 | function 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, flags["nodeps"]) | ||
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 | ||
58 | end | 71 | end |
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua index 8ce555d8..60b0c1df 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. | ||
2 | module("luarocks.manif", package.seeall) | 6 | module("luarocks.manif", package.seeall) |
3 | 7 | ||
4 | local manif_core = require("luarocks.manif_core") | 8 | local manif_core = require("luarocks.manif_core") |
@@ -94,7 +98,7 @@ function load_manifest(repo_url) | |||
94 | local name = repo_url:gsub("[/:]","_") | 98 | local name = repo_url:gsub("[/:]","_") |
95 | local file, err, errcode = fetch.fetch_url_at_temp_dir(url, "luarocks-manifest-"..name) | 99 | local file, err, errcode = fetch.fetch_url_at_temp_dir(url, "luarocks-manifest-"..name) |
96 | if not file then | 100 | if not file then |
97 | return nil, "Failed fetching manifest for "..repo_url, errcode | 101 | return nil, "Failed fetching manifest for "..repo_url..(err and " - "..err or ""), errcode |
98 | end | 102 | end |
99 | pathname = file | 103 | pathname = file |
100 | end | 104 | end |
@@ -172,12 +176,11 @@ local function sort_package_matching_table(tbl) | |||
172 | end | 176 | end |
173 | end | 177 | end |
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. | ||
181 | local function update_dependencies(manifest) | 184 | local 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. | ||
208 | local function store_results(results, manifest) | 213 | local 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. | ||
18 | function manifest_loader(file, repo_url, quick) | 19 | function 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/new_version.lua b/src/luarocks/new_version.lua new file mode 100644 index 00000000..b453704f --- /dev/null +++ b/src/luarocks/new_version.lua | |||
@@ -0,0 +1,141 @@ | |||
1 | |||
2 | --- Module implementing the LuaRocks "new_version" command. | ||
3 | -- Utility function that writes a new rockspec, updating data from a previous one. | ||
4 | module("luarocks.new_version", package.seeall) | ||
5 | |||
6 | local util = require("luarocks.util") | ||
7 | local cfg = require("luarocks.cfg") | ||
8 | local download = require("luarocks.download") | ||
9 | local fetch = require("luarocks.fetch") | ||
10 | local persist = require("luarocks.persist") | ||
11 | local dir = require("luarocks.dir") | ||
12 | local fs = require("luarocks.fs") | ||
13 | |||
14 | help_summary = "Auto-write a rockspec for a new version of a rock." | ||
15 | help_arguments = "{<program>|<rockspec>} [<new_version>] [<new_url>]" | ||
16 | help = [[ | ||
17 | This is a utility function that writes a new rockspec, updating data | ||
18 | from a previous one. | ||
19 | |||
20 | If a package name is given, it downloads the latest rockspec from the | ||
21 | default server. If a rockspec is given, it uses it instead. | ||
22 | |||
23 | If the version number is not given, it only increments the revision | ||
24 | number of the given (or downloaded) rockspec. | ||
25 | |||
26 | If a URL is given, it replaces the one from the old rockspec with the | ||
27 | given URL. If a URL is not given and a new version is given, it tries | ||
28 | to guess the new URL by replacing occurrences of the version number | ||
29 | in the URL or tag. It also tries to download the new URL to determine | ||
30 | the new MD5 checksum. | ||
31 | |||
32 | WARNING: it writes the new rockspec to the current directory, | ||
33 | overwriting the file if it already exists. | ||
34 | ]] | ||
35 | |||
36 | local order = {"rockspec_format", "package", "version", | ||
37 | { "source", { "url", "tag", "branch", "md5" } }, | ||
38 | { "description", {"summary", "detailed", "homepage", "license" } }, | ||
39 | "supported_platforms", "dependencies", "external_dependencies", | ||
40 | { "build", {"type", "modules", "copy_directories", "platforms"} }, | ||
41 | "hooks"} | ||
42 | |||
43 | local function try_replace(tbl, field, old, new) | ||
44 | if not tbl[field] then | ||
45 | return false | ||
46 | end | ||
47 | local old_field = tbl[field] | ||
48 | local new_field = tbl[field]:gsub(old, new) | ||
49 | if new_field ~= old_field then | ||
50 | util.printout("Guessing new '"..field.."' field as "..new_field) | ||
51 | tbl[field] = new_field | ||
52 | return true | ||
53 | end | ||
54 | return false | ||
55 | end | ||
56 | |||
57 | local function check_url_and_update_md5(out_rs, out_name) | ||
58 | out_rs.source.md5 = nil | ||
59 | local file, temp_dir = fetch.fetch_url_at_temp_dir(out_rs.source.url, "luarocks-new-version-"..out_name) | ||
60 | if file then | ||
61 | util.printout("File successfully downloaded. Updating MD5 checksum...") | ||
62 | out_rs.source.md5 = fs.get_md5(file) | ||
63 | else | ||
64 | util.printerr("Warning: invalid URL - "..temp_dir) | ||
65 | end | ||
66 | end | ||
67 | |||
68 | function run(...) | ||
69 | local flags, input, version, url = util.parse_flags(...) | ||
70 | if not input then | ||
71 | return nil, "Missing arguments: expected program or rockspec. See help." | ||
72 | end | ||
73 | assert(type(input) == "string") | ||
74 | |||
75 | local filename = input | ||
76 | if not input:match(".rockspec$") then | ||
77 | local err | ||
78 | filename, err = download.download("rockspec", input) | ||
79 | if not input then | ||
80 | return nil, err | ||
81 | end | ||
82 | end | ||
83 | |||
84 | local valid_rs, err = fetch.load_rockspec(filename) | ||
85 | if not valid_rs then | ||
86 | return nil, err | ||
87 | end | ||
88 | |||
89 | local old_ver, old_rev = valid_rs.version:match("(.*)%-(%d+)$") | ||
90 | local new_ver, new_rev | ||
91 | |||
92 | if version then | ||
93 | new_ver, new_rev = version:match("(.*)%-(%d+)$") | ||
94 | new_rev = tonumber(new_rev) | ||
95 | if not new_rev then | ||
96 | new_ver = version | ||
97 | new_rev = 1 | ||
98 | end | ||
99 | else | ||
100 | new_ver = old_ver | ||
101 | new_rev = tonumber(old_rev) + 1 | ||
102 | end | ||
103 | |||
104 | |||
105 | local out_rs = persist.load_into_table(filename) | ||
106 | local out_name = out_rs.package:lower() | ||
107 | out_rs.version = new_ver.."-"..new_rev | ||
108 | if url then | ||
109 | out_rs.source.url = url | ||
110 | check_url_and_update_md5(out_rs, out_name) | ||
111 | else | ||
112 | if new_ver ~= old_ver then | ||
113 | local ok = try_replace(out_rs.source, "url", old_ver, new_ver) | ||
114 | if ok then | ||
115 | check_url_and_update_md5(out_rs, out_name) | ||
116 | else | ||
117 | ok = try_replace(out_rs.source, "tag", old_ver, new_ver) | ||
118 | if not ok then | ||
119 | return nil, "Failed to determine the location of the new version." | ||
120 | end | ||
121 | end | ||
122 | end | ||
123 | end | ||
124 | |||
125 | if out_rs.build and out_rs.build.type == "module" then | ||
126 | out_rs.build.type = "builtin" | ||
127 | end | ||
128 | |||
129 | local out_filename = out_name.."-"..new_ver.."-"..new_rev..".rockspec" | ||
130 | |||
131 | persist.save_from_table(out_filename, out_rs, order) | ||
132 | |||
133 | util.printout("Wrote "..out_filename) | ||
134 | |||
135 | local valid_out_rs, err = fetch.load_local_rockspec(out_filename) | ||
136 | if not valid_out_rs then | ||
137 | return nil, "Failed loading generated rockspec: "..err | ||
138 | end | ||
139 | |||
140 | return true | ||
141 | end | ||
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. |
83 | function pack_binary_rock(name, version) | 83 | local 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 |
150 | end | 150 | end |
151 | 151 | ||
152 | function 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) | ||
177 | end | ||
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. |
5 | module("luarocks.path", package.seeall) | 5 | module("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" |
26 | end | 26 | end |
27 | 27 | ||
28 | function rocks_dir(repo) | 28 | function 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 |
35 | end | 35 | end |
36 | 36 | ||
@@ -41,156 +41,156 @@ function root_dir(rocks_dir) | |||
41 | return rocks_dir:match("(.*)" .. suffix .. "$") | 41 | return rocks_dir:match("(.*)" .. suffix .. "$") |
42 | end | 42 | end |
43 | 43 | ||
44 | function deploy_bin_dir(repo) | 44 | function 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 |
51 | end | 51 | end |
52 | 52 | ||
53 | function deploy_lua_dir(repo) | 53 | function 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 |
60 | end | 60 | end |
61 | 61 | ||
62 | function deploy_lib_dir(repo) | 62 | function 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 |
69 | end | 69 | end |
70 | 70 | ||
71 | function manifest_file(repo) | 71 | function 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 |
78 | end | 78 | end |
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. |
85 | function versions_dir(name, repo) | 85 | function 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) |
89 | end | 89 | end |
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. |
97 | function install_dir(name, version, repo) | 97 | function 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) |
102 | end | 102 | end |
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. |
110 | function rockspec_file(name, version, repo) | 110 | function 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") |
115 | end | 115 | end |
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. |
123 | function rock_manifest_file(name, version, repo) | 123 | function 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") |
128 | end | 128 | end |
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. |
136 | function lib_dir(name, version, repo) | 136 | function 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") |
141 | end | 141 | end |
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. |
149 | function lua_dir(name, version, repo) | 149 | function 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") |
154 | end | 154 | end |
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. |
162 | function doc_dir(name, version, repo) | 162 | function 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") |
167 | end | 167 | end |
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. |
175 | function conf_dir(name, version, repo) | 175 | function 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") |
180 | end | 180 | end |
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. |
189 | function bin_dir(name, version, repo) | 189 | function 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") |
194 | end | 194 | end |
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. |
310 | function run(...) | 310 | function 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 |
314 | end | 314 | end |
315 | 315 | ||
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua index c809b51c..0d37b04a 100644 --- a/src/luarocks/persist.lua +++ b/src/luarocks/persist.lua | |||
@@ -18,37 +18,88 @@ 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 |
29 | end | 46 | end |
30 | 47 | ||
48 | local write_table | ||
49 | |||
50 | --- Write a value as Lua code, invoking write_table. | ||
51 | -- This function handles only numbers, strings and tables | ||
52 | -- are keys (tables are handled recursively). | ||
53 | -- @param out userdata: a file object, open for writing. | ||
54 | -- @param v: the value to be written. | ||
55 | -- @param level number: the indentation level | ||
56 | -- @param sub_order table: optional prioritization table | ||
57 | -- @see write_table | ||
58 | local function write_value(out, v, level, sub_order) | ||
59 | if type(v) == "table" then | ||
60 | write_table(out, v, level + 1, sub_order) | ||
61 | elseif type(v) == "string" then | ||
62 | if v:match("\n") then | ||
63 | local open, close = "[[", "]]" | ||
64 | local equals = 0 | ||
65 | while v:find(open,1,true) or v:find(close,1,true) do | ||
66 | equals = equals + 1 | ||
67 | local eqs = ("="):rep(equals) | ||
68 | open, close = "["..eqs.."[", "]"..eqs.."]" | ||
69 | end | ||
70 | out:write(open.."\n"..v..close) | ||
71 | else | ||
72 | out:write("\""..v:gsub("\"", "\\\"").."\"") | ||
73 | end | ||
74 | else | ||
75 | out:write(tostring(v)) | ||
76 | end | ||
77 | end | ||
78 | |||
31 | --- Write a table as Lua code representing a table to disk | 79 | --- Write a table as Lua code representing a table to disk |
32 | -- (that is, in curly brackets notation). | 80 | -- (that is, in curly brackets notation). |
33 | -- This function handles only numbers, strings and tables | 81 | -- This function handles only numbers, strings and tables |
34 | -- are keys (tables are handled recursively). | 82 | -- are keys (tables are handled recursively). |
35 | -- @param out userdata: a file object, open for writing. | 83 | -- @param out userdata: a file object, open for writing. |
36 | -- @param tbl table: the table to be written. | 84 | -- @param tbl table: the table to be written. |
37 | local function write_table(out, tbl, level) | 85 | -- @param level number: the indentation level |
86 | -- @param field_order table: optional prioritization table | ||
87 | write_table = function(out, tbl, level, field_order) | ||
38 | out:write("{") | 88 | out:write("{") |
39 | local sep = "\n" | 89 | local sep = "\n" |
90 | local indentation = " " | ||
40 | local indent = true | 91 | local indent = true |
41 | local i = 1 | 92 | local i = 1 |
42 | for k, v in util.sortedpairs(tbl) do | 93 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
43 | out:write(sep) | 94 | out:write(sep) |
44 | if indent then | 95 | if indent then |
45 | for n = 1,level do out:write(" ") end | 96 | for n = 1,level do out:write(indentation) end |
46 | end | 97 | end |
47 | sep = ",\n" | 98 | sep = ",\n" |
48 | indent = true | 99 | indent = true |
49 | if type(k) == "number" then | 100 | if type(k) == "number" then |
50 | if k ~= i then | 101 | if k ~= i then |
51 | out:write('['..tostring(k).."]=") | 102 | out:write("["..tostring(k).."]=") |
52 | else | 103 | else |
53 | i = i + 1 | 104 | i = i + 1 |
54 | end | 105 | end |
@@ -57,25 +108,19 @@ local function write_table(out, tbl, level) | |||
57 | elseif type(k) == "table" then | 108 | elseif type(k) == "table" then |
58 | out:write("[") | 109 | out:write("[") |
59 | write_table(out, k, level + 1) | 110 | write_table(out, k, level + 1) |
60 | out:write("]=") | 111 | out:write("] = ") |
61 | else | 112 | else |
62 | if k:match("^[a-z_]+$") then | 113 | if k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then |
63 | out:write(k.."=") | 114 | out:write(k.." = ") |
64 | else | 115 | else |
65 | out:write("['"..k:gsub("'", "\\'").."']=") | 116 | out:write("['"..k:gsub("'", "\\'").."'] = ") |
66 | end | 117 | end |
67 | end | 118 | end |
68 | if type(v) == "table" then | 119 | write_value(out, v, level, sub_order) |
69 | write_table(out, v, level + 1) | ||
70 | elseif type(v) == "string" then | ||
71 | out:write("'"..v:gsub("'", "\\'").."'") | ||
72 | else | ||
73 | out:write(tostring(v)) | ||
74 | end | ||
75 | end | 120 | end |
76 | if sep ~= "\n" then | 121 | if sep ~= "\n" then |
77 | out:write("\n") | 122 | out:write("\n") |
78 | for n = 1,level-1 do out:write(" ") end | 123 | for n = 1,level-1 do out:write(indentation) end |
79 | end | 124 | end |
80 | out:write("}") | 125 | out:write("}") |
81 | end | 126 | end |
@@ -84,16 +129,19 @@ end | |||
84 | -- Each element of the table is saved as a global assignment. | 129 | -- Each element of the table is saved as a global assignment. |
85 | -- Only numbers, strings and tables (containing numbers, strings | 130 | -- Only numbers, strings and tables (containing numbers, strings |
86 | -- or other recursively processed tables) are supported. | 131 | -- or other recursively processed tables) are supported. |
132 | -- @param filename string: the output filename | ||
133 | -- @param tbl table: the table containing the data to be written | ||
134 | -- @param field_order table: an optional array indicating the order of top-level fields. | ||
87 | -- @return boolean or (nil, string): true if successful, or nil and a | 135 | -- @return boolean or (nil, string): true if successful, or nil and a |
88 | -- message in case of errors. | 136 | -- message in case of errors. |
89 | function save_from_table(filename, tbl) | 137 | function save_from_table(filename, tbl, field_order) |
90 | local out = io.open(filename, "w") | 138 | local out = io.open(filename, "w") |
91 | if not out then | 139 | if not out then |
92 | return nil, "Cannot create file at "..filename | 140 | return nil, "Cannot create file at "..filename |
93 | end | 141 | end |
94 | for k, v in util.sortedpairs(tbl) do | 142 | for k, v, sub_order in util.sortedpairs(tbl, field_order) do |
95 | out:write(k.." = ") | 143 | out:write(k.." = ") |
96 | write_table(out, v, 1) | 144 | write_value(out, v, 0, sub_order) |
97 | out:write("\n") | 145 | out:write("\n") |
98 | end | 146 | end |
99 | out:close() | 147 | out:close() |
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. | ||
2 | module("luarocks.refresh_cache", package.seeall) | 3 | module("luarocks.refresh_cache", package.seeall) |
3 | 4 | ||
4 | local util = require("luarocks.util") | 5 | local util = require("luarocks.util") |
@@ -15,7 +16,7 @@ from the configuration file is used instead. | |||
15 | 16 | ||
16 | function run(...) | 17 | function 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 |
195 | end | 195 | end |
196 | 196 | ||
197 | function deploy_files(name, version) | 197 | function 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 | ||
207 | end | ||
208 | |||
209 | function 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..5df2bd38 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua | |||
@@ -331,10 +331,10 @@ 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. |
337 | function act_on_src_or_rockspec(action, name, version) | 337 | function act_on_src_or_rockspec(action, name, version, ...) |
338 | assert(type(action) == "function") | 338 | assert(type(action) == "function") |
339 | assert(type(name) == "string") | 339 | assert(type(name) == "string") |
340 | assert(type(version) == "string" or not version) | 340 | assert(type(version) == "string" or not version) |
@@ -343,7 +343,7 @@ function act_on_src_or_rockspec(action, name, version) | |||
343 | query.arch = "src|rockspec" | 343 | query.arch = "src|rockspec" |
344 | local results, err = find_suitable_rock(query) | 344 | local results, err = find_suitable_rock(query) |
345 | if type(results) == "string" then | 345 | if type(results) == "string" then |
346 | return action(results) | 346 | return action(results, ...) |
347 | elseif type(results) == "table" and next(results) then | 347 | elseif type(results) == "table" and next(results) then |
348 | util.printout("Multiple search results were returned.") | 348 | util.printout("Multiple search results were returned.") |
349 | util.printout() | 349 | util.printout() |
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) | ||
2 | module("luarocks.tools.tar", package.seeall) | 3 | module("luarocks.tools.tar", package.seeall) |
3 | 4 | ||
4 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |
diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua index 19f6af85..35428d91 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. | ||
2 | module("luarocks.tools.zip", package.seeall) | 4 | module("luarocks.tools.zip", package.seeall) |
3 | 5 | ||
4 | local zlib = require("zlib") | 6 | local zlib = require("zlib") |
@@ -107,7 +109,7 @@ local function zipwriter_add(self, file) | |||
107 | if not ok then | 109 | if not ok then |
108 | err = "error in opening "..file.." in zipfile" | 110 | err = "error in opening "..file.." in zipfile" |
109 | else | 111 | else |
110 | fin = io.open(file, "rb") | 112 | fin = io.open(fs.absolute_name(file), "rb") |
111 | if not fin then | 113 | if not fin then |
112 | ok = false | 114 | ok = false |
113 | err = "error opening "..file.." for reading" | 115 | err = "error opening "..file.." for reading" |
@@ -190,7 +192,7 @@ function new_zipwriter(name) | |||
190 | 192 | ||
191 | local zw = {} | 193 | local zw = {} |
192 | 194 | ||
193 | zw.ziphandle = io.open(name, "wb") | 195 | zw.ziphandle = io.open(fs.absolute_name(name), "wb") |
194 | if not zw.ziphandle then | 196 | if not zw.ziphandle then |
195 | return nil | 197 | return nil |
196 | end | 198 | end |
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. |
5 | module("luarocks.type_check", package.seeall) | 5 | module("luarocks.type_check", package.seeall) |
6 | 6 | ||
7 | local cfg = require("luarocks.cfg") | ||
8 | |||
7 | rockspec_format = "1.0" | 9 | rockspec_format = "1.0" |
8 | 10 | ||
9 | rockspec_types = { | 11 | rockspec_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 | ||
77 | function load_extensions() | ||
78 | rockspec_format = "1.1" | ||
79 | rockspec_types.deploy = { | ||
80 | wrap_bin_scripts = true, | ||
81 | } | ||
82 | end | ||
83 | |||
84 | if cfg.use_extensions then | ||
85 | load_extensions() | ||
86 | end | ||
87 | |||
75 | rockspec_types.build.platforms.ANY = rockspec_types.build | 88 | rockspec_types.build.platforms.ANY = rockspec_types.build |
76 | rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies | 89 | rockspec_types.dependencies.platforms.ANY = rockspec_types.dependencies |
77 | rockspec_types.external_dependencies.platforms.ANY = rockspec_types.external_dependencies | 90 | rockspec_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. |
188 | type_check_table = function(tbl, types, context) | 216 | type_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. |
219 | function type_check_rockspec(rockspec) | 249 | function 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, "") |
222 | end | 256 | end |
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. |
50 | local function unpack_rock(rock_file, dir_name, kind) | 52 | local function unpack_rock(rock_file, dir_name, kind) |
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 562953d9..2955be50 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua | |||
@@ -1,10 +1,11 @@ | |||
1 | 1 | ||
2 | local 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 | |||
7 | local global_env = _G | ||
8 | |||
8 | module("luarocks.util", package.seeall) | 9 | module("luarocks.util", package.seeall) |
9 | 10 | ||
10 | local scheduled_functions = {} | 11 | local 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. |
31 | function remove_scheduled_function(item) | 32 | function 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 |
@@ -231,17 +236,42 @@ end | |||
231 | -- @see sortedpairs | 236 | -- @see sortedpairs |
232 | local function sortedpairs_iterator(tbl, sort_function) | 237 | local function sortedpairs_iterator(tbl, sort_function) |
233 | local ks = keys(tbl) | 238 | local ks = keys(tbl) |
234 | table.sort(ks, sort_function or default_sort) | 239 | if not sort_function or type(sort_function) == "function" then |
235 | for _, k in ipairs(ks) do | 240 | table.sort(ks, sort_function or default_sort) |
236 | coroutine.yield(k, tbl[k]) | 241 | for _, k in ipairs(ks) do |
242 | coroutine.yield(k, tbl[k]) | ||
243 | end | ||
244 | else | ||
245 | local order = sort_function | ||
246 | local done = {} | ||
247 | for _, k in ipairs(order) do | ||
248 | local sub_order | ||
249 | if type(k) == "table" then | ||
250 | sub_order = k[2] | ||
251 | k = k[1] | ||
252 | end | ||
253 | if tbl[k] then | ||
254 | done[k] = true | ||
255 | coroutine.yield(k, tbl[k], sub_order) | ||
256 | end | ||
257 | end | ||
258 | table.sort(ks, default_sort) | ||
259 | for _, k in ipairs(ks) do | ||
260 | if not done[k] then | ||
261 | coroutine.yield(k, tbl[k]) | ||
262 | end | ||
263 | end | ||
237 | end | 264 | end |
238 | end | 265 | end |
239 | 266 | ||
240 | --- A table iterator generator that returns elements sorted by key, | 267 | --- A table iterator generator that returns elements sorted by key, |
241 | -- to be used in "for" loops. | 268 | -- to be used in "for" loops. |
242 | -- @param tbl table: The table to be iterated. | 269 | -- @param tbl table: The table to be iterated. |
243 | -- @param sort_function function or nil: An optional comparison function | 270 | -- @param sort_function function or table or nil: An optional comparison function |
244 | -- to be used by table.sort when sorting keys. | 271 | -- to be used by table.sort when sorting keys, or an array listing an explicit order |
272 | -- for keys. If a value itself is an array, it is taken so that the first element | ||
273 | -- is a string representing the field name, and the second element is a priority table | ||
274 | -- for that key. | ||
245 | -- @return function: the iterator function. | 275 | -- @return function: the iterator function. |
246 | function sortedpairs(tbl, sort_function) | 276 | function sortedpairs(tbl, sort_function) |
247 | return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end) | 277 | return coroutine.wrap(function() sortedpairs_iterator(tbl, sort_function) end) |
@@ -283,7 +313,7 @@ function split_string(str, delim, maxNb) | |||
283 | local pat = "(.-)" .. delim .. "()" | 313 | local pat = "(.-)" .. delim .. "()" |
284 | local nb = 0 | 314 | local nb = 0 |
285 | local lastPos | 315 | local lastPos |
286 | for part, pos in string.gfind(str, pat) do | 316 | for part, pos in string.gmatch(str, pat) do |
287 | nb = nb + 1 | 317 | nb = nb + 1 |
288 | result[nb] = part | 318 | result[nb] = part |
289 | lastPos = pos | 319 | lastPos = pos |
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). | ||
2 | module("luarocks.validate", package.seeall) | 3 | module("luarocks.validate", package.seeall) |
3 | 4 | ||
4 | local fs = require("luarocks.fs") | 5 | local fs = require("luarocks.fs") |