feat: add ZipEntry:unixMode() to get unix mode values as octals

Updates tests, and makes the `tour` example display the perms instead of
the raw external attributes.
This commit is contained in:
Erica Marigold 2025-01-09 16:16:38 +00:00
parent 6c1f517b75
commit ecace02e7f
Signed by: DevComp
GPG key ID: 429EF1C337871656
3 changed files with 28 additions and 4 deletions

View file

@ -22,9 +22,9 @@ local function formatTree(tree: Tree): Tree<string>
local truncContents = content:gsub("\n", ""):sub(1, 100)
result[key] = string.format(
"(%d bytes), attrs: 0x%x, content: %s",
"(%d bytes), perms: %s, content: %s",
fileEntry.size,
fileEntry.attributes,
fileEntry.unixMode.perms,
truncContents .. (if #content > 100 then "..." else "")
)
end
@ -35,6 +35,7 @@ end
local tree: Tree = {}
type Tree<T = EntryData> = { [string]: T | Tree<T> }
type EntryData = {
unixMode: zip.UnixMode,
path: string,
size: number,
attributes: number,
@ -69,6 +70,7 @@ reader:walk(function(entry, depth)
current[name] = {}
else
current[name] = {
unixMode = assert(entry:unixMode(), "Not a unix file"),
path = entry:getPath(),
size = entry.size,
attributes = entry.attributes,

View file

@ -184,7 +184,7 @@ function ZipEntry.sanitizePath(self: ZipEntry): string
end
function ZipEntry.compressionEfficiency(self: ZipEntry): number?
if self.size == 0 or self.compressedSize == 0 then
if self.size == 0 or self.compressedSize == 0 then
return nil
end
@ -192,7 +192,25 @@ function ZipEntry.compressionEfficiency(self: ZipEntry): number?
return math.round(ratio * 100)
end
-- TODO: More methods for `ZipEntry`, handle octals and unix perms
function ZipEntry.isFile(self: ZipEntry): boolean
return not (self.isDirectory and self:isSymlink())
end
export type UnixMode = { perms: string, typeFlags: string }
function ZipEntry.unixMode(self: ZipEntry): UnixMode?
if self.versionMadeBy.os ~= "UNIX" then
return nil
end
local mode = bit32.rshift(self.attributes, 16)
local typeFlags = bit32.band(self.attributes, 0x1FF)
local perms = bit32.band(mode, 0x01FF)
return {
perms = string.format("0o%o", perms),
typeFlags = string.format("0o%o", typeFlags),
}
end
local ZipReader = {}
export type ZipReader = typeof(setmetatable({} :: ZipReaderInner, { __index = ZipReader }))

View file

@ -121,6 +121,10 @@ return function(test: typeof(frktest.test))
local entry = assert(zip:findEntry(assert(name)))
if entry.versionMadeBy.os == "UNIX" then
check.not_nil(entry:unixMode())
end
local ok, zipinfoResult = pcall(process.spawn, "zipinfo", { file, name })
if ok then
-- Errors can only occur when there is a non utf-8 file name, in which case