diff options
author | hisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c> | 2009-04-16 22:17:48 +0000 |
---|---|---|
committer | hisham <hisham@9ca3f7c1-7366-0410-b1a3-b5c78f85698c> | 2009-04-16 22:17:48 +0000 |
commit | 4f15619eabf3b47853406bbb5b52f5878121df44 (patch) | |
tree | 3ed033d2aae9b17b030e8389a945d598ba506404 /src | |
parent | f994a726c346fc1df003debd071a79fa109141f0 (diff) | |
download | luarocks-4f15619eabf3b47853406bbb5b52f5878121df44.tar.gz luarocks-4f15619eabf3b47853406bbb5b52f5878121df44.tar.bz2 luarocks-4f15619eabf3b47853406bbb5b52f5878121df44.zip |
Greatly simplified the LuaRocks fs abstractions system
git-svn-id: http://luarocks.org/svn/luarocks/trunk@8 9ca3f7c1-7366-0410-b1a3-b5c78f85698c
Diffstat (limited to 'src')
-rw-r--r-- | src/luarocks/cfg.lua | 4 | ||||
-rw-r--r-- | src/luarocks/fs.lua | 43 | ||||
-rw-r--r-- | src/luarocks/fs/lua.lua | 119 | ||||
-rw-r--r-- | src/luarocks/fs/unix.lua | 415 | ||||
-rw-r--r-- | src/luarocks/fs/win32.lua | 267 | ||||
-rw-r--r-- | src/luarocks/manif_core.lua | 1 | ||||
-rw-r--r-- | src/luarocks/tools/zip.lua | 6 |
7 files changed, 98 insertions, 757 deletions
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua index 71efea47..b667f8e7 100644 --- a/src/luarocks/cfg.lua +++ b/src/luarocks/cfg.lua | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | local rawset, next, table, pairs, print, require, io, os, setmetatable = | 2 | local rawset, next, table, pairs, print, require, io, os, setmetatable, program_version = |
3 | rawset, next, table, pairs, print, require, io, os, setmetatable | 3 | rawset, next, table, pairs, print, require, io, os, setmetatable, program_version |
4 | 4 | ||
5 | --- Configuration for LuaRocks. | 5 | --- Configuration for LuaRocks. |
6 | -- Tries to load the user's configuration file and | 6 | -- Tries to load the user's configuration file and |
diff --git a/src/luarocks/fs.lua b/src/luarocks/fs.lua index a905755d..d2cb3ddb 100644 --- a/src/luarocks/fs.lua +++ b/src/luarocks/fs.lua | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | local rawset = rawset | 2 | local pairs = pairs |
3 | 3 | ||
4 | --- Proxy module for filesystem and platform abstractions. | 4 | --- Proxy module for filesystem and platform abstractions. |
5 | -- All code using "fs" code should require "luarocks.fs", | 5 | -- All code using "fs" code should require "luarocks.fs", |
@@ -10,33 +10,30 @@ module("luarocks.fs", package.seeall) | |||
10 | 10 | ||
11 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.cfg") |
12 | 12 | ||
13 | local fs_impl = nil | 13 | local function load_fns(fs_table) |
14 | for _, platform in ipairs(cfg.platforms) do | 14 | for name, fn in pairs(fs_table) do |
15 | local ok, result = pcall(require, "luarocks.fs."..platform) | 15 | if not _M[name] then |
16 | if ok then | 16 | _M[name] = fn |
17 | fs_impl = result | ||
18 | if fs_impl then | ||
19 | break | ||
20 | end | 17 | end |
21 | end | 18 | end |
22 | end | 19 | end |
23 | 20 | ||
24 | local fs_lua = require("luarocks.fs.lua") | 21 | -- Load platform-specific functions |
25 | local fs_unix = require("luarocks.fs.unix") | 22 | local loaded_platform = nil |
26 | 23 | for _, platform in ipairs(cfg.platforms) do | |
27 | local fs_mt = { | 24 | local ok, fs_plat = pcall(require, "luarocks.fs."..platform) |
28 | __index = function(t, k) | 25 | if ok and fs_plat then |
29 | local impl = fs_lua[k] or fs_impl[k] or fs_unix[k] | 26 | loaded_platform = platform |
30 | rawset(t, k, impl) | 27 | load_fns(fs_plat) |
31 | return impl | 28 | break |
32 | end | 29 | end |
33 | } | 30 | end |
34 | 31 | ||
35 | setmetatable(luarocks.fs, fs_mt) | 32 | -- Load platform-independent pure-Lua functionality |
33 | local fs_lua = require("luarocks.fs.lua") | ||
34 | load_fns(fs_lua) | ||
36 | 35 | ||
37 | fs_lua.init_fs_functions(luarocks.fs) | 36 | -- Load platform-specific fallbacks for missing Lua modules |
38 | fs_unix.init_fs_functions(luarocks.fs) | 37 | local ok, fs_plat_tools = pcall(require, "luarocks.fs."..loaded_platform..".tools") |
39 | if fs_impl then | 38 | if ok and fs_plat_tools then load_fns(fs_plat_tools) end |
40 | fs_impl.init_fs_functions(luarocks.fs) | ||
41 | end | ||
42 | 39 | ||
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 7d411e49..9f9a4b63 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua | |||
@@ -6,6 +6,8 @@ local assert, type, table, io, package, math, os, ipairs = | |||
6 | -- using LuaFileSystem, LZLib, MD5 and LuaCurl. | 6 | -- using LuaFileSystem, LZLib, MD5 and LuaCurl. |
7 | module("luarocks.fs.lua", package.seeall) | 7 | module("luarocks.fs.lua", package.seeall) |
8 | 8 | ||
9 | local fs = require("luarocks.fs") | ||
10 | |||
9 | local cfg = require("luarocks.cfg") | 11 | local cfg = require("luarocks.cfg") |
10 | local dir = require("luarocks.dir") | 12 | local dir = require("luarocks.dir") |
11 | 13 | ||
@@ -23,36 +25,6 @@ math.randomseed(os.time()) | |||
23 | 25 | ||
24 | dir_separator = "/" | 26 | dir_separator = "/" |
25 | 27 | ||
26 | local fs_absolute_name, | ||
27 | fs_copy, | ||
28 | fs_current_dir, | ||
29 | fs_dir_stack, | ||
30 | fs_execute, | ||
31 | fs_execute_string, | ||
32 | fs_exists, | ||
33 | fs_find, | ||
34 | fs_is_dir, | ||
35 | fs_is_file, | ||
36 | fs_make_dir, | ||
37 | fs_set_time, | ||
38 | fs_Q | ||
39 | |||
40 | function init_fs_functions(impl) | ||
41 | fs_absolute_name = impl.absolute_name | ||
42 | fs_copy = impl.copy | ||
43 | fs_current_dir = impl.current_dir | ||
44 | fs_dir_stack = impl.dir_stack | ||
45 | fs_execute = impl.execute | ||
46 | fs_execute_string = impl.execute_string | ||
47 | fs_exists = impl.exists | ||
48 | fs_find = impl.find | ||
49 | fs_is_dir = impl.is_dir | ||
50 | fs_is_file = impl.is_file | ||
51 | fs_make_dir = impl.make_dir | ||
52 | fs_set_time = impl.set_time | ||
53 | fs_Q = impl.Q | ||
54 | end | ||
55 | |||
56 | --- Quote argument for shell processing. | 28 | --- Quote argument for shell processing. |
57 | -- Adds single quotes and escapes. | 29 | -- Adds single quotes and escapes. |
58 | -- @param arg string: Unquoted argument. | 30 | -- @param arg string: Unquoted argument. |
@@ -73,7 +45,7 @@ end | |||
73 | function is_writable(file) | 45 | function is_writable(file) |
74 | assert(file) | 46 | assert(file) |
75 | local result | 47 | local result |
76 | if fs_is_dir(file) then | 48 | if fs.is_dir(file) then |
77 | local file2 = file .. '/.tmpluarockstestwritable' | 49 | local file2 = file .. '/.tmpluarockstestwritable' |
78 | local fh = io.open(file2, 'w') | 50 | local fh = io.open(file2, 'w') |
79 | result = fh ~= nil | 51 | result = fh ~= nil |
@@ -95,31 +67,13 @@ function make_temp_dir(name) | |||
95 | assert(type(name) == "string") | 67 | assert(type(name) == "string") |
96 | 68 | ||
97 | local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) | 69 | local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) |
98 | if fs_make_dir(temp_dir) then | 70 | if fs.make_dir(temp_dir) then |
99 | return temp_dir | 71 | return temp_dir |
100 | else | 72 | else |
101 | return nil | 73 | return nil |
102 | end | 74 | end |
103 | end | 75 | end |
104 | 76 | ||
105 | --- Return an absolute pathname from a potentially relative one. | ||
106 | -- @param pathname string: pathname to convert. | ||
107 | -- @param relative_to string or nil: path to prepend when making | ||
108 | -- pathname absolute, or the current dir in the dir stack if | ||
109 | -- not given. | ||
110 | -- @return string: The pathname converted to absolute. | ||
111 | function absolute_name(pathname, relative_to) | ||
112 | assert(type(pathname) == "string") | ||
113 | assert(type(relative_to) == "string" or not relative_to) | ||
114 | |||
115 | relative_to = relative_to or fs_current_dir() | ||
116 | if pathname:sub(1,1) == "/" then | ||
117 | return pathname | ||
118 | else | ||
119 | return relative_to .. "/" .. pathname | ||
120 | end | ||
121 | end | ||
122 | |||
123 | --- Split protocol and path from an URL or local pathname. | 77 | --- Split protocol and path from an URL or local pathname. |
124 | -- URLs should be in the "protocol://path" format. | 78 | -- URLs should be in the "protocol://path" format. |
125 | -- For local pathnames, "file" is returned as the protocol. | 79 | -- For local pathnames, "file" is returned as the protocol. |
@@ -134,11 +88,28 @@ function split_url(url) | |||
134 | pathname = url | 88 | pathname = url |
135 | end | 89 | end |
136 | if protocol == "file" then | 90 | if protocol == "file" then |
137 | pathname = fs_absolute_name(pathname) | 91 | pathname = fs.absolute_name(pathname) |
138 | end | 92 | end |
139 | return protocol, pathname | 93 | return protocol, pathname |
140 | end | 94 | end |
141 | 95 | ||
96 | --- Run the given command, quoting its arguments. | ||
97 | -- The command is executed in the current directory in the dir stack. | ||
98 | -- @param command string: The command to be executed. No quoting/escaping | ||
99 | -- is applied. | ||
100 | -- @param ... Strings containing additional arguments, which are quoted. | ||
101 | -- @return boolean: true if command succeeds (status code 0), false | ||
102 | -- otherwise. | ||
103 | function execute(command, ...) | ||
104 | assert(type(command) == "string") | ||
105 | |||
106 | for _, arg in ipairs({...}) do | ||
107 | assert(type(arg) == "string") | ||
108 | command = command .. " " .. fs.Q(arg) | ||
109 | end | ||
110 | return fs.execute_string(command) | ||
111 | end | ||
112 | |||
142 | --------------------------------------------------------------------- | 113 | --------------------------------------------------------------------- |
143 | -- LuaFileSystem functions | 114 | -- LuaFileSystem functions |
144 | --------------------------------------------------------------------- | 115 | --------------------------------------------------------------------- |
@@ -158,23 +129,6 @@ function execute_string(cmd) | |||
158 | end | 129 | end |
159 | end | 130 | end |
160 | 131 | ||
161 | --- Run the given command, quoting its arguments. | ||
162 | -- The command is executed in the current directory in the dir stack. | ||
163 | -- @param command string: The command to be executed. No quoting/escaping | ||
164 | -- is applied. | ||
165 | -- @param ... Strings containing additional arguments, which are quoted. | ||
166 | -- @return boolean: true if command succeeds (status code 0), false | ||
167 | -- otherwise. | ||
168 | function execute(command, ...) | ||
169 | assert(type(command) == "string") | ||
170 | |||
171 | for _, arg in ipairs({...}) do | ||
172 | assert(type(arg) == "string") | ||
173 | command = command .. " " .. fs_Q(arg) | ||
174 | end | ||
175 | return fs_execute_string(command) | ||
176 | end | ||
177 | |||
178 | --- Obtain current directory. | 132 | --- Obtain current directory. |
179 | -- Uses the module's internal dir stack. | 133 | -- Uses the module's internal dir stack. |
180 | -- @return string: the absolute pathname of the current directory. | 134 | -- @return string: the absolute pathname of the current directory. |
@@ -190,7 +144,6 @@ end | |||
190 | function change_dir(d) | 144 | function change_dir(d) |
191 | table.insert(dir_stack, lfs.currentdir()) | 145 | table.insert(dir_stack, lfs.currentdir()) |
192 | lfs.chdir(d) | 146 | lfs.chdir(d) |
193 | --local x="CHDIR: " for _,d in ipairs(dir_stack) do x=x.." "..d end print(x) | ||
194 | end | 147 | end |
195 | 148 | ||
196 | --- Change directory to root. | 149 | --- Change directory to root. |
@@ -200,14 +153,12 @@ function change_dir_to_root() | |||
200 | table.insert(dir_stack, lfs.currentdir()) | 153 | table.insert(dir_stack, lfs.currentdir()) |
201 | -- TODO Does this work on Windows? | 154 | -- TODO Does this work on Windows? |
202 | lfs.chdir("/") | 155 | lfs.chdir("/") |
203 | --local x="CHDIR ROOT: " for _,d in ipairs(dir_stack) do x=x.." "..d end print(x) | ||
204 | end | 156 | end |
205 | 157 | ||
206 | --- Change working directory to the previous in the dir stack. | 158 | --- Change working directory to the previous in the dir stack. |
207 | -- @return true if a pop ocurred, false if the stack was empty. | 159 | -- @return true if a pop ocurred, false if the stack was empty. |
208 | function pop_dir() | 160 | function pop_dir() |
209 | local d = table.remove(dir_stack) | 161 | local d = table.remove(dir_stack) |
210 | --local x="POP DIR: " for _,d in ipairs(dir_stack) do x=x.." "..d end print(x) | ||
211 | if d then | 162 | if d then |
212 | lfs.chdir(d) | 163 | lfs.chdir(d) |
213 | return true | 164 | return true |
@@ -280,11 +231,11 @@ local function recursive_copy(src, dest) | |||
280 | local srcmode = lfs.attributes(src, "mode") | 231 | local srcmode = lfs.attributes(src, "mode") |
281 | 232 | ||
282 | if srcmode == "file" then | 233 | if srcmode == "file" then |
283 | local ok = fs_copy(src, dest) | 234 | local ok = fs.copy(src, dest) |
284 | if not ok then return false end | 235 | if not ok then return false end |
285 | elseif srcmode == "directory" then | 236 | elseif srcmode == "directory" then |
286 | local subdir = dir.path(dest, dir.base_name(src)) | 237 | local subdir = dir.path(dest, dir.base_name(src)) |
287 | fs_make_dir(subdir) | 238 | fs.make_dir(subdir) |
288 | for file in lfs.dir(src) do | 239 | for file in lfs.dir(src) do |
289 | if file ~= "." and file ~= ".." then | 240 | if file ~= "." and file ~= ".." then |
290 | local ok = recursive_copy(dir.path(src, file), subdir) | 241 | local ok = recursive_copy(dir.path(src, file), subdir) |
@@ -354,9 +305,9 @@ end | |||
354 | function list_dir(at) | 305 | function list_dir(at) |
355 | assert(type(at) == "string" or not at) | 306 | assert(type(at) == "string" or not at) |
356 | if not at then | 307 | if not at then |
357 | at = fs_current_dir() | 308 | at = fs.current_dir() |
358 | end | 309 | end |
359 | if not fs_is_dir(at) then | 310 | if not fs.is_dir(at) then |
360 | return {} | 311 | return {} |
361 | end | 312 | end |
362 | local result = {} | 313 | local result = {} |
@@ -392,9 +343,9 @@ end | |||
392 | function find(at) | 343 | function find(at) |
393 | assert(type(at) == "string" or not at) | 344 | assert(type(at) == "string" or not at) |
394 | if not at then | 345 | if not at then |
395 | at = fs_current_dir() | 346 | at = fs.current_dir() |
396 | end | 347 | end |
397 | if not fs_is_dir(at) then | 348 | if not fs.is_dir(at) then |
398 | return {} | 349 | return {} |
399 | end | 350 | end |
400 | local result = {} | 351 | local result = {} |
@@ -448,7 +399,7 @@ end | |||
448 | function unzip(zipfile) | 399 | function unzip(zipfile) |
449 | assert(zipfile) | 400 | assert(zipfile) |
450 | -- FIXME!!!! | 401 | -- FIXME!!!! |
451 | return fs_execute("unzip", zipfile) | 402 | return fs.execute("unzip", zipfile) |
452 | end | 403 | end |
453 | 404 | ||
454 | end | 405 | end |
@@ -506,7 +457,7 @@ if md5_ok then | |||
506 | -- @return boolean: true if the MD5 checksum for 'file' equals 'md5sum', false if not | 457 | -- @return boolean: true if the MD5 checksum for 'file' equals 'md5sum', false if not |
507 | -- or if it could not perform the check for any reason. | 458 | -- or if it could not perform the check for any reason. |
508 | function check_md5(file, md5sum) | 459 | function check_md5(file, md5sum) |
509 | file = fs_absolute_name(file) | 460 | file = fs.absolute_name(file) |
510 | local file = io.open(file, "r") | 461 | local file = io.open(file, "r") |
511 | if not file then return false end | 462 | if not file then return false end |
512 | local computed = md5.sumhexa(file:read("*a")) | 463 | local computed = md5.sumhexa(file:read("*a")) |
@@ -545,13 +496,13 @@ function unpack_archive(archive) | |||
545 | 496 | ||
546 | local ok | 497 | local ok |
547 | if archive:match("%.tar%.gz$") or archive:match("%.tgz$") then | 498 | if archive:match("%.tar%.gz$") or archive:match("%.tgz$") then |
548 | -- ok = fs_execute("tar zxvpf ", archive) | 499 | -- ok = fs.execute("tar zxvpf ", archive) |
549 | ok = fs_execute_string("gunzip -c "..archive.."|tar -xf -") | 500 | ok = fs.execute_string("gunzip -c "..archive.."|tar -xf -") |
550 | elseif archive:match("%.tar%.bz2$") then | 501 | elseif archive:match("%.tar%.bz2$") then |
551 | -- ok = fs_execute("tar jxvpf ", archive) | 502 | -- ok = fs.execute("tar jxvpf ", archive) |
552 | ok = fs_execute_string("bunzip2 -c "..archive.."|tar -xf -") | 503 | ok = fs.execute_string("bunzip2 -c "..archive.."|tar -xf -") |
553 | elseif archive:match("%.zip$") then | 504 | elseif archive:match("%.zip$") then |
554 | ok = fs_execute("unzip ", archive) | 505 | ok = fs.execute("unzip ", archive) |
555 | elseif archive:match("%.lua$") or archive:match("%.c$") then | 506 | elseif archive:match("%.lua$") or archive:match("%.c$") then |
556 | -- Ignore .lua and .c files; they don't need to be extracted. | 507 | -- Ignore .lua and .c files; they don't need to be extracted. |
557 | return true | 508 | return true |
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua index 1f8411c9..dba152ef 100644 --- a/src/luarocks/fs/unix.lua +++ b/src/luarocks/fs/unix.lua | |||
@@ -5,389 +5,14 @@ local assert, type, table, io, package, math, os, ipairs = | |||
5 | --- Unix implementation of filesystem and platform abstractions. | 5 | --- Unix implementation of filesystem and platform abstractions. |
6 | module("luarocks.fs.unix", package.seeall) | 6 | module("luarocks.fs.unix", package.seeall) |
7 | 7 | ||
8 | local fs = require("luarocks.fs") | ||
9 | |||
8 | local cfg = require("luarocks.cfg") | 10 | local cfg = require("luarocks.cfg") |
9 | local dir = require("luarocks.dir") | 11 | local dir = require("luarocks.dir") |
12 | local fs = require("luarocks.fs") | ||
10 | 13 | ||
11 | math.randomseed(os.time()) | 14 | math.randomseed(os.time()) |
12 | 15 | ||
13 | dir_stack = {} | ||
14 | |||
15 | local fs_absolute_name, | ||
16 | fs_copy, | ||
17 | fs_current_dir, | ||
18 | fs_dir_stack, | ||
19 | fs_execute, | ||
20 | fs_execute_string, | ||
21 | fs_is_dir, | ||
22 | fs_is_file, | ||
23 | fs_make_dir, | ||
24 | fs_exists, | ||
25 | fs_find, | ||
26 | fs_Q | ||
27 | |||
28 | function init_fs_functions(impl) | ||
29 | fs_absolute_name = impl.absolute_name | ||
30 | fs_copy = impl.copy | ||
31 | fs_current_dir = impl.current_dir | ||
32 | fs_dir_stack = impl.dir_stack | ||
33 | fs_execute = impl.execute | ||
34 | fs_execute_string = impl.execute_string | ||
35 | fs_is_dir = impl.is_dir | ||
36 | fs_is_file = impl.is_file | ||
37 | fs_make_dir = impl.make_dir | ||
38 | fs_exists = impl.exists | ||
39 | fs_find = impl.find | ||
40 | fs_Q = impl.Q | ||
41 | end | ||
42 | |||
43 | --- Quote argument for shell processing. | ||
44 | -- Adds single quotes and escapes. | ||
45 | -- @param arg string: Unquoted argument. | ||
46 | -- @return string: Quoted argument. | ||
47 | function Q(arg) | ||
48 | assert(type(arg) == "string") | ||
49 | |||
50 | return "'" .. arg:gsub("\\", "\\\\"):gsub("'", "'\\''") .. "'" | ||
51 | end | ||
52 | |||
53 | --- Obtain current directory. | ||
54 | -- Uses the module's internal dir stack. | ||
55 | -- @return string: the absolute pathname of the current directory. | ||
56 | function current_dir() | ||
57 | local current = os.getenv("PWD") | ||
58 | if not current then | ||
59 | local pipe = io.popen("pwd") | ||
60 | current = pipe:read("*l") | ||
61 | pipe:close() | ||
62 | end | ||
63 | for _, d in ipairs(fs_dir_stack) do | ||
64 | current = fs_absolute_name(d, current) | ||
65 | end | ||
66 | return current | ||
67 | end | ||
68 | |||
69 | --- Run the given command. | ||
70 | -- The command is executed in the current directory in the dir stack. | ||
71 | -- @param cmd string: No quoting/escaping is applied to the command. | ||
72 | -- @return boolean: true if command succeeds (status code 0), false | ||
73 | -- otherwise. | ||
74 | function execute_string(cmd) | ||
75 | if os.execute("cd " .. fs_Q(fs_current_dir()) .. " && " .. cmd) == 0 then | ||
76 | return true | ||
77 | else | ||
78 | return false | ||
79 | end | ||
80 | end | ||
81 | |||
82 | --- Run the given command, quoting its arguments. | ||
83 | -- The command is executed in the current directory in the dir stack. | ||
84 | -- @param command string: The command to be executed. No quoting/escaping | ||
85 | -- is applied. | ||
86 | -- @param ... Strings containing additional arguments, which are quoted. | ||
87 | -- @return boolean: true if command succeeds (status code 0), false | ||
88 | -- otherwise. | ||
89 | function execute(command, ...) | ||
90 | assert(type(command) == "string") | ||
91 | |||
92 | for _, arg in ipairs({...}) do | ||
93 | assert(type(arg) == "string") | ||
94 | command = command .. " " .. fs_Q(arg) | ||
95 | end | ||
96 | return fs_execute_string(command) | ||
97 | end | ||
98 | |||
99 | --- Change the current directory. | ||
100 | -- Uses the module's internal dir stack. This does not have exact | ||
101 | -- semantics of chdir, as it does not handle errors the same way, | ||
102 | -- but works well for our purposes for now. | ||
103 | -- @param d string: The directory to switch to. | ||
104 | function change_dir(d) | ||
105 | assert(type(d) == "string") | ||
106 | table.insert(fs_dir_stack, d) | ||
107 | end | ||
108 | |||
109 | --- Change directory to root. | ||
110 | -- Allows leaving a directory (e.g. for deleting it) in | ||
111 | -- a crossplatform way. | ||
112 | function change_dir_to_root() | ||
113 | table.insert(fs_dir_stack, "/") | ||
114 | end | ||
115 | |||
116 | --- Change working directory to the previous in the dir stack. | ||
117 | function pop_dir() | ||
118 | local d = table.remove(fs_dir_stack) | ||
119 | return d ~= nil | ||
120 | end | ||
121 | |||
122 | --- Create a directory if it does not already exist. | ||
123 | -- If any of the higher levels in the path name does not exist | ||
124 | -- too, they are created as well. | ||
125 | -- @param d string: pathname of directory to create. | ||
126 | -- @return boolean: true on success, false on failure. | ||
127 | function make_dir(d) | ||
128 | assert(d) | ||
129 | return fs_execute("mkdir -p", d) | ||
130 | end | ||
131 | |||
132 | --- Remove a directory if it is empty. | ||
133 | -- Does not return errors (for example, if directory is not empty or | ||
134 | -- if already does not exist) | ||
135 | -- @param dir string: pathname of directory to remove. | ||
136 | function remove_dir_if_empty(d) | ||
137 | assert(d) | ||
138 | fs_execute_string("rmdir "..fs_Q(d).." 1> /dev/null 2> /dev/null") | ||
139 | end | ||
140 | |||
141 | --- Copy a file. | ||
142 | -- @param src string: Pathname of source | ||
143 | -- @param dest string: Pathname of destination | ||
144 | -- @return boolean or (boolean, string): true on success, false on failure, | ||
145 | -- plus an error message. | ||
146 | function copy(src, dest) | ||
147 | assert(src and dest) | ||
148 | if fs_execute("cp", src, dest) then | ||
149 | return true | ||
150 | else | ||
151 | return false, "Failed copying "..src.." to "..dest | ||
152 | end | ||
153 | end | ||
154 | |||
155 | --- Recursively copy the contents of a directory. | ||
156 | -- @param src string: Pathname of source | ||
157 | -- @param dest string: Pathname of destination | ||
158 | -- @return boolean or (boolean, string): true on success, false on failure, | ||
159 | -- plus an error message. | ||
160 | function copy_contents(src, dest) | ||
161 | assert(src and dest) | ||
162 | if fs_execute_string("cp -pPR "..fs_Q(src).."/* "..fs_Q(dest).." 1> /dev/null 2>/dev/null") then | ||
163 | return true | ||
164 | else | ||
165 | return false, "Failed copying "..src.." to "..dest | ||
166 | end | ||
167 | end | ||
168 | |||
169 | --- Delete a file or a directory and all its contents. | ||
170 | -- For safety, this only accepts absolute paths. | ||
171 | -- @param arg string: Pathname of source | ||
172 | -- @return boolean: true on success, false on failure. | ||
173 | function delete(arg) | ||
174 | assert(arg) | ||
175 | assert(arg:sub(1,1) == "/") | ||
176 | return fs_execute_string("rm -rf " .. fs_Q(arg) .. " 1> /dev/null 2>/dev/null") | ||
177 | end | ||
178 | |||
179 | --- List the contents of a directory. | ||
180 | -- @param at string or nil: directory to list (will be the current | ||
181 | -- directory if none is given). | ||
182 | -- @return table: an array of strings with the filenames representing | ||
183 | -- the contents of a directory. | ||
184 | function list_dir(at) | ||
185 | assert(type(at) == "string" or not at) | ||
186 | if not at then | ||
187 | at = fs_current_dir() | ||
188 | end | ||
189 | if not fs_is_dir(at) then | ||
190 | return {} | ||
191 | end | ||
192 | local result = {} | ||
193 | local pipe = io.popen("cd "..fs_Q(at).." && ls") | ||
194 | for file in pipe:lines() do | ||
195 | table.insert(result, file) | ||
196 | end | ||
197 | pipe:close() | ||
198 | return result | ||
199 | end | ||
200 | |||
201 | --- Recursively scan the contents of a directory. | ||
202 | -- @param at string or nil: directory to scan (will be the current | ||
203 | -- directory if none is given). | ||
204 | -- @return table: an array of strings with the filenames representing | ||
205 | -- the contents of a directory. | ||
206 | function find(at) | ||
207 | assert(type(at) == "string" or not at) | ||
208 | if not at then | ||
209 | at = fs_current_dir() | ||
210 | end | ||
211 | if not fs_is_dir(at) then | ||
212 | return {} | ||
213 | end | ||
214 | local result = {} | ||
215 | local pipe = io.popen("cd "..fs_Q(at).." && find * 2>/dev/null") | ||
216 | for file in pipe:lines() do | ||
217 | table.insert(result, file) | ||
218 | end | ||
219 | pipe:close() | ||
220 | return result | ||
221 | end | ||
222 | |||
223 | --- Compress files in a .zip archive. | ||
224 | -- @param zipfile string: pathname of .zip archive to be created. | ||
225 | -- @param ... Filenames to be stored in the archive are given as | ||
226 | -- additional arguments. | ||
227 | -- @return boolean: true on success, false on failure. | ||
228 | function zip(zipfile, ...) | ||
229 | return fs_execute("zip -r", zipfile, ...) | ||
230 | end | ||
231 | |||
232 | --- Uncompress files from a .zip archive. | ||
233 | -- @param zipfile string: pathname of .zip archive to be extracted. | ||
234 | -- @return boolean: true on success, false on failure. | ||
235 | function unzip(zipfile) | ||
236 | assert(zipfile) | ||
237 | return fs_execute("unzip", zipfile) | ||
238 | end | ||
239 | |||
240 | --- Test for existance of a file. | ||
241 | -- @param file string: filename to test | ||
242 | -- @return boolean: true if file exists, false otherwise. | ||
243 | function exists(file) | ||
244 | assert(file) | ||
245 | return fs_execute("test -r", file) | ||
246 | end | ||
247 | |||
248 | --- Test is file/dir is writable. | ||
249 | -- @param file string: filename to test | ||
250 | -- @return boolean: true if file exists, false otherwise. | ||
251 | function is_writable(file) | ||
252 | assert(file) | ||
253 | return fs_execute("test -w", file) | ||
254 | end | ||
255 | |||
256 | --- Test is pathname is a directory. | ||
257 | -- @param file string: pathname to test | ||
258 | -- @return boolean: true if it is a directory, false otherwise. | ||
259 | function is_dir(file) | ||
260 | assert(file) | ||
261 | return fs_execute("test -d", file) | ||
262 | end | ||
263 | |||
264 | --- Test is pathname is a regular file. | ||
265 | -- @param file string: pathname to test | ||
266 | -- @return boolean: true if it is a regular file, false otherwise. | ||
267 | function is_file(file) | ||
268 | assert(file) | ||
269 | return fs_execute("test -f", file) | ||
270 | end | ||
271 | |||
272 | --- Download a remote file. | ||
273 | -- @param url string: URL to be fetched. | ||
274 | -- @param filename string or nil: this function attempts to detect the | ||
275 | -- resulting local filename of the remote file as the basename of the URL; | ||
276 | -- if that is not correct (due to a redirection, for example), the local | ||
277 | -- filename can be given explicitly as this second argument. | ||
278 | -- @return boolean: true on success, false on failure. | ||
279 | function download(url, filename) | ||
280 | assert(type(url) == "string") | ||
281 | assert(type(filename) == "string" or not filename) | ||
282 | |||
283 | if cfg.downloader == "wget" then | ||
284 | local wget_cmd = "wget --user-agent="..cfg.user_agent.." --quiet --continue " | ||
285 | if filename then | ||
286 | return fs_execute(wget_cmd.." --output-document ", filename, url) | ||
287 | else | ||
288 | return fs_execute(wget_cmd, url) | ||
289 | end | ||
290 | elseif cfg.downloader == "curl" then | ||
291 | filename = filename or dir.base_name(url) | ||
292 | return fs_execute_string("curl --user-agent "..cfg.user_agent.." "..fs_Q(url).." 2> /dev/null 1> "..fs_Q(filename)) | ||
293 | end | ||
294 | end | ||
295 | |||
296 | --- Create a temporary directory. | ||
297 | -- @param name string: name pattern to use for avoiding conflicts | ||
298 | -- when creating temporary directory. | ||
299 | -- @return string or nil: name of temporary directory or nil on failure. | ||
300 | function make_temp_dir(name) | ||
301 | assert(type(name) == "string") | ||
302 | |||
303 | local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) | ||
304 | if fs_make_dir(temp_dir) then | ||
305 | return temp_dir | ||
306 | else | ||
307 | return nil | ||
308 | end | ||
309 | end | ||
310 | |||
311 | function chmod(pathname, mode) | ||
312 | return fs_execute("chmod "..mode, pathname) | ||
313 | end | ||
314 | |||
315 | --- Apply a patch. | ||
316 | -- @param patchname string: The filename of the patch. | ||
317 | function apply_patch(patchname) | ||
318 | return fs_execute("patch -p1 -f -i ", patchname) | ||
319 | end | ||
320 | |||
321 | --- Unpack an archive. | ||
322 | -- Extract the contents of an archive, detecting its format by | ||
323 | -- filename extension. | ||
324 | -- @param archive string: Filename of archive. | ||
325 | -- @return boolean or (boolean, string): true on success, false and an error message on failure. | ||
326 | function unpack_archive(archive) | ||
327 | assert(type(archive) == "string") | ||
328 | |||
329 | local ok | ||
330 | if archive:match("%.tar%.gz$") or archive:match("%.tgz$") then | ||
331 | -- ok = fs_execute("tar zxvpf ", archive) | ||
332 | ok = fs_execute_string("gunzip -c "..archive.."|tar -xf -") | ||
333 | elseif archive:match("%.tar%.bz2$") then | ||
334 | -- ok = fs_execute("tar jxvpf ", archive) | ||
335 | ok = fs_execute_string("bunzip2 -c "..archive.."|tar -xf -") | ||
336 | elseif archive:match("%.zip$") then | ||
337 | ok = fs_execute("unzip ", archive) | ||
338 | elseif archive:match("%.lua$") or archive:match("%.c$") then | ||
339 | -- Ignore .lua and .c files; they don't need to be extracted. | ||
340 | return true | ||
341 | else | ||
342 | local ext = archive:match(".*(%..*)") | ||
343 | return false, "Unrecognized filename extension "..(ext or "") | ||
344 | end | ||
345 | if not ok then | ||
346 | return false, "Failed extracting "..archive | ||
347 | end | ||
348 | return true | ||
349 | end | ||
350 | |||
351 | --- Check the MD5 checksum for a file. | ||
352 | -- @param file string: The file to be checked. | ||
353 | -- @param md5sum string: The string with the expected MD5 checksum. | ||
354 | -- @return boolean: true if the MD5 checksum for 'file' equals 'md5sum', false if not | ||
355 | -- or if it could not perform the check for any reason. | ||
356 | function check_md5(file, md5sum) | ||
357 | file = fs_absolute_name(file) | ||
358 | local computed | ||
359 | if cfg.md5checker == "md5sum" then | ||
360 | local pipe = io.popen("md5sum "..file) | ||
361 | computed = pipe:read("*l"):gsub("[^%x]+", "") | ||
362 | pipe:close() | ||
363 | if computed then | ||
364 | computed = computed:sub(1,32) | ||
365 | end | ||
366 | elseif cfg.md5checker == "openssl" then | ||
367 | local pipe = io.popen("openssl md5 "..file) | ||
368 | computed = pipe:read("*l") | ||
369 | pipe:close() | ||
370 | if computed then | ||
371 | computed = computed:sub(-32) | ||
372 | end | ||
373 | elseif cfg.md5checker == "md5" then | ||
374 | local pipe = io.popen("md5 "..file) | ||
375 | computed = pipe:read("*l") | ||
376 | pipe:close() | ||
377 | if computed then | ||
378 | computed = computed:sub(-32) | ||
379 | end | ||
380 | end | ||
381 | if not computed then | ||
382 | return false | ||
383 | end | ||
384 | if computed:match("^"..md5sum) then | ||
385 | return true | ||
386 | else | ||
387 | return false | ||
388 | end | ||
389 | end | ||
390 | |||
391 | --- Return an absolute pathname from a potentially relative one. | 16 | --- Return an absolute pathname from a potentially relative one. |
392 | -- @param pathname string: pathname to convert. | 17 | -- @param pathname string: pathname to convert. |
393 | -- @param relative_to string or nil: path to prepend when making | 18 | -- @param relative_to string or nil: path to prepend when making |
@@ -398,7 +23,7 @@ function absolute_name(pathname, relative_to) | |||
398 | assert(type(pathname) == "string") | 23 | assert(type(pathname) == "string") |
399 | assert(type(relative_to) == "string" or not relative_to) | 24 | assert(type(relative_to) == "string" or not relative_to) |
400 | 25 | ||
401 | relative_to = relative_to or fs_current_dir() | 26 | relative_to = relative_to or fs.current_dir() |
402 | if pathname:sub(1,1) == "/" then | 27 | if pathname:sub(1,1) == "/" then |
403 | return pathname | 28 | return pathname |
404 | else | 29 | else |
@@ -420,7 +45,7 @@ function split_url(url) | |||
420 | pathname = url | 45 | pathname = url |
421 | end | 46 | end |
422 | if protocol == "file" then | 47 | if protocol == "file" then |
423 | pathname = fs_absolute_name(pathname) | 48 | pathname = fs.absolute_name(pathname) |
424 | end | 49 | end |
425 | return protocol, pathname | 50 | return protocol, pathname |
426 | end | 51 | end |
@@ -446,7 +71,7 @@ function wrap_script(file, dest) | |||
446 | wrapper:write('export LUA_PATH LUA_CPATH\n') | 71 | wrapper:write('export LUA_PATH LUA_CPATH\n') |
447 | wrapper:write('exec "'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.require "'..file..'" "$@"\n') | 72 | wrapper:write('exec "'..dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter)..'" -lluarocks.require "'..file..'" "$@"\n') |
448 | wrapper:close() | 73 | wrapper:close() |
449 | if fs_execute("chmod +x",wrapname) then | 74 | if fs.execute("chmod +x",wrapname) then |
450 | return true | 75 | return true |
451 | else | 76 | else |
452 | return nil, "Could not make "..wrapname.." executable." | 77 | return nil, "Could not make "..wrapname.." executable." |
@@ -487,7 +112,33 @@ function is_actual_binary(filename) | |||
487 | return false | 112 | return false |
488 | end | 113 | end |
489 | 114 | ||
115 | function is_actual_binary(filename) | ||
116 | if filename:match("%.lua$") then | ||
117 | return false | ||
118 | end | ||
119 | local file = io.open(filename) | ||
120 | if file then | ||
121 | local found = false | ||
122 | local first = file:read() | ||
123 | if first:match("#!.*lua") then | ||
124 | file:close() | ||
125 | return true | ||
126 | elseif first:match("#!/bin/sh") then | ||
127 | local line = file:read() | ||
128 | line = file:read() | ||
129 | if not(line and line:match("LUA_PATH")) then | ||
130 | file:close() | ||
131 | return true | ||
132 | end | ||
133 | end | ||
134 | file:close() | ||
135 | else | ||
136 | return true | ||
137 | end | ||
138 | return false | ||
139 | end | ||
140 | |||
490 | function copy_binary(filename, dest) | 141 | function copy_binary(filename, dest) |
491 | return fs_copy(filename, dest) | 142 | return fs.copy(filename, dest) |
492 | end | 143 | end |
493 | 144 | ||
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index da9b7d60..d005781e 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua | |||
@@ -3,25 +3,11 @@ | |||
3 | -- used by this module. | 3 | -- used by this module. |
4 | module("luarocks.fs.win32", package.seeall) | 4 | module("luarocks.fs.win32", package.seeall) |
5 | 5 | ||
6 | local fs = require("luarocks.fs") | ||
7 | |||
6 | local cfg = require("luarocks.cfg") | 8 | local cfg = require("luarocks.cfg") |
7 | local dir = require("luarocks.dir") | 9 | local dir = require("luarocks.dir") |
8 | 10 | ||
9 | local fs_copy, | ||
10 | fs_current_dir, | ||
11 | fs_execute, | ||
12 | fs_execute_string, | ||
13 | fs_is_dir, | ||
14 | fs_Q | ||
15 | |||
16 | function init_fs_functions(impl) | ||
17 | fs_copy = impl.copy | ||
18 | fs_current_dir = impl.current_dir | ||
19 | fs_execute = impl.execute | ||
20 | fs_execute_string = impl.execute_string | ||
21 | fs_is_dir = impl.is_dir | ||
22 | fs_Q = impl.Q | ||
23 | end | ||
24 | |||
25 | --- Quote argument for shell processing. Fixes paths on Windows. | 11 | --- Quote argument for shell processing. Fixes paths on Windows. |
26 | -- Adds single quotes and escapes. | 12 | -- Adds single quotes and escapes. |
27 | -- @param arg string: Unquoted argument. | 13 | -- @param arg string: Unquoted argument. |
@@ -36,202 +22,6 @@ function Q(arg) | |||
36 | return '"' .. arg:gsub('"', '\\"') .. '"' | 22 | return '"' .. arg:gsub('"', '\\"') .. '"' |
37 | end | 23 | end |
38 | 24 | ||
39 | local function command_at(directory, cmd) | ||
40 | local drive = directory:match("^([A-Za-z]:)") | ||
41 | cmd = "cd " .. fs_Q(directory) .. " & " .. cmd | ||
42 | if drive then | ||
43 | cmd = drive .. " & " .. cmd | ||
44 | end | ||
45 | return cmd | ||
46 | end | ||
47 | |||
48 | --- Run the given command. | ||
49 | -- The command is executed in the current directory in the dir stack. | ||
50 | -- @param cmd string: No quoting/escaping is applied to the command. | ||
51 | -- @return boolean: true if command succeeds (status code 0), false | ||
52 | -- otherwise. | ||
53 | function execute_string(cmd) | ||
54 | if os.execute(command_at(fs_current_dir(), cmd)) == 0 then | ||
55 | return true | ||
56 | else | ||
57 | return false | ||
58 | end | ||
59 | end | ||
60 | |||
61 | --- Test for existance of a file. | ||
62 | -- @param file string: filename to test | ||
63 | -- @return boolean: true if file exists, false otherwise. | ||
64 | function exists(file) | ||
65 | assert(file) | ||
66 | return fs_execute("if not exist " .. fs_Q(file) .. | ||
67 | " invalidcommandname 2>NUL 1>NUL") | ||
68 | end | ||
69 | |||
70 | --- Test is pathname is a directory. | ||
71 | -- @param file string: pathname to test | ||
72 | -- @return boolean: true if it is a directory, false otherwise. | ||
73 | function is_dir(file) | ||
74 | assert(file) | ||
75 | return fs_execute("chdir /D " .. fs_Q(file) .. " 2>NUL 1>NUL") | ||
76 | end | ||
77 | |||
78 | --- Test is pathname is a regular file. | ||
79 | -- @param file string: pathname to test | ||
80 | -- @return boolean: true if it is a regular file, false otherwise. | ||
81 | function is_dir(file) | ||
82 | assert(file) | ||
83 | return fs_execute("test -d" .. fs_Q(file) .. " 2>NUL 1>NUL") | ||
84 | end | ||
85 | |||
86 | --- Test is file/dir is writable. | ||
87 | -- @param file string: filename to test | ||
88 | -- @return boolean: true if file exists, false otherwise. | ||
89 | function is_writable(file) | ||
90 | assert(file) | ||
91 | local result | ||
92 | if is_dir(file) then | ||
93 | local file2 = file .. '/.tmpluarockstestwritable' | ||
94 | local fh = io.open(file2, 'w') | ||
95 | result = fh ~= nil | ||
96 | if fh then fh:close() end | ||
97 | os.remove(file2) | ||
98 | else | ||
99 | local fh = io.open(file, 'r+') | ||
100 | result = fh ~= nil | ||
101 | if fh then fh:close() end | ||
102 | end | ||
103 | return result | ||
104 | end | ||
105 | |||
106 | |||
107 | --- Create a directory if it does not already exist. | ||
108 | -- If any of the higher levels in the path name does not exist | ||
109 | -- too, they are created as well. | ||
110 | -- @param d string: pathname of directory to create. | ||
111 | -- @return boolean: true on success, false on failure. | ||
112 | function make_dir(d) | ||
113 | assert(d) | ||
114 | fs_execute("mkdir "..fs_Q(d).." 1> NUL 2> NUL") | ||
115 | return 1 | ||
116 | end | ||
117 | |||
118 | --- Remove a directory if it is empty. | ||
119 | -- Does not return errors (for example, if directory is not empty or | ||
120 | -- if already does not exist) | ||
121 | -- @param d string: pathname of directory to remove. | ||
122 | function remove_dir_if_empty(d) | ||
123 | assert(d) | ||
124 | fs_execute_string("rmdir "..fs_Q(d).." 1> NUL 2> NUL") | ||
125 | end | ||
126 | |||
127 | --- Copy a file. | ||
128 | -- @param src string: Pathname of source | ||
129 | -- @param dest string: Pathname of destination | ||
130 | -- @return boolean or (boolean, string): true on success, false on failure, | ||
131 | -- plus an error message. | ||
132 | function copy(src, dest) | ||
133 | assert(src and dest) | ||
134 | if dest:match("[/\\]$") then dest = dest:sub(1, -2) end | ||
135 | if fs_execute("cp", src, dest) then | ||
136 | return true | ||
137 | else | ||
138 | return false, "Failed copying "..src.." to "..dest | ||
139 | end | ||
140 | end | ||
141 | |||
142 | --- Recursively copy the contents of a directory. | ||
143 | -- @param src string: Pathname of source | ||
144 | -- @param dest string: Pathname of destination | ||
145 | -- @return boolean or (boolean, string): true on success, false on failure, | ||
146 | -- plus an error message. | ||
147 | function copy_contents(src, dest) | ||
148 | assert(src and dest) | ||
149 | if fs_execute_string("cp -a "..src.."\\*.* "..fs_Q(dest).." 1> NUL 2> NUL") then | ||
150 | return true | ||
151 | else | ||
152 | return false, "Failed copying "..src.." to "..dest | ||
153 | end | ||
154 | end | ||
155 | |||
156 | --- Delete a file or a directory and all its contents. | ||
157 | -- For safety, this only accepts absolute paths. | ||
158 | -- @param arg string: Pathname of source | ||
159 | -- @return boolean: true on success, false on failure. | ||
160 | function delete(arg) | ||
161 | assert(arg) | ||
162 | assert(arg:match("^[\a-zA-Z]?:?[\\/]")) | ||
163 | fs_execute("chmod a+rw -R ", arg) | ||
164 | return fs_execute_string("rm -rf " .. fs_Q(arg) .. " 1> NUL 2> NUL") | ||
165 | end | ||
166 | |||
167 | --- List the contents of a directory. | ||
168 | -- @param at string or nil: directory to list (will be the current | ||
169 | -- directory if none is given). | ||
170 | -- @return table: an array of strings with the filenames representing | ||
171 | -- the contents of a directory. | ||
172 | function list_dir(at) | ||
173 | assert(type(at) == "string" or not at) | ||
174 | if not at then | ||
175 | at = fs_current_dir() | ||
176 | end | ||
177 | if not fs_is_dir(at) then | ||
178 | return {} | ||
179 | end | ||
180 | local result = {} | ||
181 | local pipe = io.popen(command_at(at, "ls")) | ||
182 | for file in pipe:lines() do | ||
183 | table.insert(result, file) | ||
184 | end | ||
185 | pipe:close() | ||
186 | |||
187 | return result | ||
188 | end | ||
189 | |||
190 | --- Recursively scan the contents of a directory. | ||
191 | -- @param at string or nil: directory to scan (will be the current | ||
192 | -- directory if none is given). | ||
193 | -- @return table: an array of strings with the filenames representing | ||
194 | -- the contents of a directory. Paths are returned with forward slashes. | ||
195 | function find(at) | ||
196 | assert(type(at) == "string" or not at) | ||
197 | if not at then | ||
198 | at = fs_current_dir() | ||
199 | end | ||
200 | if not fs_is_dir(at) then | ||
201 | return {} | ||
202 | end | ||
203 | local result = {} | ||
204 | local pipe = io.popen(command_at(at, "find 2> NUL")) | ||
205 | for file in pipe:lines() do | ||
206 | -- Windows find is a bit different | ||
207 | if file:sub(1,2)==".\\" then file=file:sub(3) end | ||
208 | if file ~= "." then | ||
209 | table.insert(result, (file:gsub("\\", "/"))) | ||
210 | end | ||
211 | end | ||
212 | return result | ||
213 | end | ||
214 | |||
215 | |||
216 | --- Download a remote file. | ||
217 | -- @param url string: URL to be fetched. | ||
218 | -- @param filename string or nil: this function attempts to detect the | ||
219 | -- resulting local filename of the remote file as the basename of the URL; | ||
220 | -- if that is not correct (due to a redirection, for example), the local | ||
221 | -- filename can be given explicitly as this second argument. | ||
222 | -- @return boolean: true on success, false on failure. | ||
223 | function download(url, filename) | ||
224 | assert(type(url) == "string") | ||
225 | assert(type(filename) == "string" or not filename) | ||
226 | local wget_cmd = "wget --user-agent="..cfg.user_agent.." --quiet --continue " | ||
227 | |||
228 | if filename then | ||
229 | return fs_execute(wget_cmd.." --output-document ", filename, url) | ||
230 | else | ||
231 | return fs_execute(wget_cmd, url) | ||
232 | end | ||
233 | end | ||
234 | |||
235 | --- Strip the last extension of a filename. | 25 | --- Strip the last extension of a filename. |
236 | -- Example: "foo.tar.gz" becomes "foo.tar". | 26 | -- Example: "foo.tar.gz" becomes "foo.tar". |
237 | -- If filename has no dots, returns it unchanged. | 27 | -- If filename has no dots, returns it unchanged. |
@@ -243,55 +33,6 @@ local function strip_extension(filename) | |||
243 | return (filename:gsub("%.[^.]+$", "")) or filename | 33 | return (filename:gsub("%.[^.]+$", "")) or filename |
244 | end | 34 | end |
245 | 35 | ||
246 | --- Uncompress gzip file. | ||
247 | -- @param archive string: Filename of archive. | ||
248 | -- @return boolean : success status | ||
249 | local function gunzip(archive) | ||
250 | local cmd = fs_execute("gunzip -h 1>NUL 2>NUL") and 'gunzip' or | ||
251 | fs_execute("gzip -h 1>NUL 2>NUL") and 'gzip -d' | ||
252 | local ok = fs_execute(cmd, archive) | ||
253 | return ok | ||
254 | end | ||
255 | |||
256 | --- Unpack an archive. | ||
257 | -- Extract the contents of an archive, detecting its format by | ||
258 | -- filename extension. | ||
259 | -- @param archive string: Filename of archive. | ||
260 | -- @return boolean or (boolean, string): true on success, false and an error message on failure. | ||
261 | function unpack_archive(archive) | ||
262 | assert(type(archive) == "string") | ||
263 | |||
264 | local ok | ||
265 | if archive:match("%.tar%.gz$") then | ||
266 | ok = gunzip(archive) | ||
267 | if ok then | ||
268 | ok = fs_execute("tar -xf ", strip_extension(archive)) | ||
269 | end | ||
270 | elseif archive:match("%.tgz$") then | ||
271 | ok = gunzip(archive) | ||
272 | if ok then | ||
273 | ok = fs_execute("tar -xf ", strip_extension(archive)..".tar") | ||
274 | end | ||
275 | elseif archive:match("%.tar%.bz2$") then | ||
276 | ok = fs_execute("bunzip2 ", archive) | ||
277 | if ok then | ||
278 | ok = fs_execute("tar -xf ", strip_extension(archive)) | ||
279 | end | ||
280 | elseif archive:match("%.zip$") then | ||
281 | ok = fs_execute("unzip ", archive) | ||
282 | elseif archive:match("%.lua$") or archive:match("%.c$") then | ||
283 | -- Ignore .lua and .c files; they don't need to be extracted. | ||
284 | return true | ||
285 | else | ||
286 | local ext = archive:match(".*(%..*)") | ||
287 | return false, "Unrecognized filename extension "..(ext or "") | ||
288 | end | ||
289 | if not ok then | ||
290 | return false, "Failed extracting "..archive | ||
291 | end | ||
292 | return true | ||
293 | end | ||
294 | |||
295 | --- Return an absolute pathname from a potentially relative one. | 36 | --- Return an absolute pathname from a potentially relative one. |
296 | -- @param pathname string: pathname to convert. | 37 | -- @param pathname string: pathname to convert. |
297 | -- @param relative_to string or nil: path to prepend when making | 38 | -- @param relative_to string or nil: path to prepend when making |
@@ -302,7 +43,7 @@ function absolute_name(pathname, relative_to) | |||
302 | assert(type(pathname) == "string") | 43 | assert(type(pathname) == "string") |
303 | assert(type(relative_to) == "string" or not relative_to) | 44 | assert(type(relative_to) == "string" or not relative_to) |
304 | 45 | ||
305 | relative_to = relative_to or fs_current_dir() | 46 | relative_to = relative_to or fs.current_dir() |
306 | if pathname:match("^[\.a-zA-Z]?:?[\\/]") then | 47 | if pathname:match("^[\.a-zA-Z]?:?[\\/]") then |
307 | return pathname | 48 | return pathname |
308 | else | 49 | else |
@@ -344,7 +85,7 @@ function is_actual_binary(name) | |||
344 | end | 85 | end |
345 | 86 | ||
346 | function copy_binary(filename, dest) | 87 | function copy_binary(filename, dest) |
347 | local ok, err = fs_copy(filename, dest) | 88 | local ok, err = fs.copy(filename, dest) |
348 | if not ok then | 89 | if not ok then |
349 | return nil, err | 90 | return nil, err |
350 | end | 91 | end |
diff --git a/src/luarocks/manif_core.lua b/src/luarocks/manif_core.lua index 941c569d..d1eb4ebb 100644 --- a/src/luarocks/manif_core.lua +++ b/src/luarocks/manif_core.lua | |||
@@ -1,5 +1,6 @@ | |||
1 | 1 | ||
2 | --- Core functions for querying manifest files. | 2 | --- Core functions for querying manifest files. |
3 | -- This module requires no specific 'fs' functionality. | ||
3 | module("luarocks.manif_core", package.seeall) | 4 | module("luarocks.manif_core", package.seeall) |
4 | 5 | ||
5 | local persist = require("luarocks.persist") | 6 | local persist = require("luarocks.persist") |
diff --git a/src/luarocks/tools/zip.lua b/src/luarocks/tools/zip.lua index 621beae1..18ad967e 100644 --- a/src/luarocks/tools/zip.lua +++ b/src/luarocks/tools/zip.lua | |||
@@ -209,9 +209,9 @@ function zip(zipfile, ...) | |||
209 | 209 | ||
210 | local ok, err | 210 | local ok, err |
211 | for _, file in pairs({...}) do | 211 | for _, file in pairs({...}) do |
212 | if fs_is_dir(file) then | 212 | if fs.is_dir(file) then |
213 | for _, file in pairs(fs_find(file)) do | 213 | for _, file in pairs(fs.find(file)) do |
214 | if fs_is_file(file) then | 214 | if fs.is_file(file) then |
215 | ok, err = add_to_zip(file) | 215 | ok, err = add_to_zip(file) |
216 | if not ok then break end | 216 | if not ok then break end |
217 | end | 217 | end |