152 lines
5.3 KiB
Lua
152 lines
5.3 KiB
Lua
|
-- System functions
|
||
|
|
||
|
module ("dist.utils", package.seeall)
|
||
|
|
||
|
local sys = require "dist.sys"
|
||
|
|
||
|
-- Returns a deep copy of 'table' with reference to the same metadata table.
|
||
|
-- Source: http://lua-users.org/wiki/CopyTable
|
||
|
function deepcopy(object)
|
||
|
local lookup_table = {}
|
||
|
local function _copy(object)
|
||
|
if type(object) ~= "table" then
|
||
|
return object
|
||
|
elseif lookup_table[object] then
|
||
|
return lookup_table[object]
|
||
|
end
|
||
|
local new_table = {}
|
||
|
lookup_table[object] = new_table
|
||
|
for index, value in pairs(object) do
|
||
|
new_table[_copy(index)] = _copy(value)
|
||
|
end
|
||
|
return setmetatable(new_table, getmetatable(object))
|
||
|
end
|
||
|
return _copy(object)
|
||
|
end
|
||
|
|
||
|
-- Return deep copy of table 'array', containing only items for which 'predicate_fn' returns true.
|
||
|
function filter(array, predicate_fn)
|
||
|
assert(type(array) == "table", "utils.filter: Argument 'array' is not a table.")
|
||
|
assert(type(predicate_fn) == "function", "utils.filter: Argument 'predicate_fn' is not a function.")
|
||
|
local filtered = {}
|
||
|
for _,v in pairs(array) do
|
||
|
if predicate_fn(v) == true then table.insert(filtered, deepcopy(v)) end
|
||
|
end
|
||
|
return filtered
|
||
|
end
|
||
|
|
||
|
-- Return deep copy of table 'array', sorted according to the 'compare_fn' function.
|
||
|
function sort(array, compare_fn)
|
||
|
assert(type(array) == "table", "utils.sort: Argument 'array' is not a table.")
|
||
|
assert(type(compare_fn) == "function", "utils.sort: Argument 'compare_fn' is not a function.")
|
||
|
local sorted = deepcopy(array)
|
||
|
table.sort(sorted, compare_fn)
|
||
|
return sorted
|
||
|
end
|
||
|
|
||
|
-- Return whether the 'value' is in the table 'tbl'.
|
||
|
function contains(tbl, value)
|
||
|
assert(type(tbl) == "table", "utils.contains: Argument 'tbl' is not a table.")
|
||
|
for _,v in pairs(tbl) do
|
||
|
if v == value then return true end
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
-- Return single line string consisting of values in 'tbl' separated by comma.
|
||
|
-- Used for printing the dependencies/provides/conflicts.
|
||
|
function table_tostring(tbl, label)
|
||
|
assert(type(tbl) == "table", "utils.table_tostring: Argument 'tbl' is not a table.")
|
||
|
local str = ""
|
||
|
for k,v in pairs(tbl) do
|
||
|
if type(v) == "table" then
|
||
|
str = str .. table_tostring(v, k)
|
||
|
else
|
||
|
if label ~= nil then
|
||
|
str = str .. tostring(v) .. " [" .. tostring(label) .. "]" .. ", "
|
||
|
else
|
||
|
str = str .. tostring(v) .. ", "
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
return str
|
||
|
end
|
||
|
|
||
|
-- Return table made up from values of the string, separated by separator.
|
||
|
function make_table(str, separator)
|
||
|
assert(type(str) == "string", "utils.make_table: Argument 'str' is not a string.")
|
||
|
assert(type(separator) == "string", "utils.make_table: Argument 'separator' is not a string.")
|
||
|
|
||
|
local tbl = {}
|
||
|
for val in str:gmatch("(.-)" .. separator) do
|
||
|
table.insert(tbl, val)
|
||
|
end
|
||
|
local last_val = str:gsub(".-" .. separator, "")
|
||
|
if last_val and last_val ~= "" then
|
||
|
table.insert(tbl, last_val)
|
||
|
end
|
||
|
return tbl
|
||
|
end
|
||
|
|
||
|
-- Return whether the 'cache_timeout' for 'file' has expired.
|
||
|
function cache_timeout_expired(cache_timeout, file)
|
||
|
assert(type(cache_timeout) == "number", "utils.cache_timeout_expired: Argument 'cache_timeout' is not a number.")
|
||
|
assert(type(file) == "string", "utils.cache_timeout_expired: Argument 'file' is not a string.")
|
||
|
return sys.last_modification_time(file) + cache_timeout < sys.current_time()
|
||
|
end
|
||
|
|
||
|
-- Return the string 'str', with all magic (pattern) characters escaped.
|
||
|
function escape_magic(str)
|
||
|
assert(type(str) == "string", "utils.escape: Argument 'str' is not a string.")
|
||
|
local escaped = str:gsub('[%-%.%+%[%]%(%)%^%%%?%*%^%$]','%%%1')
|
||
|
return escaped
|
||
|
end
|
||
|
|
||
|
-- Return the boolean representation of an 'arg'.
|
||
|
function to_boolean(arg)
|
||
|
return not not arg
|
||
|
end
|
||
|
|
||
|
|
||
|
math.randomseed(os.time())
|
||
|
|
||
|
-- Return pseudo-random number in range [0, 1], [1, n] or [n, m].
|
||
|
function rand(...)
|
||
|
return math.random(...)
|
||
|
end
|
||
|
|
||
|
-- Perform check of system dependency, which isn't provided in the LuaDist
|
||
|
-- installation itself and if it is missing, print instructions how
|
||
|
-- to install it. The 'command' is used for testing, 'name' when printing
|
||
|
-- information to the user.
|
||
|
function system_dependency_available(name, command)
|
||
|
assert(type(name) == "string", "utils.system_dependency_available: Argument 'name' is not a string.")
|
||
|
assert(type(command) == "string", "utils.system_dependency_available: Argument 'command' is not a string.")
|
||
|
|
||
|
if not sys.exec(command) then
|
||
|
print("Error: command '" .. name .. "' not found on system. See installation instructions at\nhttps://github.com/LuaDist/Repository/wiki/Installation-of-System-Dependencies")
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
-- Obtain LuaDist location by checking available package locations
|
||
|
function get_luadist_location()
|
||
|
local paths = {}
|
||
|
local path = package.path:gsub("([^;]+)", function(c) table.insert(paths, c) end)
|
||
|
|
||
|
for _, path in pairs(paths) do
|
||
|
if (sys.is_abs(path) and path:find("[/\\]lib[/\\]lua[/\\]%?.lua$")) then
|
||
|
-- Remove path to lib/lua
|
||
|
path = path:gsub("[/\\]lib[/\\]lua[/\\]%?.lua$", "")
|
||
|
-- Clean the path up a bit
|
||
|
path = path:gsub("[/\\]bin[/\\]%.[/\\]%.%.", "")
|
||
|
path = path:gsub("[/\\]bin[/\\]%.%.", "")
|
||
|
return path
|
||
|
end
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
|