added repoinstaller, still need to write docs

This commit is contained in:
Izaya 2018-08-01 19:24:56 +10:00
parent 74417fab68
commit 2fa3af5170
1 changed files with 229 additions and 0 deletions

229
repoinstaller.lua Normal file
View File

@ -0,0 +1,229 @@
local serial = require "serialization"
local event = require "event"
local fs = require "filesystem"
local unicode = require "unicode"
local tArgs = {...}
local ipackages = {} -- installed packages
local rpath = tArgs[1] or install.from
local tpath = tArgs[2] or install.to
if tpath == "//" then
tpath = "/usr/"
end
tpath, rpath = fs.canonical(tpath), fs.canonical(rpath)
local fobj = io.open(rpath.."/master/programs.cfg","rb") -- read packages list from floppy
if not fobj then
error("installer disk not properly configured")
end
local packages = serial.unserialize(fobj:read("*a"))
fobj:close()
local function ripackages()
local fobj = io.open("/etc/opdata.svd","rb") -- attempt to read installed packages
if fobj then
ipackages = serial.unserialize(fobj:read("*a"))
fobj:close()
end
end
ripackages()
local function wipackages()
local fobj = io.open("/etc/opdata.svd","wb") -- attempt to read installed packages
if fobj then
fobj:write(serial.serialize(ipackages))
fobj:close()
end
end
local pkgmap = {} -- alphabetically sorted list of package names
for k,v in pairs(packages) do
pkgmap[#pkgmap+1] = k
end
table.sort(pkgmap)
local function clear()
io.write("\27[2J\27[H")
end
function info(pkg) -- shows info for pkg
clear()
print(string.format("%s - %s",pkg,packages[pkg].name))
print(packages[pkg].description)
if packages[pkg].files then
print("\nFiles:")
for k,v in pairs(packages[pkg].files) do
print(string.format("%s -> %s",k,v))
end
end
if packages[pkg].dependencies then
print("\nDependencies")
for k,v in pairs(packages[pkg].dependencies) do
print(" - "..k)
end
end
end
local preamble = false
local fobj = io.open(rpath.."/.info","rb") -- read the pre-inst screen
if fobj then
preamble = fobj:read("*a")
fobj:close()
end
if preamble then -- display pre-inst screen
clear()
if install.label then
print(install.label .. " installer")
end
print(preamble)
print("Press any key to continue.")
event.pull("key_down")
end
local selected = 1
local function drawmenu() -- draw the menu display - nothing but text and VT100 escape codes
clear()
if install.label then
print(install.label .. " installer")
end
for k,v in pairs(pkgmap) do
if k == selected then
io.write("\27[30;47m")
end
if packages[v].selected then
io.write(" "..unicode.char(0x25A0).." ")
else
io.write(" "..unicode.char(0x25A1).." ")
end
io.write(v)
print("\27[0m")
end
print("Use the arrow keys to navigate. (De)select options with space. View more info by pressing i, and quit by pressing q. Confirm with enter.")
end
--[[
Key codes:
0 208 down
0 200 up
13 28 enter
32 57 space
105 23 i
113 16 q
121 21 y
]]--
local run, install = true, true
while run do -- menu loop
drawmenu()
local _, _, ch, co = event.pull("key_down")
if ch == 13 and co == 28 then
run = false
elseif ch == 113 and co == 16 then
run = false
install = false
elseif ch == 105 and co == 23 then
info(pkgmap[selected])
print("\nPress any key to return to the menu.")
event.pull("key_down")
elseif ch == 0 and co == 208 then
selected = selected + 1
if selected > #pkgmap then
selected = #pkgmap
end
elseif ch == 0 and co == 200 then
selected = selected - 1
if selected < 1 then
selected = 1
end
elseif ch == 32 and co == 57 then
packages[pkgmap[selected]].selected = not packages[pkgmap[selected]].selected
end
end
clear()
if not install then -- pressed q
print("Aborted.")
return
end
local toinstall, postinstall = {}, {} -- table of commands to run after installation
print("Resolving dependencies...") -- build a table of what to install
for k,v in pairs(packages) do
if v.selected then
toinstall[k] = true
if v.dependencies then
for l,m in pairs(v.dependencies) do -- including dependencies
if not toinstall[l] then
print("Package "..k.." depends on "..l)
toinstall[l] = m
end
end
end
end
end
print("You have selected to install the following packages to "..tpath..":")
for k,v in pairs(toinstall) do
print(" - "..k)
end
print("Continue? [y/N] ")
_, _, _, co = event.pull("key_down")
if co ~= 21 then -- confirm they want the packages installed
print("Aborted.")
return
end
local function install(pkg,where) -- installs a package, pkg, to where
where = where or tpath
if type(where) ~= string then where = tpath end
print("Installing "..pkg.."...")
if packages[pkg] then
ipackages[pkg] = {}
print("Copying files...")
for l,m in pairs(packages[pkg].files) do
local lseg = fs.segments(l)
if m:sub(1,2) ~= "//" then
if not fs.exists(fs.canonical(where.."/"..m)) then
os.execute("mkdir "..fs.canonical(where.."/"..m))
end
os.execute("cp -v "..rpath.."/"..l.." "..fs.canonical(where.."/"..m))
ipackages[pkg][l] = fs.canonical(where.."/"..m).."/"..lseg[#lseg]
else
if not fs.exists(fs.canonical(m:sub(2))) then
os.execute("mkdir "..fs.canonical(m:sub(2)))
end
os.execute("cp -v "..rpath.."/"..l.." "..fs.canonical(m:sub(2)))
ipackages[pkg][l] = fs.canonical(m:sub(2)).."/"..lseg[#lseg]
end
end
if packages[pkg].postinstall then
for k,v in pairs(packages[pkg].postinstall) do
postinstall[#postinstall+1] = v
end
end
else
print("Package not on disk. Attempting to install via oppm.")
print("oppm install "..pkg.." "..where)
wipackages()
os.execute("oppm install "..pkg.." "..where)
ripackages()
end
wipackages()
end
for k,v in pairs(toinstall) do
install(k,v)
end
if #postinstall > 0 then
print("Running post-install commands...")
for k,v in pairs(postinstall) do
print(v)
os.execute(v)
end
end