aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2010-12-21 20:35:08 -0200
committerHisham Muhammad <hisham@gobolinux.org>2010-12-21 20:35:08 -0200
commitb4c57525f4b5b6a8fa1c4cf0ab15ac95e9031c4c (patch)
treeb814ba0bb0e2751012c818395382f81c30b67adc
parent9f6ff4c8564e721e26faa7cff1bc2e0923f809e9 (diff)
parent24af3a8dd304b0e56c1bfe78ba51651dba50b765 (diff)
downloadluarocks-2.0.4.tar.gz
luarocks-2.0.4.tar.bz2
luarocks-2.0.4.zip
Merge branch 'master' of github.com:keplerproject/luarocksv2.0.4
Conflicts: src/luarocks/fs/lua.lua
-rw-r--r--src/luarocks/cfg.lua4
-rw-r--r--src/luarocks/deps.lua15
-rw-r--r--src/luarocks/fetch.lua4
-rw-r--r--src/luarocks/fs/lua.lua83
-rw-r--r--src/luarocks/manif.lua4
-rw-r--r--src/luarocks/manif_core.lua4
-rw-r--r--src/luarocks/persist.lua10
-rw-r--r--src/luarocks/tools/zip.lua187
-rw-r--r--src/luarocks/util.lua16
9 files changed, 168 insertions, 159 deletions
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua
index d1735ff0..4bb376a4 100644
--- a/src/luarocks/cfg.lua
+++ b/src/luarocks/cfg.lua
@@ -243,12 +243,12 @@ if detected.unix then
243 defaults.variables.LIBFLAG = "-shared" 243 defaults.variables.LIBFLAG = "-shared"
244 defaults.external_deps_patterns = { 244 defaults.external_deps_patterns = {
245 bin = { "?" }, 245 bin = { "?" },
246 lib = { "lib?.a", "lib?.so" }, 246 lib = { "lib?.a", "lib?.so", "lib?.so.*" },
247 include = { "?.h" } 247 include = { "?.h" }
248 } 248 }
249 defaults.runtime_external_deps_patterns = { 249 defaults.runtime_external_deps_patterns = {
250 bin = { "?" }, 250 bin = { "?" },
251 lib = { "lib?.so" }, 251 lib = { "lib?.so", "lib?.so.*" },
252 include = { "?.h" } 252 include = { "?.h" }
253 } 253 }
254 defaults.local_cache = home.."/.cache/luarocks" 254 defaults.local_cache = home.."/.cache/luarocks"
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua
index b10594a3..4f16c2a6 100644
--- a/src/luarocks/deps.lua
+++ b/src/luarocks/deps.lua
@@ -543,9 +543,18 @@ function check_external_deps(rockspec, mode)
543 if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then 543 if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then
544 f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) 544 f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension)
545 end 545 end
546 local testfile = dir.path(dirdata.dir, f) 546 if f:match("%*") then
547 if fs.exists(testfile) then 547 local replaced = f:gsub("%.", "%%."):gsub("%*", ".*")
548 found = true 548 for _, entry in ipairs(fs.list_dir(dirdata.dir)) do
549 if entry:match(replaced) then
550 found = true
551 break
552 end
553 end
554 else
555 found = fs.exists(dir.path(dirdata.dir, f))
556 end
557 if found then
549 break 558 break
550 else 559 else
551 if failed_file then 560 if failed_file then
diff --git a/src/luarocks/fetch.lua b/src/luarocks/fetch.lua
index 25add66a..ff77882e 100644
--- a/src/luarocks/fetch.lua
+++ b/src/luarocks/fetch.lua
@@ -30,9 +30,9 @@ function fetch_url(url, filename)
30 if protocol == "file" then 30 if protocol == "file" then
31 return fs.absolute_name(pathname) 31 return fs.absolute_name(pathname)
32 elseif protocol == "http" or protocol == "ftp" or protocol == "https" then 32 elseif protocol == "http" or protocol == "ftp" or protocol == "https" then
33 local ok = fs.download(url, filename) 33 local ok, err = fs.download(url, filename)
34 if not ok then 34 if not ok then
35 return nil, "Failed downloading "..url, "network" 35 return nil, "Failed downloading "..url.." - "..err, "network"
36 end 36 end
37 return dir.path(fs.current_dir(), filename or dir.base_name(url)) 37 return dir.path(fs.current_dir(), filename or dir.base_name(url))
38 else 38 else
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua
index a9fca7b4..e055f67e 100644
--- a/src/luarocks/fs/lua.lua
+++ b/src/luarocks/fs/lua.lua
@@ -478,50 +478,27 @@ end
478if socket_ok then 478if socket_ok then
479 479
480local ltn12 = require("ltn12") 480local ltn12 = require("ltn12")
481 481local luasec_ok, https = pcall(require, "ssl.https")
482--- Download a remote file. 482
483-- @param url string: URL to be fetched. 483local function http_request(url, http)
484-- @param filename string or nil: this function attempts to detect the 484 local proxy = cfg.proxy
485-- resulting local filename of the remote file as the basename of the URL; 485 local url_arg, proxy_result
486-- if that is not correct (due to a redirection, for example), the local 486 if proxy then
487-- filename can be given explicitly as this second argument. 487 proxy_result = {}
488-- @return boolean: true on success, false on failure. 488 url_arg = { url = url, proxy = proxy, sink = ltn12.sink.table(proxy_result) }
489function download(url, filename) 489 else
490 assert(type(url) == "string") 490 url_arg = url
491 assert(type(filename) == "string" or not filename)
492
493 filename = dir.path(fs.current_dir(), filename or dir.base_name(url))
494
495 local content, err
496 if util.starts_with(url, "http:") then
497 local proxy = cfg.proxy
498 local url_arg, proxy_result
499 if proxy then
500 proxy_result = {}
501 url_arg = { url = url, proxy = proxy, sink = ltn12.sink.table(proxy_result) }
502 else
503 url_arg = url
504 end
505 local res, status, headers, line = http.request(url_arg)
506 if not res then
507 err = status
508 elseif status ~= 200 then
509 err = line
510 else
511 if proxy_result then res = table.concat(proxy_result) end
512 content = res
513 end
514 elseif util.starts_with(url, "ftp:") then
515 content, err = ftp.get(url)
516 end 491 end
517 if not content then 492 local res, status, headers, line = http.request(url_arg)
518 return false, "Failed downloading: " .. err 493 if not res then
494 err = status
495 elseif status ~= 200 then
496 err = line
497 else
498 if proxy_result then res = table.concat(proxy_result) end
499 content = res
519 end 500 end
520 local file = io.open(filename, "wb") 501 return content, err
521 if not file then return false end
522 file:write(content)
523 file:close()
524 return true
525end 502end
526 503
527--- Download a remote file. 504--- Download a remote file.
@@ -536,22 +513,23 @@ function download(url, filename)
536 assert(type(filename) == "string" or not filename) 513 assert(type(filename) == "string" or not filename)
537 514
538 filename = dir.path(fs.current_dir(), filename or dir.base_name(url)) 515 filename = dir.path(fs.current_dir(), filename or dir.base_name(url))
539 516
540 local content, err 517 local content, err
541 if util.starts_with(url, "http:") then 518 if util.starts_with(url, "http:") then
542 local res, status, headers, line = http.request(url) 519 content, err = http_request(url, http)
543 if not res then
544 err = status
545 elseif status ~= 200 then
546 err = line
547 else
548 content = res
549 end
550 elseif util.starts_with(url, "ftp:") then 520 elseif util.starts_with(url, "ftp:") then
551 content, err = ftp.get(url) 521 content, err = ftp.get(url)
522 elseif util.starts_with(url, "https:") then
523 if luasec_ok then
524 content, err = http_request(url, https)
525 else
526 err = "Unsupported protocol - install luasec to get HTTPS support."
527 end
528 else
529 err = "Unsupported protocol"
552 end 530 end
553 if not content then 531 if not content then
554 return false, "Failed downloading: " .. err 532 return false, err
555 end 533 end
556 local file = io.open(filename, "wb") 534 local file = io.open(filename, "wb")
557 if not file then return false end 535 if not file then return false end
@@ -560,7 +538,6 @@ function download(url, filename)
560 return true 538 return true
561end 539end
562 540
563
564end 541end
565--------------------------------------------------------------------- 542---------------------------------------------------------------------
566-- MD5 functions 543-- MD5 functions
diff --git a/src/luarocks/manif.lua b/src/luarocks/manif.lua
index c677a22c..a7211d70 100644
--- a/src/luarocks/manif.lua
+++ b/src/luarocks/manif.lua
@@ -304,9 +304,9 @@ local function find_providers(file, root)
304 assert(type(file) == "string") 304 assert(type(file) == "string")
305 root = root or cfg.root_dir 305 root = root or cfg.root_dir
306 306
307 local manifest = manif_core.load_local_manifest(path.rocks_dir(root)) 307 local manifest, err = manif_core.load_local_manifest(path.rocks_dir(root))
308 if not manifest then 308 if not manifest then
309 return nil, "manifest file is missing. Corrupted local rocks tree?" 309 return nil, err .. " -- corrupted local rocks tree?"
310 end 310 end
311 local deploy_bin = path.deploy_bin_dir(root) 311 local deploy_bin = path.deploy_bin_dir(root)
312 local deploy_lua = path.deploy_lua_dir(root) 312 local deploy_lua = path.deploy_lua_dir(root)
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua
index d1eb4ebb..2e1a9518 100644
--- a/src/luarocks/manif_core.lua
+++ b/src/luarocks/manif_core.lua
@@ -16,9 +16,9 @@ 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.
18function manifest_loader(file, repo_url, quick) 18function manifest_loader(file, repo_url, quick)
19 local manifest = persist.load_into_table(file) 19 local manifest, err = persist.load_into_table(file)
20 if not manifest then 20 if not manifest then
21 return nil, "Failed loading manifest for "..repo_url 21 return nil, "Failed loading manifest for "..repo_url..": "..err
22 end 22 end
23 if not quick then 23 if not quick then
24 local ok, err = type_check.type_check_manifest(manifest) 24 local ok, err = type_check.type_check_manifest(manifest)
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua
index d74a805e..c809b51c 100644
--- a/src/luarocks/persist.lua
+++ b/src/luarocks/persist.lua
@@ -28,10 +28,6 @@ function load_into_table(filename, tbl)
28 return result 28 return result
29end 29end
30 30
31local function string_sort(a,b)
32 return tostring(a) < tostring(b)
33end
34
35--- Write a table as Lua code representing a table to disk 31--- Write a table as Lua code representing a table to disk
36-- (that is, in curly brackets notation). 32-- (that is, in curly brackets notation).
37-- This function handles only numbers, strings and tables 33-- This function handles only numbers, strings and tables
@@ -43,7 +39,7 @@ local function write_table(out, tbl, level)
43 local sep = "\n" 39 local sep = "\n"
44 local indent = true 40 local indent = true
45 local i = 1 41 local i = 1
46 for k, v in util.sortedpairs(tbl, string_sort) do 42 for k, v in util.sortedpairs(tbl) do
47 out:write(sep) 43 out:write(sep)
48 if indent then 44 if indent then
49 for n = 1,level do out:write(" ") end 45 for n = 1,level do out:write(" ") end
@@ -52,7 +48,7 @@ local function write_table(out, tbl, level)
52 indent = true 48 indent = true
53 if type(k) == "number" then 49 if type(k) == "number" then
54 if k ~= i then 50 if k ~= i then
55 out:write(tostring(k).."=") 51 out:write('['..tostring(k).."]=")
56 else 52 else
57 i = i + 1 53 i = i + 1
58 end 54 end
@@ -95,7 +91,7 @@ function save_from_table(filename, tbl)
95 if not out then 91 if not out then
96 return nil, "Cannot create file at "..filename 92 return nil, "Cannot create file at "..filename
97 end 93 end
98 for k, v in util.sortedpairs(tbl, string_sort) do 94 for k, v in util.sortedpairs(tbl) do
99 out:write(k.." = ") 95 out:write(k.." = ")
100 write_table(out, v, 1) 96 write_table(out, v, 1)
101 out:write("\n") 97 out:write("\n")
diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua
index 18ad967e..caeb4ac9 100644
--- a/src/luarocks/tools/zip.lua
+++ b/src/luarocks/tools/zip.lua
@@ -1,7 +1,11 @@
1 1
2module("luarocks.tools.zip", package.seeall) 2module("luarocks.tools.zip", package.seeall)
3 3
4local zlib = require "zlib" 4local zlib = require("zlib")
5local fs = require("luarocks.fs")
6local dir = require("luarocks.dir")
7
8local size_buf = 65535
5 9
6local function number_to_bytestring(number, nbytes) 10local function number_to_bytestring(number, nbytes)
7 local out = {} 11 local out = {}
@@ -13,34 +17,17 @@ local function number_to_bytestring(number, nbytes)
13 return table.concat(out) 17 return table.concat(out)
14end 18end
15 19
16--- Return a zip handle open for writing.
17-- @param name filename of the zipfile to be created.
18-- @return a zip handle, or nil in case of error.
19function write_open(name)
20
21 local zf = {}
22
23 zf.ziphandle = io.open(name, "w")
24 if not zf.ziphandle then
25 return nil
26 end
27 zf.files = {}
28 zf.in_open_file = false
29
30 return zf
31end
32
33--- Begin a new file to be stored inside the zipfile. 20--- Begin a new file to be stored inside the zipfile.
34-- @param zf handle of the zipfile being written. 21-- @param self handle of the zipfile being written.
35-- @param filename filenome of the file to be added to the zipfile. 22-- @param filename filenome of the file to be added to the zipfile.
36-- @return true if succeeded, nil in case of failure. 23-- @return true if succeeded, nil in case of failure.
37function write_open_new_file_in_zip(zf, filename) 24local function zipwriter_open_new_file_in_zip(self, filename)
38 if zf.in_open_file then 25 if self.in_open_file then
39 close_file_in_zip(zf) 26 self:close_file_in_zip()
40 return nil 27 return nil
41 end 28 end
42 local lfh = {} 29 local lfh = {}
43 zf.local_file_header = lfh 30 self.local_file_header = lfh
44 lfh.last_mod_file_time = 0 -- TODO 31 lfh.last_mod_file_time = 0 -- TODO
45 lfh.last_mod_file_date = 0 -- TODO 32 lfh.last_mod_file_date = 0 -- TODO
46 lfh.crc32 = 0 -- initial value 33 lfh.crc32 = 0 -- initial value
@@ -49,40 +36,41 @@ function write_open_new_file_in_zip(zf, filename)
49 lfh.file_name_length = #filename 36 lfh.file_name_length = #filename
50 lfh.extra_field_length = 0 37 lfh.extra_field_length = 0
51 lfh.file_name = filename:gsub("\\", "/") 38 lfh.file_name = filename:gsub("\\", "/")
52 zf.in_open_file = true 39 lfh.external_attr = 0 -- TODO properly store permissions
53 zf.data = {} 40 self.in_open_file = true
41 self.data = {}
54 return true 42 return true
55end 43end
56 44
57--- Write data to the file currently being stored in the zipfile. 45--- Write data to the file currently being stored in the zipfile.
58-- @param zf handle of the zipfile being written. 46-- @param self handle of the zipfile being written.
59-- @param buf string containing data to be written. 47-- @param buf string containing data to be written.
60-- @return true if succeeded, nil in case of failure. 48-- @return true if succeeded, nil in case of failure.
61function write_in_file_in_zip(zf, buf) 49local function zipwriter_write_file_in_zip(self, buf)
62 if not zf.in_open_file then 50 if not self.in_open_file then
63 return nil 51 return nil
64 end 52 end
65 local lfh = zf.local_file_header 53 local lfh = self.local_file_header
66 local cbuf = zlib.compress(buf):sub(3, -5) 54 local cbuf = zlib.compress(buf):sub(3, -5)
67 lfh.crc32 = zlib.crc32(lfh.crc32, buf) 55 lfh.crc32 = zlib.crc32(lfh.crc32, buf)
68 lfh.compressed_size = lfh.compressed_size + #cbuf 56 lfh.compressed_size = lfh.compressed_size + #cbuf
69 lfh.uncompressed_size = lfh.uncompressed_size + #buf 57 lfh.uncompressed_size = lfh.uncompressed_size + #buf
70 table.insert(zf.data, cbuf) 58 table.insert(self.data, cbuf)
71 return true 59 return true
72end 60end
73 61
74--- Complete the writing of a file stored in the zipfile. 62--- Complete the writing of a file stored in the zipfile.
75-- @param zf handle of the zipfile being written. 63-- @param self handle of the zipfile being written.
76-- @return true if succeeded, nil in case of failure. 64-- @return true if succeeded, nil in case of failure.
77function write_close_file_in_zip(zf) 65local function zipwriter_close_file_in_zip(self)
78 local zh = zf.ziphandle 66 local zh = self.ziphandle
79 67
80 if not zf.in_open_file then 68 if not self.in_open_file then
81 return nil 69 return nil
82 end 70 end
83 71
84 -- Local file header 72 -- Local file header
85 local lfh = zf.local_file_header 73 local lfh = self.local_file_header
86 lfh.offset = zh:seek() 74 lfh.offset = zh:seek()
87 zh:write(number_to_bytestring(0x04034b50, 4)) -- signature 75 zh:write(number_to_bytestring(0x04034b50, 4)) -- signature
88 zh:write(number_to_bytestring(20, 2)) -- version needed to extract: 2.0 76 zh:write(number_to_bytestring(20, 2)) -- version needed to extract: 2.0
@@ -98,7 +86,7 @@ function write_close_file_in_zip(zf)
98 zh:write(lfh.file_name) 86 zh:write(lfh.file_name)
99 87
100 -- File data 88 -- File data
101 for _, cbuf in ipairs(zf.data) do 89 for _, cbuf in ipairs(self.data) do
102 zh:write(cbuf) 90 zh:write(cbuf)
103 end 91 end
104 92
@@ -107,23 +95,59 @@ function write_close_file_in_zip(zf)
107 zh:write(number_to_bytestring(lfh.compressed_size, 4)) 95 zh:write(number_to_bytestring(lfh.compressed_size, 4))
108 zh:write(number_to_bytestring(lfh.uncompressed_size, 4)) 96 zh:write(number_to_bytestring(lfh.uncompressed_size, 4))
109 97
110 table.insert(zf.files, lfh) 98 table.insert(self.files, lfh)
111 zf.in_open_file = false 99 self.in_open_file = false
112 100
113 return true 101 return true
114end 102end
115 103
104-- @return boolean or (boolean, string): true on success,
105-- false and an error message on failure.
106local function zipwriter_add(self, file)
107 local fin
108 local ok, err = self:open_new_file_in_zip(file)
109 if not ok then
110 err = "error in opening "..file.." in zipfile"
111 else
112 fin = io.open(file, "rb")
113 if not fin then
114 ok = false
115 err = "error opening "..file.." for reading"
116 end
117 end
118 while ok do
119 local buf = fin:read(size_buf)
120 if not buf then
121 break
122 end
123 ok = self:write_file_in_zip(buf)
124 if not ok then
125 err = "error in writing "..file.." in the zipfile"
126 end
127 end
128 if fin then
129 fin:close()
130 end
131 if ok then
132 ok = self:close_file_in_zip()
133 if not ok then
134 err = "error in writing "..file.." in the zipfile"
135 end
136 end
137 return ok == true, err
138end
139
116--- Complete the writing of the zipfile. 140--- Complete the writing of the zipfile.
117-- @param zf handle of the zipfile being written. 141-- @param self handle of the zipfile being written.
118-- @return true if succeeded, nil in case of failure. 142-- @return true if succeeded, nil in case of failure.
119function write_close(zf) 143local function zipwriter_close(self)
120 local zh = zf.ziphandle 144 local zh = self.ziphandle
121 145
122 local central_directory_offset = zh:seek() 146 local central_directory_offset = zh:seek()
123 147
124 local size_of_central_directory = 0 148 local size_of_central_directory = 0
125 -- Central directory structure 149 -- Central directory structure
126 for _, lfh in ipairs(zf.files) do 150 for _, lfh in ipairs(self.files) do
127 zh:write(number_to_bytestring(0x02014b50, 4)) -- signature 151 zh:write(number_to_bytestring(0x02014b50, 4)) -- signature
128 zh:write(number_to_bytestring(3, 2)) -- version made by: UNIX 152 zh:write(number_to_bytestring(3, 2)) -- version made by: UNIX
129 zh:write(number_to_bytestring(20, 2)) -- version needed to extract: 2.0 153 zh:write(number_to_bytestring(20, 2)) -- version needed to extract: 2.0
@@ -139,7 +163,7 @@ function write_close(zf)
139 zh:write(number_to_bytestring(0, 2)) -- file comment length 163 zh:write(number_to_bytestring(0, 2)) -- file comment length
140 zh:write(number_to_bytestring(0, 2)) -- disk number start 164 zh:write(number_to_bytestring(0, 2)) -- disk number start
141 zh:write(number_to_bytestring(0, 2)) -- internal file attributes 165 zh:write(number_to_bytestring(0, 2)) -- internal file attributes
142 zh:write(number_to_bytestring(0, 4)) -- external file attributes 166 zh:write(number_to_bytestring(lfh.external_attr, 4)) -- external file attributes
143 zh:write(number_to_bytestring(lfh.offset, 4)) -- relative offset of local header 167 zh:write(number_to_bytestring(lfh.offset, 4)) -- relative offset of local header
144 zh:write(lfh.file_name) 168 zh:write(lfh.file_name)
145 size_of_central_directory = size_of_central_directory + 46 + lfh.file_name_length 169 size_of_central_directory = size_of_central_directory + 46 + lfh.file_name_length
@@ -149,8 +173,8 @@ function write_close(zf)
149 zh:write(number_to_bytestring(0x06054b50, 4)) -- signature 173 zh:write(number_to_bytestring(0x06054b50, 4)) -- signature
150 zh:write(number_to_bytestring(0, 2)) -- number of this disk 174 zh:write(number_to_bytestring(0, 2)) -- number of this disk
151 zh:write(number_to_bytestring(0, 2)) -- number of disk with start of central directory 175 zh:write(number_to_bytestring(0, 2)) -- number of disk with start of central directory
152 zh:write(number_to_bytestring(#zf.files, 2)) -- total number of entries in the central dir on this disk 176 zh:write(number_to_bytestring(#self.files, 2)) -- total number of entries in the central dir on this disk
153 zh:write(number_to_bytestring(#zf.files, 2)) -- total number of entries in the central dir 177 zh:write(number_to_bytestring(#self.files, 2)) -- total number of entries in the central dir
154 zh:write(number_to_bytestring(size_of_central_directory, 4)) 178 zh:write(number_to_bytestring(size_of_central_directory, 4))
155 zh:write(number_to_bytestring(central_directory_offset, 4)) 179 zh:write(number_to_bytestring(central_directory_offset, 4))
156 zh:write(number_to_bytestring(0, 2)) -- zip file comment length 180 zh:write(number_to_bytestring(0, 2)) -- zip file comment length
@@ -159,40 +183,27 @@ function write_close(zf)
159 return true 183 return true
160end 184end
161 185
162-- @return boolean or (boolean, string): true on success, 186--- Return a zip handle open for writing.
163-- false and an error message on failure. 187-- @param name filename of the zipfile to be created.
164local function add_to_zip(zf, file) 188-- @return a zip handle, or nil in case of error.
165 local fin 189function new_zipwriter(name)
166 local ok, err = write_open_new_file_in_zip(zf, file) 190
167 if not ok then 191 local zw = {}
168 err = "error in opening "..file.." in zipfile" 192
169 else 193 zw.ziphandle = io.open(name, "w")
170 fin = io.open(file, "rb") 194 if not zw.ziphandle then
171 if not fin then 195 return nil
172 ok = false
173 err = "error opening "..file.." for reading"
174 end
175 end
176 while ok do
177 local buf = fin:read(size_buf)
178 if not buf then
179 break
180 end
181 ok = write_in_file_in_zip(zf, buf)
182 if not ok then
183 err = "error in writing "..file.." in the zipfile"
184 end
185 end
186 if fin then
187 fin:close()
188 end
189 if ok then
190 ok = write_close_file_in_zip(zf)
191 if not ok then
192 err = "error in writing "..file.." in the zipfile"
193 end
194 end 196 end
195 return ok == true, err 197 zw.files = {}
198 zw.in_open_file = false
199
200 zw.add = zipwriter_add
201 zw.close = zipwriter_close
202 zw.open_new_file_in_zip = zipwriter_open_new_file_in_zip
203 zw.write_file_in_zip = zipwriter_write_file_in_zip
204 zw.close_file_in_zip = zipwriter_close_file_in_zip
205
206 return zw
196end 207end
197 208
198--- Compress files in a .zip archive. 209--- Compress files in a .zip archive.
@@ -202,29 +213,31 @@ end
202-- @return boolean or (boolean, string): true on success, 213-- @return boolean or (boolean, string): true on success,
203-- false and an error message on failure. 214-- false and an error message on failure.
204function zip(zipfile, ...) 215function zip(zipfile, ...)
205 local zf = write_open(filename) 216 local zw = new_zipwriter(zipfile)
206 if not zf then 217 if not zw then
207 return nil, "error opening "..filename 218 return nil, "error opening "..zipfile
208 end 219 end
209 220
210 local ok, err 221 local ok, err
211 for _, file in pairs({...}) do 222 for _, file in pairs({...}) do
212 if fs.is_dir(file) then 223 if fs.is_dir(file) then
213 for _, file in pairs(fs.find(file)) do 224 for _, entry in pairs(fs.find(file)) do
214 if fs.is_file(file) then 225 local fullname = dir.path(file, entry)
215 ok, err = add_to_zip(file) 226 if fs.is_file(fullname) then
227 ok, err = zw:add(fullname)
216 if not ok then break end 228 if not ok then break end
217 end 229 end
218 end 230 end
219 else 231 else
220 ok, err = add_to_zip(file) 232 ok, err = zw:add(file)
221 if not ok then break end 233 if not ok then break end
222 end 234 end
223 end 235 end
224 236
225 local ok = write_close(zf) 237 local ok = zw:close()
226 if not ok then 238 if not ok then
227 return false, "error closing "..filename 239 return false, "error closing "..zipfile
228 end 240 end
229 return ok, err 241 return ok, err
230end 242end
243
diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua
index 10fc1e36..e0c01421 100644
--- a/src/luarocks/util.lua
+++ b/src/luarocks/util.lua
@@ -216,6 +216,20 @@ function keys(tbl)
216 return ks 216 return ks
217end 217end
218 218
219local function default_sort(a, b)
220 local ta = type(a)
221 local tb = type(b)
222 if ta == "number" and tb == "number" then
223 return a < b
224 elseif ta == "number" then
225 return true
226 elseif tb == "number" then
227 return false
228 else
229 return tostring(a) < tostring(b)
230 end
231end
232
219-- The iterator function used internally by util.sortedpairs. 233-- The iterator function used internally by util.sortedpairs.
220-- @param tbl table: The table to be iterated. 234-- @param tbl table: The table to be iterated.
221-- @param sort_function function or nil: An optional comparison function 235-- @param sort_function function or nil: An optional comparison function
@@ -223,7 +237,7 @@ end
223-- @see sortedpairs 237-- @see sortedpairs
224local function sortedpairs_iterator(tbl, sort_function) 238local function sortedpairs_iterator(tbl, sort_function)
225 local ks = keys(tbl) 239 local ks = keys(tbl)
226 table.sort(ks, sort_function) 240 table.sort(ks, sort_function or default_sort)
227 for _, k in ipairs(ks) do 241 for _, k in ipairs(ks) do
228 coroutine.yield(k, tbl[k]) 242 coroutine.yield(k, tbl[k])
229 end 243 end