package building infrastructure

This commit is contained in:
Izaya 2020-06-06 18:37:32 +10:00
parent d1f166425b
commit 9e4464e2fa
4 changed files with 275 additions and 0 deletions

5
buildall.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
for dir in $(find -maxdepth 1 -not -path '*/\.*' -not -path '\.' -type d); do
echo lua makepkg.lua "$dir" "$1" "$(git rev-parse --short HEAD)"
lua makepkg.lua "$dir" "$1" "$(git rev-parse --short HEAD)"
done

123
lzss.lua Normal file
View File

@ -0,0 +1,123 @@
--[[----------------------------------------------------------------------------
LZSS - encoder / decoder
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
--]]----------------------------------------------------------------------------
--------------------------------------------------------------------------------
local M = {}
local string, table = string, table
--------------------------------------------------------------------------------
local POS_BITS = 12
local LEN_BITS = 16 - POS_BITS
local POS_SIZE = 1 << POS_BITS
local LEN_SIZE = 1 << LEN_BITS
local LEN_MIN = 3
--------------------------------------------------------------------------------
function M.compress(input)
local offset, output = 1, {}
local window = ''
local function search()
for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
local str = string.sub(input, offset, offset + i - 1)
local pos = string.find(window, str, 1, true)
if pos then
return pos, str
end
end
end
while offset <= #input do
local flags, buffer = 0, {}
for i = 0, 7 do
if offset <= #input then
local pos, str = search()
if pos and #str >= LEN_MIN then
local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
buffer[#buffer + 1] = string.pack('>I2', tmp)
else
flags = flags | (1 << i)
str = string.sub(input, offset, offset)
buffer[#buffer + 1] = str
end
window = string.sub(window .. str, -POS_SIZE)
offset = offset + #str
else
break
end
end
if #buffer > 0 then
output[#output + 1] = string.char(flags)
output[#output + 1] = table.concat(buffer)
end
end
return table.concat(output)
end
--------------------------------------------------------------------------------
function M.decompress(input)
local offset, output = 1, {}
local window = ''
while offset <= #input do
local flags = string.byte(input, offset)
offset = offset + 1
for i = 1, 8 do
local str = nil
if (flags & 1) ~= 0 then
if offset <= #input then
str = string.sub(input, offset, offset)
offset = offset + 1
end
else
if offset + 1 <= #input then
local tmp = string.unpack('>I2', input, offset)
offset = offset + 2
local pos = (tmp >> LEN_BITS) + 1
local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
str = string.sub(window, pos, pos + len - 1)
end
end
flags = flags >> 1
if str then
output[#output + 1] = str
window = string.sub(window .. str, -POS_SIZE)
end
end
end
return table.concat(output)
end
return M

97
makepkg.lua Normal file
View File

@ -0,0 +1,97 @@
local serial = require "serialization"
local w, lzss = pcall(require,"lzss")
if not w then lzss = nil end
local tArgs = {...}
local fsnames = {"lfs","luafilesystem","filesystem"}
local w, fs
for k,v in pairs(fsnames) do
w,fs = pcall(require,v)
if w then break end
end
if not w then error("luafilesystem not detected") end
local function cint(n,l)
local t={}
for i = 0, 7 do
t[i+1] = (n >> (i * 8)) & 0xFF
end
return string.reverse(string.char(table.unpack(t)):sub(1,l))
end
local function genHeader(fname,len)
return string.format("%s%s%s",cint(fname:len(),2),fname,cint(len,2))
end
local function fnormalize(path)
local rt = {}
for segment in path:gmatch("[^/]+") do
if segment ~= "." and segment ~= ".." then
rt[#rt+1] = segment
end
end
return table.concat(rt,"/")
end
local dirs, files = {tArgs[1]},{}
for _,dir in ipairs(dirs) do
for file in fs.dir(dir) do
if file == "." or file == ".." then
elseif fs.attributes(dir.."/"..file).mode == "directory" then
dirs[#dirs+1] = dir.."/"..file
elseif file ~= "package.cfg" then
files[#files+1] = dir.."/"..file
end
end
end
local f = io.open(tArgs[1].."/package.cfg","rb")
if not f then error("no package.cfg in source") end
local pkginfo = serial.unserialize(f:read("*a"))
f:close()
local outpath = tArgs[2].."/"..tArgs[1]..".mtar"
local of = io.open(outpath,"wb")
for k,v in ipairs(files) do
local f = io.open(v,"rb")
if f then
local content = f:read("*a")
f:close()
of:write(genHeader(fnormalize(v:sub(tArgs[1]:len()+1)),content:len()))
of:write(content)
end
end
of:write(string.char(0):rep(2))
of:close()
if lzss then
print("Compressing "..outpath.." to "..outpath..".lss")
local f = io.open(outpath,"rb")
local of = io.open(outpath..".lss","wb")
while true do
local b = f:read(4096)
if not b or b:len() < 1 then break end
b = lzss.compress(b)
of:write(b)
end
f:close()
of:close()
outpath = outpath .. ".lss"
pkginfo.compressed = true
end
pkginfo.filename = fnormalize(outpath:sub(tArgs[2]:len()+1))
pkginfo.version = tArgs[3]
local repo = {}
local f = io.open(tArgs[2].."/packages.cfg","rb")
if f then
repo = serial.unserialize(f:read("*a")) or {}
f:close()
end
repo[tArgs[1]] = pkginfo
local f = io.open(tArgs[2].."/packages.cfg","wb")
if f then
f:write(serial.serialize(repo))
f:close()
end

50
serialization.lua Normal file
View File

@ -0,0 +1,50 @@
local serial = {}
local local_pairs=function(tbl)
local mt=getmetatable(tbl)
return (mt and mt.__pairs or pairs)(tbl)
end
function serial.serialize(value,af) -- boolean -- string -- serialize *value* into a string. If *af* is true, allow functions. This breaks unserialization.
local kw={["and"]=true,["break"]=true,["do"]=true,["else"]=true,["elseif"]=true,["end"]=true,["false"]=true,["for"]=true,["function"]=true,["goto"]=true,["if"]=true,["in"]=true,["local"]=true,["nil"]=true,["not"]=true,["or"]=true,["repeat"]=true,["return"]=true,["then"]=true,["true"]=true,["until"]=true,["while"]=true}
local id="^[%a_][%w_]*$"
local ts={}
local function s(v,l)
local t=type(v)
if t=="nil" then return "nil"
elseif t=="boolean" then return v and "true" or "false"
elseif t=="number" then
if v~=v then return "0/0"
elseif v==math.huge then return "math.huge"
elseif v==-math.huge then return "-math.huge"
else return tostring(v) end
elseif t=="string" then return string.format("%q",v):gsub("\\\n","\\n")
elseif t=="table" then
if ts[v] then error("tcyc") end
ts[v]=true
local i,r=1, nil
local f=table.pack(local_pairs(v))
for k,v in table.unpack(f) do
if r then r=r..","..(("\n"..string.rep(" ",l)) or "")
else r="{" end
local tk=type(k)
if tk=="number" and k==i then
i=i+1
r=r..s(v,l+1)
else
if tk == "string" and not kw[k] and string.match(k,id) then r=r..k
else r=r.."["..s(k,l+1).."]" end
r=r.."="..s(v,l+1) end end
ts[v]=nil
return (r or "{").."}"
elseif t=="function" and af then
return tostring(v)
else error("ut "..t) end end
return s(value, 1)
end
function serial.unserialize(data) -- string -- -- return *data*, but unserialized
local result, reason = load("return " .. data, "=data", _, {math={huge=math.huge}})
if not result then return nil, reason end
local ok, output = pcall(result)
if not ok then return nil, output end
return output
end
return serial