v1.0.0 - Added Argentum as well as other major improvements and bugfixes.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
local agcfg = {
|
||||
["halyde"] = {
|
||||
["maindir"] = "",
|
||||
["version"] = "1.1.0",
|
||||
["description"] = "A universal, customizable and feature-packed operating system for OpenComputers.",
|
||||
["directories"] = {
|
||||
"halyde/apps",
|
||||
"halyde/apps/helpdb",
|
||||
"halyde/config",
|
||||
"halyde/core",
|
||||
"halyde/lib"
|
||||
},
|
||||
["files"] = {
|
||||
"init.lua",
|
||||
"halyde/apps/helpdb/cat.txt",
|
||||
"halyde/apps/helpdb/cd.txt",
|
||||
"halyde/apps/helpdb/clear.txt",
|
||||
"halyde/apps/helpdb/cp.txt",
|
||||
"halyde/apps/helpdb/default.txt",
|
||||
"halyde/apps/helpdb/echo.txt",
|
||||
"halyde/apps/helpdb/fetch.txt",
|
||||
"halyde/apps/helpdb/help.txt",
|
||||
"halyde/apps/helpdb/ls.txt",
|
||||
"halyde/apps/helpdb/lua.txt",
|
||||
"halyde/apps/helpdb/mv.txt",
|
||||
"halyde/apps/helpdb/rm.txt",
|
||||
"halyde/apps/cat.lua",
|
||||
"halyde/apps/cd.lua",
|
||||
"halyde/apps/clear.lua",
|
||||
"halyde/apps/cp.lua",
|
||||
"halyde/apps/download.lua",
|
||||
"halyde/apps/echo.lua",
|
||||
"halyde/apps/fetch.lua",
|
||||
"halyde/apps/help.lua",
|
||||
"halyde/apps/ls.lua",
|
||||
"halyde/apps/lua.lua",
|
||||
"halyde/apps/mv.lua",
|
||||
"halyde/apps/rm.lua",
|
||||
"halyde/config/shell.cfg",
|
||||
"halyde/config/startupapps.cfg",
|
||||
"halyde/core/boot.lua",
|
||||
"halyde/core/cormgr.lua",
|
||||
"halyde/core/datatools.lua",
|
||||
"halyde/core/evmgr.lua",
|
||||
"halyde/core/fullkb.lua",
|
||||
"halyde/core/shell.lua",
|
||||
"halyde/core/termlib.lua",
|
||||
"halyde/lib/component.lua",
|
||||
"halyde/lib/event.lua",
|
||||
"halyde/lib/filesystem.lua",
|
||||
"halyde/lib/raster.lua"
|
||||
}
|
||||
},
|
||||
["argentum"] = {
|
||||
["maindir"] = "",
|
||||
["version"] = "1.0.0",
|
||||
["description"] = "The default package manager for Halyde.",
|
||||
["directories"] = {
|
||||
"argentum",
|
||||
"argentum/store"
|
||||
},
|
||||
["files"] = {
|
||||
"argentum/registry.cfg",
|
||||
"halyde/apps/argentum.lua",
|
||||
"halyde/apps/helpdb/argentum.txt"
|
||||
}
|
||||
},
|
||||
["edit"] = {
|
||||
["maindir"] = "",
|
||||
["version"] = "1.1.0",
|
||||
["description"] = "The default text editor for Halyde.",
|
||||
["files"] = {
|
||||
"halyde/apps/edit.lua",
|
||||
"halyde/apps/helpdb/edit.txt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return agcfg
|
||||
@@ -0,0 +1,7 @@
|
||||
local agregistry = {
|
||||
["halyde"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
|
||||
["edit"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/",
|
||||
["argentum"] = "https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/"
|
||||
}
|
||||
|
||||
return agregistry
|
||||
@@ -0,0 +1,6 @@
|
||||
Aargentum/registry.cfg
|
||||
Ahalyde/apps/argentum.lua
|
||||
Ahalyde/apps/helpdb/argentum.txt
|
||||
V1.0.0
|
||||
Aargentum/
|
||||
Aargentum/store/
|
||||
@@ -0,0 +1,3 @@
|
||||
Ahalyde/apps/edit.lua
|
||||
Ahalyde/apps/helpdb/edit.txt
|
||||
V1.1.0
|
||||
@@ -0,0 +1,45 @@
|
||||
Ainit.lua
|
||||
Ahalyde/apps/helpdb/cat.txt
|
||||
Ahalyde/apps/helpdb/cd.txt
|
||||
Ahalyde/apps/helpdb/clear.txt
|
||||
Ahalyde/apps/helpdb/cp.txt
|
||||
Ahalyde/apps/helpdb/default.txt
|
||||
Ahalyde/apps/helpdb/echo.txt
|
||||
Ahalyde/apps/helpdb/fetch.txt
|
||||
Ahalyde/apps/helpdb/help.txt
|
||||
Ahalyde/apps/helpdb/ls.txt
|
||||
Ahalyde/apps/helpdb/lua.txt
|
||||
Ahalyde/apps/helpdb/mv.txt
|
||||
Ahalyde/apps/helpdb/rm.txt
|
||||
Ahalyde/apps/cat.lua
|
||||
Ahalyde/apps/cd.lua
|
||||
Ahalyde/apps/clear.lua
|
||||
Ahalyde/apps/cp.lua
|
||||
Ahalyde/apps/download.lua
|
||||
Ahalyde/apps/echo.lua
|
||||
Ahalyde/apps/fetch.lua
|
||||
Ahalyde/apps/help.lua
|
||||
Ahalyde/apps/ls.lua
|
||||
Ahalyde/apps/lua.lua
|
||||
Ahalyde/apps/mv.lua
|
||||
Ahalyde/apps/rm.lua
|
||||
Ahalyde/config/shell.cfg
|
||||
Ahalyde/config/startupapps.cfg
|
||||
Ahalyde/core/boot.lua
|
||||
Ahalyde/core/cormgr.lua
|
||||
Ahalyde/core/datatools.lua
|
||||
Ahalyde/core/evmgr.lua
|
||||
Ahalyde/core/fullkb.lua
|
||||
Ahalyde/core/shell.lua
|
||||
Ahalyde/core/termlib.lua
|
||||
Ahalyde/lib/component.lua
|
||||
Ahalyde/lib/event.lua
|
||||
Ahalyde/lib/filesystem.lua
|
||||
Ahalyde/lib/raster.lua"
|
||||
V1.0.0
|
||||
Ahalyde/
|
||||
Ahalyde/apps/
|
||||
Ahalyde/apps/helpdb/
|
||||
Ahalyde/config/
|
||||
Ahalyde/core/
|
||||
Ahalyde/lib/
|
||||
@@ -0,0 +1,550 @@
|
||||
local packages = {...}
|
||||
local command = packages[1]
|
||||
table.remove(packages, 1)
|
||||
local fs = import("filesystem")
|
||||
local agReg = import("/argentum/registry.cfg")
|
||||
if not command then
|
||||
shell.run("help argentum")
|
||||
return
|
||||
end
|
||||
if not component.list("internet")() then
|
||||
print("\27[91mThis program requires an internet card to run.")
|
||||
return
|
||||
end
|
||||
local internet = component.proxy(component.list("internet")())
|
||||
local source
|
||||
if table.find(packages, "-s") then
|
||||
source = table.remove(packages, table.find(packages, "-s") + 1)
|
||||
table.remove(packages, table.find(packages, "-s"))
|
||||
print("Using " .. source .. " as package source")
|
||||
elseif table.find(packages, "--source") then
|
||||
source = table.remove(packages, table.find(packages, "--source") + 1)
|
||||
table.remove(packages, table.find(packages, "--source"))
|
||||
print("Using " .. source .. " as package source")
|
||||
else
|
||||
print("Using main registry as package source")
|
||||
end
|
||||
if source and source:sub(1, 1) == "/" and source:sub(-1, -1) ~= "/" then
|
||||
source = source .. "/"
|
||||
end
|
||||
local packageList = table.copy(packages)
|
||||
|
||||
local function getFile(path)
|
||||
if path:sub(1,1) == "/" then
|
||||
if not fs.exists(path) then
|
||||
return false, "file does not exist"
|
||||
end
|
||||
local handle, data, tmpdata = fs.open(path, "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
return data
|
||||
else
|
||||
local request, data, tmpdata = nil, "", nil
|
||||
local status, errorMessage = pcall(function()
|
||||
request = internet.request(path)
|
||||
request:finishConnect()
|
||||
end)
|
||||
if not status then
|
||||
return false, errorMessage
|
||||
end
|
||||
local responseCode = request:response()
|
||||
if responseCode and responseCode ~= 200 then
|
||||
return false, responseCode
|
||||
end
|
||||
repeat
|
||||
tmpdata = request.read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
return data
|
||||
end
|
||||
end
|
||||
|
||||
local i = 1
|
||||
|
||||
local function getAgConfig(package, source)
|
||||
source = source or agReg[package]
|
||||
local data, errorMessage = getFile(source .. "argentum.cfg")
|
||||
if not data or data == "" then
|
||||
print("\27[91mCould not fetch Ag config: " .. (errorMessage or "returned nil data"))
|
||||
return false
|
||||
end
|
||||
local func, errorMessage = load(data, "=argentum.cfg", "bt", {})
|
||||
if not func then
|
||||
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
|
||||
return false
|
||||
end
|
||||
local agcfg
|
||||
local status, errorMessage = pcall(function()
|
||||
agcfg = func()
|
||||
end)
|
||||
if not status then
|
||||
print("\27[91mCould not fetch Ag config: " .. errorMessage .. "\nPlease contact the package owner.")
|
||||
return false
|
||||
end
|
||||
if not agcfg[package] or not agcfg[package].maindir or not agcfg[package].directories or not agcfg[package].files or not agcfg[package].version then
|
||||
local response = ("\27[91mAg config of " .. package .. " is improperly configured.\nPlease contact the package owner.")
|
||||
end
|
||||
return agcfg
|
||||
end
|
||||
|
||||
local function doChecks(package)
|
||||
if not agReg[package] and not source then
|
||||
print("\27[91mPackage " .. package .. " does not exist.")
|
||||
return false
|
||||
end
|
||||
if fs.exists("/argentum/store/" .. package) then
|
||||
print("\27[91mPackage " .. package .. " is already installed.")
|
||||
return false
|
||||
end
|
||||
agcfg = getAgConfig(package, source)
|
||||
if not agcfg then
|
||||
return false
|
||||
end
|
||||
if agcfg[package].dependencies then
|
||||
for _, dependency in ipairs(agcfg[package].dependencies) do
|
||||
if not agReg[dependency] and not agcfg[dependency] then
|
||||
local response = read(nil, "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]")
|
||||
if response:lower() ~= "s" then
|
||||
fs.remove("/argentum/store/" .. package)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, dependency in pairs(agcfg[package].dependencies) do
|
||||
print(package .. " depends on " .. dependency)
|
||||
if not table.find(packages, dependency) and doChecks(dependency) then
|
||||
table.insert(packages, table.find(packages, package), dependency)
|
||||
table.insert(packageList, dependency)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function installPackage(package)
|
||||
print("Installing " .. package .. "...")
|
||||
local agcfg = getAgConfig(package, source)
|
||||
if not agcfg then
|
||||
return false
|
||||
end
|
||||
local source = source or agReg[package]
|
||||
local packageStore = "V" .. agcfg[package].version
|
||||
if agcfg[package].dependencies then
|
||||
for _, dependency in ipairs(agcfg[package].dependencies) do
|
||||
if not agReg[dependency] and not agcfg[dependency] then
|
||||
local response = read(nil, "\27[91mPackage " .. package .. " requires dependency " .. dependency .. " that does not exist.\n[A - Abort/s - Skip]")
|
||||
if response:lower() ~= "s" then
|
||||
fs.remove("/argentum/store/" .. package)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, dependency in pairs(agcfg[package].dependencies) do
|
||||
if agReg[dependency] or agcfg[dependency] then
|
||||
--installPackage(dependency)
|
||||
packageStore = packageStore .. "\nD" .. dependency
|
||||
end
|
||||
end
|
||||
end
|
||||
if agcfg[package].directories then
|
||||
for _, directory in pairs(agcfg[package].directories) do
|
||||
if directory:sub(-1, -1) ~= "/" then
|
||||
directory = directory .. "/"
|
||||
end
|
||||
packageStore = "A" .. directory .. "\n" .. packageStore
|
||||
if not fs.exists(directory) then
|
||||
fs.makeDirectory(directory)
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, file in ipairs(agcfg[package].files) do
|
||||
::retry::
|
||||
print(" Downloading " .. file .. "...")
|
||||
local data, errorMessage = getFile(source .. agcfg[package].maindir .. file)
|
||||
if not data then
|
||||
local response = read(nil, "\27[91mCould not fetch " .. file .. ": " .. errorMessage .. "\n\27[0m[a - Abort/R - Retry/s - Skip]")
|
||||
if response:lower() == "a" then
|
||||
fs.remove("/argentum/store/" .. package)
|
||||
return false
|
||||
elseif response:lower() == "s" then
|
||||
goto skip
|
||||
else
|
||||
goto retry
|
||||
end
|
||||
end
|
||||
if fs.exists(file) then
|
||||
if not fs.exists("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)")) then
|
||||
fs.makeDirectory("/argentum/store/" .. package .. "/files/" .. file:match("(.*/)"))
|
||||
end
|
||||
fs.copy(file, "/argentum/store/" .. package .. "/files/" .. file)
|
||||
packageStore = packageStore .. "\nM" .. file
|
||||
else
|
||||
packageStore = packageStore .. "\nA" .. file
|
||||
end
|
||||
local handle = fs.open(file, "w")
|
||||
handle:write(data)
|
||||
handle:close()
|
||||
::skip::
|
||||
end
|
||||
fs.makeDirectory("/argentum/store/" .. package)
|
||||
local handle = fs.open("/argentum/store/" .. package .. "/package.cfg", "w")
|
||||
handle:write(packageStore)
|
||||
handle:close()
|
||||
return true
|
||||
end
|
||||
|
||||
local function removePackage(package)
|
||||
print("Removing " .. package .. "...")
|
||||
if not fs.exists("/argentum/store/" .. package .. "/package.cfg") then
|
||||
print("\27[91mLocal Ag config of " .. package .. " does not exist.")
|
||||
return false
|
||||
end
|
||||
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
for line in (data.."\n"):gmatch("(.-)\n") do
|
||||
if line:sub(1, 1) == "A" then
|
||||
::retry::
|
||||
print(" Removing " .. line:sub(2) .. "...")
|
||||
if line:sub(-1, -1) == "/" and fs.list(line:sub(2))[1] then
|
||||
print(" There are still files in " .. line:sub(2) .. ". Skipping.")
|
||||
else
|
||||
local result, errorMessage = fs.remove(line:sub(2))
|
||||
if not result then
|
||||
local response = read(nil, "\27[91mFailed to remove " .. line:sub(2) .. ": " .. errorMessage .. "\n\27[0m[a - Abort/r - Retry/S - Skip]")
|
||||
if response:lower() == "a" then
|
||||
return false
|
||||
elseif response:lower() == "r" then
|
||||
goto retry
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif line:sub(1, 1) == "M" then
|
||||
::retry::
|
||||
print(" Reverting " .. line:sub(2) .. "...")
|
||||
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/files/" .. line:sub(2), "r"), "", nil
|
||||
if not handle then
|
||||
local response = read(nil, "\27[91mFailed to revert " .. line:sub(2) .. ": " .. data .. "\n\27[0m[a - Abort/R - Retry/s - Skip]") -- this is pretty stupid but i think the error message would get pushed to data
|
||||
if response:lower() == "a" then
|
||||
return false
|
||||
elseif response:lower() == "s" then
|
||||
goto skip
|
||||
else
|
||||
goto retry
|
||||
end
|
||||
end
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
local handle = fs.open(line:sub(2), "w")
|
||||
handle:write(data)
|
||||
handle:close()
|
||||
::skip::
|
||||
end
|
||||
end
|
||||
fs.remove("/argentum/store/" .. package .. "/")
|
||||
return true
|
||||
end
|
||||
|
||||
-- Update registry
|
||||
local fails = {}
|
||||
if command == "install" then
|
||||
if not packages or not packages[1] then
|
||||
print("Please specify packages to install.")
|
||||
return
|
||||
end
|
||||
while true do
|
||||
if not doChecks(packages[i]) then
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
end
|
||||
i = i + 1
|
||||
if i > #packages then
|
||||
break
|
||||
end
|
||||
end
|
||||
local answer
|
||||
if #fails == 0 then
|
||||
print("Packages that will be installed: " .. table.concat(packageList, ", "))
|
||||
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
|
||||
return
|
||||
end
|
||||
elseif #packageList == 0 then
|
||||
print("None of the packages can be installed.")
|
||||
return
|
||||
else
|
||||
print("Some packages cannot be installed.")
|
||||
print("Packages that will be installed: " .. table.concat(packageList, ", "))
|
||||
print("Packages that cannot be installed: " .. table.concat(fails, ", "))
|
||||
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
|
||||
return
|
||||
end
|
||||
end
|
||||
for _, failedPackage in pairs(fails) do
|
||||
table.remove(packages, table.find(packages, failedPackage))
|
||||
end
|
||||
fails = {}
|
||||
for _, package in ipairs(packages) do
|
||||
if not installPackage(package) then
|
||||
table.insert(fails, package)
|
||||
table.remove(packageList, table.find(packageList, package))
|
||||
end
|
||||
end
|
||||
if #fails == 0 then
|
||||
print("Installation completed successfully.")
|
||||
print("Packages installed: " .. table.concat(packageList, ", "))
|
||||
elseif #packageList == 0 then
|
||||
print("All packages failed to install.")
|
||||
print("Packages that could not be installed: " .. table.concat(fails, ", "))
|
||||
else
|
||||
print("Some packages failed to install.")
|
||||
print("Packages installed: " .. table.concat(packageList, ", "))
|
||||
print("Packages that could not be installed: " .. table.concat(fails, ", "))
|
||||
end
|
||||
elseif command == "remove" then
|
||||
if not packages or not packages[1] then
|
||||
print("Please specify packages to remove.")
|
||||
return
|
||||
end
|
||||
while true do
|
||||
if not fs.exists("/argentum/store/" .. packages[i]) then
|
||||
print("\27[91mPackage " .. packages[i] .. " is not installed.")
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
i = i - 1
|
||||
elseif packages[i] == "halyde" then -- yes, this stuff is hard-coded.
|
||||
print("\27[91mFor obvious reasons, you can't uninstall Halyde.")
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
i = i - 1
|
||||
elseif packages[i] == "argentum" then
|
||||
print("\27[91mFor obvious reasons, you can't uninstall Argentum.")
|
||||
print("\27[91mFor obvious reasons, you can't uninstall Halyde.")
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
i = i - 1
|
||||
end
|
||||
i = i + 1
|
||||
if i > #packages then
|
||||
break
|
||||
end
|
||||
end
|
||||
-- do dependency checks
|
||||
local packagesInstalled = fs.list("/argentum/store")
|
||||
for _, currentPackage in pairs(packagesInstalled) do
|
||||
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
|
||||
local handle, data, tmpdata = fs.open("/argentum/store/" .. currentPackage .. "package.cfg", "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
for line in (data.."\n"):gmatch("(.-)\n") do
|
||||
for i = 1, #packages do
|
||||
if line == "D" .. packages[i] then
|
||||
print(packages[i] .. " depends on " .. currentPackage:sub(1, -2))
|
||||
if not table.find(packages, currentPackage:sub(1, -2)) then
|
||||
table.insert(packages, table.find(packages, packages[i]), currentPackage:sub(1, -2))
|
||||
table.insert(packageList, currentPackage:sub(1, -2))
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local answer
|
||||
if #fails == 0 then
|
||||
print("Packages that will be removed: " .. table.concat(packageList, ", "))
|
||||
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
|
||||
return
|
||||
end
|
||||
elseif #packageList == 0 then
|
||||
print("None of the packages can be removed.")
|
||||
return
|
||||
else
|
||||
print("Some packages cannot be removed.")
|
||||
print("Packages that will be removed: " .. table.concat(packageList, ", "))
|
||||
print("Packages that cannot be removed: " .. table.concat(fails, ", "))
|
||||
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
|
||||
return
|
||||
end
|
||||
end
|
||||
for _, failedPackage in pairs(fails) do
|
||||
table.remove(packages, table.find(packages, failedPackage))
|
||||
end
|
||||
fails = {}
|
||||
for _, package in ipairs(packages) do
|
||||
if not removePackage(package) then
|
||||
table.insert(fails, package)
|
||||
table.remove(packageList, table.find(packageList, package))
|
||||
end
|
||||
end
|
||||
if #fails == 0 then
|
||||
print("Removal completed successfully.")
|
||||
print("Packages removed: " .. table.concat(packageList, ", "))
|
||||
elseif #packageList == 0 then
|
||||
print("All packages failed to be removed.")
|
||||
print("Packages that could not be removed: " .. table.concat(fails, ", "))
|
||||
else
|
||||
print("Some packages failed to be removed.")
|
||||
print("Packages removed: " .. table.concat(packageList, ", "))
|
||||
print("Packages that could not be removed: " .. table.concat(fails, ", "))
|
||||
end
|
||||
elseif command == "update" then
|
||||
if not packages[1] then
|
||||
local packagesInstalled = fs.list("/argentum/store/")
|
||||
for _, currentPackage in pairs(packagesInstalled) do
|
||||
if currentPackage:sub(-1, -1) == "/" and fs.exists("/argentum/store/" .. currentPackage .. "package.cfg") then
|
||||
table.insert(packages, currentPackage:sub(1, -2))
|
||||
table.insert(packageList, currentPackage:sub(1, -2))
|
||||
end
|
||||
end
|
||||
end
|
||||
while true do
|
||||
if not fs.exists("/argentum/store/" .. packages[i]) then
|
||||
print("\27[91mPackage " .. packages[i] .. " is not installed.")
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
i = i - 1
|
||||
end
|
||||
i = i + 1
|
||||
if i > #packages then
|
||||
break
|
||||
end
|
||||
end
|
||||
local answer
|
||||
if #fails == 0 then
|
||||
print("Packages that will be updated: " .. table.concat(packageList, ", "))
|
||||
if read(nil, "Would you like to proceed? [Y/n] "):lower() == "n" then
|
||||
return
|
||||
end
|
||||
elseif #packageList == 0 then
|
||||
print("None of the packages can be updated.")
|
||||
return
|
||||
else
|
||||
print("Some packages cannot be updated.")
|
||||
print("Packages that will be updated: " .. table.concat(packageList, ", "))
|
||||
print("Packages that cannot be updated: " .. table.concat(fails, ", "))
|
||||
if read(nil, "Would you like to proceed? [y/N] "):lower() ~= "y" then
|
||||
return
|
||||
end
|
||||
end
|
||||
for _, failedPackage in pairs(fails) do
|
||||
table.remove(packages, table.find(packages, failedPackage))
|
||||
end
|
||||
fails = {}
|
||||
for _, package in pairs(packages) do
|
||||
local agcfg = getAgConfig(package, source)
|
||||
if not agcfg then
|
||||
return false
|
||||
end
|
||||
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
local version = "0.0.0"
|
||||
for line in (data.."\n"):gmatch("(.-)\n") do
|
||||
if line:sub(1, 1) == "V" then
|
||||
version = line:sub(2)
|
||||
break
|
||||
end
|
||||
end
|
||||
local handle, data, tmpdata = fs.open("/argentum/store/" .. package .. "/package.cfg", "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
local version = "0.0.0"
|
||||
for line in (data.."\n"):gmatch("(.-)\n") do
|
||||
if line:sub(1, 1) == "V" then
|
||||
version = line:sub(2)
|
||||
break
|
||||
end
|
||||
end
|
||||
if agcfg[package].version == version then
|
||||
print(package .. " is up to date")
|
||||
goto skip
|
||||
end
|
||||
if not removePackage(package) then
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
goto skip
|
||||
end
|
||||
if not installPackage(package) then
|
||||
table.insert(fails, packages[i])
|
||||
table.remove(packageList, table.find(packageList, packages[i]))
|
||||
table.remove(packages, table.find(packages, packages[i]))
|
||||
goto skip
|
||||
end
|
||||
::skip::
|
||||
end
|
||||
if #fails == 0 then
|
||||
print("Update completed successfully.")
|
||||
print("Packages updated: " .. table.concat(packageList, ", "))
|
||||
elseif #packageList == 0 then
|
||||
print("All packages failed to update.")
|
||||
print("Packages that could not update: " .. table.concat(fails, ", "))
|
||||
else
|
||||
print("Some packages failed to update.")
|
||||
print("Packages updated: " .. table.concat(packageList, ", "))
|
||||
print("Packages that could not update: " .. table.concat(fails, ", "))
|
||||
end
|
||||
elseif command == "info" then
|
||||
if not packages[1] then
|
||||
print("Please specify a package to show information about.")
|
||||
return
|
||||
end
|
||||
if not agReg[packages[1]] and not source then
|
||||
print("\27[91mPackage " .. packages[1] .. " does not exist.")
|
||||
return
|
||||
end
|
||||
local agcfg = getAgConfig(packages[1], source)
|
||||
if not agcfg then
|
||||
return false
|
||||
end
|
||||
print("\27[93m" .. packages[1] .. "\27[0m v" .. agcfg[packages[1]].version .. "\n " .. (agcfg[packages[1]].description or "No description."):gsub("\n", " \n"))
|
||||
elseif command == "search" then
|
||||
if not packages[1] then
|
||||
print("Please specify a search term.")
|
||||
return
|
||||
end
|
||||
local searchResults = {}
|
||||
for packageName, _ in pairs(agReg) do
|
||||
if packageName:find(packages[1], 1, true) then
|
||||
table.insert(searchResults, packageName)
|
||||
end
|
||||
end
|
||||
if not searchResults[1] then
|
||||
print("No search results found for " .. packages[1] .. ".")
|
||||
return
|
||||
end
|
||||
table.sort(searchResults)
|
||||
print("Search results: \n " .. table.concat(searchResults, "\n "))
|
||||
elseif command == "list" then
|
||||
local sortedPackages = {}
|
||||
for packageName, _ in pairs(agReg) do
|
||||
table.insert(sortedPackages, packageName)
|
||||
end
|
||||
table.sort(sortedPackages)
|
||||
print("List of available Ag packages: \n " .. table.concat(sortedPackages, "\n "))
|
||||
else
|
||||
shell.run("help ag")
|
||||
end
|
||||
@@ -183,7 +183,7 @@ local function processEvent(args)
|
||||
changesMade = true
|
||||
cursorRenderFlag = true
|
||||
cursorWhite = true
|
||||
if cursorPosY + scrollPosY - 1 > 1 then
|
||||
if cursorPosX == 1 and cursorPosY + scrollPosY - 1 > 1 then
|
||||
cursorPosY = cursorPosY - 1
|
||||
if cursorPosY < 1 then
|
||||
scrollPosY = scrollPosY - 1
|
||||
@@ -256,7 +256,11 @@ local function save()
|
||||
end
|
||||
local handle, errorMessage = fs.open(savepath, "w")
|
||||
if handle then
|
||||
handle:write(table.concat(tmpdata, "\n"))
|
||||
if table.concat(tmpdata, "\n"):sub(-1, -1) == "\n" then
|
||||
handle:write(table.concat(tmpdata, "\n"))
|
||||
else
|
||||
handle:write(table.concat(tmpdata, "\n") .. "\n") -- add a newline at the end to follow POSIX standards
|
||||
end
|
||||
handle:close()
|
||||
rawset(1, height - 1, "\27[107m\27[30m" .. filestring .. string.rep(" ", width))
|
||||
else
|
||||
|
||||
@@ -14,7 +14,7 @@ print("\27[92mComponents\27[0m: "..tostring(componentCounter))
|
||||
termlib.cursorPosX = 17
|
||||
print("\27[92mCoroutines\27[0m: "..tostring(#cormgr.corList))
|
||||
termlib.cursorPosX = 17
|
||||
print("\27[92mBattery\27[0m: "..tostring(math.floor(computer.maxEnergy() / computer.energy() * 1000 + 0.5) / 10).."%")
|
||||
print("\27[92mBattery\27[0m: "..tostring(math.floor(computer.energy() / computer.maxEnergy() * 1000 + 0.5) / 10).."%")
|
||||
termlib.cursorPosX = 17
|
||||
local totalMemory = computer.totalMemory()
|
||||
local usedMemory = computer.totalMemory() - computer.freeMemory()
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
Usage: argentum [COMMAND] [PACKAGES]
|
||||
Uses the Argentum package manager.
|
||||
|
||||
COMMAND Specifies the operation for Ag to do.
|
||||
install Installs packages.
|
||||
remove Removes packages.
|
||||
update Updates packages.
|
||||
list Lists all available packages.
|
||||
search Searches all available packages.
|
||||
info Shows information on a specific package.
|
||||
PACKAGES* Packages to apply operations to.
|
||||
|
||||
Examples:
|
||||
ag install hal-draw Installs the hal-draw package.
|
||||
ag list Lists all packages.
|
||||
ag info hal-draw Shows information about hal-draw.
|
||||
ag update hal-draw Updates the hal-draw package if it's not at the newest version.
|
||||
ag update Updates all packages.
|
||||
@@ -1,16 +1,17 @@
|
||||
All current Halyde shell commands:
|
||||
cat Concatenates and prints a file.
|
||||
cd Changes directory.
|
||||
clear Clears the screen.
|
||||
cp Copies a file.
|
||||
echo Prints a message.
|
||||
fetch Displays system information.
|
||||
help Shows this.
|
||||
ls Lists files.
|
||||
lua Starts the Lua shell.
|
||||
mv Moves/renames a file.
|
||||
rm Deletes a file.
|
||||
edit Opens the text editor.
|
||||
All default Halyde shell commands:
|
||||
cat Concatenates and prints a file.
|
||||
cd Changes directory.
|
||||
clear Clears the screen.
|
||||
cp Copies a file.
|
||||
echo Prints a message.
|
||||
fetch Displays system information.
|
||||
help Shows this.
|
||||
ls Lists files.
|
||||
lua Starts the Lua shell.
|
||||
mv Moves/renames a file.
|
||||
rm Deletes a file.
|
||||
edit Opens the text editor.
|
||||
argentum Uses the Argentum package manager.
|
||||
|
||||
You can get additional information on any app or command by running:
|
||||
help [COMMAND]
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Usage: mkdir [PATH]
|
||||
Removes files and directories.
|
||||
|
||||
PATH Specifies the path to create the directory in.
|
||||
|
||||
Examples:
|
||||
mkdir a Creates a directory named a in the current shell working directory.
|
||||
@@ -1,10 +1,7 @@
|
||||
Usage: rm [FLAGS] [PATH]
|
||||
Usage: rm [PATH]
|
||||
Removes files and directories.
|
||||
|
||||
-r, --recursive Removes directories and their contents recursively.
|
||||
-f, --force Ignores nonexistent files or directories.
|
||||
PATH Specifies the file to be moved/renamed.
|
||||
PATH Specifies the file to be moved/renamed.
|
||||
|
||||
Examples:
|
||||
rm a.txt Removes a.txt in the current shell working directory.
|
||||
rm -r -f /halyde/core/ Removes everything in /halyde/core/ forcedly and recursively.
|
||||
rm a.txt Removes a.txt in the current shell working directory.
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
local args = {...}
|
||||
local directory = args[1]
|
||||
args = nil
|
||||
local fs = import("filesystem")
|
||||
|
||||
if not directory then
|
||||
shell.run("help mkdir")
|
||||
return
|
||||
end
|
||||
if directory:sub(1, 1) ~= "/" then
|
||||
directory = shell.workingDirectory .. directory
|
||||
end
|
||||
if fs.exists(file) then
|
||||
print("\27[91mAn object already exists at the specified path.")
|
||||
end
|
||||
fs.makeDirectory(file)
|
||||
+24
-4
@@ -1,6 +1,6 @@
|
||||
local shellcfg = {
|
||||
["startupMessage"] = "\n │\n │ ".._OSVERSION..'\n │ Welcome! Type "help" to get started.\n │\n ', -- message shown on startup
|
||||
["prompt"] = "\x1b[92m%s > \x1b[0m", -- shell prompt, %s will be replaced with working directory. example: "%s > " turns to "/current/working/directory > "
|
||||
["startupMessage"] = "\n │\n │ ".._OSVERSION..'\n │ %s\n │\n ', -- message shown on startup. %s will be replaced with splash message.
|
||||
["prompt"] = "\x1b[92m%s > \x1b[0m", -- shell prompt. %s will be replaced with working directory.
|
||||
["path"] = { -- default locations where programs will be run from
|
||||
"/halyde/apps/"
|
||||
}, ["aliases"] = { -- shell command aliases
|
||||
@@ -14,8 +14,28 @@ local shellcfg = {
|
||||
["del"] = "rm",
|
||||
["delete"] = "rm",
|
||||
["remove"] = "rm",
|
||||
[".."] = "cd .."
|
||||
}, ["defaultWorkingDirectory"] = "/home/" -- the working directory that gets set when halyde starts
|
||||
[".."] = "cd ..",
|
||||
["wget"] = "download",
|
||||
["ag"] = "argentum"
|
||||
}, ["defaultWorkingDirectory"] = "/home/", -- the working directory that gets set when halyde starts
|
||||
["splashMessages"] = { -- messages shown on startup
|
||||
"Made by John Haly- I mean Cerulean Blue.",
|
||||
'Welcome! Type "help" to get started.',
|
||||
"Also try KOCOS!",
|
||||
"Welcome back, Commander. We have no idea what we're doing.",
|
||||
"99.9% bug-free. The remaining 0.1% are features.",
|
||||
"0 days since last error.",
|
||||
"Everything is fine. The fire is decorative.",
|
||||
"Please don't feed the background processes.",
|
||||
"Also has fetch!",
|
||||
"Anything red is no man's land. Trust me.",
|
||||
"Machine...",
|
||||
"Abort, Retry, Fail?",
|
||||
"What's the deal with /argentum/store?",
|
||||
"So cutting-edge you can't hold it in your hand.",
|
||||
"Americans are the reason you see colors on-screen. I'm talking about ANSI escape codes, not politics.",
|
||||
"Shoutout to Ponali!"
|
||||
}
|
||||
}
|
||||
|
||||
return shellcfg
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local loadfile = ...
|
||||
local filesystem = loadfile("/halyde/lib/filesystem.lua")(loadfile)
|
||||
|
||||
_G._OSVERSION = "Halyde 0.10.1"
|
||||
_G._OSVERSION = "Halyde 1.0.0"
|
||||
|
||||
function _G.import(module, ...)
|
||||
local args = table.pack(...)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local shellcfg = import("/halyde/config/shell.cfg")
|
||||
import("/halyde/core/termlib.lua")
|
||||
local event = import("event")
|
||||
--local ocelot = component.proxy(component.list("ocelot")())
|
||||
local ocelot = component.proxy(component.list("ocelot")())
|
||||
local filesystem = import("filesystem")
|
||||
local gpu = component.proxy(component.list("gpu")())
|
||||
|
||||
@@ -55,14 +55,14 @@ function _G.shell.run(command)
|
||||
if not args[1] then
|
||||
return
|
||||
end
|
||||
if filesystem.exists(args[1]) then
|
||||
if filesystem.exists(args[1]) and not filesystem.isDirectory(args[1]) then
|
||||
foundfile = true
|
||||
local path = args[1]
|
||||
table.remove(args, 1)
|
||||
runAsCoroutine(path, table.unpack(args))
|
||||
else
|
||||
for _, item in pairs(shellcfg["path"]) do
|
||||
if filesystem.exists(item..args[1]) then
|
||||
if filesystem.exists(item..args[1]) and not filesystem.isDirectory(item .. args[1]) then
|
||||
foundfile = true
|
||||
local path = item..args[1]
|
||||
table.remove(args, 1)
|
||||
@@ -71,10 +71,10 @@ function _G.shell.run(command)
|
||||
else -- try to look for it without the file extension
|
||||
local files = filesystem.list(item)
|
||||
for _, file in pairs(files) do
|
||||
if args[1] == file:match("(.+)%.[^%.]+$") then
|
||||
if args[1] == file:match("(.+)%.[^%.]+$") and not filesystem.isDirectory(item .. file) then
|
||||
foundfile = true
|
||||
table.remove(args, 1)
|
||||
runAsCoroutine(item..file, table.unpack(args))
|
||||
runAsCoroutine(item .. file, table.unpack(args))
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -86,14 +86,14 @@ function _G.shell.run(command)
|
||||
end
|
||||
end
|
||||
|
||||
print(shellcfg["startupMessage"])
|
||||
print(shellcfg["startupMessage"]:format(shellcfg.splashMessages[math.random(1, #shellcfg.splashMessages)]))
|
||||
while true do
|
||||
coroutine.yield()
|
||||
-- print(shell.workingDirectory .. " >")
|
||||
--print(shellcfg["prompt"]:format(shell.workingDirectory),false)
|
||||
-- termlib.cursorPosX = #(shell.workingDirectory .. " > ")
|
||||
-- termlib.cursorPosY = termlib.cursorPosY - 1
|
||||
local shellCommand = read("shell", shellcfg["prompt"]:format(shell.workingDirectory))
|
||||
local shellCommand = read("shell", shellcfg.prompt:format(shell.workingDirectory))
|
||||
shell.run(shellCommand)
|
||||
gpu.freeAllBuffers()
|
||||
end
|
||||
|
||||
+16
-8
@@ -70,20 +70,23 @@ local function parseCodeNumbers(code)
|
||||
return o
|
||||
end
|
||||
|
||||
function _G.print(text, endNewLine, wordWrap)
|
||||
function _G.print(text, endNewLine, textWrap)
|
||||
|
||||
-- you don't know how tiring this was just for ANSI escape code support
|
||||
|
||||
if endNewLine == nil then
|
||||
endNewLine = true
|
||||
end
|
||||
if wordWrap == nil then
|
||||
wordWrap = true
|
||||
if textWrap == nil then
|
||||
textWrap = true
|
||||
end
|
||||
|
||||
if not text or not tostring(text) then
|
||||
return
|
||||
end
|
||||
if text:find("\a") then
|
||||
computer.beep()
|
||||
end
|
||||
text = "\27[0m" .. text:gsub("\t", " ")
|
||||
text = tostring(text)
|
||||
readBreak = 0
|
||||
@@ -95,12 +98,17 @@ function _G.print(text, endNewLine, wordWrap)
|
||||
if #section==0 then
|
||||
return
|
||||
end
|
||||
gpu.set(termlib.cursorPosX,termlib.cursorPosY,section)
|
||||
termlib.cursorPosX = termlib.cursorPosX+unicode.wlen(section)
|
||||
if termlib.cursorPosX>width and wordWrap then
|
||||
newLine()
|
||||
while true do
|
||||
gpu.set(termlib.cursorPosX,termlib.cursorPosY,section)
|
||||
termlib.cursorPosX = termlib.cursorPosX+unicode.wlen(section)
|
||||
if unicode.wlen(section) > width and textWrap then
|
||||
newLine()
|
||||
else
|
||||
break
|
||||
end
|
||||
section = section:sub(width + 1)
|
||||
end
|
||||
section=""
|
||||
section = ""
|
||||
end
|
||||
|
||||
for i=1,#text do
|
||||
|
||||
@@ -170,4 +170,13 @@ function filesystem.remove(path)
|
||||
return component.invoke(address, "remove", absPath)
|
||||
end
|
||||
|
||||
function filesystem.makeDirectory(path)
|
||||
checkArg(1, path, "string")
|
||||
local address, absPath = filesystem.processPath(path)
|
||||
if not address then
|
||||
return false
|
||||
end
|
||||
return component.invoke(address, "makeDirectory", absPath)
|
||||
end
|
||||
|
||||
return(filesystem)
|
||||
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
local component = require("component")
|
||||
if not component.isAvailable("internet") then
|
||||
io.stderr.write("This program requires an internet card to run.")
|
||||
return
|
||||
end
|
||||
local internet = component.internet
|
||||
local computer = require("computer")
|
||||
local fs = require("filesystem")
|
||||
local installLocation
|
||||
local drives = {}
|
||||
for drive in fs.list("/mnt/") do
|
||||
table.insert(drives, drive)
|
||||
end
|
||||
if #drives == 1 and not component.invoke(component.get(drives[1]:sub(1, 3), "filesystem"), "isReadOnly") then
|
||||
installLocation = drives[1]
|
||||
elseif #drives == 1 then
|
||||
io.stderr.write("All drives are read-only.\nHalyde cannot be installed.")
|
||||
else
|
||||
local installDrivesText = "Possible drives to install to:"
|
||||
for i = 1, #drives do
|
||||
local address = component.get(drives[i]:sub(1, 3), "filesystem")
|
||||
local fsComponent = component.proxy(address)
|
||||
if not fsComponent.isReadOnly() then
|
||||
local label = fsComponent.getLabel()
|
||||
if label then
|
||||
installDrivesText = installDrivesText .. "\n " .. tostring(i) .. ". - " .. label .. "(" .. address:sub(1, 5) .. "...)"
|
||||
else
|
||||
installDrivesText = installDrivesText .. "\n " .. tostring(i) .. ". - " .. address:sub(1, 5) .. "..."
|
||||
end
|
||||
end
|
||||
end
|
||||
io.write(installDrivesText .. "\nPlease select a drive by entering its number or \"q\" to quit. ")
|
||||
local answer
|
||||
while true do
|
||||
answer = io.read()
|
||||
if tonumber(answer) and tonumber(answer) >= 1 and tonumber(answer) <= #drives then
|
||||
break
|
||||
elseif answer == "q" then
|
||||
return
|
||||
else
|
||||
print("Answer invalid, try again.")
|
||||
end
|
||||
end
|
||||
installLocation = "/mnt/" .. drives[tonumber(answer)]
|
||||
end
|
||||
if not installLocation then
|
||||
print("All drives are read-only.\nHalyde cannot be installed.")
|
||||
return
|
||||
end
|
||||
io.write("Are you sure you would like to install Halyde to " .. installLocation .. "? This will erase all data on this disk. [Y/n] ")
|
||||
if io.read():lower() == "n" then
|
||||
return
|
||||
end
|
||||
|
||||
-- installation
|
||||
local computer = require("computer")
|
||||
local oldFiles = {}
|
||||
for oldFile in fs.list(installLocation) do
|
||||
if oldFile ~= "home/" then
|
||||
table.insert(oldFiles, oldFile)
|
||||
end
|
||||
end
|
||||
local function getFile(url)
|
||||
local request, data, tmpdata = nil, "", nil
|
||||
local status, errorMessage = pcall(function()
|
||||
request = internet.request(url)
|
||||
request:finishConnect()
|
||||
end)
|
||||
if not status then
|
||||
return false, errorMessage
|
||||
end
|
||||
local responseCode = request:response()
|
||||
if responseCode and responseCode ~= 200 then
|
||||
return false, responseCode
|
||||
end
|
||||
repeat
|
||||
tmpdata = request.read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
return data
|
||||
end
|
||||
|
||||
local function getFile(path)
|
||||
if path:sub(1,1) == "/" then
|
||||
if not fs.exists(path) then
|
||||
return false, "file does not exist"
|
||||
end
|
||||
local handle, data, tmpdata = fs.open(path, "r"), "", nil
|
||||
repeat
|
||||
tmpdata = handle:read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
handle:close()
|
||||
return data
|
||||
else
|
||||
local request, data, tmpdata = nil, "", nil
|
||||
local status, errorMessage = pcall(function()
|
||||
request = internet.request(path)
|
||||
request:finishConnect()
|
||||
end)
|
||||
if not status then
|
||||
return false, errorMessage
|
||||
end
|
||||
local responseCode = request:response()
|
||||
if responseCode and responseCode ~= 200 then
|
||||
return false, responseCode
|
||||
end
|
||||
repeat
|
||||
tmpdata = request.read(math.huge)
|
||||
data = data .. (tmpdata or "")
|
||||
until not tmpdata
|
||||
return data
|
||||
end
|
||||
end
|
||||
print("a")
|
||||
local webInstallConfig = getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/argentum.cfg")
|
||||
print("a")
|
||||
webInstallConfig = load(webInstallConfig)
|
||||
print("a")
|
||||
webInstallConfig = webInstallConfig()
|
||||
print("a")
|
||||
installationOrder = {"halyde", "edit", "argentum"}
|
||||
for i = 1, 3 do
|
||||
local webInstallConfig = webInstallConfig[installationOrder[i]]
|
||||
print("a")
|
||||
if webInstallConfig.directories then
|
||||
for _, directory in pairs(webInstallConfig.directories) do
|
||||
print("Creating " .. directory .. "...")
|
||||
fs.makeDirectory(installLocation .. directory)
|
||||
end
|
||||
end
|
||||
for _, file in pairs(webInstallConfig.files) do
|
||||
print("Downloading " .. file .. "...")
|
||||
local handle = fs.open(installLocation .. file, "w")
|
||||
handle:write(getFile("https://raw.githubusercontent.com/Team-Cerulean-Blue/Halyde/refs/heads/main/" .. file))
|
||||
handle:close()
|
||||
end
|
||||
end
|
||||
computer.shutdown(true)
|
||||
Reference in New Issue
Block a user