mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
* Installs luarocks WITH it's executable (easy to install other rocks if necessary) * Use Lua supplied with luarocks * Create Utils/luadocumentor.bat, which works with RELATIVE PATH ! -> Everybody can generate the doc * Updated launch files accordingly
157 lines
5.2 KiB
Lua
157 lines
5.2 KiB
Lua
|
|
--- Common fs operations implemented with third-party tools.
|
|
local tools = {}
|
|
|
|
local fs = require("luarocks.fs")
|
|
local dir = require("luarocks.dir")
|
|
local cfg = require("luarocks.cfg")
|
|
|
|
local vars = cfg.variables
|
|
|
|
local dir_stack = {}
|
|
|
|
--- Obtain current directory.
|
|
-- Uses the module's internal directory stack.
|
|
-- @return string: the absolute pathname of the current directory.
|
|
function tools.current_dir()
|
|
local current = cfg.cache_pwd
|
|
if not current then
|
|
local pipe = io.popen(fs.quiet_stderr(fs.Q(vars.PWD)))
|
|
current = pipe:read("*l")
|
|
pipe:close()
|
|
cfg.cache_pwd = current
|
|
end
|
|
for _, directory in ipairs(dir_stack) do
|
|
current = fs.absolute_name(directory, current)
|
|
end
|
|
return current
|
|
end
|
|
|
|
--- Change the current directory.
|
|
-- Uses the module's internal directory stack. This does not have exact
|
|
-- semantics of chdir, as it does not handle errors the same way,
|
|
-- but works well for our purposes for now.
|
|
-- @param directory string: The directory to switch to.
|
|
-- @return boolean or (nil, string): true if successful, (nil, error message) if failed.
|
|
function tools.change_dir(directory)
|
|
assert(type(directory) == "string")
|
|
if fs.is_dir(directory) then
|
|
table.insert(dir_stack, directory)
|
|
return true
|
|
end
|
|
return nil, "directory not found: "..directory
|
|
end
|
|
|
|
--- Change directory to root.
|
|
-- Allows leaving a directory (e.g. for deleting it) in
|
|
-- a crossplatform way.
|
|
function tools.change_dir_to_root()
|
|
table.insert(dir_stack, "/")
|
|
end
|
|
|
|
--- Change working directory to the previous in the directory stack.
|
|
function tools.pop_dir()
|
|
local directory = table.remove(dir_stack)
|
|
return directory ~= nil
|
|
end
|
|
|
|
--- Run the given command.
|
|
-- The command is executed in the current directory in the directory stack.
|
|
-- @param cmd string: No quoting/escaping is applied to the command.
|
|
-- @return boolean: true if command succeeds (status code 0), false
|
|
-- otherwise.
|
|
function tools.execute_string(cmd)
|
|
local current = fs.current_dir()
|
|
if not current then return false end
|
|
cmd = fs.command_at(current, cmd)
|
|
local code = os.execute(cmd)
|
|
if code == 0 or code == true then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
--- Internal implementation function for fs.dir.
|
|
-- Yields a filename on each iteration.
|
|
-- @param at string: directory to list
|
|
-- @return nil
|
|
function tools.dir_iterator(at)
|
|
local pipe = io.popen(fs.command_at(at, fs.Q(vars.LS)))
|
|
for file in pipe:lines() do
|
|
if file ~= "." and file ~= ".." then
|
|
coroutine.yield(file)
|
|
end
|
|
end
|
|
pipe:close()
|
|
end
|
|
|
|
--- Download a remote file.
|
|
-- @param url string: URL to be fetched.
|
|
-- @param filename string or nil: this function attempts to detect the
|
|
-- resulting local filename of the remote file as the basename of the URL;
|
|
-- if that is not correct (due to a redirection, for example), the local
|
|
-- filename can be given explicitly as this second argument.
|
|
-- @return (boolean, string): true and the filename on success,
|
|
-- false and the error message on failure.
|
|
function tools.use_downloader(url, filename, cache)
|
|
assert(type(url) == "string")
|
|
assert(type(filename) == "string" or not filename)
|
|
|
|
filename = fs.absolute_name(filename or dir.base_name(url))
|
|
|
|
local ok
|
|
if cfg.downloader == "wget" then
|
|
local wget_cmd = fs.Q(vars.WGET).." "..vars.WGETNOCERTFLAG.." --no-cache --user-agent=\""..cfg.user_agent.." via wget\" --quiet "
|
|
if cfg.connection_timeout and cfg.connection_timeout > 0 then
|
|
wget_cmd = wget_cmd .. "--timeout="..tonumber(cfg.connection_timeout).." --tries=1 "
|
|
end
|
|
if cache then
|
|
-- --timestamping is incompatible with --output-document,
|
|
-- but that's not a problem for our use cases.
|
|
fs.change_dir(dir.dir_name(filename))
|
|
ok = fs.execute_quiet(wget_cmd.." --timestamping ", url)
|
|
fs.pop_dir()
|
|
elseif filename then
|
|
ok = fs.execute_quiet(wget_cmd.." --output-document ", filename, url)
|
|
else
|
|
ok = fs.execute_quiet(wget_cmd, url)
|
|
end
|
|
elseif cfg.downloader == "curl" then
|
|
local curl_cmd = fs.Q(vars.CURL).." "..vars.CURLNOCERTFLAG.." -f -L --user-agent \""..cfg.user_agent.." via curl\" "
|
|
if cfg.connection_timeout and cfg.connection_timeout > 0 then
|
|
curl_cmd = curl_cmd .. "--connect-timeout "..tonumber(cfg.connection_timeout).." "
|
|
end
|
|
ok = fs.execute_string(fs.quiet_stderr(curl_cmd..fs.Q(url).." > "..fs.Q(filename)))
|
|
end
|
|
if ok then
|
|
return true, filename
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
local md5_cmd = {
|
|
md5sum = fs.Q(vars.MD5SUM),
|
|
openssl = fs.Q(vars.OPENSSL).." md5",
|
|
md5 = fs.Q(vars.MD5),
|
|
}
|
|
|
|
--- Get the MD5 checksum for a file.
|
|
-- @param file string: The file to be computed.
|
|
-- @return string: The MD5 checksum or nil + message
|
|
function tools.get_md5(file)
|
|
local cmd = md5_cmd[cfg.md5checker]
|
|
if not cmd then return nil, "no MD5 checker command configured" end
|
|
local pipe = io.popen(cmd.." "..fs.Q(fs.absolute_name(file)))
|
|
local computed = pipe:read("*a")
|
|
pipe:close()
|
|
if computed then
|
|
computed = computed:match("("..("%x"):rep(32)..")")
|
|
end
|
|
if computed then return computed end
|
|
return nil, "Failed to compute MD5 hash for file "..tostring(fs.absolute_name(file))
|
|
end
|
|
|
|
return tools
|