First Commit
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
-- path.lua -- minimal self-contained filesystem helpers for zeta-makepkg.
|
||||
--
|
||||
-- Deliberately avoids any external dependencies so the toolchain can run
|
||||
-- without Zeta installed. All subprocess calls use plain os.execute.
|
||||
|
||||
local path = {}
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- String helpers
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
-- Join path components with a single separator. The first non-empty
|
||||
-- component decides whether the result is absolute; later components are
|
||||
-- treated as plain name pieces even if they carry a leading slash.
|
||||
function path.join(...)
|
||||
local parts = {}
|
||||
local abs = false
|
||||
local first = true
|
||||
for i = 1, select("#", ...) do
|
||||
local part = tostring((select(i, ...)))
|
||||
if part == "/" then
|
||||
if first then abs = true end
|
||||
elseif part ~= "" then
|
||||
local p = part:gsub("^/+", ""):gsub("/+$", "")
|
||||
if p ~= "" then
|
||||
if first then abs = (part:match("^/") ~= nil) end
|
||||
parts[#parts + 1] = p
|
||||
end
|
||||
end
|
||||
first = false
|
||||
end
|
||||
if #parts == 0 then return "/" end
|
||||
local out = table.concat(parts, "/")
|
||||
if abs then out = "/" .. out end
|
||||
return out
|
||||
end
|
||||
|
||||
function path.is_abs(p)
|
||||
return p:match("^/") ~= nil
|
||||
end
|
||||
|
||||
function path.basename(p)
|
||||
p = p:gsub("/+$", "")
|
||||
return p:match("[^/]+$") or p
|
||||
end
|
||||
|
||||
function path.dirname(p)
|
||||
p = p:gsub("/+$", "")
|
||||
if p == "" then return "." end
|
||||
local d = p:match("^(.*)/[^/]+$")
|
||||
if not d then return "." end
|
||||
if d == "" then return "/" end
|
||||
return d
|
||||
end
|
||||
|
||||
-- Shell-quote a value for safe use in a command. Values containing only
|
||||
-- "safe" characters are returned as-is; everything else is single-quoted.
|
||||
function path.quote(s)
|
||||
if s == "" then return "''" end
|
||||
if s:match("^[%w%._%/+%-:=@,]+$") then return s end
|
||||
return "'" .. s:gsub("'", "'\\''") .. "'"
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Filesystem helpers
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
-- Run a shell command, streaming output to the parent. Returns true on
|
||||
-- exit status 0. Compatible with Lua 5.1 through 5.4.
|
||||
function path.run(cmd)
|
||||
local a, b, c = os.execute(cmd)
|
||||
if type(a) == "number" then return a == 0 end
|
||||
return a == true and b == "exit" and c == 0
|
||||
end
|
||||
|
||||
-- mkdir -p wrapper.
|
||||
function path.mkdir_p(dir)
|
||||
if dir == "" or dir == "/" then return true end
|
||||
return path.run("mkdir -p " .. path.quote(dir))
|
||||
end
|
||||
|
||||
-- True if a file or directory (or dangling symlink) exists.
|
||||
function path.exists(p)
|
||||
local f = io.open(p, "rb")
|
||||
if f then
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
return path.run("test -e " .. path.quote(p) .. " -o -L " .. path.quote(p))
|
||||
end
|
||||
|
||||
-- Package names must be tightly constrained (alphanumeric, dots, underscores,
|
||||
-- plus, hyphen). No slashes, no leading dots, no other special characters.
|
||||
function path.sanitize_name(name)
|
||||
if type(name) ~= "string" then return nil end
|
||||
if name == "" then return nil end
|
||||
if name:match("^%.") then return nil end
|
||||
if not name:match("^[%w%._+%-]+$") then return nil end
|
||||
return name
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
-- Download / tool detection
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
-- True if the given command is available on PATH.
|
||||
function path.have(cmd)
|
||||
local f = io.popen("command -v " .. cmd .. " 2>/dev/null")
|
||||
if not f then return false end
|
||||
local out = f:read("*l")
|
||||
f:close()
|
||||
return out ~= nil and out ~= ""
|
||||
end
|
||||
|
||||
-- Capture stdout of a command. Returns output string or nil on failure.
|
||||
function path.capture(cmd)
|
||||
local f = io.popen(cmd .. " 2>/dev/null")
|
||||
if not f then return nil end
|
||||
local out = f:read("*a")
|
||||
f:close()
|
||||
return out
|
||||
end
|
||||
|
||||
return path
|
||||
Reference in New Issue
Block a user